From df77f908dff2c9de5f196352cd86345323abf66a Mon Sep 17 00:00:00 2001 From: aloekun Date: Thu, 30 Apr 2026 00:48:28 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat(takt):=20Bundle=20T=20(reviewer=20face?= =?UTF-8?q?t=20=E6=94=B9=E5=96=84=20+=20.claude/=20filter)=20+=20Bundle=20?= =?UTF-8?q?U=20=E7=99=BB=E9=8C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit token 削減 Phase 2 (Bundle T) の本実装と、Bundle U の todo 登録を同梱する。 両者は token-reduction 系で論理的近接 + rate-limit 不安定期の PR 数最小化方針による同居。 ## Bundle T 本実装 (順位 9 + 14) ### 順位 9: Reviewer facet 改善 (PR #82 T3-combined) `.takt/facets/instructions/review-simplicity.md`: - Scope of DRY / YAGNI セクション追加 - DRY 適用範囲: コードロジックのみ。docs 階層化や docs/code 重複は対象外 - YAGNI 適用範囲: 実装 only。"Phase 2 検討" 等の計画書記述は対象外 `.takt/facets/instructions/review-security.md`: - Docs-only changes: trust boundary criterion セクション追加 - trust boundary 不変な docs 変更 (ポリシー説明・用語定義等) は APPROVE 即判定 - trust boundary 関連 (権限境界の再定義等) は通常 review ### 順位 14: post-pr-review fix loop の `.claude/` filter + ADR-030 制約明記 `.takt/facets/instructions/analyze-coderabbit.md`: - Sensitive-file protection filter 追加 (`.claude/**` → `user_decision_path`) - Scope mismatch を `.git/`, `.jj/`, `node_modules/`, `target/` まで拡張 - Verdict rule: `user_decision_path` は severity 問わず `user_decision` 経路へ - Output Format に User Decision Path テーブル追加 `docs/adr/adr-030-deterministic-post-merge-feedback.md`: - 「post-pr-review fix loop の対象外パス」セクション追加 - 3 カテゴリ documented: Claude sensitive-file / VCS 内部 / 依存物 - PR #91 で実証された 8 step 空費 pathological loop の採用根拠 - Verdict ルールの整合表と関連 ADR への参照 ## Bundle U 登録 (順位 29 + 30) `docs/todo.md`: - 順位 29 (Tier 1): 非 docs ファイル `docs/todo` 参照検出 lint rule - 順位 30 (Tier 3): Cross-File Reference Lifecycle ルールに具体例追記 - narrative に Bundle U 説明追加 `docs/todo3.md`: 上記 2 件の詳細エントリ追加 ## todo cleanup - todo.md table から順位 9, 14 削除 - todo2.md から順位 9 詳細削除 - todo3.md から順位 14 詳細削除 - 関連 narrative を完了状態に更新 ## 期待効果 - false positive iteration 削減: docs PR で simplicity/security の DRY/YAGNI 誤検出ゼロ - pathological loop 防止: `.claude/` 配下に finding が出る PR で 8 step 空費が再発しない - review report の透明性向上: User Decision Path として明示分類 ## 検証 - markdown lint: 全ファイル 0 errors - jj diff --stat: 7 files changed - 実装テスト: facet 変更は dogfood まで定量検証不能 (LLM 挙動)、初回適用 PR で観察 --- .../facets/instructions/analyze-coderabbit.md | 14 +- .takt/facets/instructions/review-security.md | 17 +++ .../facets/instructions/review-simplicity.md | 15 ++ ...r-030-deterministic-post-merge-feedback.md | 38 +++++ docs/todo.md | 13 +- docs/todo2.md | 50 ------- docs/todo3.md | 133 ++++++++++++------ 7 files changed, 178 insertions(+), 102 deletions(-) diff --git a/.takt/facets/instructions/analyze-coderabbit.md b/.takt/facets/instructions/analyze-coderabbit.md index 66ff6bb..b1ee997 100644 --- a/.takt/facets/instructions/analyze-coderabbit.md +++ b/.takt/facets/instructions/analyze-coderabbit.md @@ -22,11 +22,13 @@ CodeRabbit sometimes raises findings that are not applicable to this project. Be 2. For each finding, check: - **Platform scope**: This project targets Windows only. Findings about cross-platform compatibility (e.g., `.exe` hardcoding) are NOT applicable -- downgrade to `Info` - **Intentional design**: Check if the finding contradicts an ADR decision. If so, mark as `not_applicable` - - **Scope mismatch**: If the finding targets a read-only zone (`.takt/`, `docs/adr/`, `templates/`), mark as `not_applicable` + - **Sensitive-file protection** (Edit-blocked): If the finding targets `.claude/` (Claude Code sensitive-file protected — Edit/Write tool will refuse), mark as `user_decision_path` (NOT `not_applicable` — the issue may be real, but auto-fix cannot apply it) + - **Scope mismatch**: If the finding targets a read-only zone (`.takt/`, `docs/adr/`, `templates/`) or a non-source path (`.git/`, `.jj/`, `node_modules/`, `target/`), mark as `not_applicable` - **False positive**: If the finding misunderstands the code logic, mark as `not_applicable` Mark each finding as: - `applicable` -- genuine issue that should be addressed +- `user_decision_path` -- finding is real but auto-fix is blocked by sensitive-file protection (`.claude/`); user decides - `not_applicable` -- does not apply to this project (with reason) ### Step 3: Severity classification @@ -50,6 +52,11 @@ For `applicable` findings only, classify by severity: |---|-------------|-------|---------------| | 1 | path:line | ... | Platform scope: Windows only | +### User Decision Path (sensitive-file protected) +| # | File (Line) | Severity | Issue | Path Reason | +|---|-------------|----------|-------|-------------| +| 1 | .claude/... | Major | ... | sensitive-file protection — auto-fix blocked | + ### Applicable Findings by Severity #### Critical / High / Major @@ -69,12 +76,13 @@ For `applicable` findings only, classify by severity: - **approved**: No applicable findings, OR all applicable findings are Info/Low severity - Output: `approved` condition -- **needs_fix**: Any applicable Critical, High, or Major finding exists +- **needs_fix**: Any applicable Critical, High, or Major finding exists (excluding `user_decision_path`) - Output: `needs_fix` condition - These will be automatically fixed in the next step -- **user_decision**: Only Medium or lower applicable findings exist (no Critical/High/Major) +- **user_decision**: Only Medium or lower applicable findings exist, OR all remaining findings are `user_decision_path` (sensitive-file protected) regardless of severity - Output: `user_decision` condition - These are reported but NOT auto-fixed; the user decides + - **Important**: A `.claude/` finding of any severity routes here to prevent fix loop pathology (auto-fix would attempt 4+ Edit calls all blocked by sensitive-file protection, wasting iterations) ## Important diff --git a/.takt/facets/instructions/review-security.md b/.takt/facets/instructions/review-security.md index d76f56e..26dc6d1 100644 --- a/.takt/facets/instructions/review-security.md +++ b/.takt/facets/instructions/review-security.md @@ -31,3 +31,20 @@ Before evaluating the change, **read the following project documents** using the - Whether the change enables new privilege, data access, code execution, or prompt modification 3. For each detected issue, classify it as blocking or non-blocking 4. If there is even one blocking issue, judge as REJECT + +## Docs-only changes: trust boundary criterion + +For changes that touch **only documentation** (`docs/**`, ADRs, README, comments) and no executable code or configuration: + +- **Pass criterion**: If the change does NOT alter a trust boundary, judge as APPROVE without further security analysis +- **Trust boundary unchanged** (APPROVE immediately): + - Policy explanations, terminology definitions, design rationale + - Workflow descriptions, ADR records of past decisions + - Reformatting, hierarchy reorganization, cross-reference updates +- **Trust boundary changed** (apply full security review): + - Documentation of new authentication / authorization policies + - Redefinition of permission scopes or privilege boundaries + - Changes to documented secret handling, credential storage, or trust assumptions + - Specifications that other systems will rely on (API contracts, security guarantees) + +Rationale: documentation that does not redefine who-can-do-what cannot introduce security vulnerabilities by itself. Treating descriptive docs as security-relevant produces false-positive iterations and erodes review signal. diff --git a/.takt/facets/instructions/review-simplicity.md b/.takt/facets/instructions/review-simplicity.md index afeeb1f..2e156e2 100644 --- a/.takt/facets/instructions/review-simplicity.md +++ b/.takt/facets/instructions/review-simplicity.md @@ -20,6 +20,21 @@ Review ONLY the lines changed in the diff. Do NOT explore cross-file dependencie - **YAGNI violations**: Flag speculative abstractions, unused parameters, or over-engineered patterns that serve no current need - **Naming clarity**: Flag ambiguous variable/function names that obscure intent +## Scope of DRY / YAGNI (do NOT raise findings outside this scope) + +The DRY and YAGNI criteria above apply **only to executable code logic**. + +- **DRY scope**: Flag duplicated *code logic* (copy-paste functions, repeated control flow, redundant computations). Do NOT flag: + - Documentation hierarchies that intentionally restate context (e.g., a summary table followed by detailed bullet points) + - Repetition between docs and code (docs explain, code executes — they serve different audiences) + - Test code mirroring production code structure (test independence > test DRY) +- **YAGNI scope**: Flag *speculative code abstractions* (unused parameters, premature interfaces, over-engineered patterns in production code). Do NOT flag: + - Planning documents listing "future candidates", "Phase 2 検討", or "out of scope but worth considering" sections — these capture design intent for shared understanding, not speculative implementation + - ADR alternatives sections describing rejected options — these document the decision rationale + - Comments documenting *known constraints or limitations* of the current implementation (these are not speculation; they are recorded reality) + +If a finding cannot be tied to executable code logic, it is out of scope — do not raise it. + ## Judgment procedure 1. Read the diff from `.takt/review-diff.txt` diff --git a/docs/adr/adr-030-deterministic-post-merge-feedback.md b/docs/adr/adr-030-deterministic-post-merge-feedback.md index f36eb41..3cd53fc 100644 --- a/docs/adr/adr-030-deterministic-post-merge-feedback.md +++ b/docs/adr/adr-030-deterministic-post-merge-feedback.md @@ -281,6 +281,44 @@ GitHub 上に観測可能な成果物 (PR / tag / commit description) は一切 `pnpm merge-pr` 自体は ADR-028 の対象 (PR マージは外部可視) だが、これは既存ゲートで管理済み。本 ADR で追加するのは merge **後** の post_steps のみ。 +### post-pr-review fix loop の対象外パス + +post-pr-review workflow の `analyze` step が CodeRabbit findings を分類する際、以下のパスに該当する finding は `user_decision_path` (severity に関わらず `user_decision` verdict 経路) に分類し、自動 fix loop に流さない。 + +#### 対象外条件 + +| カテゴリ | パスパターン | 理由 | +|---------|-------------|------| +| Claude Code sensitive-file protection | `.claude/**` | Edit/Write tool が refuse する。fix loop が回ると `fix.1` / `fix_supervisor.1-3` の 4 step が空費される pathological loop に陥る | +| VCS 内部 | `.git/**`, `.jj/**` | バージョン管理系の内部ファイルは手作業対象外 | +| 依存物 | `node_modules/**`, `target/**` | ビルド成果物 / 外部依存。リポジトリ内のソース変更で対応すべき | + +#### 採用根拠 + +PR #91 で実証された pathological loop: + +- CodeRabbit が `.claude/` 配下のファイルへの finding を生成 +- `analyze` step が `needs_fix` 判定 → `fix` step 起動 +- `fix` step の Edit tool 呼び出しが Claude Code の sensitive-file protection でブロック +- supervisor が「fix 失敗」と判定して再 fix トリガー、最大 4 iteration まで全失敗 +- 結果: 8 step (analyze + fix×4 + supervisor×3) が空費され、rate-limit を浪費し review feedback が遅延 + +実装は `.takt/facets/instructions/analyze-coderabbit.md` の "Sensitive-file protection" / "Scope mismatch" filter として配置 (本 ADR は仕様のみ規定)。 + +#### Verdict ルールの整合 + +| Severity | 通常 path | `.claude/` etc. (対象外 path) | +|----------|----------|-------------------------------| +| Critical/High/Major | `needs_fix` (auto-fix) | `user_decision` (報告のみ、user に委ねる) | +| Medium 以下 | `user_decision` | `user_decision` (同左) | + +`user_decision` 経路に流すことで、findings 自体は report に含まれユーザーが判断できる一方、fix loop は走らないため pathological loop が発生しない。findings の握りつぶしではなく **責任の所在を auto-fix から user に移す** 設計。 + +#### 関連 ADR + +- ADR-022 (責務分離) — Edit-blocked path を auto-fix 対象から除外することで、自動化と手動操作の境界が明確化 +- ADR-018 (post-pr-monitor 移行) — post-pr-review workflow が `.takt/facets/` 配下の facet で挙動制御される設計の前提 + ## 実装タスク 詳細な実装手順は [`docs/todo.md`](../todo.md) の「マージ後フィードバック機構の決定論化」セクション Phase B-F を参照。本 ADR は仕様のみを規定する。 diff --git a/docs/todo.md b/docs/todo.md index eab35b2..bde9502 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -25,17 +25,15 @@ | 6 | 🚀 Tier 1 | ADR-032 PR-pre: GitHub Branch Protection 整備 | todo2.md | 設定のみ | なし (依存タスクは完了済) | | 7 | 🚀 Tier 1 | **PowerShell custom-lint-rule の `(?i)` フラグ自動検証 (PR #91 T1-1)** | todo3.md | S | なし (PR #91 直接対策、code-review.md 追記も同 PR で land) | | 8 | 🔧 Tier 2 | 週次レビュー (ADR-031) Phase B 実装 | todo.md | 中-高 | なし (順位 20 の compensating check 前提) | -| 9 | 🔧 Tier 2 | reviewer facet 改善 (review-simplicity / review-security の DRY/YAGNI/security 軸明文化) | todo2.md | S | なし | | 10 | 🔧 Tier 2 | ADR-032 PR-broken-link: broken-link-check + 内部アンカー検査 統合 | todo2.md | Small-中 | なし (clean baseline 確立済) | | 11 | 🔧 Tier 2 | `cli-pr-monitor` プロセス正常終了の integration test (PR #85 T2-2) | todo2.md | S | なし | | 12 | 🔧 Tier 2 | **`cli-pr-monitor` ポーリング延長 + 重複起動ロック (PR #88 T2-4)** ★ rate-limit critical | todo3.md | Medium | なし (Polling anti-pattern 検出 (PR #86 T1-1, 完了済) と補完) | | 13 | 🔧 Tier 2 | **post-pr-review に rate-limit 自動検出 + 再トリガー (PR #89 T2-1)** ★ rate-limit critical | todo3.md | Medium | なし (順位 12 と補完) | -| 14 | 🔧 Tier 2 | **post-pr-review fix loop の `.claude/` filter + ADR-030 制約明記 (PR #91 T2-1 + T3-2 Bundle)** ★ convergence | todo3.md | S + XS | なし (PR #91 直接対策、analyze facet + ADR 追記の同 PR Bundle) | | 15 | 🔧 Tier 2 | **cli-pr-monitor 通知 Recovery 経路 (SessionStart hook 拡張)** ★ silent loss prevention | todo3.md | S/M | なし (ADR-030 L2 recovery パターンを cli-pr-monitor に適用) | | 16 | 🔧 Tier 2 | **`vitest` を devDependencies に固定 (PR #88 T2-3)** | todo3.md | Small | なし | | 17 | 🔧 Tier 2 | **`pnpm create-pr` 必須引数ヘルプ改善 (PR #88 T2-5)** | todo3.md | Small | なし | | 18 | 🔧 Tier 2 | **`.failed` marker への recovery 手順自己文書化 (PR #90 T2-2)** | todo3.md | S | なし | -| 19 | 🔧 Tier 2 | **takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2)** | todo3.md | M | 順位 14 (path-based 解決) land 後推奨 | +| 19 | 🔧 Tier 2 | **takt ハーネスの `REJECT-ESCALATE` terminal verdict 実装 (PR #91 T2-2)** | todo3.md | M | post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) land 後推奨 | | 20 | 💎 Tier 3 | ADR-032 PR-β: 実装 (enabled=false default) | todo2.md | 中-高 | 6, 8, 10 | | 21 | 💎 Tier 3 | ADR-032 PR-γ: enablement (1 行 flip) | todo2.md | XS | 順位 8 dogfood + 順位 20 | | 22 | 💎 Tier 3 | ADR-032 PR-δ: dogfood + メトリクス検証 | todo2.md | (運用) | 順位 21 | @@ -45,18 +43,21 @@ | 26 | 💎 Tier 3 | **post-pr-monitor polling 禁止のグローバル明文化 (PR #86 T3-2)** | todo2.md | XS | なし | | 27 | 🧹 Tier 4 | ADR-030 Phase E/F: 旧機構廃止 + dogfood | todo.md | 中 | なし (cleanup) | | 28 | ⏳ Tier 5 | (追って) ADR-030 の takt-test-vc 反映 | todo.md | 中 | 順位 27 Phase F | +| 29 | 🚀 Tier 1 | **非 docs ファイル `docs/todo` 参照検出 lint rule (PR #94 T1-1) ★ Bundle U** | todo3.md | S | なし (PR #94 直接対策、Cross-File Reference Lifecycle の決定論的防止層) | +| 30 | 💎 Tier 3 | **Cross-File Reference Lifecycle ルールに具体例追記 (PR #94 T3-2) ★ Bundle U** | todo3.md | XS | なし (Bundle U で 29 と並行 land 推奨) | **戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。 **Bundle 1 完了 + post-merge-feedback 反映 (2026-04-29)**: PR #91 (Bundle 1: PowerShell + Markdown anchor lint rules) merge 後の post-merge-feedback で **4 件の新規 task を追加** (PowerShell `(?i)` 自動検証 / `.claude/` filter + ADR-030 制約 / cli-pr-monitor 通知 Recovery 経路 / takt REJECT-ESCALATE)。**前 2 件は本 PR で実証された「fix iteration の根因」に対する決定論的防止策で最優先候補**。**日付ベース見出しアンカーのグローバル明文化 task は決定論的防止 (no-mutable-anchor rule) との二重防衛として継続有効**。 -**reviewer facet 改善 task は全 PR の review 精度を即時向上させ、Tier 2 内で 週次レビュー Phase B / ADR-032 PR-broken-link / cli-pr-monitor exit test と並列実施可能**。 +**reviewer facet 改善 (Bundle T で land 済)** + **post-pr-review fix loop の `.claude/` filter (Bundle T で land 済)** が完了し、reviewer 精度向上 + convergence cost 削減の二段構えが成立。残る Tier 2 では rate-limit critical 系 (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) を最優先候補とする。 **rate-limit 系の 2 タスク (cli-pr-monitor ポーリング延長 + 重複起動ロック / post-pr-review rate-limit 自動検出 + 再トリガー) は rate-limit 直撃のため Tier 2 内で最優先候補**。前者 = ポーリング頻度全体の削減、後者 = review 単位での自動再トリガー、Polling anti-pattern 検出 (PR #86 T1-1、完了済) を含む 3 層で rate-limit を抑制する設計。 -**post-pr-review fix loop の `.claude/` filter + Recovery 経路 (SessionStart hook 拡張) は本 PR #91 の直接観測知見**。前者 = path-based filter で 8 step 空費の pathological loop を防止 / 後者 = SessionStart hook で再起動跨ぎの通知ロスト防止。 +**cli-pr-monitor 通知 Recovery 経路 (SessionStart hook 拡張) は PR #91 の直接観測知見**。SessionStart hook で再起動跨ぎの通知ロスト防止。post-pr-review fix loop の `.claude/` filter (path-based 解決) は Bundle T で land 済。 **Stop hook の `pnpm lint:md` 統合 task は Markdown linter hook 統合 (PR #88 で merged) の gap closure**。**AI 生成一時スクリプト pattern 検出は push 前 untracked `__*` hook (PR #85 T1-4) と関連** (実装前に擦り合わせ要)。 **`.failed` marker 自己文書化 task は ADR-030 soft-fail 機構の運用負荷削減** (PR #89 セッションで recovery が機能した実証から派生、Effort S)。 -**takt REJECT-ESCALATE は post-pr-review fix loop の `.claude/` filter task の verdict-based 一般解**。path-based 解決の land 後に着手することで、補完関係になる。 +**takt REJECT-ESCALATE は post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) の verdict-based 一般解**。path-based 解決が完了したので、本 task 着手で補完関係を完成させる。 **T3 グローバルルール 4 件 (日付ベース見出しアンカー / jj conflict リカバリ / `__` prefix scratch / post-pr-monitor polling 禁止) は `~/.claude/` 配下への XS 追記なので並列実施推奨**。 +**Bundle U (Cross-File Reference Lifecycle 強化) は PR #94 post-merge-feedback 直接対策**。非 docs ファイル `docs/todo` 参照検出 lint rule (Tier 1 = 決定論的防止) と Cross-File Reference Lifecycle ルール具体例追記 (Tier 3 = preventive guidance) を 1 PR で land 推奨。両者は同一テーマ (永続成果物→ephemeral 参照禁止の二層化) で補完関係、effort 合計 S+XS。 --- diff --git a/docs/todo2.md b/docs/todo2.md index 027ffe1..31f2874 100644 --- a/docs/todo2.md +++ b/docs/todo2.md @@ -362,56 +362,6 @@ Phase 観測 (4-6 週) Phase 2 (任意、段階的緩和) ``` -### Reviewer facet 改善 (review-simplicity / review-security の判定軸明文化、PR #82 T3-combined) - -> **動機**: PR #82 の pre-push-review で simplicity-review が docs 階層化を DRY 違反と誤検出する余地を観測 (実害は出なかったが false positive 発生条件)。post-merge-feedback (PR #82) が 3 件の reviewer 改善提案を生成 (simplicity の DRY スコープ規定 / YAGNI スコープ規定 / security の docs-only 判定軸)。reviewer の精度向上は **全 PR の review 効率に直結**。 -> -> **本タスクの位置づけ**: 既存 reviewer facet (`.takt/facets/instructions/review-simplicity.md` / `review-security.md`) のガイドライン明文化。新 facet 作成ではなく既存 instruction の補強。pre-push-review のみならず ADR-031 週次レビューや ADR-032 docs-only fast path にも整合性として効く。 -> -> **参照**: `.claude/feedback-reports/82.md` の Tier 3 #2-4 findings (3 件を統合) -> -> **実行優先度**: 🔧 **Tier 2** — 全 PR の review 精度を即時向上、false positive iteration の削減効果。Tier 2 内で 週次レビュー Phase B / ADR-032 PR-broken-link / cli-pr-monitor termination test と並列実施可能。Effort S × 3 = ~S。 - -#### 背景 - -- 本セッションでの観測: - - simplicity-review が docs 階層化や YAGNI 適用範囲を誤って指摘する余地 - - security-review が docs-only 変更で「trust boundary 不変」を正しく判定したが、判定軸が明文化されていない -- 全て小さな issue だが、reviewer の精度は全 PR の効率に直結 (false positive iteration はコスト) -- post-merge-feedback (PR #82) が 3 件を Tier 3 として独立に提案 - -#### 設計決定 (案) - -3 つの finding を 1 タスクに統合し、2 ファイルへの追記で完結: - -##### `.takt/facets/instructions/review-simplicity.md` への追記 - -- **DRY 適用範囲**: 「DRY 適用対象は **コードロジックのみ**。ドキュメントの階層化や記述の重複 (テーブル + bullet 等) は対象外」 -- **YAGNI 適用範囲**: 「YAGNI 適用対象はコード。**計画書・ドキュメント内の "将来候補" / "Phase 2 検討" 記述は対象外** (これらは設計の前提共有が目的で、実装の投機ではない)」 - -##### `.takt/facets/instructions/review-security.md` への追記 - -- **docs-only 変更の判定軸**: 「docs-only 変更の security 評価は **trust boundary の変化有無** で判断する。trust boundary が変化しない docs 変更 (ポリシー説明、用語定義、設計記述等) はリスクなしと即判定。trust boundary に関わる docs 変更 (認証ポリシー変更の文書化、権限境界の再定義等) は通常通り security review を実施」 - -#### 作業計画 - -- [ ] `.takt/facets/instructions/review-simplicity.md` に DRY スコープ + YAGNI スコープ規定を追記 -- [ ] `.takt/facets/instructions/review-security.md` に docs-only 判定軸を追記 -- [ ] takt 単体 dry-run で reviewer の判定挙動を確認 (false positive 削減) -- [ ] 派生 facet (`review-simplicity-whole.md` / `review-security-whole.md` を作成する場合、ADR-031 Phase B で派生時) にも同じ規定を継承 -- [ ] dogfood: 次回 docs PR や docs 階層化を含む PR で reviewer の判定が安定することを観察 -- [ ] 本 todo2.md エントリを削除 - -#### 完了基準 - -- review-simplicity / review-security の判定軸が明文化され、false positive 発生条件が縮小 -- 派生 facet (whole-tree 版を作る場合) にも同規定が継承される -- 次回 docs PR で simplicity-review / security-review の判定が安定 (DRY false positive ゼロ、security 軸の明確化を確認) - -#### 詰まっている箇所 - -なし (Effort S、既存 instruction への追記のみ) - ### push 前 untracked `__*` ファイル警告 hook (PR #85 T1-4) > **動機**: PR #85 で `__parse_transcripts.ps1` が jj auto-snapshot 経由で commit に意図せず混入。`.gitignore` への `__*` 追加で当面の再発は防止できたが、将来 `.gitignore` 漏れの可能性は残る。push 前に `__*` 命名の untracked file が working directory に残っていないか機械的に検出する安全網が必要。 diff --git a/docs/todo3.md b/docs/todo3.md index 371e12e..cfaf55d 100644 --- a/docs/todo3.md +++ b/docs/todo3.md @@ -416,47 +416,6 @@ prompt and prompt Claude to re-run the workflow. --- -### post-pr-review fix loop の `.claude/` filter + ADR-030 制約明記 (PR #91 T2-1 + T3-2 Bundle) - -> **動機**: PR #91 の post-pr-review で takt fix step が `.claude/` 配下のファイル (本ケースは存在しなかったが原則として) を fix loop 対象として扱った場合、Claude Code の sensitive-file protection により `Edit` ツールが実行時にブロックされ、`fix.1` / `fix_supervisor.1-3` の 4 回すべてが適用不能となり 8 ステップが空費される pathological loop が発生する。本 PR では実害は小さかったが、`.claude/` 配下に変更がある PR で発生すると review feedback の遅延 + rate-limit の早期消費を招く。 -> -> **本タスクの位置づけ**: post-pr-review の analyze step に **path-based filter** (`.claude/` 配下を fix 対象から除外し `user_decision` に分類) を追加。同 PR で ADR-030 (または ADR-022) に制約として「`.claude/` 配下は post-pr-review fix loop の対象外」を明記 (report Tier 3 #2 を統合)。 -> -> **参照**: `.claude/feedback-reports/91.md` の Tier 2 #1 + Tier 3 #2 (Bundle 統合採用) -> -> **実行優先度**: 🔧 **Tier 2** — 工数 S + XS。convergence cost 削減に即効。本 PR で 8 step 空費を直接観測した知見を取り込む。 - -#### 設計決定 (案) - -- 配置先: `.takt/facets/instructions/analyze-coderabbit.md` (または相当する analyze step facet) -- フィルタロジック (案): - - finding の対象 path が `.claude/` で始まる場合 → `verdict = user_decision`、`reason = ".claude/ is sensitive-file protected"` - - 同様に他の Edit-blocked path (`.git/`, `node_modules/` 等) も追加検討 -- ADR 改訂 (同 PR): - - ADR-030 に「post-pr-review fix loop の対象外パス」セクション追加 - - 対象外条件: ① Claude Code sensitive-file protection 配下、② `.git/` 等の VCS 内部、③ `node_modules/` 等の依存物 -- analyze-coderabbit.md と fix.md の read-only zone 定義の齟齬 (todo.md 「スコープ外だが将来検討」内既述) も同時解決の機会 - -#### 作業計画 - -- [ ] analyze step facet にパスフィルタ実装 -- [ ] fix step facet との read-only zone 定義整合性を確認 -- [ ] ADR-030 (または ADR-022) に制約を追記 -- [ ] dogfood: `.claude/` 配下に変更を含む PR を意図的に作って fix loop が回らないことを確認 -- [ ] 本 todo3.md エントリを削除 - -#### 完了基準 - -- analyze step が `.claude/` 配下の finding を `user_decision` 分類し fix loop に渡さない -- ADR-030 (または ADR-022) に制約が明文化される -- 8 step 空費の pathological loop が再発しない - -#### 詰まっている箇所 - -なし (Effort S+XS、analyze facet の path filter 追加 + ADR 追記のみ) - ---- - ### cli-pr-monitor 通知 Recovery 経路 (SessionStart hook 拡張) > **動機**: cli-pr-monitor は `pnpm push` / `pnpm create-pr` 内で in-process 同期実行され、CodeRabbit findings の検出結果を **親プロセスの stdout** で Claude shell に渡す設計 (ADR-018)。しかし Claude Code の再起動 / parent shell の orphan 化が起きると stdout が消失し、`.claude/pr-monitor-state.json` の `notified=false` 状態のまま silent loss する。本リポジトリでも PR #91 直後に Claude Code 再起動でこの事象を実体験。 @@ -514,7 +473,7 @@ prompt and prompt Claude to re-run the workflow. > > **参照**: `.claude/feedback-reports/91.md` の Tier 2 #2 > -> **実行優先度**: 🔧 **Tier 2** — 工数 M (数日)。takt 本体改修なので大きい。**rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) と post-pr-review fix loop の `.claude/` filter Bundle の land 後に実施推奨**。本 task は根本解だが、path-based filter で path-related な pathological loop は先に解決できる。 +> **実行優先度**: 🔧 **Tier 2** — 工数 M (数日)。takt 本体改修なので大きい。**rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に実施推奨**。本 task は根本解だが、post-pr-review fix loop の `.claude/` filter (Bundle T で land 済) で path-related な pathological loop は既に解決済み。 #### 設計決定 (案) @@ -547,4 +506,92 @@ prompt and prompt Claude to re-run the workflow. #### 詰まっている箇所 - takt 本体改修のため `~/.claude/projects/takt-test-vc/` 連動も視野に入れる必要あり -- rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) と post-pr-review fix loop の `.claude/` filter Bundle の land 後に着手することで、路径ベースの解決と verdict ベースの解決が補完関係になる +- rate-limit 系 task (cli-pr-monitor ポーリング延長 / post-pr-review rate-limit 自動検出) の land 後に着手することで、verdict ベースの一般解として完成する。post-pr-review fix loop の `.claude/` filter (Bundle T、完了済) は path-based 解決の対 (補完関係) + +### 非 docs ファイル `docs/todo` 参照検出 lint rule (PR #94 T1-1) + +> **動機**: PR #93 で `~/.claude/rules/common/coding-style.md` に Cross-File Reference Lifecycle 原則 (永続成果物 → ephemeral `docs/todo*.md` セクション参照禁止) を追加し、PR #94 で 3 ファイル (`src/hooks-pre-tool-validate/src/main.rs` / `.claude/custom-lint-rules.toml` / `.markdownlint-cli2.jsonc`) の retroactive 修正を実施した。ただしルールはガイドラインのみで決定論的検出はなく、新規ファイルへの混入は再発する。 +> +> **本タスクの位置づけ**: Cross-File Reference Lifecycle ルールの決定論的防止層。Bundle U として Cross-File Reference Lifecycle ルール具体例追記 (Tier 3) と並行 land 推奨。両者は preventive guidance (rule) + deterministic detection (lint) の補完関係。 +> +> **参照**: `.claude/feedback-reports/94.md` の Tier 1 #1 finding +> +> **実行優先度**: 🚀 **Tier 1** — 工数 S。新規ファイルでの再発を確実に防ぐ決定論的検出。Cross-File Reference Lifecycle ルールが既に存在するため、lint rule は同ルールの自動 enforcement 層として整合的。 + +#### 背景 + +- PR #94 で 3 ファイルの stale reference を grep 経由で発見・修正 +- ガイドラインだけでは AI が新規ファイル作成時に類似 pattern を再導入しうる +- `.claude/custom-lint-rules.toml` は既に literal 検出 + extension filter の枠組みを持つ (PowerShell `(?i)` フラグ検証等で実証済み) + +#### 設計決定 (案) + +- 配置先: `.claude/custom-lint-rules.toml` の新規 `[[rules]]` エントリ +- 検出 pattern (案): `docs/todo[0-9]*\.md` を非 `.md` ファイルから検出 + - `extensions = ["rs", "toml", "jsonc", "json", "ts", "tsx", "js", "jsx", "py", "ps1"]` で md 自体を除外 + - ただし custom-lint-rules.toml 自身が `.toml` で false positive 候補になるため、ルール記述用の例外パターン or 自己除外ロジックを設計時に確認 +- 提案メッセージ (案): 「永続成果物から ephemeral な docs/todo*.md セクション参照は禁止。ADR / PR 番号 / 安定 docs/ パスを使用。詳細は `~/.claude/rules/common/coding-style.md` Cross-File Reference Lifecycle セクション参照」 + +#### 作業計画 + +- [ ] `extensions` 設計: md 除外 + custom-lint-rules.toml 自身の self-exclusion 検証 +- [ ] 既存ファイルへの dogfood: 全リポジトリ grep で 0 matches を確認 +- [ ] テスト追加 (custom_lint_rule pattern の正規表現テスト枠組みがあれば活用) +- [ ] 派生プロジェクトへ deploy (Cross-File Reference Lifecycle ルールが global なのでセットで適用) +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- 非 md ファイルでの `docs/todo` literal 参照が hook で検出され警告/ブロックされる +- custom-lint-rules.toml 自身は false positive を起こさない +- 既存ファイル全体で 0 detection (clean baseline) + +#### 詰まっている箇所 + +- custom-lint-rules.toml への self-reference をどう扱うか (rule の文書化目的での `docs/todo` 言及をどう許可するか)。ルール記述部の delimiter 設計が必要 + +### Cross-File Reference Lifecycle ルールに具体例追記 (PR #94 T3-2) + +> **動機**: `~/.claude/rules/common/coding-style.md` に Cross-File Reference Lifecycle セクションを追加した (PR #93 post-merge-feedback で採用した Tier 3 #1) が、抽象的な原則のみで具体的な誤用例が乏しい。PR #94 で 3 種類の異なるファイル (Rust ソース / `.toml` config / `.jsonc` config) で同一 pattern が発生したという実証を活かし、各ファイル種における誤用例を明記することで AI が将来類似 context で警戒できるようにする。 +> +> **本タスクの位置づけ**: Cross-File Reference Lifecycle ルールの preventive guidance 層。Bundle U として 非 docs ファイル `docs/todo` 参照検出 lint rule (Tier 1) と並行 land 推奨。両者は preventive guidance (rule) + deterministic detection (lint) の補完関係で、ルール = AI の意識化、lint = 機械的検出。 +> +> **参照**: `.claude/feedback-reports/94.md` の Tier 3 #2 finding +> +> **実行優先度**: 💎 **Tier 3** — 工数 XS。`~/.claude/rules/` への既存セクション拡充のみ。Bundle U として Tier 1 と同 PR で land すれば、ルール文 + lint pattern の整合性を 1 review で確認できる。 + +#### 背景 + +- PR #93 で `~/.claude/rules/common/coding-style.md` に Cross-File Reference Lifecycle セクションを追加 +- 原則は抽象的: 「永続成果物 → ephemeral 成果物の参照禁止」 +- PR #94 で実証された 3 ファイル種の具体的誤用例: + - Rust raw string literal (`r#"..."#`) 内の block message + - TOML コメント内の引用例文字列 + - JSONC config ファイルのヘッダーコメント +- Boy Scout 修正 (`を参照。を参照。` 重複) も raw string 編集時の典型的注意点として補完価値あり + +#### 設計決定 (案) + +- 既存セクション (Cross-File Reference Lifecycle) に `### 具体的なアンチパターン例` サブセクションを追加 +- 例 1 (Rust): block message 内の `docs/todo.md の「
」を参照` 形式 +- 例 2 (TOML): コメント内の `[label](file.md#anchor)` 形式の引用 (引用すること自体が anti-pattern を再生産する構造的問題) +- 例 3 (JSONC): `// per docs/todo.md "" task` 形式の origin 記述 → PR 番号で置換 +- raw string 編集時の補足: 編集後の重複表現 (例: `を参照。を参照。`) を grep で目視確認することを推奨手順として追記 + +#### 作業計画 + +- [ ] `~/.claude/rules/common/coding-style.md` の Cross-File Reference Lifecycle セクションに具体例追加 +- [ ] PR #94 の 3 種類のファイル例を引用 (実証ベース) +- [ ] raw string 編集時の重複表現確認手順を補記 +- [ ] 動作確認: 次セッションで類似編集時に AI が anti-pattern を回避するか観察 +- [ ] 本 todo3.md エントリを削除 + +#### 完了基準 + +- グローバルルール `~/.claude/rules/common/coding-style.md` Cross-File Reference Lifecycle セクションに 3 種類のファイル例が記載される +- raw string 編集時の重複確認手順が明記される +- Bundle U の Tier 1 lint rule と整合 (lint pattern が検出する全 case が rule 例と対応) + +#### 詰まっている箇所 + +なし From c983377f4a808bf297e376c1432e6341502d8249 Mon Sep 17 00:00:00 2001 From: aloekun Date: Thu, 30 Apr 2026 01:31:18 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix(takt):=20CodeRabbit=20=E6=8C=87?= =?UTF-8?q?=E6=91=98=202=20=E4=BB=B6=E3=81=B8=E3=81=AE=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=20(PR=20#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finding #1 (Major, analyze-coderabbit.md): Step 3 と新規 User Decision Path テーブルの severity 列の整合性を解消。Step 3 を「Severity は CodeRabbit の severity field から取得 (`applicable` と `user_decision_path` 共通)」に明記し、 理由 (user の優先度判断に有用) を補足。`not_applicable` は severity 不要と 明記。 Finding #2 (Minor, ADR-030 line 315): LanguageTool 文法指摘に従い 「設計。」を「設計である。」に変更 (DOUSI_DEHA rule)。 --- .takt/facets/instructions/analyze-coderabbit.md | 4 +++- docs/adr/adr-030-deterministic-post-merge-feedback.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.takt/facets/instructions/analyze-coderabbit.md b/.takt/facets/instructions/analyze-coderabbit.md index b1ee997..1b300ea 100644 --- a/.takt/facets/instructions/analyze-coderabbit.md +++ b/.takt/facets/instructions/analyze-coderabbit.md @@ -32,9 +32,11 @@ Mark each finding as: - `not_applicable` -- does not apply to this project (with reason) ### Step 3: Severity classification -For `applicable` findings only, classify by severity: +For both `applicable` and `user_decision_path` findings, take the severity from CodeRabbit's `severity` field (do not reclassify): - Critical > High > Major > Medium > Minor > Low > Info +The severity is preserved on `user_decision_path` findings so the user can prioritize their manual decision (a Critical `.claude/` finding still warrants attention even though auto-fix cannot apply it). For `not_applicable` findings, severity is irrelevant and may be omitted from the report. + ### Step 4: Produce report and verdict ## Output Format diff --git a/docs/adr/adr-030-deterministic-post-merge-feedback.md b/docs/adr/adr-030-deterministic-post-merge-feedback.md index 3cd53fc..c4bcb18 100644 --- a/docs/adr/adr-030-deterministic-post-merge-feedback.md +++ b/docs/adr/adr-030-deterministic-post-merge-feedback.md @@ -312,7 +312,7 @@ PR #91 で実証された pathological loop: | Critical/High/Major | `needs_fix` (auto-fix) | `user_decision` (報告のみ、user に委ねる) | | Medium 以下 | `user_decision` | `user_decision` (同左) | -`user_decision` 経路に流すことで、findings 自体は report に含まれユーザーが判断できる一方、fix loop は走らないため pathological loop が発生しない。findings の握りつぶしではなく **責任の所在を auto-fix から user に移す** 設計。 +`user_decision` 経路に流すことで、findings 自体は report に含まれユーザーが判断できる一方、fix loop は走らないため pathological loop が発生しない。findings の握りつぶしではなく **責任の所在を auto-fix から user に移す** 設計である。 #### 関連 ADR From f57621981d3031f49f15f9b916454659bfd3c1c1 Mon Sep 17 00:00:00 2001 From: aloekun Date: Thu, 30 Apr 2026 03:23:26 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix(adr):=20ADR-030=20=E3=81=A8=20analyze-c?= =?UTF-8?q?oderabbit.md=20=E3=81=AE=E6=95=B4=E5=90=88=E6=80=A7=E3=82=92?= =?UTF-8?q?=E8=A7=A3=E6=B6=88=20(PR=20#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit 再レビューで検出された Major × 2 件への対応: Finding A (line 286-287): 「すべての除外 path は user_decision_path」記述が 実装と乖離していた。実装では `.claude/**` のみ user_decision_path で、 VCS/依存物は not_applicable (別経路、Step 2 でフィルタ)。本 commit で 2 種類の分類を明示。前回 commit で Scope mismatch を 4 path に拡張した際の ADR テキスト更新漏れの drift を解消。 Finding B (line 310-313): Verdict テーブルヘッダ「.claude/ etc. (対象外 path)」 が verdict routing に参加する全 path を示すよう誤読されるため、 「.claude/ (user_decision_path)」に変更。テーブル前に「verdict routing に 参加する applicable と user_decision_path のみを示す」注記を追加し、 not_applicable が verdict に関与しないことを明記。 両者とも CodeRabbit suggestion 準拠 (commit_id c983377f を root とする 分類整合性問題、本 commit で完全に整合)。 --- ...r-030-deterministic-post-merge-feedback.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/adr/adr-030-deterministic-post-merge-feedback.md b/docs/adr/adr-030-deterministic-post-merge-feedback.md index c4bcb18..65605ee 100644 --- a/docs/adr/adr-030-deterministic-post-merge-feedback.md +++ b/docs/adr/adr-030-deterministic-post-merge-feedback.md @@ -283,15 +283,18 @@ GitHub 上に観測可能な成果物 (PR / tag / commit description) は一切 ### post-pr-review fix loop の対象外パス -post-pr-review workflow の `analyze` step が CodeRabbit findings を分類する際、以下のパスに該当する finding は `user_decision_path` (severity に関わらず `user_decision` verdict 経路) に分類し、自動 fix loop に流さない。 +post-pr-review workflow の `analyze` step が CodeRabbit findings を分類する際、以下のパスに該当する finding は自動 fix loop に流さない。分類は **2 種類**: + +- `.claude/**` → `user_decision_path` (severity 付きで報告し `user_decision` verdict 経路へ) +- VCS 内部 / 依存物 → `not_applicable` (Step 2 でフィルタされ verdict routing には参加しない) #### 対象外条件 -| カテゴリ | パスパターン | 理由 | -|---------|-------------|------| -| Claude Code sensitive-file protection | `.claude/**` | Edit/Write tool が refuse する。fix loop が回ると `fix.1` / `fix_supervisor.1-3` の 4 step が空費される pathological loop に陥る | -| VCS 内部 | `.git/**`, `.jj/**` | バージョン管理系の内部ファイルは手作業対象外 | -| 依存物 | `node_modules/**`, `target/**` | ビルド成果物 / 外部依存。リポジトリ内のソース変更で対応すべき | +| カテゴリ | パスパターン | 分類 | 理由 | +|---------|-------------|------|------| +| Claude Code sensitive-file protection | `.claude/**` | `user_decision_path` | Edit/Write tool が refuse する。fix loop が回ると `fix.1` / `fix_supervisor.1-3` の 4 step が空費される pathological loop に陥る。finding は実在しうるため severity 付きで報告し user に判断を委ねる | +| VCS 内部 | `.git/**`, `.jj/**` | `not_applicable` | バージョン管理系の内部ファイルはプロジェクト対象外。"Filtered Findings" として記録のみ | +| 依存物 | `node_modules/**`, `target/**` | `not_applicable` | ビルド成果物 / 外部依存。リポジトリ内のソース変更で対応すべき | #### 採用根拠 @@ -307,9 +310,11 @@ PR #91 で実証された pathological loop: #### Verdict ルールの整合 -| Severity | 通常 path | `.claude/` etc. (対象外 path) | -|----------|----------|-------------------------------| -| Critical/High/Major | `needs_fix` (auto-fix) | `user_decision` (報告のみ、user に委ねる) | +以下のテーブルは verdict routing に参加する findings (`applicable` および `user_decision_path`) のみを示す。`not_applicable` findings (VCS 内部 / 依存物) は Step 2 で既にフィルタされ verdict には関与しない。 + +| Severity | 通常 path (`applicable`) | `.claude/` (`user_decision_path`) | +|----------|--------------------------|-----------------------------------| +| Critical/High/Major | `needs_fix` (auto-fix) | `user_decision` (報告のみ) | | Medium 以下 | `user_decision` | `user_decision` (同左) | `user_decision` 経路に流すことで、findings 自体は report に含まれユーザーが判断できる一方、fix loop は走らないため pathological loop が発生しない。findings の握りつぶしではなく **責任の所在を auto-fix から user に移す** 設計である。 From 4dc098b66298835feaf3e79c19f48585f4f93674 Mon Sep 17 00:00:00 2001 From: aloekun Date: Thu, 30 Apr 2026 04:01:33 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix(adr):=20ADR-030=20line=20325=20?= =?UTF-8?q?=E3=81=AE=20ADR-018=20=E8=A1=A8=E8=A8=98=E3=82=92=20'cli-pr-mon?= =?UTF-8?q?itor=20takt=20=E7=A7=BB=E8=A1=8C'=20=E3=81=AB=E7=B5=B1=E4=B8=80?= =?UTF-8?q?=20(PR=20#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeRabbit 再レビュー指摘 (Minor) への対応。本文 line 35 / References line 365 で既に 'cli-pr-monitor' 表記に統一されていたが、本 PR の前 commit で追加した '関連 ADR' セクションのみ 'post-pr-monitor 移行' と誤記。post-pr-monitor は workflow 名で ADR-018 の対象 tool ('cli-pr-monitor') と異なる概念のため事実誤認。 実 ADR-018 タイトル ('cli-pr-monitor の takt ベース移行と CronCreate 廃止') に 合わせて統一。 --- docs/adr/adr-030-deterministic-post-merge-feedback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/adr/adr-030-deterministic-post-merge-feedback.md b/docs/adr/adr-030-deterministic-post-merge-feedback.md index 65605ee..718bab1 100644 --- a/docs/adr/adr-030-deterministic-post-merge-feedback.md +++ b/docs/adr/adr-030-deterministic-post-merge-feedback.md @@ -322,7 +322,7 @@ PR #91 で実証された pathological loop: #### 関連 ADR - ADR-022 (責務分離) — Edit-blocked path を auto-fix 対象から除外することで、自動化と手動操作の境界が明確化 -- ADR-018 (post-pr-monitor 移行) — post-pr-review workflow が `.takt/facets/` 配下の facet で挙動制御される設計の前提 +- ADR-018 (cli-pr-monitor takt 移行) — post-pr-review workflow が `.takt/facets/` 配下の facet で挙動制御される設計の前提 ## 実装タスク