Skip to content

レビュー要判断リストの実施(FFI再設計 / 学習有効化 / モデルDL堅牢化 / CIキャッシュ修正)#4

Merged
unok merged 2 commits into
chore/upstream-divergence-cleanupfrom
fix/review-followups
Jun 12, 2026
Merged

レビュー要判断リストの実施(FFI再設計 / 学習有効化 / モデルDL堅牢化 / CIキャッシュ修正)#4
unok merged 2 commits into
chore/upstream-divergence-cleanupfrom
fix/review-followups

Conversation

@unok

@unok unok commented Jun 12, 2026

Copy link
Copy Markdown
Owner

概要

PR #3 の「要判断リスト」を実施するスタックPR。Swift FFI の構造問題3点をまとめて解消し、学習機能を有効化、モデルダウンロードを改竄耐性ありに強化した。

変更内容

🏗 Swift FFI 再設計(要判断 #1: 構造問題3点の解消)

  • 内部ロック導入: 全エクスポート関数を NSLock で排他(const な Convert が複数スレッドから呼ばれても状態が混線しない)
  • ConvertText(key, allowLearning) → JSON 単発APIを新設: Mozc の Convert() は従来の ClearText→AppendText→GetCandidates 3呼び出しをやめてこれのみ使用(呼び出し間の割り込み余地を根本排除)
  • Initialize が成功/失敗を返す: 辞書パス不正等が C++ 側 initialized_ に反映され、NoOp フォールバックが正しく働く(従来は「無言で候補が出ないIME」になっていた)
  • 参照カウント化: Engine::ReloadModules で新旧コンバータが交差しても、旧側の Shutdown が新側のエンジン状態を壊さない
  • TextReplacer(絵文字辞書ロード)をキャッシュ化(変換毎の再生成をやめる)

📖 ユーザー学習の有効化(要判断 #4 — 確認済み: 有効化)

  • GetAzooKeyMemoryPath() 新設: %APPDATA%\Mozc\azookey_memory を作成して配線
  • シークレットモード(enable_user_history_for_conversion=false)のリクエストは学習しない
  • 学習ディレクトリが作成できない場合は学習なしで安全に続行

🔒 モデルDLの堅牢化(要判断 #2

  • URL を コミット固定ddf6e44b…)に変更し、SHA256 照合(CNG/BCrypt、ストリーミング計算)を追加
  • 期待値: 4de930c0…f6c / 73,871,968 bytes(HF API から取得した現行 main の値)
  • SYSTEM 権限での DL → Program Files 書き込みに対する差し替え・改竄・切り詰め耐性

⚙️ CI の Bazel キャッシュ修正(要判断 #3

  • 実効性のなかった ~/.cache/bazel キャッシュを廃止し、--repository_cache を ワークスペース配下の明示パスに固定してキャッシュ(bazelisk は ~/AppData/Local/bazelisk

🔡 細部(要判断 #5 の一部)

  • C++ JSON パーサに \uXXXX の正式デコードを実装(サロゲートペア対応。従来は文字が無言で欠落)
  • correspondingCount<=0 の候補を「完全一致扱い」せず除外(契約: rubyCount は必ず1以上)
  • docs/architecture.md を新 FFI 契約(単発API・ロック・学習)に更新

検証

  • swift build -c release(新ロック・ConvertText 込み)
  • bazelisk build //win32/installer:installer_x64 → MSI 生成成功(mozc submodule 43d858b5a
  • ⚠️ 実機での変換動作確認を推奨(FFI 契約変更のため、インストールして入力テストしてください。学習は %APPDATA%\Mozc\azookey_memory にファイルが生成されることで確認可能)

対象外(継続課題)

  • インストール先カスタマイズとモデルパス解決の不一致(レジストリ設計が必要)
  • GetZenzaiStatus の "active" がファイル存在チェックのみ(実ロード成否の反映)

🤖 Generated with Claude Code

- Swift FFI 再設計: 全エクスポートを内部ロックで排他、ConvertText 単発API新設、
  Initialize を成功/失敗返却 + 参照カウント化、TextReplacer をキャッシュ
- ユーザー学習を有効化 (memory_path 配線、シークレットモードで抑止)
- モデルDL: URLコミット固定 + SHA256照合 (mozc submodule 43d858b5a)
- JSON \uXXXX デコード実装、correspondingCount<=0 の契約明確化
- CI: 実効性のなかった ~/.cache/bazel キャッシュを --repository_cache
  明示パス方式に修正
- docs/architecture.md を新FFI契約に更新

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 12, 2026 11:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the “review decision list” items from PR #3 by redesigning the Swift FFI surface to be thread-safe and single-call for conversion, enabling user learning via a persisted memory path, hardening model download integrity, and fixing ineffective CI Bazel caching on Windows.

Changes:

  • Refactors Swift FFI to use an internal lock, adds ConvertText(key, allowLearning) -> JSON, and changes Initialize to return success/failure with reference counting semantics.
  • Updates architecture documentation to reflect the new FFI contract (single-shot conversion API, locking, and learning behavior).
  • Adjusts the Windows CI workflow to use an explicit Bazel --repository_cache and cache Bazelisk’s download cache.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/swift-engine/Sources/azookey-engine/AzookeyEngine.swift Introduces locked, reference-counted global engine state; adds one-shot ConvertText; changes Initialize return type/behavior.
docs/architecture.md Documents the new FFI API contract (locking, ConvertText, learning semantics).
.github/workflows/build-x64.yml Fixes Bazel cache effectiveness by caching a fixed --repository_cache directory and Bazelisk cache.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +114 to +121
/// Initialize the engine. Returns 1 on success, 0 on failure.
/// 参照カウント方式: Mozc 側はコンバータインスタンスごとに Initialize/Shutdown を
/// 呼ぶが、エンジン状態はプロセスグローバル単一のため、Engine::ReloadModules で
/// 新旧インスタンスが入れ替わる際に旧側の Shutdown が新側を壊さないようにする。
@_silgen_name("Initialize")
public func initialize(_ dictionaryPath: UnsafePointer<CChar>?, _ memoryPath: UnsafePointer<CChar>?) -> Int32 {
engineLock.lock()
defer { engineLock.unlock() }

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot 修正済みです(5caf44f37): zenzai_test.cpp の typedef を int 戻り値に更新し、Initialize 失敗時は ABORT するようにしました。mozc 側のローダーは前コミットで更新済みです。確認をお願いします。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5caf44f で確認しました。tests/zenzai_test.cppInitializeint 戻り値で受けるよう更新されており、初期化失敗時に ABORT する形になっています。追加対応は不要です。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確認しました。tests/zenzai_test.cppInitialize 関数ポインタ型は戻り値ありに揃っており、失敗時ABORTの分岐も入っていて問題ありません。追加対応は不要です。

Comment on lines +123 to +128
if let dictPath = dictionaryPath {
config.dictionaryPath = String(cString: dictPath)
}
if let memPath = memoryPath {
config.memoryPath = String(cString: memPath)
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot 修正済みです(5caf44f37): converter 初期化済みの場合は設定の上書き・検証を行わず、参照カウントのみ増やして成功を返すようにしました。確認をお願いします。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5caf44f で確認しました。converter != nil の場合は設定更新や検証を行わず参照カウントだけ増やして成功を返すようになっているので、この指摘点は解消されています。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確認しました。converter != nil 時に設定上書き・検証をスキップして参照カウントのみ増やす挙動になっており、指摘されていた多重Initialize時の不安定化は解消されています。追加対応は不要です。

- zenzai_test.cpp: InitializeFunc の typedef を int 戻り値の新契約に更新し、
  失敗時は ABORT するように変更
- AzookeyEngine.swift: 初期化済みの場合は設定の上書き・検証をせず
  参照カウントのみ増やして成功を返す (多重 Initialize で正常稼働中の
  エンジンが誤って失敗扱いになる問題を解消)
- tests/ のビルド成果物・ログ (.obj, stdout/stderr/result) を追跡から除外し
  .gitignore に追加

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot finished work on behalf of unok June 12, 2026 15:06
Copilot finished work on behalf of unok June 12, 2026 15:06
@unok unok merged commit fc1915c into chore/upstream-divergence-cleanup Jun 12, 2026
2 checks passed
@unok unok deleted the fix/review-followups branch June 12, 2026 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants