本稿は「デジタル伴侶制作記」の第3篇である。伴侶システムは、いずれ内容区分の問題に直面する。本プロジェクトは通常モードとプライベートモードという二つの文脈に分けた。要件はプロンプトに注意書きを入れることではない。通常モードがプライベート文脈の内容を構造上まったく読めないことである。三度の失敗と再構築を経たこの機構は、全体で最も残す価値のある部分になった。
弁:非対称は意図的である
二つのモードを結ぶ扉は一つだけで、規則は最初から固定した。
- 起動時は必ず通常側。 初期版は前回のプライベート状態を復元したが、再起動が認証を迂回する裏口になった。
- すべての失敗は通常側へ倒れる。 モード照会のタイムアウト、接続不能、設定欠落の結果はすべて通常モード。fail-safeは安全な方向へ倒れなければならない。
- 入る時は認証し、出る時は不要。 非対称は欠陥ではない。誤って入ることは事故だが、誤って出ることは興ざめにすぎない。
- 自動判定は制限を強めることだけができる。 自動処理がシステムを動かせる方向は通常側だけである。
記憶を囲む四つの壁
- 二つの人格。 プライベート側の追加人格はそのモードだけで文脈へ入り、通常側のプロンプトには文字列自体が存在しない。
- 二つの要約。 ローリング要約は別キーで折り畳む。重要なのは、通常側の要約入力が遮蔽後の表示を使うこと。保護区間は長期文脈へ圧縮される前に消える。
- 二つの長期記憶。 安定した事実を別ファイルに持ち、プライベート側は通常モードで読み込まない。
- 区間遮蔽。 通常モードが全時間軸を読むとき、各プライベート区間を一つの接続文へ置き換える。
プレースホルダーを固定する理由
固定文は「以前プライベートな時間があったが、内容を再述せず日常へ戻った」という程度の意味を持つ。文脈から自然な接続文を生成する案も検討したが、退けた。
保護内容から接続文を生成すれば、その接続文自体が漏洩経路になる。
区間を要約した文は、どれほど婉曲でも情報を運ぶ。固定定数が運ぶ内容情報はゼロで、通常側が知るのは区間の存在だけである。自然さは安全性を緩めるのではなく、十分に汎用的な定型文で担保する。
プライベートモードを離れる際の台詞も、意図は固定、言い回しは可変とした。相手を気遣い、水を差し出し、日常の話題へ戻り、具体的内容には触れないという指示は固定し、変化は表現だけに許す。
クラッシュ時の意味:fail closed
プライベートモード中のクラッシュは、開始点だけを持つ「開いた区間」を残す。再起動時は、すべての開放区間を記録末尾で閉じる。クラッシュ前は遮蔽区間内、再起動後は区間外になる。通常会話を少し多く隠す方が、保護された一文を漏らすよりよい。
三度の分離障害
事故1:分離が一度も動かず、テストはすべて成功。 ページとローカルサービスが別オリジンで、ブラウザがモード照会を静かに遮断した。fail-safeにより照会失敗は通常モードとなるため、分離経路は一度も実行されなかった。ネットワークをmockしたテストは全件成功した。fail-safeは正しく働いたが、mockされたテストは実経路が存在しないことを発見できない。以後、実経路の検査を追加した。
事故2:二重切り詰め。 再構築時、要約済み部分を文脈窓から二度差し引き、毎回の可視履歴がゼロになった。繰り返し挨拶し、記憶も知性も失ったように見えたが、原因は窓の算術だった。この症状を直接狙う回帰テストを加えた。
事故3:前置部の一括削除。 初期の遮蔽は、プライベート区間より前をすべて切り落とした。単純だが、通常側自身の古い履歴も消え、区間をまたぐ日常会話が続かない。区間単位の遮蔽へ変え、前後の通常履歴をつなぎ、その間だけ固定文を置いた。
検証
22項目の回帰テストが仕様を守る。通常側が区間前後の自分の履歴を保持すること、各区間に固定文が一つだけ入ること、複数区間を別々に扱うこと、クラッシュ区間が閉じられ再起動後の内容が外側にあること、二つの要約水位が独立すること、通常要約入力に保護文字が一つもないこと、通常側の検索が遮蔽後の表示だけを対象にすること。後に記憶システムを上流から分離して書き直した際も、この22項目をそのまま移し、移行の合格条件にした。
再利用できる原則
- 内容区分はデータ可視性の層で行う。プロンプトは礼儀であって壁ではない。
- 自動動作の失敗方向を事前に宣言し、安全側へ倒す。
- 保護内容から生成したメタ情報は、無害に見える移行文も含めて漏洩経路になる。
- fail-safeは経路障害を隠し得る。よく働くほど、接続そのものを調べる独立テストが必要になる。