前回まで、仕様書の書き方とAIの報告の検証術を書きました。第4回は、その両方が機能しなかったときの最後の砦——書き込みの直前に置く「完了確認」の話です。
結論を先に書きます。完了確認は、数値を報告させるだけでは足りません。異常時に「止まる」という振る舞いまで、条件として明記して初めて機能します。
1. 定型の8項目から始まった
大きな設計文書(要件定義書・設計書など、1本あたり数千行を超える)を編集する作業では、TAKTに次の8項目を確認させてから書き込ませる形を定型にしています。
| 項目 | 止まる条件 |
|---|---|
バックアップの md5sum と wc -l |
— |
編集前後の wc -l(行数) |
減少していたら止まる |
| 編集前後の見出し数 | 減少していたら止まる |
編集前後の wc -m(総文字数) |
減少していたら止まる |
| 差分のあった各ハンクの文字数(前→後) | 減少していたら止まる |
diff の変更箇所の種別 |
d(削除)が出たら止まる |
| 打ち消し線記号の総数 | 奇数なら止まる |
| 打ち消し線が奇数個の行の件数 | 0件でなければ止まる |
「減っていたら報告して止まる」「奇数なら報告して止まる」と、止まったあとにどうするかまで書きます。 ここまでが土台です。
2. 8項目では検知できない破損があった
ある日、設計文書の一節で、アンカーとして行の前半だけを使いました。93字の行が、その途中で切断され、後半の断片が別の行の末尾へくっついてしまいました。
この破損を、8項目のどれも検知できませんでした。 行数は変わりません。見出し数も変わりません。総文字数もほぼ変わりません。打ち消し線の数も変わりません——行が分割されただけでは、これらの指標はすべて保存されます。
気づいたのは、別の作業(第2回で書いた是正条件による走査)が、その断片を条件に該当するものとして拾い上げたときでした。完了確認は素通りしていたのです。
3. 9〜11番目の項目を追加する
この経験から、3項目を追加しました。
| 項目 | 止まる条件 |
|---|---|
| 強調記号が奇数個の行の件数 | 増えていたら止まる |
| アンカー行そのものの文字数 | 編集前と異なれば止まる |
差分の種別(insert か replace か) |
insert を期待した箇所に replace が出たら止まる |
これらは、行の分割を検知するための項目です。 行の途中へ追記するとき、アンカーの切り方を誤ると行が分割されます。
- アンカー行の文字数の運用:追記文を改行で始まる形にすれば、アンカー行そのものの文字数は変わらないはずです。編集前の実測値を、そのまま期待値にします
- 差分の種別の運用:行末への追記は
insert、行の一部の置換はreplaceになります。どちらを期待するかを、ラウンドごとに明記します
「差分の組数」(いくつのハンクに分かれるか)は、値そのものでは止めていません。試走で作った再現ファイルと、本番の実ファイルとでは、diffアルゴリズムが変更をまとめる単位が変わり、組数が食い違うことがあるためです。止めるのは組数ではなく、種別(delete の有無・insert/replace の別)です。
4. 正しい条件が、正しい作業を止めることがある
11項目が揃っても、それで終わりではありません。条件の立て方を誤ると、今度は正常な作業のほうを止めてしまいます。
旧い記述を打ち消し線で別の場所へ移す作業では、移動元のハンクは必ず短くなります。「減少していたら止まる」をそのまま適用すると、この正常な移動のたびに作業が止まります。
実際、この例外を指示文に書き落としたことがありました。TAKTは、減少した2つのハンク(−17字・−197字)を「形式上は止まる条件に該当する」として正しく報告し、そこで作業を止めました。移動元と移動先を合算した値(1,053字→1,629字、+576字)も併せて報告しており、TAKTの振る舞いは正しく、原因は指示文の側にありました。
以降、この種の作業には次の一文を必ず添えています。
移動元と移動先を合算した文字数で判定してよい。合算しても減少していたら止まること。合算で判定した場合は、その旨と合算値を必ず報告すること。
同じ構造の例外は、識別子をより短い名前へ改名する場合にも起きます。ある回では既存の識別子をより短い名前に改名する作業で、1つのハンクが必ず数字減りました。ここでもTAKTは独自に例外扱いをせず、「形式上は止まる条件に該当する」とだけ報告し、例外にするかどうかの判断は人に委ねました。
この設計は意図的です。 「事前に算出できる減少だから、自動的に許容してよい」という判断を、ひかり(対話AI)が独自に行うことはしません。TAKTには止まる条件として淡々と報告させ、例外にするかどうかは、必ず人が判断します。
5. 「0件であること」が、正しい記述を止めることがある
もう一つ、頻発したパターンがあります。「〇〇が0件であること」という絶対条件が、編集前から存在していた正当な記述に反応して止まるというものです。
課題管理表の更新スクリプトで、ある列の値を絶対条件(件数がゼロ)で検証したところ、編集前から同じ形の記述が存在する項目にひっかかり、書き込み前に停止しました。同種の再発は、記録されているだけで通算7回起きています。日付の記述、識別子の名称、件数のスナップショットなど、是正の記述そのものが言及する語は、過去の記録として既に文書内に存在しうるのです。
対処の一般形はこうなります。
検証条件は「編集前後の集合が一致すること」で書く。「0件であること」ではなく「編集前と同じ集合であること」。数ではなく、どの行かを突き合わせる。
絶対条件(件数がゼロ)をどうしても使いたい場合は、「編集前が0件であったこと」自体を、独立した検証項目として先に置きます。 前提を検証項目として明示すれば、絶対条件も安全に使えます。
6. 完了確認は、指示文の他の部分と衝突することがある
最後に、完了確認そのものではなく、完了確認と、指示文の他の部分が矛盾するケースを挙げます。
ある回で、「旧記述の逐語保存を確認する」という条件と、「表はセルごとに打ち消し線で囲む」という指示を同時に出したことがありました。この2つは両立しません。表のセルを個別に打ち消し線で囲むと、Markdownの表としての描画が壊れ、結果として「逐語保存」の確認方法自体が崩れるためです。
TAKTは、止まる条件を優先して行まるごとを打ち消し線で囲む方式を採り、その代償(表としての描画が失われること)を明記して報告しました。 矛盾する指示の中では、最も正しい処理だったと考えています。
完了確認の項目は、指示文の他の部分と1つずつ照合してから書きます。 これが定型化した理由です。
7. まとめ——完了確認は仕様書の裏側である
11項目まで積み上げても、その大半は「行の分割」というたった一種類の破損を検知するために追加されたものです。そして条件を厳しくするたびに、今度は正常な作業を止めてしまう副作用が生まれ、その都度、例外を明文化してきました。
完了確認とは、結局のところ仕様書の裏側にあります。 仕様書が「何を直すか」を書くものだとすれば、完了確認は「直した結果が、意図しない形に壊れていないか」を機械的に問うものです。そしてその機械的な問いかけ自体も、書き方を誤れば正しい作業を止め、あるいは誤った作業を通してしまいます。両方とも、実測してから書く以外に近道はありません。
次回(第5回):バックアップと復旧——git checkout を使わせない理由と、git worktree の使いどころ。壊れたときに、どこまで戻れるようにしておくかという設計を書きます。
動画作成には自信があります!

