diff --git a/docs/todo-summary.md b/docs/todo-summary.md index 9c41e23..6460ed7 100644 --- a/docs/todo-summary.md +++ b/docs/todo-summary.md @@ -32,7 +32,6 @@ | 36 | 🔧 Tier 2 | **cargo-mutants を post-PR pipeline に統合 — test ⇄ impl 制約の機械測定 (PR #96 T2-flaky) ★ Bundle X** | todo4.md | M | Bundle W land 後推奨 (PBT properties の後付け検証層、変更 crate + 1-hop 依存 scope) | | 37 | 🔧 Tier 2 | **pre-push concurrency stress runner (N=100) — scheduling space の random sampling (PR #96 T2-flaky) ★ Bundle X** | todo4.md | S | 順位 36 と同 PR (Bundle X、cli-push-runner に +~1 秒 step 追加) | | 38 | 💎 Tier 3 | **L3 weekly: cargo-mutants workspace 全体 + stress N=1000 を ADR-031 週次レビューに統合 (PR #96 T3-flaky)** | todo4.md | S | ADR-031 Phase B (順位 8) と同 bundle 化推奨、long-tail flake と coverage 全体監査 | -| 39 | 🚀 Tier 1 | **takt workflow `model` フィールド必須化 lint rule (PR #98 T1-1)** | todo4.md | S | なし (Bundle Y2 完全性: post-pr-review.yaml supervise step の `model:` 欠落を契機に決定論的防止層を追加) | | 40 | 🚀 Tier 1 | **prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2)** | todo4.md | XS | なし (本セッション再現の push 失敗を Step 1 fallback で早期検出。skill repo 側更新) | | 41 | 🔧 Tier 2 | **Bundle Y2 効果の定量計測 — post-merge-feedback / post-pr-review の avg time 比較 (PR #98 T2-2)** | todo4.md | M | なし (PR #97 sonnet baseline vs PR #98 以降 haiku の実測比較。Bundle Z / Z2 の ROI 判断材料、PR #98 merge 後 3-5 PR の観察ベース) | | 42 | 🔧 Tier 2 | **cli-pr-monitor の rate-limit auto-retry + `@coderabbitai review` auto-trigger 実装 (PR #99 T2-4) ★ Bundle a Sub-PR 2** | todo4.md | M | 順位 45 と同 PR (Sub-PR 2、Sub-PR 1 の `--list-findings` API を消費) | @@ -78,6 +77,7 @@ | 133 | 💎 Tier 3 | **docs-governance §Retirement Workflow に「diff context 由来 false alarm 防止 = grep hit は実ファイル Read で確認」明記 (PR #156 T3 #1 採用)** | todo8.md | XS | なし (PR #156 で 5 件以上の false alarm 発生、`feedback_no_unenforced_rules.md` 例外 = 既存実践の明文化 + guide 効果、順位 122 / 127 と同じロジック、`~/.claude/` global 配下で派生プロジェクトに自動波及) | | 134 | 💎 Tier 3 | **ADR-035 に docs-only PR 評価の適用外基準リスト追加 (mutation / error handling / DRY / YAGNI / function length / test coverage / magic-number 等) (PR #156 T3 #2 採用)** | todo8.md | S | なし (Severity Medium = reviewer の criteria 誤適用による unnecessary review overhead / 開発体験劣化、ADR-035 は分類基準のみ定義済で適用外基準が未明示、`feedback_no_unenforced_rules.md` 例外 = ADR への追加で機械強制ではなく reviewer / Claude の judgment 補助) | | 135 | 💎 Tier 3 | **todo entry の ADR 番号 hardcode 撤廃 — 「ADR-NNN (採番未確定、land 時に確定)」placeholder 採用 (順位 78 番号 conflict 2026-05-16 観測由来)** | todo8.md | XS | なし (順位 78 (旧 ADR-038 → ADR-041) で番号 conflict が顕在化、queue 滞留 entry の hardcode が後発 PR の採番と衝突する構造リスクを convention で予防、`~/.claude/rules/common/docs-governance.md` に 2-3 行追記。採番予約簿は管理コスト過剰のため見送り、land 時 PR で空き番号確定の軽量運用に統一) | +| 136 | 🚀 Tier 1 | **working copy staleness 検出 hook 2 段構え: SessionStart (jj git fetch + lineage 報告) + PreToolUse (stale 時 docs/todo*.md edit block) — 本セッション cleanup-stale-rank-39 由来** | todo8.md | M | なし (本セッションで実証された「stale parent で docs/todo*.md 読込 → 既削除 entry を再度削除提案」failure mode の structural enforcement。Claude Code Web 並列セッション運用前提下で再発確実。`feedback_no_unenforced_rules.md` 例外 = 2 つの hook で機械強制可能、案 A 予防層 + 案 B 最終 backstop の二段構え、ADR-039 experimental pattern 適用) | **戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 diff --git a/docs/todo4.md b/docs/todo4.md index 846e2c3..fede2bf 100644 --- a/docs/todo4.md +++ b/docs/todo4.md @@ -262,46 +262,6 @@ --- -### takt workflow `model` フィールド必須化 lint rule (PR #98 T1-1) - -> **動機**: Bundle Y2 (PR #98) で post-pr-review.yaml の analyze step に `model: haiku` を明示追加した結果、post-merge-feedback で同 yaml の `supervise` step (line 106-124) に `model:` フィールドが未指定であることが指摘された。`persona:` を持つ step で `model:` 未指定は default `sonnet` に落ちるため、Bundle Y2 ゴール (analyze 系 haiku / supervise・fix は sonnet 維持) では現時点で偶然合致しているが、将来 default 変更や persona 追加で意図せぬモデル選択が混入しうる。 -> -> **本タスクの位置づけ**: Bundle Y2 完全性 follow-up + 決定論的防止層の追加。`persona:` を持つ step に `model:` がないパターンを `.claude/custom-lint-rules.toml` の正規表現 lint rule として検出する。ADR-007 (custom-lint-rule の正規表現層 / AST 層線引き) の正規表現層に該当。 -> -> **参照**: `.claude/feedback-reports/98.md` Tier 1 #1 -> -> **実行優先度**: 🚀 **Tier 1** — Effort Small。yaml 設定変更のみで lint rule 追加可能。Bundle Y2 の完全性 (post-pr-review.yaml supervise step への `model: sonnet` 明示追加) も同 PR で land する想定。 - -#### 設計決定 (案) - -- **配置先**: `.claude/custom-lint-rules.toml` の新規 rule entry -- **検出ロジック (正規表現案)**: yaml ファイル内で `persona:` 行を見つけ、その同 step block 内に `model:` がない場合を検出する。yaml の階層を厳密に解析する場合は ADR-007 の AST 層昇格を検討 (Tree-sitter / yaml-rust) -- **適用対象**: `.takt/workflows/*.yaml` のみ (extensions: ["yaml"] + path filter) -- **副次作業**: post-pr-review.yaml supervise step に `model: sonnet` を明示追加 (Bundle Y2 完全性)。lint rule 導入と同 commit で実施することで、新 rule が clean baseline を保つ -- **rule 名 (案)**: `takt-workflow-persona-without-model` - -#### 作業計画 - -- [ ] 既存 `.claude/custom-lint-rules.toml` の構造を確認 -- [ ] 正規表現 + path filter を新 rule として記述 -- [ ] PostToolUse hook の lint runner で post-pr-review.yaml supervise step が検出されることを確認 -- [ ] post-pr-review.yaml supervise step に `model: sonnet` を明示追加 (Bundle Y2 完全性) -- [ ] pre-push-review.yaml / post-merge-feedback.yaml も全 step に `model:` が揃っているか確認 -- [ ] `pnpm deploy:hooks` で派生プロジェクトに rule を配布 -- [ ] 本 todo4.md エントリを削除 - -#### 完了基準 - -- `.claude/custom-lint-rules.toml` に新 rule が追加され `.takt/workflows/*.yaml` 全 step で `persona:` ⇔ `model:` 対応が確立 -- post-pr-review.yaml supervise step に `model: sonnet` 明示追加 (Bundle Y2 完全性確保) -- lint rule が将来の workflow 編集時に欠落を検出可能 - -#### 詰まっている箇所 - -- yaml の階層構造を正規表現のみで完全表現するのは難しい。実 workflow ファイルで false positive がないか着手時に確認。多発する場合は ADR-007 の AST 層昇格判断。 - ---- - ### prepare-pr skill Step 1 bookmark 存在チェック強化 (PR #98 T1-2) > **動機**: PR #98 セッションで、Bundle Y2 commit の `jj describe` 後の `pnpm push` がローカル bookmark 未作成のまま実行され、`jj git push` の default revset (`remote_bookmarks(remote=origin)..@`) で対象 0 件 → "Nothing changed" warning となり実質 push 失敗。push-runner は bookmark 自動採番ロジックを持たず、prepare-pr skill の Step 1 fallback (bookmark `/` 自動採番) でリカバリしたが、Step 1 の state 確認コマンド一覧に `jj bookmark list` の output 確認が明示されておらず、検出が「Step 1 fallback 表の `local_bookmarks` 空判定」に依存していた。 diff --git a/docs/todo8.md b/docs/todo8.md index c437ee0..541aba5 100644 --- a/docs/todo8.md +++ b/docs/todo8.md @@ -364,6 +364,74 @@ --- +### working copy staleness 検出 hook 2 段構え: SessionStart + PreToolUse (本セッション cleanup-stale-rank-39 由来) + +> **動機**: 本セッション (PR cleanup-stale-rank-39 作業中) で「local working copy が stale parent (master と sibling) のまま docs/todo*.md を読み込み、master 上で既に削除済の entry 2 件 (順位 104 / 126) を『stale entry として削除する』と誤判定」failure mode を実証した (実 stale entry は 1 件のみだった)。memory rule `feedback_verify_task_not_already_done.md` (todo 着手前に既実装検証 → stale entry 削除に再目的化) は強制力ゼロで再発確実 = memory rule 全般の限界 (`feedback_no_unenforced_rules.md` 原則の自己事例)。Claude Code Web との並列セッション運用前提下では構造的に同 mode が発生する。 +> +> **本タスクの位置づけ**: 本セッション post-merge-feedback 相当の structural defense。`feedback_no_unenforced_rules.md` 例外条件 = **2 つの hook で機械強制可能**。案 A (予防層 = session 起動時に状況認識) + 案 B (最終 backstop = stale 状態での編集を hard block) のセット二段構え。 +> +> **参照**: 本セッション (2026-05-18) PR cleanup-stale-rank-39 root cause 分析 (ユーザー対話)、memory `feedback_verify_task_not_already_done.md`、ADR-039 (Experimental feature 標準パターン) +> +> **実行優先度**: 🚀 **Tier 1** — Effort Medium (案 A ~80 行 + 案 B ~30 行)。本セッションの実観測 failure mode に対する直接対策で、並列セッション運用が常態化している現状で再発確率が高い。 + +#### 設計決定 (案 A + B) + +**案 A: SessionStart hook で `jj git fetch` + lineage 報告** + +- 配置: `src/hooks-session-start/` (既存があれば拡張、なければ新設) +- 動作: + 1. `jj git fetch --quiet` を timeout 付き (3 秒) で実行 + 2. `master..@-` / `@-..master` の commit 数を比較 + 3. additional context として AI に出力 (例): + ```text + [working-copy-freshness] + @: lmzvnwlu (parent: #159) + master: #161 (2 commits ahead of @-) + warning: working copy is behind master; recommend `jj rebase -d master` + ``` +- kill-switch: `hooks-config.toml` の `[session_start]` section に `enabled` flag +- 最適化: `.git/FETCH_HEAD` mtime を確認して「5 分以内なら fetch skip」 (network cost 抑制) +- fail-open: fetch timeout / 失敗時は warning なしで pass-through (block しない、AI 操作は継続可能) + +**案 B: PreToolUse hook で stale 時の `docs/todo*.md` edit を block** + +- 配置: 既存 `src/hooks-pre-tool-validate/` に統合 (~30 行追加) +- 動作: Edit / Write の対象が `docs/todo*.md` 系列のとき、master と @- の lineage 確認 → master が ahead なら hard block +- block message: + ```text + ❌ working copy parent (#X) is N commits behind master (#Y). + docs/todo*.md は state を反映する artifact のため、master と同期した状態で編集すること。 + 修正手順: `jj git fetch && jj new master` + ``` +- scope 限定: `docs/todo*.md` のみ block (コード / config までは過剰、false positive リスク) +- 案 A と異なり、本 hook は fail-closed (lineage 判定不能なら block) で安全側に倒す + +#### 作業計画 + +- [ ] 既存 SessionStart hook の有無確認 (`src/hooks-session-start/` または settings.json の `SessionStart` entry) +- [ ] `jj git fetch` の timeout / kill-switch / network 例外処理設計 +- [ ] `master..@-` の lineage 計算ロジック実装 (`jj log -r "master..@-" --no-graph -T 'description'` 等) +- [ ] additional context 出力フォーマット決定 (一行 vs 複数行、AI 読み飛ばし耐性検証) +- [ ] `hooks-pre-tool-validate.exe` に `docs/todo*.md` edit block ロジック追加 +- [ ] ADR 起案 (新 hook 設計 + ADR-039 experimental pattern 適用、land 時採番確定) +- [ ] dogfood 期間設定 (試験運用 flag で N 週間運用後採否決定) +- [ ] 派生プロジェクト (techbook-ledger / auto-review-fix-vc) deploy 検討 +- [ ] 本エントリ削除 + todo-summary.md 行削除 + +#### 完了基準 + +- session 開始時に working copy が master より遅れている場合、AI が context 出力で即座に状況を認識する +- stale parent 状態で `docs/todo*.md` を編集しようとすると hard block + 修正手順 (`jj git fetch && jj new master`) 表示 +- ADR-039 experimental pattern に従い kill-switch 装備 (network 異常 / feature branch 運用への退避経路) +- 派生プロジェクトでの動作確認 + +#### 詰まっている箇所 + +- `jj git fetch` の timeout が低速 network で頻発した場合の UX → 案 A は fail-open で warning なし pass-through、案 B は fail-closed (lineage 不能 = stale 扱い) で安全側に倒す trade-off +- master 判定ロジック: 現状 trunk-based 前提で master を正と扱う。feature branch 運用が始まると assumption が破綻するが、本リポジトリは当面 trunk-based のため問題なし。trunk 名 (master / main) は config 可能にしておく + +--- + ## 既知課題 (記録のみ、本セッションで未対応) ### post-merge-feedback workflow が長時間 stale marker を残す問題 (PR #119 marker observed 2026-05-15)