メインコンテンツまでスキップ

改修サイクルの実例

この連載が記述する時点

本連載は執筆時点のハーネス実環境 (設定ファイルの内容、実行記録、ファイル数) を素材にした記録です。ハーネス本体は公開後も改修が続いているため、引用したファイル内容や個数、手順は現在の実体と異なる場合があります。本連載の主眼は個々の値ではなく設計の考え方 (5 関心分離、検証ゲート、成長規律) にあります。

本章は、bootstrap (= 新ハーネス投入) の後に表面化した問題と、それらを構造的に解消した改修サイクルを、代表的な実例で walkthrough します。

以下は、ハーネス本体の ~/.claude/plans/immutable-popping-planet.md §11 の T1-T8 検証で発見された残課題のうち、構造的な改修につながったものを選んだものです。

#改修内容検出経路改修案
改修 1 (§11 #2)commit gate hook が subagent transcript を拾えない問題の lasting fixT2 で autodev developer subagent が hook block されて commit 不能jq filter で tool_use_id を持つ user content を除外
改修 2 (§11 #3)per-repo doc 更新義務の pointer 層 vs 実 repo を SKILL + テンプレで明示T2 で developer が pointer 層を worktree 内に作ろうとしたautodev SKILL ①/②'/③ に 1 句追記 + plan.md テンプレを column 化
改修 3 (§11 #4 + #7)developer subagent の二重 worktree 解消.claude/worktrees/agent-<id>/ 残骸の cleanup 経路欠如agents/developer.md frontmatter から isolation: worktree を削除
改修 4 (§11 #6)smi-auto-dev SKILL の ⓪' assert 詳細未記載 (silent drop リスク)本セッション静的解析で発見autodev SKILL の ⓪' 記述を smi-auto-dev SKILL に verbatim copy
改修 5 (§11 #11)verbatim diverge 容認の方針確定改修 4 の派生課題/harness-prune の現行 4 検出項目に追加せず独立進化を容認

各改修を 4 段で見ていきます。

8.1. 改修 1: commit gate hook の subagent transcript 対応

問題発見 (T2, reverse-string task)

T2 で reverse-string task を autodev フローで走らせたところ、③ developer spawn の最終 step (task branch commit) で git commitblock されて完走できない事象が発生しました。

block を仕掛けていたのは hooks/check-git-commit-gate.sh (PreToolUse / Bash) です。この hook は次のロジックでした。

# 旧版: 直近 user turn (= 最後の type:"user" message) のテキストを取得
LAST_USER_TEXT=$(jq -r '...' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)

# トリガー語 (commit / コミット / push / ...) が含まれるか
if echo "$LAST_USER_TEXT" | grep -iqE 'commit|コミット|push|...'; then
exit 0
fi
exit 2

main agent transcript ではこれで動きます。直近 user turn には人間 (= 筆者) の text 発話があり、人間が「commit して」と言っていればトリガー語が含まれます。

ところが subagent transcript では話が違いました。subagent transcript の構造は次のようになります。

[user] spawn prompt (top-of-transcript、最初の 1 個のみ)
[assistant] tool_use (Bash 等)
[user] tool_result (= Bash 等の出力)
[assistant] tool_use
[user] tool_result
...

直近 user turn を取ると tool_result が拾われ、spawn prompt の text は奥に押しやられます。spawn prompt にはトリガー語 (commit / task branch にcommit する 等) が含まれているのに、hook はそれを見つけられず、subagent が git commit を試みた瞬間に exit 2 で block する状態でした。

分析

直近 user turn を grep するロジックが、main agent と subagent で挙動が変わるのが本質的な問題です。main agent transcript では「直近 user turn = 人間発話」が成立しますが、subagent transcript では「直近 user turn = tool_result」になってしまいます。

主要な分析論点は次の通りです。

  • subagent の context loss を hook 経路でも引き起こす構造的不整合
  • T2 期は CLAUDE_HOOK_SKIP_GIT_COMMIT_GATE=1 で迂回したが、これは一時しのぎ
  • 同型の問題は将来の subagent 種別追加でも再発する可能性あり
  • 改修案 3 つ:
    • (a) hook 修正 — tool_use_id を持つ user content を除外して spawn prompt が候補に残るようにする
    • (b) autodev SKILL ③ を「developer は staging まで、commit は main agent 代行」に変更
    • (c) git.md トリガー語規律を subagent では適用しない whitelist 経路を追加

採用判断は (a) が最有力でした。理由:

  • hook 側で構造的に解決 → SKILL / Policy 側の文面を変えずに済む
  • subagent の自律性を保持できる (autodev フローの設計を変えなくていい)
  • 副次効果: tool_result content に「commit」等が含まれるケース (= 従来の false negative) も同時解消できる

修正

hooks/check-git-commit-gate.shLAST_USER_TEXT 抽出ロジックを次のように改修しました (実コード抜粋)。

# 直近 user 由来 message の text 抽出 (lenient parse)
# user role には (a) 人間/orchestrator の発話 と (b) tool_result の 2 系統が混在する。
# subagent transcript では最後の user message が tool_result になりがちで、(a) を取り損ねる
# (= spawn prompt のトリガー語が見えなくなる)。対策として content array に tool_use_id を
# 持つ要素 (= tool_result) を含むものは除外し、純 text 由来の最後の user message を取る。
LAST_USER_TEXT=$(
jq -R 'fromjson?' "$TRANSCRIPT_PATH" 2>/dev/null \
| jq -s -r '
[.[]
| select(.type=="user")
| select(
(.message.content | type == "string") or
(.message.content | type == "array" and
([.[] | select(has("tool_use_id"))] | length == 0))
)
] | last
| .message.content
| if type=="string" then .
elif type=="array" then ([.[] | (.text // .content // "")] | join("\n"))
else "" end
' 2>/dev/null
)

核心は select(has("tool_use_id")) の判定です。

  • content array 内に tool_use_id を持つ要素 (= tool_result) が含まれない user message のみを採用
  • main agent transcript: 通常の人間 (筆者) text 発話 (string or pure-text array) が最後に残り、従来通り動作
  • subagent transcript: tool_result が除外され、spawn prompt (top-of-transcript の user message) が候補に残る

agents/developer.md.bak 版を残置 (revert ハッチとして)、新版を本適用しました。

検証

hooks/tests/test-check-git-commit-gate.sh に subagent transcript 用の test fixture を 3 種追加しました。

  • S1 (PASS 期待): subagent transcript の最初の user message (= spawn prompt) にトリガー語あり、その後に tool_result が連続 → 通過
  • S2 (BLOCK 期待): subagent transcript の spawn prompt にトリガー語なし、tool_result の text にも無し → block
  • S3 (BLOCK 期待): tool_result content にのみ「commit」文字列が含まれる (= 旧 hook が false negative で通していたケース) → block

既存 14 fixture + 新規 3 fixture = 17/17 PASS を確認しました。

end-to-end 検証は anagram-check task で行いました。state.md 履歴に次の記載があります。

- 検証 (b) PASS: developer subagent が自律 commit (4651e09e) に到達、
新 hook 改修で block されず通過
= §11 #2 lasting fix の実環境実証

これにより、subagent の自律 commit 経路が hook block されずに通過することが実環境で確認できました。

8.2. 改修 2: per-repo doc 更新義務の column 化

問題発見 (T2, reverse-string task)

T2 で architect が plan.md §7 (ドキュメント更新義務 section) に「CONTEXT.md 既存 3 行の下に追記」と書いた結果、developer が 実 repo (/Users/<name>/Dev/autodev-smoke/) に CONTEXT.md を新規作成してしまう事象が発生しました。

実際には CONTEXT.md は pointer 層 (~/.claude/repos/autodev-smoke/CONTEXT.md) にのみ存在し、worktree 内には base SHA 時点で CONTEXT.md がありません。「CONTEXT.md に追記」と書かれた時、developer はそれが pointer 層なのか実 repo なのかを判断する手がかりを持たず、worktree 内に新規作成する判断に至りました。

人間 (筆者) が手動で revert + pointer 層を main agent が代行追記して回避しましたが、これは構造的な不整合です。

分析

主要な分析論点:

  • autodev SKILL の文面が「per-repo 知識 (CLAUDE.md / CONTEXT.md / INDEX.md) は pointer 層であり worktree 内 commit に含めない」を明示していない
  • architect / developer が pointer 層と実 repo を混同する余地が常に残る
  • output-contracts/plan.md テンプレートに「層」の概念が無く、自由記述だった

改修案:

  • (a) autodev SKILL ①/②'/③ の per-repo 知識注入文言に「これらは pointer 層であり worktree 内 commit に含めない / doc 更新義務は main agent が pointer 層を更新する経路」を明記
  • (b) output-contracts/plan.md テンプレートに doc 更新義務の対象を明示 column 化

両方を実施しました。

修正

修正 (a) : autodev SKILL ① / ②' / ③ に 1 句ずつ追記しました。

## ① architect spawn (read-only, fresh)
spawn prompt に spec.md + **per-repo 知識を絶対パス注入** (`~/.claude/repos/<repo>/CLAUDE.md`
policy / `CONTEXT.md` 用語 / 選択 knowledge、worktree 越境で自動到達しない上に
**pointer 層 = worktree 外なので developer commit 対象外**) → architect が plan.md を生成

## ②' story.md 合成
... **doc 更新義務が pointer 層対象 (`~/.claude/repos/<repo>/CLAUDE.md` / `CONTEXT.md` /
他) の場合は story に明記の上 developer でなく orchestrator が代行する**

## ③ developer spawn (worktree 隔離, baseRef=head)
story.md を単一入力 → 依存 install → 実装 → pass 条件を worktree 内で実行 → done.md に
証跡 → task branch commit (**pointer 層 doc 更新は対象外 = orchestrator 代行**)

修正 (b): output-contracts/plan.md テンプレを column 化しました。

## ドキュメント更新義務

<列挙: 対象パス + 層 (pointer / 実 repo) + 更新者 (developer / orchestrator 代行)
+ 検証経路を column 化。auditor の照合元、orchestrator が story.md に verbatim 転記する>

| 対象パス || 更新者 | 検証経路 |
| --- | --- | --- | --- |
| ... | pointer / 実 repo | developer (worktree commit) / orchestrator (代行) |
auditor Read / git diff |

「層」列が pointer / 実 repo を区別し、「更新者」が developer / orchestrator 代行 を分岐する 4 列表になりました。

検証

anagram-check task で end-to-end 検証を行いました。state.md 履歴に次の記載があります。

- ① architect 完了 (VERDICT: PASS、column 化された
## ドキュメント更新義務 表を生成 = 検証 (c) OK)
- ④ auditor 完了 (VERDICT: PASS、3 本柱整合、column 表通り
CONTEXT.md 代行を doc 更新漏れではないと判定)

検証 (c) として、architect が column 化された doc 更新義務表を自然に生成 (= テンプレ通り) し、auditor が column 表通りに照合判定する挙動が確認できました。SKILL の文言を 1 句変えるだけで subagent 出力が連動するのは、Faceted Prompting の合成規約 (preload 経路) がきちんと効いている証拠でもあります。

8.3. 改修 3: developer subagent の二重 worktree 解消

問題発見 (T2 で発見 → T5 で解消)

T2 で developer subagent を spawn したところ、main agent が手動で git worktree add /tmp/autodev-smoke-reverse-string を作っていたにも関わらず、Agent tool が重ねて /Users/<name>/Dev/autodev-smoke/.claude/worktrees/agent-a0cf210624305e2c8/ を自動作成しました。

[autodev SKILL ③ の手動 worktree]
/tmp/autodev-smoke-reverse-string (baseRef=HEAD で main agent が pin 制御)

[Agent tool isolation が自動作成]
/Users/<name>/Dev/autodev-smoke/.claude/worktrees/agent-a0cf210624305e2c8/
(untracked file 残存、`git worktree remove` が fail、`--force` 必須)

機能上は致命的でなく autodev フローは完走できていましたが、後者の自動 worktree は cleanup 経路がなく、untracked changes が残った状態で git worktree remove が fail、--force 削除する以外に手立てがない状態でした。残骸は branch (worktree-agent-a0cf210624305e2c8) と一緒にぶら下がり続け、月次 /harness-prune.claude/worktrees/ を対象に入れていなかったため検出されません。

分析

agents/developer.md の frontmatter に isolation: worktree 指定があったことが発生源でした。

---
name: developer
description: ...
model: inherit
tools: Read, Write, Edit, Bash
isolation: worktree # ← これが Agent tool 経由で自動 worktree を作る
---

isolation: worktree は Agent tool が subagent spawn 時に自動で .claude/worktrees/agent-<id>/ を作るオプションです。一方、autodev SKILL ③ では orchestrator が手動で git worktree add /tmp/<repo>-<task> を作って spawn prompt で cwd を指定する設計でした。両者が独立に worktree を作るため、二重に分岐する状態になっていました。

主要な分析論点:

  • §11 #4 (二重 worktree の cleanup 経路欠如) の発生源を §11 #7 で特定
  • 既存 [factorial state.md] の task_branch: (deleted) worktree-agent-ad58eb1f2b0ebea55 表記も同型 (smi-auto-dev 経由の autodev でも同じ frontmatter)
  • 改修案:
    • (a) developer.md frontmatter から isolation: worktree削除し、autodev SKILL ③ の手動 baseRef=HEAD worktree に一本化
    • (b) または autodev SKILL ③ を Agent tool isolation 依存に変更し、手動 worktree を巻き戻す (cd-less 設計と矛盾するため非推奨)

(a) を採用しました。Phase 1-3 で構築した cd-less 設計 (orchestrator が worktree_path を state.md で pin して制御する経路) と整合性が高く、§4 Phase 4-6 の task-centric 設計とも一貫します。

修正

agents/developer.md frontmatter から isolation: worktree を削除しました。revert ハッチとして developer.md.bak を残置 (月次 /harness-prune.bak cleanup 候補)。

---
name: developer
description: story.md を単一入力に worktree 内で実装し、pass 条件を実行して証跡を残す。
model: inherit
tools: Read, Write, Edit, Bash
---
あなたは spec に忠実な実装者。story.md を唯一の主入力とし、worktree 内 (HEAD から
分岐) で実装する。

cleanup として、T8 で発見された orphan worktree 内の 完全実装 (fizzbuzz-cli の src + test) は失われないよう 新 branch に保全 commit してから worktree を --force 削除しました。fizzbuzz-cli は最終的に master に rebase + ff merge され、新 commit 8eb7cc4 として master に統合されました。

検証

T5 で palindrome-check spec を autodev フルで走らせたところ、.claude/worktrees/agent-* 新規発生せず、autodev SKILL ③ の手動 baseRef=HEAD worktree (/tmp/autodev-smoke-palindrome-check) に一本化されました。

anagram-check state.md 履歴にも記録があります。

- 検証 (a) 継続: .claude/worktrees/agent-* 新規発生せず

これで二重 worktree 問題は構造的に解消し、残骸 cleanup の困難さも同時に消えました。

8.4. 改修 4: smi-auto-dev SKILL の ⓪' assert verbatim copy

問題発見 (本セッション静的解析)

smi-auto-dev SKILL は冒頭で次のことを宣言しています。

## 品質ゲート + resume は autodev と共有 (自己完結再掲)
spawn 連鎖・VERDICT ゲート・state.md カウンタ・handoff + ⓪' の resume 分岐は
autodev と同一。①-⑤ の骨子も autodev と同じだが、silent drop 回避のため **autodev
SKILL.md を Read 合成せず本 skill で完結させる**

ところが、Phase 1-3 改修で autodev SKILL に追加した ⓪' assert (spec パス絶対化 / <repo> 抽出 / .repo_root Read/trim / dir + git work tree assert / fallback) の文言が、smi-auto-dev SKILL 本文には再記載されていない状態でした。

文面通り読むと smi-auto-dev は Phase 1-3 改修済の ⓪' をシェアできない構造で、「autodev と同一」を main agent が読み取って autodev SKILL を参照する経路は実態としてあり得るものの、SKILL 規律 (= Read 合成せず完結) と矛盾するため silent drop リスクがあります。

分析

主要な論点:

  • silent drop 回避を宣言した SKILL 自身が silent drop リスクを内包する矛盾
  • bootstrap (= 新ハーネス投入) 時点で smi-auto-dev 側の再記載が漏れた可能性
  • 改修案:
    • (a) smi-auto-dev SKILL.md に ⓪' assert の詳細を autodev SKILL から verbatim copy (自己完結方針に整合、サイズ上限 ≤80 行を超えないか要確認)
    • (b) frontmatter で「smi-auto-dev は autodev SKILL.md を bootstrap で先読みする」設定を追加 (faceted 思想 = 1 ファイル 1 関心 は崩れる)
    • (c) 動作確認のみで文面ズレを許容 (silent drop リスクは残る)

(a) を採用しました。1 ファイル 1 関心の規律 (= 各 SKILL は self-contained) を保持し、サイズも上限内に収まる見込みだったためです。

修正

smi-auto-dev/SKILL.md に次の section を追加しました (autodev SKILL の ⓪' を verbatim copy)。

## ⓪' 起動前 assert + resume 判定 (autodev と verbatim)
- spec パス引数を realpath で絶対化 → `~/.claude/repos/<repo>/...` から `<repo>`
抽出 → `~/.claude/repos/<repo>/.repo_root` Read/trim → repo_root 取得
(assert: dir 存在 + `git -C <repo_root> rev-parse --is-inside-work-tree` true)
- 上記失敗 (絶対化失敗 / `<repo>` 抽出失敗 / `.repo_root` 不在 or 破損) は
AskUserQuestion で repo 選択
- `~/.claude/repos/<repo>/INDEX.md` を Read → タスク関連の知識ファイルのみ on-demand 選択 Read
- `git -C <repo_root> rev-parse HEAD` を base SHA として state.md に記録
- **resume 分岐 (別セッション閉鎖耐性)**: 既存 handoff dir / state.md があれば Read →
`last_completed_step` の次から続行

5 bullet で、autodev SKILL の ⓪' 記述を verbatim にコピーしました。これで「silent drop 回避のため autodev SKILL.md を Read 合成せず本 skill で完結」の主張が本当に成立します。

検証

サイズ確認: smi-auto-dev SKILL.md の改修後サイズは 28/80 行 で、上限内に収まりました (autodev の例外上限 ≤100 を借りる必要なし)。

silent drop リスクの解消: smi-auto-dev SKILL が独立に Phase 1-3 改修済の ⓪' を備えている形になり、Read 経路に依存しません。

8.5. 改修 5: verbatim diverge 容認の方針確定

問題発見 (改修 4 の派生課題)

改修 4 で smi-auto-dev SKILL に autodev SKILL の ⓪' を verbatim copy したことで、新たな課題が浮上しました。

「verbatim copy だと将来 autodev SKILL の ⓪' が変わったら、smi-auto-dev 側の手動 sync が必要になるのでは?」

これは合理的な懸念です。同じ文言が 2 箇所に置かれると、片方だけ更新されたときに divergence (= 内容ズレ) が発生します。再構築前の症状 2 (同種指示の複数 facet 散在) を再現するリスクです。

分析

主要な選択肢:

  • (A) 月次 /harness-pruneverbatim diverge 検知を追加 (autodev SKILL ⓪' と smi-auto-dev SKILL ⓪' の文字列差分を自動検出)
  • (B) verbatim copy を諦め、frontmatter 先読み (改修 4 案 (b)) に切り替え
  • (C) 独立進化を容認 — 各 SKILL は self-contained に進化していい、verbatim 整合は要求しない

(A) は技術的に可能ですが、/harness-prune の検出項目を 4 → 5 に増やすため、規律 (= 検出項目は固定で metrics 集計を内包しない) と矛盾します。

(B) は 1 ファイル 1 関心 (各 SKILL は self-contained) を崩します。

(C) を採用しました。理由:

  • 各 SKILL の責務は独立であり、autodev と smi-auto-dev は派生関係にあるが同一ではない
  • ⓪' assert の中身が変わった時、片方だけ変える判断が現実的にあり得る (例: smi-auto-dev は理解ゲート付きで Phase 0 詰問が長いため、resume 経路の bullet を 1 つ追加する等)
  • silent diverge を防ぐ目的でメンテコストを払うより、独立進化を許容して各 SKILL が責務に応じて自由に進化する方が運用上健全

修正

~/.claude/plans/immutable-popping-planet.md §11 #11 に方針として明記しました。

**本適用済**: revert ハッチ無し (純粋追記)。autodev SKILL ⓪' と本節はこの改修時点で verbatim
だが、**将来 diverge してよい** (各 SKILL は self-contained 進化を容認、verbatim 整合
の検知は `/harness-prune` の当時の 4 検出項目 = 30 日参照ゼロ / サイズ超過 / orphan hook /
参照切れ では**実装されておらず**、本セッション追加検証で SKILL.md 仕様を Read して確認
した)。silent diverge を防ぎたい場合は **新 lint** が必要だが、当面は (D) 独立進化容認の方針。

これは「/harness-prune の検出項目を増やさない」という規律保持と整合します。

検証

検証は方針確定の周辺メタ確認になります。

  • /harness-prune の検出項目が 4 のまま (機能拡張なし) — ~/.claude/skills/harness-prune/SKILL.md を Read で確認、この改修時点では検出 4 項目で固定
  • smi-auto-dev SKILL.md と autodev SKILL.md の ⓪' はこの改修時点で文字列一致 (= verbatim) — 静的検査済
  • 将来 diverge した場合、それは構造的に許容する (= bug ではない)

これにより、「verbatim copy で silent drop を解消したが、その代償として diverge リスクを抱える」状態を意図的な選択として確定しました。

8.6. 改修サイクルの総括

ここまでの改修を 1 つの図にまとめると、次のような ratchet が走りました。

ratchet のキーポイント:

  • bootstrap で完璧な構成は投入できない — 投入後に必ず silent drop / 二重 worktree / 文言ズレが表面化する
  • 表面化した問題は §11 残課題 として記録し、改修案を 2-3 案併記して採否判定する
  • 採用した改修案は 本適用 + .bak 残置 (revert ハッチ) で実装し、その効果を別 task で end-to-end 検証する
  • 検証 PASS を state.md 履歴に記録することで、改修が 実環境で効いた証拠を残す

ここまでの改修はそれぞれ独立な改修ですが、共通するのは「問題発見から本適用までを 1 セッション内で完結」させた点です。bootstrap → T1-T4 → 改修案 → T5-T8 → 確定の流れは複数セッションにまたがって回りました。

ratchet サイクルの本質

bootstrap で完璧を目指さないのが核心です。構成を頭の中でどれだけ詰めても、実際に subagent を 1 周回すと silent drop / 二重 worktree / 文言ズレが必ず出てきます。

これらを 1 周ごとに lasting fix で構造解消していくサイクルが、新ハーネスを安定期に持っていく主動力でした。「失敗を構造的に学ぶ」道具として §11 残課題リスト + .bak 残置 + state.md 履歴の組が機能します。

8.7. 改修は git history で検証可能

ここまで扱った改修は、いずれも ~/.claude/ の git history に実際の commit として残っています (git -C ~/.claude log --oneline で確認できます)。例えば改修 1 (commit gate hook) は feat(hooks): git commit 暴発防止 PreToolUse gate + 関連 facet 整備 という commit に対応し、同じ commit に検証 fixture (hooks/tests/test-check-git-commit-gate.sh の追加テストケース) も含まれています。「口頭で語られた改修」ではなく「diff として残る改修」であることが、本章の実例を裏付けています。

8.8. 継続する改修の実例

ここまでの改修は、いずれも 1 セッション内で問題発見から本適用まで完結した lasting fix でした。ただし改修はこれで終わりではなく、運用を続ける限り usage-driven に発生し続けます。ここでは、facet の追加という形を取らない改修の実例を 1 つ紹介します (facet の追加自体は 07 章 で扱います)。

rules/response-links.md の規範修正: 当初は「workspace 外パスを file:///<絶対パス> URI で書けば clickable になる」と仮定して規範を書いていました。ところが実際に Claude Code の VSCode 拡張で確認したところ、この URI 形式は clickable にならないことが判明しました。規範を「素の絶対パス直書き / file:/// vscode://file/... vscode://open?url=... はいずれも動作しない」に修正し、本連載中の ~/.claude/repos/<repo>/... への参照もすべてこの方針で書き直しました。

この事例が示すのは、規範は一度書いたら終わりではなく、実機検証で覆ることがあるという点です。「動くはずだ」という仮定に基づく規範は、実際に動かしてみるまで正しいかどうか分かりません。

8.9. 本章のまとめ

要点
  • bootstrap 後に必ず silent drop / 二重 worktree / 文言ズレが表面化する。完璧な投入は不可能
  • 代表的な改修を各々 4 段 (問題発見 → 分析 → 修正 → 検証) で walkthrough:
    • commit gate hook の subagent transcript 対応 (tool_use_id 除外フィルタ)
    • doc 更新義務の column 化 (SKILL 文言 1 句追記 + plan.md テンプレ 4 列表)
    • developer 二重 worktree 解消 (isolation: worktree frontmatter 削除)
    • smi-auto-dev ⓪' verbatim copy (silent drop リスク解消)
    • verbatim diverge 容認 (/harness-prune 検出項目を増やさない方針確定)
  • facet の追加を伴わない改修も継続的に発生する (例: 実機検証で規範の前提が覆った response-links.md の修正)
  • 改修サイクル = §11 残課題リスト + .bak 残置 + state.md 履歴 + end-to-end fixture/task の組
  • 「失敗を構造的に学ぶ」道具立てが ratchet を回す動力

次章は、本連載のまとめとして、3 段要約 / 4 Quality metrics の現状 / これからの道筋を整理します。