付録

本付録は、本文で語った事件を再説明する場ではありません。再利用可能な設計パターン、章とADR・コミットの対応関係、用語の定義、参考文献を、検索して参照するための資料としてまとめます。

全体像: 最終的なレイヤー構成と、そこへ至る流れ

事件ごとの詳細に入る前に、最終的にawaseがどんな形に落ち着いたかを俯瞰します。主経路 (入力から出力まで)は4段階を経て、以下の図が示す最終形に至りました。

段階時期(章)追加されたもの主経路の形
第1段階第1章なし(engine一つで完結)入力から出力までの素朴な一本道
第2段階第1〜2章n-gramによる統計的タイブレーク、Decision/Effectモデル、アプリ種別ごとの出力切り替え一本の経路の中だけで完結
第3段階第3〜8章観測・信念層(観測は信念を直接上書きしない)、アプリ適応層(物理キーを渡すか制御)主経路の外側に別の層が新設される
第4段階(最終形)第9章〜観測・信念層と適応層を4層reducerへ統合、世代照合という型「作用してよいか」を最後に一箇所で判断する経路が完成

awaseの最終レイヤー構成: 4つのまとまりがどこで互いの実行・送信を差し止めているか

第1段階(第1章): 入力から出力までの素朴な一本道

第2段階(第1〜2章): 統計的タイブレークとアプリ別出力の追加

第3段階(第3〜8章): 観測・信念層とアプリ適応層が経路の外側に新設される

出力の先には、メモ帳・Word(Win32/UWP)、Chrome・Edge、Windows Terminal・VS Codeという 具体的なアプリ名を置き、その先で実際にかな漢字変換を行うGJI(Google 日本語入力)・ MS-IMEという2つの競合IMEへつながります。フックからIME確定文字までの間、 WH_KEYBOARD_LL・IMM32/TSF・GetProcessIoCountersといったWindows APIのどこに 触れているかも矢印に添えました。

この経路は、送った命令が事実どおりに届いたか(柱A)、同じ分岐に押し込んでいた変化が 本当に一つの軸だったか(柱B)という2つの問いにまだ答えていません。第10〜11章は柱Aを、 第12章は柱Bを、第13〜15章は同じ照合の発想を開発プロセスへ向けます。

パターンカタログ

本文全体から抽出した12個の設計パターンです。各パターンは「パターン名・文脈・問題・働く力・解決・結果・限界・関連する章とADR」の8項目で統一しています。

1. Observer never overrides desired(観測は信念を上書きしない)

2. Generation/epoch fencing(世代照合による足止め)

3. Own the channel, don't filter the noise(チャネルを断つ、ノイズは濾さない)

4. Side-channel observability(副次観測)

5. Confidence-tiered sensor fusion(確信度による観測の融合)

6. Shadow-mode migration(並走移行)

7. FeedbackPolicy: 読み戻せるかどうかで補正ループを分岐させる

8. Blast radius(破壊範囲)で取り消し操作を選ぶ

9. 静的な軸は型へ、動的な軸は共有機構へ

10. 大局的な疑いを、修正ループの外へ独立させる

11. 診断フラグ→実機ソーク→恒久化→物理削除の4段階

12. 同じ場所を書き換える権利を、空間と時間の両軸で区切る

ADR・コミット対応表

章・事件・ADR番号・主要コミットの対応です。本文の再説明はせず、参照先として使う表です。

事件名症状ADR番号主要コミット現在の限界
第9章IME belief/SSOTモデルの変遷observationがintentを上書きADR-032, 077d2e183f, f8dd8d4, 6baabf9, a4db93e, 604cf99admit後・適用前のepoch遷移(TOCTOU)
第9章(補)凝集性リファクタ第2幕(21タスク一括)循環依存・God Object・ImeBelief.input_modepub公開ADR-069d79c25e未確認(残タスクは個別コミットの追跡が必要)
第9章(補)GJI前置キー待機キューの所有権移管probe切り替え時にdeferred VKが破棄される(「にゅうりょく」→「にうりょく」)ADR-07115ac8d8StepCoroのself-priming漏れは別途対応
第10章conv-mode増幅ループ(ConvModeMgrの自己参照)cold warmupのたびに誤ったbeliefがreal IMEへ再書き込みADR-078e7cc6d7, d495649最小対策は第13章で撤去され、型設計は未実装
第10章drift correctionのActuation型化675ミリ秒の間にVK_IME_OFFを16回無限再送ADR-08068d73d5実機ソーク未実施、暫定値のまま
第11章per-VK confirmのstale confirm誤帰属世代の異なる確定証拠をbackspaceが取り違え無関係な文字を消すADR-0797b54a96, 1817925, a3be20dESC+限定replayによる回収(Stage 2)は未実装
第12章プロファイル別capabilityドライバへの分離共有ループのプロファイル分岐がcross-profile spilloverを生む(既知バグ43件中11件)ADR-081123801b, 4af265f, bc3d13e実機配線と旧経路撤去は未着手
第12章(補)journal配線によるActuation出所・世代の記録分離移行中どちらの経路が真実か分からなくなる期間が生じうるADR-0824503223, b1ea94c本体は提案段階、journal配線のみ実施済み
第3章Windows Terminal/TSFコールドスタートliteral化ローマ字キーストロークのリテラル漏れADR-04926373e2, 84e6942, c089757, 97c922e, 6ecb8e9F2後の再初期化に344ms必要(idle時間に比例)
第7章ImmCross/LINE偽VK_F3/F4 echo物理KANJIキー押下が偽トグル生成要確認(未特定)d99e3f1, 77ccf34, e890a26, f84c74b, 08b8661, 0e364eaImmCrossProbeの信頼性問題(Qt子ウィジェット)
第7章(補)GJIキーバインド3世代交代F13/F14衝突ADR-034/057/0677f8291f, 81df62c, cfbbd20, b271aee, 098c663MS-IMEはVK_KANJIが必要(ADR-063)
第9章(補)VK/ScanCode混同検知dylintnewtype導入後も取り違え継続ADR-0122dd43f4未確認(現状lintで防御)
第6章捨て打ち機能(旧サクリファイシャル・ウォームアップ)Chrome cold-start中のリテラル化ADR-048, 06226bc0fe, d02ec44, 6c1732d, 22c3905vim等とのVK_A衝突(他アプリは離脱済み)
第8章StepCoro統一増殖したFSM群(5種類)の複雑化ADR-053e548e63, ccd4711, f01d401, b077c3d, 2c756dd, d1d6d17LiteralDetectFsmはコルーチン化されず残存(意図的)

注記です。第7章のコミットハッシュ(11件)は実在・内容一致を確認済みですが、対応するADR番号は未特定です。

拡張用語集

src/toc.mdの用語集に、Unitree Go2 Runtime実地検証で見つかった対応語を追記しています。

用語定義Unitree Go2 Runtime対応語
shadow stateOSが正直に教えてくれないIME状態を、自前で推測・保持する仕組みWorldState(immutableな世界モデル)
belief(信念)観測から導出した「いまのIME状態はこうだろう」という推定値BeliefView<T>(旧称BeliefSnapshot<S,B>)
Observation(観測)probe・pollから届く生の情報。beliefを直接上書きしないStateUpdate(S層が受け取る生観測)
FocusEpochフォーカス先プロセスの変更のたびに増えるカウンタ。観測の鮮度を判定する基準TickId(tick単調カウンタ。ただしepoch照合には未使用)
AcceptedObservation世代(epoch)照合(admit)を通らないと構築できない、型で保証された「新鮮な観測」現状Unitree Go2に相当機構なし
捨て打ち機能I/Oカウンタ差分で副次観測する技法(第6章、第13章で撤去)直接対応なし
Observed<T>Unitree Go2 Runtimeの観測品質型。FreshStaleUnknownBrokenの4値を持つawaseのshadow state・beliefに相当
用語定義
awase (合わせ)本書で描くWindows用日本語入力エンジン(NICOLA親指シフト方式)
NICOLA / 親指シフト親指キーとの同時打鍵タイミングで仮名を確定する日本語入力方式
TOCTOU急所admitした時点では新鮮でも、実際に適用する時点では陳腐化している間隙
FeedbackPolicy(Read/Blind)actuateの結果を読み戻せるかを型で必須指定させる設計(第10章)
liveness / safety補正が有限回で収束する性質(liveness)と、状態が嘘をつかない性質(safety)(第10章、第13章)
静的な軸 / 動的な軸実行中に変わらない軸と、実行時に変わる軸の区別(第12章)
世代フェンシング(epoch fencing)遅れて届いた証拠がどの試行に属するかを照合する仕組み(第11章、第16章)
blast radius(破壊範囲)undo操作が届きうる範囲の小ささで操作を選ぶ考え方(第11章)
count guard / contract test呼び出し箇所数の凍結と契約テストによる現実的な中間解(第10章、第12章)
Unitree Go2 Runtime著者が別に設計しているロボット(Unitree Go2)向けアプリケーションランタイム

参考文献リスト

文献書誌情報備考
Kleppmann, フェンシングトークン論Martin Kleppmann, "How to do distributed locking", 2016-02-08, https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html
Chubby (Burrows, OSDI 2006)Mike Burrows, "The Chubby lock service for loosely-coupled distributed systems", 7th USENIX OSDI '06, 2006-11. https://www.usenix.org/conference/osdi-06/presentation/chubby-lock-service-loosely-coupled-distributed-systemsPDF直リンクは要検索です。
Firefox OS/Gaia bug 1110030Bugzilla@Mozilla, Bug 1110030, "Routing hardware key events to keyboard app when an input field is focusing", https://bugzilla.mozilla.org/show_bug.cgi?id=1110030IsSynthesizedByTIP言及箇所は要検索です。
NIOSH Hierarchy of ControlsCDC/NIOSH, "Hierarchy of Controls", https://www.cdc.gov/niosh/hierarchy-of-controls/about/
Yaron Minsky, "Make illegal states unrepresentable"原典記事URLは要検索です(OCamlコミュニティで広まった言い回し)。要検索
"Typestate via Revocable Capabilities" (arXiv 2510.08889)arXiv番号のみ確認済みで、URLは要検索です。要検索
Kubernetes resourceVersionKubernetes公式ドキュメント, "API Concepts: Efficient detection of changes", https://kubernetes.io/docs/reference/using-api/api-concepts/
Raftコンセンサスアルゴリズムのterm番号Diego Ongaro, John Ousterhout, "In Search of an Understandable Consensus Algorithm", USENIX ATC 2014(第9章)
Gaffer On GamesGlenn Fiedler, "Gaffer On Games"(ネットコード分野で広く参照される個人技術ブログ), https://gafferongames.com/個別記事の直リンクは要検索です。
GGPOGGPO開発チーム, "GGPO Rollback Networking SDK", https://github.com/pond3r/ggpo
Bevy TickBevy公式ドキュメント, bevy_ecs::component::Tick, https://docs.rs/bevy_ecs/latest/bevy_ecs/component/struct.Tick.html
crossbeam-epochcrossbeam-rsプロジェクト, https://docs.rs/crossbeam-epoch/epochという語は共通ですが別問題です(false friend)。
slotmap / generational-arenaそれぞれのcrates.ioページ、https://docs.rs/slotmap/https://docs.rs/generational-arena/値の構築自体は型で制限していません。
GhostCell / generativityJoshua Yanovski et al., "GhostCell: Separating Permissions from Data in Rust"(ICFP 2021)、generativity crateドキュメント世代カウンタとの組み合わせ例は未確認です。
Peter Ferrie, アンチデバッグ手法集Peter Ferrie, "The Ultimate Anti-Debugging Reference", 2011年初出・以降改訂原典URLは要検索です。
F5/NGINXの受動的ヘルスチェックF5公式ドキュメント「Passive Health Monitoring」、NGINX公式ドキュメント「passive health checks」
チョード式キーボードの特許(US4,680,572)United States Patent 4,680,572 (1987年登録)
QMKファームウェアのtap-hold機能QMK公式ドキュメント, "Tap-Hold Configuration Options", https://docs.qmk.fm/tap_hold
Rodney Brooks, Subsumption ArchitectureRodney A. Brooks, "A Robust Layered Control System for a Mobile Robot", IEEE Journal of Robotics and Automation, 1986
Joint Detection and Estimation理論信号処理分野における、検出(detection)と推定(estimation)を同時に扱う理論の総称。個別の代表論文は要検索です。
Gary Bernhardt, "Functional Core, Imperative Shell"Gary Bernhardt, "Boundaries"(講演、2012年、Destroy All Software)講演URLは要検索です。
Android ANR(Application Not Responding)Android公式ドキュメント, "Keep your app responsive", https://developer.android.com/topic/performance/vitals/anrURLは要検索です。
Kubernetes readiness/livenessプローブKubernetes公式ドキュメント, "Configure Liveness, Readiness and Startup Probes", https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
TCP再送タイマーとKarnのアルゴリズムPhil Karn, Craig Partridge, "Improving Round-Trip Time Estimates in Reliable Transport Protocols", ACM SIGCOMM 1987
ReduxRedux公式ドキュメント, https://redux.js.org/
JavaScript/Python/Rustのasync/await各言語公式ドキュメント(ECMAScript async functions、PEP 492、Rust async book)個別URLは要検索です。
フライバイワイヤとフライトエンベロープ保護例: Airbus公式資料「Fly-by-wire」解説等個別の一次資料URLは要検索です。
CWE-367 (Time-of-check Time-of-use Race Condition)MITRE, "CWE-367", https://cwe.mitre.org/data/definitions/367.html

未確認・要確認事項