Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions docs/todo-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@
| 220 | 🔧 Tier 2 | **subprocess stress test (>64KB stdout) を ADR-031 weekly-review pipeline 経由で週次実行 (PR #217 post-merge-feedback T2-1 採用、ユーザー判断 2026-06-23 = hooks/pre-push には組み込まず週次に分離)** | todo10.md | M | なし (PR #217 で 2 module (jj_helpers.rs / todo_staleness.rs) に同型 subprocess deadlock pattern が独立観測 = Severity High + Frequency Medium、ただし手動検証困難な大 buffer 顕在化テストは毎回実行 (Stop hook / pre-push) には不適切で開発速度に影響、`#[ignore]` 付きで cargo test default skip + ADR-031 weekly workflow の rust-stress step として明示実行 (`cargo test -- --ignored --test-threads=1` 想定)、対象 = lib-subprocess の `drain_pipe_unlimited` + `wait_with_timeout_basic` 利用箇所、順位 221 (ADR docs) と test+docs の 2 層防御で相補) |
| 221 | 💎 Tier 3 | **ADR-NNN (採番未確定、land 時に確定): Safe Subprocess Stdout Pattern を ADR-016 appendix or 新 ADR で codify (PR #217 post-merge-feedback T3-1 採用)** | todo10.md | S | なし (PR #217 で `Stdio::piped()` を伴う `jj` spawn が 2 module で同一 pattern 違反 (concurrent drain なし → pipe buffer 枯渇 deadlock) を independent 観測、Severity Low + Frequency Medium + None risk、解決 pattern (`spawn_stdout_drainer` + `poll_child_with_deadline` または `lib_subprocess::drain_pipe_unlimited` + `wait_with_timeout_basic` の wrap、もしくは `Command::output()` / `Stdio::null()` の 3 択) を ADR-016 § 長時間コマンド戦略 への appendix or 新 ADR として明文化、ADR-025 CwdRestore guard pattern を precedent として cite、派生プロジェクト transferability 確保、順位 220 (test 層) と 1 PR bundle 推奨) |
| 222 | 💎 Tier 3 | **`~/.claude/CLAUDE.md` に「複数セッション跨ぎの計画文書作成時は AI が先走らずユーザー確認後に方針報告し GO/NO-GO を得る」ルール追加 (PR #218 post-merge-feedback #5 採用)** | todo10.md | XS | なし (PR #218 (docs PR) 本セッション内で Plan file 作成完了報告後、AI がユーザー承認なしに PR-W0 着手しようとして `[Request interrupted by user]` で停止された実観測、Severity Medium (AI 暴走 = UX 劣化) + Frequency Low (初観測) + Effort XS + Adoption Risk None、`~/.claude/CLAUDE.md` への 1 段落追記で全プロジェクトへ自動波及、`feedback_global_config_backup` 適用必須、memory `feedback_no_unauthorized_reorder` の補強として「計画書 / planning doc 作成のような大きな task 完了時は GO/NO-GO 確認を待つ」を明文化、本 ルール採用後は Auto mode でも planning doc レベルの完了時点では明示承認待ちが必須となる) |
| 223 | 🔧 Tier 2 | **`ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用) ★ Bundle 222-FB** | todo10.md | M | なし (PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` と hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` は同値必須 = 非対称になると両防御層の隙間に挟まる run が漏れる、現状はコメント契約のみで mechanical enforcement 欠落、`cli-merge-pipeline/src/feedback.rs:60` の derived const + 上流定数 precedent を cross-crate に拡張、Option C ベース (const re-export + `const _: () = assert!(...)` compile-time check) を MVP 推奨、analyzer Tier 1 = mechanical enforcement → memory `feedback_tier_classification` per project Tier 2 に再分類、順位 224 と 1 PR bundle 推奨 = mechanical + docs 2 層防御) |
| 224 | 💎 Tier 3 | **ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用) ★ Bundle 222-FB** | todo10.md | XS | なし (PR #222 `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` の 4 error path (mtime 取得失敗 / clock skew / malformed JSON / file read error) すべてが `false` 返却 → gate effective に倒れる fail-closed 構造を ADR-043 の concrete instantiation として codify、ADR が「概念定義 + 具体例 list」型に進化、派生プロジェクトへの transferability 向上、Severity Low + Frequency Medium + Effort XS + Adoption Risk None、順位 223 (mechanical) と相補 = 1 PR bundle 推奨、PR #222 / ADR-004 / ADR-043 の 3 文書 cross-reference 成立) |

**戦略**: Tier 1 を 2〜3 セッションで片付け → Tier 2 で ADR-032 の前提 + rate-limit + convergence cost 削減を進める → Tier 3 で ADR-032 を land + ドキュメント整備。Tier 4-5 は cleanup / 外部展開で daily efficiency への直接効果は小さい。

Expand Down
102 changes: 102 additions & 0 deletions docs/todo10.md
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,108 @@ ADR-039 (Experimental Feature 標準パターン) は「behavior の妥当性が

---

### `ACTIVE_RUN_FRESH_THRESHOLD_SECS` と `ORPHAN_THRESHOLD_SECS` の compile-time 同期 (PR #222 post-merge-feedback T1-1 採用)

> **動機**: PR #222 で hooks-stop-quality に追加した `ACTIVE_RUN_FRESH_THRESHOLD_SECS = 1500` は、hooks-session-start reaper の `ORPHAN_THRESHOLD_SECS = 1500` と **同値である必要がある** (Stop hook が「active」と判定する window と、reaper が「orphan」と判定する threshold が非対称になると、その隙間に挟まった run が両方の防御層から漏れる)。現状は `hooks-stop-quality/src/main.rs:67` のコメント (「reaper の `ORPHAN_THRESHOLD_SECS` (= 1500s) と同値」) で同期を「人間が読んで覚える」契約に留まり、片方を変更したときに他方を追従する mechanical enforcement が欠落している。
>
> 同型の precedent として `cli-merge-pipeline/src/feedback.rs:60` の `pub const ORPHAN_THRESHOLD_SECS: u64 = TAKT_TIMEOUT_SECS + 300;` が存在し、derived value として上流定数 (`TAKT_TIMEOUT_SECS`) との関係を compile-time で保証している。本 task は同じ pattern を hooks-stop-quality / hooks-session-start の magic number 同期にも適用する。
>
> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 1 #1 採用 (Severity Medium / Frequency Medium / Effort M / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「3 reports 全てで threshold alignment を言及。`cli-merge-pipeline` の precedent (const + assert 方式) が参照実装として存在、実装コスト低。drift 発生時に orphan detection window と quality gate skip window が非対称になるリスクが明確。Effort M かつ Frequency Medium で採用候補」。`feedback_tier_classification` per analyzer Tier 1 (= mechanical enforcement) → project Tier 2 (🔧) に再分類。
>
> **参照**: `.claude/feedback-reports/222.md` Tier 1 #1、`src/hooks-stop-quality/src/main.rs:67` (現状のコメント契約 + 定数定義)、`src/hooks-session-start/src/reaper.rs:29` (source of truth = `pub(crate) const ORPHAN_THRESHOLD_SECS: u64 = 1500`)、`src/cli-merge-pipeline/src/feedback.rs:60` (precedent: derived const + 上流定数 reference)、ADR-043 (Security/Quality Gate Fail-Closed) — fail-closed threshold の同期が崩れた場合のリスクを ADR で論じる経路、ADR-030 (決定論的 Post-Merge Feedback) § L2 reaper — `ORPHAN_THRESHOLD_SECS` の出処、順位 224 (ADR-043 amendment、bundle 推奨)。
>
> **実行優先度**: 🔧 **Tier 2** — Effort M。lib 抽出 (shared crate / lib module) vs cross-crate const re-export + compile-time assert の選択 + test 追加。

#### 設計決定 (案、land 時に判断)

3 案を比較し、本 task 着手時に Option 選択:

- **Option A** (shared lib crate 新設): `src/lib-takt-constants/` 等の新 crate を作成し `ORPHAN_THRESHOLD_SECS` / `ACTIVE_RUN_FRESH_THRESHOLD_SECS` を pub const として公開。reaper と stop-hook 双方が dep として import。**Pros**: 単一の source of truth、将来 takt 関連の magic number 追加に scale。**Cons**: 新 crate のため Cargo workspace への追加 + build graph 拡張、ADR-026 (Cargo workspace) との整合確認、過剰一般化のリスク (Effort M の上限)
- **Option B** (cross-crate const re-export): hooks-session-start の `reaper::ORPHAN_THRESHOLD_SECS` を `pub` に昇格、hooks-stop-quality が `[dependencies] hooks-session-start = { path = "..." }` で依存し `use hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS;` で参照。**Pros**: 新 crate 不要、変更最小。**Cons**: hooks crate 間の依存方向が逆 (本来は SessionStart hook と Stop hook は独立だが、これで一方向 dependency が発生)、cargo workspace の循環依存リスク (現状は問題なくとも将来制約に)
- **Option C** (compile-time assert via `const _: () = assert!(...)`): 各 hook crate で独立に const を定義しつつ、片方の crate 内で `const _: () = assert!(REAPER_ORPHAN_THRESHOLD_SECS == ACTIVE_RUN_FRESH_THRESHOLD_SECS);` 系の compile-time 検証を入れる。**Pros**: dep 依存 0、各 hook crate の autonomy 維持。**Cons**: 検証側 crate に「他 crate の値を埋め込む」必要があり、結局参照経路が必要 (= Option B と同等の依存になる)
- **MVP 推奨**: **Option C ベース** で、stop-hook 内に `const_eq` 系 macro / `const _: () = assert!(...)` を追加し、`hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を pub 昇格して dep + use。Option A (新 crate) は将来同型 magic number が 3+ 出てきた時に再評価
- **`cli-merge-pipeline/src/feedback.rs:60` の precedent を inline cite**: 上流定数 (`TAKT_TIMEOUT_SECS`) + derived const + 同 crate 内 const equality assert の構成例。本 task は cross-crate 版に拡張
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- **test 追加**: compile-time assert は失敗時 compile error なので runtime test は不要、ただし「片方の const を変更したら compile error になる」ことを確認する手順を README / コメントに記録 (PR description で dogfood)
- **派生プロジェクト transferability**: 本 pattern (cross-crate const sync) は派生プロジェクト (techbook-ledger / auto-review-fix-vc) でも同型ニーズが発生しうるが、現状は本 repo 固有のため transferability は ADR-016 / ADR-043 等への documentation 経由

#### 作業計画

- [ ] Option A / B / C 判断 (MVP 推奨 = Option C ベース + 必要なら dep 追加)
- [ ] `hooks-session-start::reaper::ORPHAN_THRESHOLD_SECS` を `pub` 昇格 (現状 `pub(crate)`)、必要なら module path の整理
- [ ] hooks-stop-quality の `Cargo.toml` に `hooks-session-start` dep を追加 (Option C の場合)
- [ ] hooks-stop-quality `main.rs` に `const _: () = assert!(ACTIVE_RUN_FRESH_THRESHOLD_SECS == hooks_session_start::reaper::ORPHAN_THRESHOLD_SECS);` を追加
- [ ] `cargo build --workspace` で compile-time assert が通ることを確認、片方を変更して compile error を観測 (PR description に貼付)
- [ ] hooks-stop-quality の既存コメント (line 67) を「compile-time assert で同期保証」 に更新
- [ ] 本 entry 削除 + todo-summary.md 行削除

#### 完了基準

- 片方の const を変更すると `cargo build` が compile error で失敗する
- hooks-stop-quality / hooks-session-start の magic number 同期が compile-time 契約として codified
- `cli-merge-pipeline/src/feedback.rs:60` precedent と同 pattern が確立、将来同型 magic number 追加時の参照実装になる
- ADR-030 §L2 と本 task の関係性が ADR 内で明示される (順位 224 と相補 = T1 mechanical + T3 docs)

#### 詰まっている箇所

- Option A/B/C 判断: 新 crate 追加 vs 既存 dep 追加 vs assert macro のいずれも trade-off あり、ADR-026 (Cargo workspace) との整合性を実装時に確認
- hooks crate 間の依存方向: SessionStart と Stop は本来独立な lifecycle stage だが、const 共有のため一方向 dep が必要 (Option B/C)。将来 hooks 共通 lib (= 順位 224 関連で hook_stop_quality の `meta_is_fresh` 抽出が浮上した場合) が出てきた際に再整理判断

---

### ADR-043 (Security/Quality Gate Fail-Closed) に hooks-stop-quality の error handling を具体例として追記 (PR #222 post-merge-feedback T3-1 採用)

> **動機**: PR #222 で hooks-stop-quality に追加した `meta_is_fresh()` / `meta_is_active_run()` / `takt_subsession_active()` は、すべての error path で `false` を返却することで「gate が effective (= skip しない)」状態に倒す **fail-closed pattern** を踏襲している。具体的には mtime 取得失敗 / system clock skew (future timestamp) / malformed JSON / file read error すべてが「active subsession ではないと判定」→「quality gate を skip しない」= 安全側に倒れる。
>
> ADR-043 (Security/Quality Gate での Fail-Closed 原則) は **試験運用 ADR** として既に存在するが、現状は abstract な原則記述に留まる。PR #222 の `meta_is_fresh` 実装は ADR-043 の **concrete instantiation** として価値があり、ADR 内の具体例 list に追記することで:
>
> - ADR が「概念定義 + 具体例 list」型に進化、将来同型 fail-closed pattern を実装する author の参照実装になる
> - 派生プロジェクト (techbook-ledger / auto-review-fix-vc) で hook / lint / pipeline を fail-closed で書く際の transferability 向上 (ADR は global 参照可能)
> - 順位 223 (mechanical enforcement) と相補的に、docs 層で fail-closed pattern を author 教育として codify
>
> **本タスクの位置づけ**: PR #222 post-merge-feedback Tier 3 #1 採用 (Severity Low / Frequency Medium / Effort XS / Adoption Risk None、2026-06-27 ユーザー承認)。analyzer rationale: 「ADR-043 は永続 artifact で既存。追記は XS Effort で ADR の具体例を充実。fail-closed pattern は本 PR 以外でも発生する (Frequency Medium)。Effort XS + None risk で採用候補」。
>
> **参照**: `.claude/feedback-reports/222.md` Tier 3 #1、`docs/adr/adr-043-security-gates-fail-closed.md` (追記対象、試験運用 ADR)、`src/hooks-stop-quality/src/main.rs` の `meta_is_fresh()` / `meta_is_active_run()` (具体例として cite)、PR #222 (`b0b91978`) (由来 cite)、順位 223 (T1 mechanical、bundle 推奨)、`feedback_global_config_backup` 適用は本リポジトリ docs/ のため不要 (グローバル CLAUDE.md / rules は触らない)。
>
> **実行優先度**: 💎 **Tier 3** — Effort XS。ADR-043 の既存 § 「concrete examples」 or 末尾に新 sub-section を追加 (~30 行)、mtime 取得失敗 / clock skew / malformed JSON / read error の 4 error path を列挙し、各 path で `false` 返却 → gate effective 維持を inline 説明。

#### 設計決定 (案)

- **追記位置**: ADR-043 に既存「concrete examples」section があればそこへ追加。無ければ末尾 (References 直前) に新 sub-section 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」を追加
- **記述項目**:
- 4 error path 各々で何が起き `false` 返却に倒れるか
- **mtime 取得失敗** (`std::fs::metadata()` error / `metadata.modified()` error): `Err(_) => return false`
- **system clock skew (future timestamp)**: `mtime.elapsed()` が `Err` を返した場合 `Err(_) => false` で skip 不可、orphan 扱いになる
- **malformed JSON**: `serde_json::from_str::<TaktMetaPartial>` が `Err` → `Ok(_)` 以外は `false`
- **file read error**: 同上、`fs::read_to_string` が `Err` → `false`
- 全ての error path が「subsession active ではない」= 「Stop hook の quality gate を skip しない」に倒れる構造 = fail-closed
- 反対 pattern (fail-open = error path で `true` 返却) の anti-example: orphan 1 件が残るだけで全 session の quality gate が永続 skip → ADR-004 §「freshness check の必要性」で詳細解説
- **由来 cite**: PR #222 で CR Major 指摘 (orphan 永続 skip リスク) に対応した freshness check 実装、ADR-004 amendment と本 ADR-043 追記の 2 ADR を同時更新した経緯を inline 引用
- **派生プロジェクト transferability**: ADR は global 参照可能、本 ADR を `~/.claude/rules/common/` から link することで techbook-ledger / auto-review-fix-vc 等に reference 提供
- **順位 223 との bundle**: 1 PR でまとめて land 推奨 (T1 mechanical layer + T3 docs layer の 2 層防御を 1 PR で確立)

#### 作業計画

- [ ] ADR-043 現状を read、追記位置 (既存 concrete examples or 新 sub-section) を判断
- [ ] 「Concrete instantiation: hooks-stop-quality の subsession freshness check (PR #222)」sub-section を追加 (~30 行)
- [ ] 4 error path の inline 説明 + anti-example (fail-open) の論理対比
- [ ] PR #222 + ADR-004 § freshness check との cross-reference 追加
- [ ] markdownlint clean
- [ ] 本 entry 削除 + todo-summary.md 行削除

#### 完了基準

- ADR-043 に hooks-stop-quality の error handling が concrete example として追記される
- 4 error path 各々の `false` 返却 logic と「gate effective」状態への倒し方が明示される
- PR #222 / ADR-004 / ADR-043 の 3 文書間の cross-reference が成立、reader が 1 example から原則 → 適用 → 反対例を辿れる
- 順位 223 と合わせ、mechanical (T2) + docs (T3) の 2 層防御確立

#### 詰まっている箇所

- ADR-043 が現時点で試験運用 (= ephemeral 性質を残す) のため、concrete example 追記が本採用昇格のトリガーになりうるかは現状 ADR 内容を read してから判断
- ADR-043 と ADR-004 の責務境界: 「fail-closed 原則の汎用論」(043) vs 「freshness check の必要性」(004) を ambiguous にせず、043 が「why fail-closed」、004 が「how freshness check works」と明確に分業する記述

---

## 既知課題 (記録のみ、本セッションで未対応)

(現時点で本ファイルへの既知課題は無し。docs/todo9.md 末尾を参照。)