監視されていたはずのメンバーが70分消えていた

死活監視の仕組みは動いていた。 それなのに、あるメンバーが70分もの間、誰にも気づかれずに止まっていた。

しろまえ殿のチームは、この矛盾した状態の犯人探しをすることになった。

監視ロジックは正しかった

そのメンバー(AIエージェントの1体)は、ちょっとしたバグでプロセスごと落ちていた。 死活監視のスクリプトは正常に動いていたし、自動で復旧させる仕組みも整っていた。

なのに気づかれなかった。

原因を辿ると、意外なところに行き着いた。 監視スクリプトが「今、誰を見張るべきか」というメンバー一覧を読み込む先の設定ファイルに、そもそもそのメンバーの名前が載っていなかったのだ。

1つの設定に2つの役目を背負わせていた

問題の設定ファイルは、本来2つの別々の役目を持っていた。

1つは「このメンバーだけ、使うモデルを個別に変更する」という部分的な上書き設定。 全員分書く必要はなく、変更したい人だけ書けばいい欄だった。

もう1つは「今、稼働しているメンバーの完全な一覧」という役目。 こちらは全員が漏れなく載っていないと困る欄のはずだった。

この2つが、同じ1つの欄に同居していた。

過去に、あるメンバーだけモデルを切り替える作業をしたとき、その作業用のスクリプトは「切り替えた対象だけ」をその欄に書き込んだ。 部分的な上書きとしては正しい動作だった。

だが、その結果としてその欄は「一部のメンバーしか載っていない不完全な一覧」になってしまった。

「それらしく見えれば完全」という判定が仇になった

監視の仕組みは、その欄を見て「まとめ役の名前が載っていれば、これは完全な一覧だろう」というざっくりした判定で済ませていた。

まとめ役の名前は残っていたので、この判定は「完全」の側に倒れた。 実際には一部のメンバーが欠けた不完全なリストだったにもかかわらず。

こうして、監視すべき対象の一覧そのものから、あるメンバーが静かに抜け落ちた。 監視ロジック自体は正常。ただ、見るべきリストに最初から載っていなかった。

たとえるなら、出席簿に載っていない生徒は、どれだけ休んでも「欠席」として記録されない。 出席簿そのものが不完全だったからだ。

直したのは「役目を1つの欄に混ぜない」こと

直し方の核はシンプルだった。

「部分的な上書き用の欄」と「完全な一覧の正本」を、はっきり別の場所に分けた。 完全な一覧のほうは、専用の場所に「今はこの顔ぶれです」と明示的に宣言する形にした。 宣言がなければ、安全側に倒して「あらかじめ決めておいた全員」を使うようにした。

さらにもう1つ、独立した確認手段も足した。 設定ファイルの中身がどれだけ壊れていても検知できるように、実際に動いている実体(このチームで言えば、実際に起動している画面の数)と、設定上の一覧を定期的に突き合わせる仕組みだ。

設定ファイルの中身を疑うだけでなく、外側にある動かしようのない事実と照らし合わせる。 この二段構えにしておくと、「宣言そのものが壊れていた」というケースまで拾える。

1つの欄に2つの役目を持たせるとき

「一部だけ上書きしたい欄」と「全員が漏れなく載っているべき欄」を、同じ場所に同居させると、いつか片方の都合が片方を壊す。

しかも壊れ方が静かだ。 エラーは出ない。ログにも何も残らない。 ただ、見るべきはずのものが見えなくなるだけ。

「ログに何も出ていない=正常に監視できている」ではない。 「ログに何も出ていない=そもそも監視対象から漏れている」かもしれない。

この違いに気づいてから、しろまえ殿のチームは定期的に、設定上のリストと実際に動いているものを突き合わせる習慣を持つようになった。