レビュー要判断リストの実施(FFI再設計 / 学習有効化 / モデルDL堅牢化 / CIキャッシュ修正)#4
Conversation
- 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>
There was a problem hiding this comment.
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 changesInitializeto 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_cacheand 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.
| /// 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() } |
There was a problem hiding this comment.
@copilot 修正済みです(5caf44f37): zenzai_test.cpp の typedef を int 戻り値に更新し、Initialize 失敗時は ABORT するようにしました。mozc 側のローダーは前コミットで更新済みです。確認をお願いします。
There was a problem hiding this comment.
5caf44f で確認しました。tests/zenzai_test.cpp は Initialize を int 戻り値で受けるよう更新されており、初期化失敗時に ABORT する形になっています。追加対応は不要です。
There was a problem hiding this comment.
確認しました。tests/zenzai_test.cpp の Initialize 関数ポインタ型は戻り値ありに揃っており、失敗時ABORTの分岐も入っていて問題ありません。追加対応は不要です。
| if let dictPath = dictionaryPath { | ||
| config.dictionaryPath = String(cString: dictPath) | ||
| } | ||
| if let memPath = memoryPath { | ||
| config.memoryPath = String(cString: memPath) | ||
| } |
There was a problem hiding this comment.
@copilot 修正済みです(5caf44f37): converter 初期化済みの場合は設定の上書き・検証を行わず、参照カウントのみ増やして成功を返すようにしました。確認をお願いします。
There was a problem hiding this comment.
5caf44f で確認しました。converter != nil の場合は設定更新や検証を行わず参照カウントだけ増やして成功を返すようになっているので、この指摘点は解消されています。
There was a problem hiding this comment.
確認しました。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>
概要
PR #3 の「要判断リスト」を実施するスタックPR。Swift FFI の構造問題3点をまとめて解消し、学習機能を有効化、モデルダウンロードを改竄耐性ありに強化した。
変更内容
🏗 Swift FFI 再設計(要判断 #1: 構造問題3点の解消)
NSLockで排他(const なConvertが複数スレッドから呼ばれても状態が混線しない)ConvertText(key, allowLearning) → JSON単発APIを新設: Mozc のConvert()は従来のClearText→AppendText→GetCandidates3呼び出しをやめてこれのみ使用(呼び出し間の割り込み余地を根本排除)Initializeが成功/失敗を返す: 辞書パス不正等が C++ 側initialized_に反映され、NoOp フォールバックが正しく働く(従来は「無言で候補が出ないIME」になっていた)Engine::ReloadModulesで新旧コンバータが交差しても、旧側のShutdownが新側のエンジン状態を壊さない📖 ユーザー学習の有効化(要判断 #4 — 確認済み: 有効化)
GetAzooKeyMemoryPath()新設:%APPDATA%\Mozc\azookey_memoryを作成して配線enable_user_history_for_conversion=false)のリクエストは学習しない🔒 モデルDLの堅牢化(要判断 #2)
ddf6e44b…)に変更し、SHA256 照合(CNG/BCrypt、ストリーミング計算)を追加4de930c0…f6c/ 73,871,968 bytes(HF API から取得した現行 main の値)⚙️ CI の Bazel キャッシュ修正(要判断 #3)
~/.cache/bazelキャッシュを廃止し、--repository_cacheを ワークスペース配下の明示パスに固定してキャッシュ(bazelisk は~/AppData/Local/bazelisk)🔡 細部(要判断 #5 の一部)
\uXXXXの正式デコードを実装(サロゲートペア対応。従来は文字が無言で欠落)correspondingCount<=0の候補を「完全一致扱い」せず除外(契約: rubyCount は必ず1以上)検証
swift build -c release(新ロック・ConvertText 込み)bazelisk build //win32/installer:installer_x64→ MSI 生成成功(mozc submodule43d858b5a)%APPDATA%\Mozc\azookey_memoryにファイルが生成されることで確認可能)対象外(継続課題)
🤖 Generated with Claude Code