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
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ members = [
"src/cli-nightly-task-select",
"src/cli-pr-monitor",
"src/cli-push-runner",
"src/cli-stale-branch-scan",
"src/cli-takt-timings",
"src/cli-telemetry-report",
"src/hooks-post-tool-comment-lint-rust",
Expand Down
55 changes: 54 additions & 1 deletion docs/adr/adr-031-weekly-review-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,33 @@ must-run でないことが「skill を主動線に置ける」設計上の余
|---|------|-----|------------|
| **L1 Reminder** | `hooks-session-start` (Rust) 拡張 | `.claude/weekly-review-last-run.json` の `last_run_at` を見て、7 日以上経過していれば `additionalContext` で `/weekly-review` を促す。`last_run_at` が無い旧/破損データは stale 扱い (発火) にして次回更新で移行 (mtime にはフォールバックしない) | reminder 不在 (致命的でない、ユーザーが気付けば実行) |
| **L2 Review** (AI parallel) | takt workflow `weekly-review` | 5 facets (simplicity / security / architecture / todo / jj-robustness) + 決定論的 file-size scan を **whole-tree** で並列レビュー、aggregate step で findings JSON + markdown 統合 | `.claude/weekly-reviews/<date>.md.failed` marker 残存 → 次セッションの L1 hook が recovery context を出力 |
| **L3 Approval & Apply** | skill `/weekly-review` | takt 起動 → pending JSON 読み込み → AskUserQuestion で採否一括選択 → 採用分のみ docs/todo.md に追記 | best-effort (ユーザーが skill を再起動すれば pending JSON から再開可能) |
| **L3 Approval & Apply** | skill `/weekly-review` | **決定論 scan (`pnpm stale-branch-scan`) の同期実行** → takt 起動 → pending JSON 読み込み → AskUserQuestion で採否一括選択 → 採用分のみ docs/todo.md に追記 | best-effort (ユーザーが skill を再起動すれば pending JSON から再開可能) |

#### 各層の実体がどこにあるか

**L3 (skill) だけ本リポジトリの外にある。** レビューで「ADR は L3 の実装を定義しているがリポジトリに skill ファイルが無い」と指摘されたため明記する ([PR #377](https://github.com/aloekun/claude-code-hook-test/pull/377))。

| 層 | 実体の所在 | VCS |
|---|---|---|
| L1 Reminder | `src/hooks-session-start/` | 本リポジトリ |
| L2 Review | `.takt/workflows/weekly-review.yaml` + `.takt/facets/instructions/*` | 本リポジトリ |
| L2 外の決定論 scan | `src/cli-stale-branch-scan/` (`pnpm stale-branch-scan`) | 本リポジトリ |
| **L3 Approval & Apply** | **skills repo (`$CLAUDE_SKILLS_REPO`) の `weekly-review/SKILL.md`** を `~/.claude/skills/` へ deploy | **別リポジトリ** |

skill を別リポジトリに置く構成は [ADR-062](adr-062-monthly-harness-roi-review.md) (`/monthly-review`) と同じで、本 ADR に固有の判断ではない。**帰結として、skill 側の変更は本リポジトリの PR diff に現れない** — L2/L3 をまたぐ変更をするときは、両リポジトリの更新が揃っているかを人間が確認する必要がある (自動で照合する仕組みは無く、`/skill-sync-check` が手動の確認手段)。

#### L2 に置けない決定論 scan は L3 が直接呼ぶ (2026-08-09 追記、順位 395)

**takt workflow (L2) はネットワークを持たない。** [weekly-review.yaml](../../.takt/workflows/weekly-review.yaml) は全 provider に `network_access: false` を課しており、他 3 パイプライン (`pre-push-review` / `post-pr-review` / `post-merge-feedback`) が `true` なのと意図的に異なる — whole-tree の 6 facet はローカルのソースツリーだけを読めばよく、外部へ出ないことが隔離として効いている。

そのため **`git ls-remote` / `gh` を要する決定論 scan は L2 に置けない**。1 つの scan のために `network_access: true` へ反転すると、**6 facet すべての隔離が同時に緩む**からである。代わりに L3 (skill) が takt 起動の前に決定論 exe を同期実行し、その出力を findings と並べて採否にかける。`/monthly-review` が `cli-telemetry-report` を同期実行する形 ([ADR-062](adr-062-monthly-harness-roi-review.md)) と同じ配置になる。

**判断基準**: 決定論 scan の置き場所は「ネットワークが要るか」で決まる。

| 条件 | 置き場所 | 例 |
|---|---|---|
| ローカルファイルだけで完結 | **L2** の parallel step (`file-length-watchlist` 型) | `.rs` 行数 / `todo*.md` バイト数 |
| ネットワーク (`gh` / `git ls-remote` / API) が要る | **L3** が takt 起動前に同期実行 | 残存ブランチ検出 (`cli-stale-branch-scan`) |
Comment thread
aloekun marked this conversation as resolved.

### 全体フロー

Expand Down Expand Up @@ -176,6 +202,33 @@ skill /weekly-review (Phase 1-4)
| `file-length-watchlist` | 決定論的 file-size scan (`.rs` 800 行 + `todo*.md` 50KB)。LLM 判断ゼロの機械観測 | PR-W0 拡張 (順位154) |
| `aggregate-weekly` | 6 reports → findings JSON + markdown (採否単位の構造化) | `aggregate-feedback.md` を参考 |

**workflow の外にもう 1 つ決定論 scan がある**: 残存ブランチ検出 (`cli-stale-branch-scan`、順位 395) は `gh` / `git ls-remote` を要するため本 workflow には入らず、L3 の skill が takt 起動前に実行する (§ アーキテクチャ の「L2 に置けない決定論 scan」)。

### 残存ブランチ検出 (`cli-stale-branch-scan`、2026-08-09 追加、順位 395)

**由来**: クローズ済み PR [#365](https://github.com/aloekun/claude-code-hook-test/pull/365) のブランチを手で消したことで [ADR-072](adr-072-nightly-todo-loop.md) 決定 3 の除外マーカーが失われ、同じ順位が再選択された。決定 3 自体は設計どおりで、**ブランチの存在が着手済みマーカー**である以上、浮いたブランチを定期的に片付ける場が要る。

**判定規則**: remote ブランチ 1 本ごとに、それを head とする PR を全状態で引き、

- **すべて closed / merged** → 削除候補 (提案対象)
- **open が 1 本でもある** → 対象外。close 後に別 PR を開く / reopen する形が実在するため、閉じた側だけを見て消す提案を出さない
- **PR が 1 件も無い** → 対象外。まだ PR を開いていない作業中のブランチと区別できない
- **trunk (`master` / `main` / `HEAD`)** → 常に対象外
- **`claude/nightly-*` を除外しない** (2026-08-09 ユーザー判断)。除外すると夜間 PR のブランチが永久に残り、同じ順位が二度と選ばれなくなる

state が未知の値だった場合は **open と同じ扱い (保護側)** にする。GitHub が state を追加したときに、解釈できない PR を持つブランチが「PR 無し」と誤判定されて削除提案に載るのが最悪の失敗だから。

**PR は全件引かずブランチごとに引く**。総 PR 数は単調増加する一方、remote ブランチ数は運用上小さく有界である。全件方式は取得上限の保守を延々と生み、上限に張り付いた瞬間 fail-closed で scan 自体が止まる — **実装中に実際に踏んだ** (本リポジトリは PR が 300 件を超えており、全件方式は書いた時点で既に使えなかった)。

**削除は提案までで止める** ([ADR-022](adr-022-automation-responsibility-separation.md) / [ADR-028](adr-028-pnpm-create-pr-gate.md))。出力に含めるのは人間がそのまま貼れる `git push origin --delete -- <branch>` であって、exe は実行しない。ブランチ削除は外部可視で、しかも**着手済みマーカーの破棄**でもあるため ([ADR-072](adr-072-nightly-todo-loop.md) 決定 3)、判断を自律 actor に渡さない。

**貼れるコマンドである以上、ブランチ名は攻撃面になる。** git の ref 名規則は `;` / バッククォート / `|` / `$()` を許し (`git check-ref-format` で実測)、`--force` のような `-` 始まりも有効な ref 名である。したがって出力側で 2 つの手当てを打つ:

- **`--` 区切りを必ず挟む**。これが無いと `-` 始まりのブランチ名が `git push` のフラグとして解釈される
- **安全文字 (`[A-Za-z0-9._/-]`) の allowlist から外れる名前には、そもそも貼れるコマンドを生成しない**。ブランチ名は 3 つの表すべてに出るため、無害化は描画の全経路で共通の関数を通す (出口ごとに個別対策を足すと、出口が増えたときに同じ穴が空く)

**出力に wall-clock を含めない**。同じリポジトリ状態なら同じ出力になるようにしてあり、週次で前回分と diff を取れば「今週新たに浮いたブランチ」だけが読める。時刻を混ぜると毎回全行が差分になる。実行時刻は呼び手 (skill / weekly report) が記録する。

**並列構成**: 5 review facets + 決定論的 file-size scan (計 6) を `parallel:` block で並列実行し、`aggregate-weekly` で統合する。これは [post-merge-feedback.yaml](../../.takt/workflows/post-merge-feedback.yaml) の構造を流用する (analyze 並列 → aggregate)。fix loop は不要 (修正対象がコードではなく findings レポート生成)。

### 入力源
Expand Down
2 changes: 1 addition & 1 deletion docs/harness-improvement-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Anthropic 公式のハーネスエンジニアリング指針(決定論的基
| **スモーク未確定 3 件のうち (c) `cargo` サブプロセスへのトークン露出**(順位 374 の残り。**意図的保留** — 初版 probe の設計欠陥を解消した安全な probe を設計してから 1 回で観測。ADR-072 決定 5 の Bash 再付与判断の材料でもある) | ADR-072 § 残課題 | 急がない(Bash 非付与が保守側)。**完走条件には含めない** |
| **採用率 2 週間測定**(WP 全体の受け入れ基準。人間がマージした割合 50% 超で継続・拡大 — 参考値であり統計的意味は無い、ADR-072 § 欠点)。測定は weekly-review の自律アクション棚卸し(WP-19 ステップ 3)へ載せて仕組み化。**開始起点 = スモーク完走後(2026-08-09 ユーザー決定)**。完走の定義を順位 394 の実走確認(PR に CodeRabbit の初回自動レビューが付くこと)までとし、意図的保留のトークン露出は完走条件に含めない | ADR-072 § 試験運用判断基準 | 2026-11-06 までに判定 |
| 稼働後 1 週間の run 頻度・Max 枠消費を観測して schedule 頻度を調整 | 運用ノート(本表のみ) | 稼働中 |
| **順位 395: 週次レビューで浮きブランチを検出し削除を提案** — 判定は現行の branch 単一ソース(`git ls-remote`)を維持し、滞留(最大 7 日程度)は許容する。`claude/nightly-*` も対象に含める。自動削除はしない | [todo21.md](todo21.md) | 🔧 Tier 2、WP-19 ステップ 3 の一部先取り |
| ~~順位 395: 週次レビューで浮きブランチを検出し削除を提案~~ → **実装完了(2026-08-09)**。`cli-stale-branch-scan` / `pnpm stale-branch-scan`。設計と判定規則は [ADR-031](adr/adr-031-weekly-review-pipeline.md) § 残存ブランチ検出 が正。自動削除はしない(提案のみ) | [ADR-031](adr/adr-031-weekly-review-pipeline.md) | 完了。WP-19 ステップ 3 の一部を先取り済み |
| 順位 382(injection payload regression test。依存先の順位 380 完了で unblock)/ 順位 383(`is_separator_row` のパイプ検証欠落) | [todo-summary2.md](todo-summary2.md) | 🔧 Tier 2、任意 |
| 順位 375-377(レビュー対応チェックリスト / push-runner bookmark 前進 / 防御の格上げ判断) | [todo-summary2.md](todo-summary2.md) | 🔧 2〜💎 3、WP-18 完了後 |

Expand Down
1 change: 0 additions & 1 deletion docs/todo-summary2.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@
| 390 | 🔧 Tier 2 | **台帳 framing 区切りの定数と workflow リテラルの cross-file 一致を CI 検証 (#369 T2 採用)** | todo21.md | M | なし (LEDGER_DATA_FRAME_MARKER と ===BEGIN/END_LEDGER_DATA=== が対。片側変更で ADR-072 決定 13 の framing が破れる) |
| 391 | 🔧 Tier 3 | **jj の落とし穴 (squash 方向・空コミットでの bookmark ずれ) を dev-conventions へ (#369 T3 採用)** | todo21.md | S | なし (本セッションで複数回踏んだ。コミット確定は describe+bookmark set、new は新作業時のみ、を明文化) |
| 392 | 🔧 Tier 3 | **push パイプラインの terminal outcome を telemetry へ記録し失敗回数・原因を機械集計可能にする** | todo21.md | M | なし (2026-08-09 WP-18 失敗頻度分析で構造化記録の欠落が判明。stage + reason code を ADR-055 系へ fail-open で追記し ADR-062 月次で集計。順位 386/387/376 の効果測定ベースラインにもなる) |
| 395 | 🔧 Tier 2 | **週次レビューで浮きブランチを検出し削除を提案する** | todo21.md | S-M | なし (2026-08-09 の手動ブランチ削除で ADR-072 決定 3 の除外マーカーが消え順位 203 が再選択された。判定は branch 単一ソースのまま維持し、滞留を週次で解消する) |
| 396 | 🔧 Tier 2 | **hooks smoke suite の並列実行が Linux で `ETXTBSY` を起こす** | todo21.md | S | なし (#376 CI で ubuntu のみ失敗、windows は成功、当該クレートは無変更。2 テストが並列に exe を copy→spawn し、fork した子が copy 側の書き込み fd を継承するため exec が Text file busy。直近 15 run で初出だが ADR-065 の両 OS matrix の信号品質を下げる) |

**戦略**: 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
35 changes: 2 additions & 33 deletions docs/todo21.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,40 +215,9 @@

> **由来**: 2026-08-09 に PR [#373](https://github.com/aloekun/claude-code-hook-test/pull/373) で実測した 2 件の観測から、ユーザー判断 (同日) を経て方針を確定したもの。**3 件は 1 本の根から出ている** — 夜間 PR を draft にしたことが CodeRabbit の自動レビュー対象外を招き、その回避策 ([ADR-072](adr/adr-072-nightly-todo-loop.md) 決定 11) が bot 投稿の無視で不成立になった。
>
> **順位 393 (記録の是正) と 394 (構造の是正) は実装済み・削除済み** (2026-08-09)。撤回記録は [ADR-072](adr/adr-072-nightly-todo-loop.md) 決定 11 の撤回ブロック、停止点変更は同 決定 15、背圧の指標改訂は [ADR-071](adr/adr-071-draft-pr-backpressure.md)、分類表の本体改訂は [ADR-052](adr/adr-052-autonomy-execution-boundary-classes.md) 原則 2 が正。**実走確認 (夜間 PR に CodeRabbit の初回自動レビューが付くこと) だけが残り**、計画書 WP-18 の残作業表と ADR-072 § 実走スモークが追跡する。
> **順位 393 (記録の是正) と 394 (構造の是正) は実装済み・削除済み** (2026-08-09、PR [#376](https://github.com/aloekun/claude-code-hook-test/pull/376))。撤回記録は [ADR-072](adr/adr-072-nightly-todo-loop.md) 決定 11 の撤回ブロック、停止点変更は同 決定 15、背圧の指標改訂は [ADR-071](adr/adr-071-draft-pr-backpressure.md)、分類表の本体改訂は [ADR-052](adr/adr-052-autonomy-execution-boundary-classes.md) 原則 2 が正。**実走確認 (夜間 PR に CodeRabbit の初回自動レビューが付くこと) だけが残り**、計画書 WP-18 の残作業表と ADR-072 § 実走スモークが追跡する。
>
> 以下の 395 は独立 (ブランチ運用) だが同じセッションの観測に由来する。

### 週次レビューで浮きブランチを検出し削除を提案する

> **動機**: 2026-08-09 に、クローズ済み PR [#365](https://github.com/aloekun/claude-code-hook-test/pull/365) のブランチを手動削除したことで [ADR-072](adr/adr-072-nightly-todo-loop.md) 決定 3 の除外マーカーが消え、同じ順位 203 が再選択された (PR #373)。**決定 3 自体は設計どおり動作している** — ブランチの存在が着手済みマーカーであり、それが人手で消えたことが原因。
>
> **方針 (ユーザー判断 2026-08-09)**: 判定は現行の `git ls-remote` による **branch 単一ソースのまま維持する**。「クローズ済み PR も見る」案は判定ソースが 2 つになり、fail-closed の単純さ (一致なしでも exit 0 + 空出力で「0 件」と「取得失敗」を取り違えない) を崩すため**採らない**。代わりに浮きブランチを週次で片付け、放置によるタスク滞留を解消する。
>
> - **`claude/nightly-*` も削除提案の対象に含める** (除外しない)。ブランチが残る間そのタスクが選べない期間 (最大 7 日程度) は許容する — 自動実行できる todo はほとんどが改善タスクで急がず、重要な todo はメインセッションで消化するため
> - **削除後の再挑戦も許容する**。現状のクローズは夜間ループの機能不全に起因するもので、正常動作後は採用方向の選択が多くなる見込み
>
> **対処案**: weekly-review に「クローズ済み PR の残存ブランチ」検出を追加する。既存の観点⑤ (`review-todo-whole` facet) へ相乗りさせるか決定論的 scan として持つかは実装時判断 ([ADR-031](adr/adr-031-weekly-review-pipeline.md) の構成に従う)。**削除の実行は提案までとし、自動削除はしない** ([ADR-022](adr/adr-022-automation-responsibility-separation.md) / [ADR-028](adr/adr-028-pnpm-create-pr-gate.md))。
>
> **現状**: クローズ由来で残っている `claude/` ブランチは無い。`claude/nightly-203` は open な #373 のもの、`claude/cloudharness-e2e-validation-sptfc7` / `claude/select-next-task-a9aiam` は 7 月下旬から open のままの #320 / #324 のもの (これらは PR 自体の棚卸し対象)。
>
> **参照**: [ADR-072](adr/adr-072-nightly-todo-loop.md) 決定 3、[ADR-031](adr/adr-031-weekly-review-pipeline.md) (weekly-review)、[ADR-022](adr/adr-022-automation-responsibility-separation.md)、WP-19 ステップ 3 (監査ループ — 本エントリはその一部を先取りする)。
>
> **実行優先度**: 🔧 Tier 2 — Severity Low (滞留は最大 7 日で解消され、実害は選択機会の遅延のみ) / Frequency Low (週次) / Effort S-M / Adoption Risk Low (提案のみで自動削除しない)。

#### 作業計画

- [ ] クローズ済み PR の残存ブランチを列挙する検出を weekly-review に追加する
- [ ] `claude/nightly-*` を除外せず対象に含める (除外すると滞留が永続する)
- [ ] 削除は提案までとし、実行はユーザー承認を経ることを明示する
- [ ] WP-19 ステップ 3 (自律アクションの週次棚卸し) と重複しない形で載せる

#### 完了基準

- 週次レビューがクローズ済み PR の残存ブランチを列挙し、削除を提案すること。
- 自動削除を行わないこと (提案までで止まる)。

---
> **順位 395 (週次レビューでの浮きブランチ検出) も実装済み・削除済み** (2026-08-09)。`cli-stale-branch-scan` として実装し、`pnpm stale-branch-scan` で実行する。設計は [ADR-031](adr/adr-031-weekly-review-pipeline.md) § 残存ブランチ検出 が正 — **takt workflow はネットワークを持たない** (`network_access: false`) ため決定論 scan を skill 側 (L3) に置いた経緯もそちらに記録した。

## CI 安定性 (2026-08-09 登録)

Expand Down
Loading
Loading