Contents — 7 sections

RicochetTanksでは、機械Testと人間Testを分けるために gate-status.json を持っていた。

どのBuildが対象か。

人間確認は済んだか。

競合比較は済んだか。

NOT_RUNなのか。

そういうGate状態を残すファイル。

ある編集で、このファイルが空になった。

コードではなく「状態」を失いかけた

幸い、実装そのものが消えたわけではない。

Git履歴もあった。

対象Buildも追えた。

そのため、gate-status.json を復元して、正しいBuildを指す状態へ戻せた。

修復コミットも残した。

でも事故としてはかなり嫌だった。

なぜなら失いかけたのが、

「何を確認済みとして扱ってよいか」

という判断状態だったから。

State Fileは小さいけど重要度が高い

数KBのJSON。

見た目は地味。

でも、

  • Human test未実施
  • Competitor test未実施
  • Current candidate build
  • Gateの合否

のような情報を持っている。

これが壊れると、次のAgentが

「前の試験はPASSだったらしい」

と誤認する可能性がある。

Codeより小さいのに、Workflow上の権限は大きい。

Gitがあったから戻せた

今回復元できた理由は、状態変更もVersion Controlへ入っていたから。

空になった後でも、

  • 直前の内容
  • 対象Build
  • 過去のcommit
  • Report

を照合できた。

もし状態がローカルの一時Fileだけなら、もっと危なかった。

Single Point of Failureにしない

この事故から見える対策は単純。

重要な状態を一つのmutable JSONだけへ集約しすぎない。

たとえば、

  • append-only log
  • schema validation
  • 空File拒否
  • write前backup
  • commit単位の履歴
  • Build result側にもgate参照を残す

のように、復元材料を複数持つ。

特にAgentが自動更新するFileは、書き込み前後の検査が欲しい。

「書き込み成功」と「有効なState」は別

さらに厄介なのは、Fileが存在することと内容が正しいことは別なこと。

Toolによっては、

  • 空文字
  • {}
  • 必須Field欠落

でもFile write自体は成功する。

空文字はJSONとして無効。

{} はJSONとしては有効でも、必要なFieldを満たすStateとは限らない。

だから、

書けた = State更新成功

ではない。

Schemaとsemantic checkが必要になる。

Human Gateほど壊してはいけない

CI結果なら再実行できる。

Build artifactも再生成できる。

でもHuman Gateは、

「誰かが実際に確認した」

という出来事。

それを状態Fileから消してしまうと、同じ確認をもう一度やる必要が出るかもしれない。

逆に未実施をPASSへ誤変換したら、もっと危ない。

いまの結論

Agentic workflowで怖いのは、Codeを壊すことだけではない。

判断状態を壊すこと。

RicochetTanksでは gate-status.json が一度空になったことで、その危険がかなり分かりやすく見えた。

State Fileは小さい。

でも、その中にHuman decisionが入っているなら、Codeと同じかそれ以上に慎重に扱う必要がある。

Signal / 観測記録

この記録への観測を送る

反証、再現失敗、追加で試してほしいこと。届いた SIGNAL は非公開で保存し、次の実験候補として扱います。