Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions docs/adr/adr-033-todo-numbering-simplification.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## ステータス

試験運用 (2026-04-29、2026-08-16 に「順位 = 追記型 ID」を明文化し再採番を廃止 → § 改訂)
試験運用 (2026-04-29、2026-08-16 に「順位 = 追記型 ID」を明文化し再採番を廃止 → § 改訂、2026-08-26 に機械の結合キーを順位へ移送 → § 改訂 2026-08-26)

> **本文中の「再採番」は文脈で読み分けること。** § コンテキスト・§ 検討した選択肢・§ 決定 は**起票時点の記録**で、当時の前提 (再採番は起こりうる通常運用) をそのまま残す。現行の運用は**再採番をしない**であり、その決定と理由は § 改訂 (2026-08-16) が持つ。

Expand Down Expand Up @@ -166,6 +166,59 @@ table と本文を **同じ識別子で結合** していることが線形コ
- **禁止から緩和へ変えた対象**: § ガイドライン 1・2、§ アンチパターン「本文中の番号参照を「許容」してはならない (例外なし)」、§ 検証ルール (撤回済み)
- **既存 340 箇所の一括修正は不要**。修正すべきは削除済み順位を指す参照だけで、それは通常の docs 保守で足りる

## 改訂 (2026-08-26): 機械が読む結合キーは順位、人間が読む参照はタスク名

### 前提が失効していた

決定 1「絶対番号は table のみに保持」と決定 2「本文での参照はタスク名で行う」は、**後始末が人手だった時代の判断**である。当時、完了タスクの削除は「マージ時に人間が 4 手順を実行する」運用ルールでしか存在しなかった。人間が読んで対応を取る前提なら、番号を落としてタスク名で参照するのは可読性の面で妥当だった。

**[PR #406](https://github.com/aloekun/claude-code-hook-test/pull/406) で後始末を機械化したとき、この前提が変わった。** `cli-ledger-cleanup` は順位 table の「タスク」列を読み、その文字列と `### ` 見出しの**完全一致**で詳細エントリを特定する形になった。**同じ文字列を 2 か所で人手が保つ**構造であり、drift すれば hard-fail する。本 ADR は見直されなかった。

### 実測 (2026-08-26)

| 対象 | 結果 |
|---|---|
| summary 行 257 件のうち見出しと**一致**するもの | **116 件 (45%)** |
| 不一致 | **141 件 (55%)** |
| `todoN.md` の `### ` 見出し 276 件のうち順位を持つもの | **11 件 (4%)** |

不一致の内訳: 途中が違う 57 / summary 側に末尾が余分 43 (`★ Bundle X` 等) / 対応する見出しが無い 35 / 見出し側に末尾が余分 6。

**夜間ループは全経路を順位で通している** — タスク選択・着手済み除外・ブランチ名 (`claude/nightly-<順位>`)・`cli-ledger-cleanup --ranks`・PR タイトル・コミットメッセージ。**詳細エントリの特定だけが自由記述に落ちていた。** 順位はその関数まで確実に届いており、捨てていたのは実装の都合だけだった。

実害も出た。順位 193 で 2026-08-25 18:08 UTC と 2026-08-26 14:22 UTC の 2 run が `[LEDGER_CLEANUP_BLOCK]` により同じ場所で失敗し、いずれも **agent を 1 回まるごと回してから**落ちている。

### 決定

**決定 1 / 決定 2 を次のとおり改める。**

| 用途 | 何を使うか |
|---|---|
| **機械が読む結合キー** (後始末・照合・検査) | **順位**。詳細エントリの見出しを `### 順位 N: <タイトル>` の形にする |
| **人間が読む参照** (本文中の言及・相互参照) | **タスク名**。決定 2 のとおり変更なし |

タイトルは**表示用へ降格**する。書き換えても後始末は壊れない。

**前置形 (`### 順位 N: <タイトル>`) を採る。** 行頭で機械的に読め、タイトル末尾の自由記述 (`★ Bundle X` 等) と干渉しない。既存の消費側 (`hooks-pre-tool-validate` の `extract_heading_keywords`) は前置の `順位 N:` を strip する実装を既に持っており、そのまま両立する。

**決定 1 の「絶対番号は table のみ」は撤回する** — 順位 table が唯一の source of truth である点は変わらないが、詳細エントリはその ID を**参照として持つ**。再採番をしない (§ 改訂 2026-08-16) ため、この参照が drift することはない。

### 移行 (2026-08-26 実施)

**移行対象は「順位 table に行を持つ詳細エントリ」257 件**である。`todoN.md` の `### ` 見出しは全部で 276 件あり、**残る 53 件 (順位 table に行が無いもの) は対象外**として触っていない (下記)。対象 257 件すべてへ順位を付与し、対応付けは 5 段で解決している。

| 段 | 方法 | 件数 |
|---|---|---|
| 1 | 完全一致 | 116 |
| 2 | 前方一致で一意 | 49 |
| 3 | 先頭 12 文字で一意 | 58 |
| 4 | `系統 X-N` トークン一致 (todo21 / todo22 の系統的リネーム) | 26 |
| 5 | 手動確定 (ユーザー承認) | 8 |

移送スクリプトは**残さない** — 一度きりの作業であり、再発防止は検査側が担う ([ADR-042](adr-042-rule-vs-mechanism-boundary.md) § Mechanism graveyard prevention)。

**順位 table に行を持たない見出し 53 件は触っていない。** 順位が無いため後始末の対象にならず実害が無い。これらの可視化と扱いは順位 441 の 1:1 対応検査 (Phase D の D3) が担う。

## priority table 運用ルール (PR #111 post-merge-feedback で追加)

本 ADR 採用後の運用で発見された 2 件の暗黙的設計を明文化する。
Expand Down Expand Up @@ -270,8 +323,10 @@ table の `依存` 列を `順位 6` → `Phase pre` のようにタスク名に

新規タスクを現行の追加先 todo ファイル (`docs/todo.md` preamble の routing 表が指す最新の `todoN.md`。既存タスクへの追補はその収容ファイル) に追加する際は、以下の形式で記述する:

**見出しの `順位 <N>:` は必須である** (§ 改訂 2026-08-26)。後始末の機械層 (`cli-ledger-cleanup`) はここを鍵に詳細エントリを特定するため、欠けると完了時に `[LEDGER_CLEANUP_BLOCK]` で止まる。順位は順位 table へ行を追加したときに確定する。

```markdown
### <task name> (出典: PR #<N> T<X>-<Y>)
### 順位 <N>: <task name> (出典: PR #<N> T<X>-<Y>)

> **動機**: <既存の問題、or 機会>。
>
Expand Down
12 changes: 8 additions & 4 deletions docs/defect-convergence-plan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 不具合収束計画 — 後追い発覚ループの根治

> **状態**: Phase 0 は完了 (PR T・V・W・U = マージ済み。実走確認 1 件のみ残)。**次は Phase D (D1 → D2 → D3)**、Phase 1 以降は未着手。**PR 総数は新規 10 本 (機構 4 + ルール撤廃 3 + 台帳 drift 3)**。既存の第 2 バッチ 11 本 ([bugfix-batch-plan.md](bugfix-batch-plan.md)) と交錯して進める (→ [§ 全体順序](#全体順序))。
> **状態**: Phase 0 は完了 (PR T・V・W・U = マージ済み。実走確認 1 件のみ残)。**Phase D 進行中 (D1 = マージ済み / D2 = 実装済み・未マージ / D3 = 未着手)**、Phase 1 以降は未着手。**PR 総数は新規 10 本 (機構 4 + ルール撤廃 3 + 台帳 drift 3)**。既存の第 2 バッチ 11 本 ([bugfix-batch-plan.md](bugfix-batch-plan.md)) と交錯して進める (→ [§ 全体順序](#全体順序))。
>
> **本ファイルは ephemeral な作業計画書**であり、**本ファイルと参照先の repo 内ドキュメントだけで作業に着手できる**ことを編集方針とする (実装セッションは本計画の策定会話を参照できない)。退役条件は [§ 退役手順](#退役手順)。
>
Expand All @@ -10,8 +10,8 @@

| # | PR | Phase | 状態 |
|---|---|---|---|
| D1 | `fix(nightly-todo): 台帳削除の失敗も handoff marker の対象にする` | D | 未着手 |
| D2 | `feat(ledger): 詳細エントリに順位を付与し結合キーを移す` | D | 未着手 |
| D1 | `fix(nightly-todo): 台帳削除の失敗も handoff marker の対象にする` | D | **マージ済み ([#449](https://github.com/aloekun/claude-code-hook-test/pull/449))** |
| D2 | `feat(ledger): 詳細エントリに順位を付与し結合キーを移す` | D | **実装済み (未マージ)** |
| D3 | `feat(docs-lint): 順位 ⇄ 詳細エントリの 1:1 対応検査 (順位 441 の実装)` | D | 未着手 |
| 機1 | `feat(push-runner): testability gate — I/O 癒着判定の混入を止める` | 1 | 未着手 |
| 機2 | `feat(push-runner): open-questions gate — 未解決の問いが push を止める` | 2 | 未着手 |
Expand Down Expand Up @@ -88,6 +88,10 @@

## Phase D — 台帳 drift の根治 (新規 3 本)

**進捗 (2026-08-26)**: **D1 = マージ済み ([#449](https://github.com/aloekun/claude-code-hook-test/pull/449))**、**D2 = 実装済み (未マージ)**、D3 = 未着手。

**D2 の移送結果**: 移行対象は「**順位 table に行を持つ詳細エントリ**」257 件 (`todoN.md` の `### ` 見出しは全 276 件で、順位 table に行が無い 53 件は対象外)。対象 257 件すべてへ `### 順位 N: <タイトル>` を付与し、`remove_detail_entry` を順位照合へ差し替えた。段 4 は当初 34 件だったが、todo21 / todo22 の 26 件が「summary は `(系統 A-1)` 末尾 / 見出しは `系統 A-1:` 前置」という**系統的なリネーム**と判明し規則で解決できたため、手動確定は **8 件**で済んだ (2026-08-26 ユーザー承認)。実測で **257 件すべてが順位で一意に引ける**ことを確認済み。移送スクリプトは使い捨てとし残していない。

**何を止めるか**: 詳細エントリの結合キーが自由記述のタイトル文字列であるために、夜間ループの後始末が hard-fail し、失敗しても marker が残らず同じ順位が毎晩再選択される状態。

### 根因 (2026-08-26 実測)
Expand Down Expand Up @@ -174,7 +178,7 @@ summary の「タスク」列に `★ Bundle 195-FB follow-up` が付き、todo1

- [cli-docs-lint](../src/cli-docs-lint/) に「summary 行の順位 ⇄ 詳細エントリの順位」の 1:1 対応検査を追加する
- **双方向で検出する** — 順位行があって見出しが無い / 見出しがあって順位行が無い
- 既存違反 0 で有効化する。D2 完了後なら段 1〜3 の 223 件は解消済みで、残るのは段 4 の 34 件と逆向き孤児 53 件の扱い次第
- **D2 実施後の実測 (2026-08-26)**: 順位 table の 257 行はすべて対応する見出しを持つ (方向 A の違反 0)。残る課題は**方向 B の 53 件** — 順位 table に行が無い `### ` 見出しである。この 53 件の扱い (順位を採番して table へ載せる / 完了済みとして削除する / 検査の対象外と明示する) を D3 の着手時に決める。**そこが決まらないと既存違反 0 での有効化ができない**

**完了基準**: 片側だけの登録が `pnpm push` で落ちること。変異テストで検知を確認する。順位 441 のエントリ後始末 (todo22.md 節 + todo-summary2.md 行の削除) を同乗させる。

Expand Down
2 changes: 1 addition & 1 deletion docs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@

##### 完了基準: CLAUDE.md ADR index が ADR-031 → ADR-032 (欠番明示) → ADR-033 で連続化、ADR-033 の `ADR-032 PR-β` 参照 4 箇所が dead-pointer ではなくなる、`grep -rn 'ADR-032'` で残存 dead-pointer 0 件

### (追って) ADR-030 の takt-test-vc 反映
### 順位 28: (追って) ADR-030 の takt-test-vc 反映

> **参照**: [ADR-030](adr/adr-030-deterministic-post-merge-feedback.md)。
>
Expand Down
Loading
Loading