docs(todo): WP-18 の残作業 11 件を登録し計画書を 3 PR マージ済へ更新 (順位 374-384) - #364
Conversation
WP-18 (夜間 todo 消化ループ、#361 / #362 / #363) の実装中に pre-push review・ CodeRabbit・ユーザー指摘で検出した問題 9 件のうち、todo 登録が要る 8 件を **実装時の PR 粒度**で 4 エントリへまとめる。切り分けは 2026-08-06 にユーザー確認済み。 ## 評価時の #1 を検証し、todo 登録が不要になった #1 は「Bash prefix 許可の悪用可能性検証と全経路への横展開」として登録予定だった。 ユーザー指示により登録前に検証したところ、**前提が誤りだった**。 #363 の security review は「`Bash(cargo test:*)` は前方一致でシェルを解釈しないため `cargo test` に任意コマンドを連結すると通過する」と主張していた。公式ドキュメントは これを明確に否定している: Claude Code is aware of shell operators, so a rule like `Bash(safe-cmd *)` won't give it permission to run the command `safe-cmd && other-cmd`. The recognized command separators are `&&`, `||`, `;`, `|`, `|&`, `&`, and newlines. A rule must match each subcommand independently. `--allowedTools` も同じルール体系に属する (managed settings の deny を --allowedTools で 上書きできない、と明記されている)。 結果: - `pr-monitor.yml` の Phase A 分析 agent に**当該の穴は無く、対処不要**。production の live な穴という当初の見立ては誤りだった - 残作業は `ADR-072` 決定 5 の根拠記述の訂正のみで、#363 が open のうちに同 PR へ直接 反映する。よって todo エントリを立てない 検証結果と経緯はセクション冒頭の対応表に残した。 ## この一件自体を教訓として取り込んだ 「レビュー指摘への対応時チェックリスト」エントリに 4 項目目を追加した — **指摘が技術的 前提 (ツールの挙動・仕様) に依拠しているなら、対処より先にその前提を検証する**。とくに 設計変更や他経路への横展開を伴う場合。 今回は未検証の前提のまま (a) agent から Bash を落とす設計変更を行い、(b) それを ADR の 決定として記録し、(c) さらに「同じ形が production にもある」と横展開の警告まで出していた。 一次情報に当たれば 1 回の WebFetch で否定できた。 ## 内訳 - 順位 374: WP-18 夜間ループの実走スモーク実施 (Tier 1、評価時の #2/#3) - 順位 375: レビュー指摘への対応時チェックリスト (Tier 2、評価時の #4/#5/#6 + 今回の #1) - 順位 376: push-runner の bookmark 自動前進がスタック境界を壊す (Tier 2、評価時の #7) - 順位 377: 夜間ループの防御を検知から防止へ格上げする判断 (Tier 3、評価時の #8/#9) ## まとめ方の方針 リポジトリの既存バッチ登録 (#350〜#357 の 24 件を 8 エントリへ) と同じく実装時の PR 粒度で まとめた。評価時の番号との対応はセクション冒頭に表で残してある。 順位 374 (スモーク) の観測項目は `ADR-072` の実走スモーク節に表があるため、todo 側は スケジューリングの掛かりだけを持ちチェックリストを複製しない。同じ表を 2 箇所で管理すると 必ず drift する (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ADR-033 (絶対番号は table のみに保持) に従い、エントリ本文には順位番号を書いていない。 todo20.md は 50KB 閾値内。pnpm lint:docs / markdownlint ともに green。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 最終 PR (#363、ADR-072) のマージ後 feedback が Tier 1 に 4 件・Tier 2 に 2 件を 採用候補として挙げた。ユーザー承認 (2026-08-07) を得て登録する。 ## 6 件は 1 本の根から出ている 台帳 (docs/claude-code-web-tasks.md) の 内容 / 対象ファイル / 注意 は自由記述のまま 無人 agent のプロンプトへ流入する。agent は $GITHUB_WORKSPACE 全体に書き込め、その 出力は draft PR 本文という公開面に出る。ADR-054 の信頼境界そのもの。 - 378 (XS) 台帳を ADR-035 の docs-only 除外パス表へ追加 — 他 3 件の前提。台帳だけを 変える PR が緩い評価経路に乗ると、対策そのものを迂回する台帳 PR が通りうる - 379 (S) tool scope を work/** へ限定 — ADR-072 決定 7 の改ざん検知が必要になって いる根本原因。実装後も検知層は残す (防御を 1 枚に減らす変更ではない) - 380 (M) 台帳フィールドを untrusted data として明示 framing - 381 (S) 台帳由来 SUMMARY の draft PR 本文出力に screening - 382 (M) injection payload の regression test (380 に依存) - 383 (S) is_separator_row のパイプ検証欠落 ## 期限を「定常運用開始前」に固定する 実効リスクは現時点では低い — 悪意ある台帳行を master へマージするのはユーザー自身で、 単独運用では外部からの注入経路が無い。ただし夜間ループが定常運用に入り draft PR の 流量が増えると前提が変わるため、無期限の Tier 積みにしない。 順位 374 (実走スモーク) は dry_run で PR を作らないため本件の実害が無く、待たせない。 ## 383 は実コードで確認済み is_table_row は行頭 | を要求するが、is_separator_row は split_cells の結果しか見ない。 split_cells("---") は ["---"] を返し全セルが '-' のみなので真になる。markdown の 水平線がセパレータ行として通る (todo ファイル自身が --- を使っている)。 ADR-072 決定 2 の fail-closed 設計の coverage hole。 ## 併せて 順位 374 のスモーク観測項目数を 4 → 8 へ修正した (ADR-072 側の実測と不一致だった)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
#363 のマージ (2026-08-07) で WP-18 の実装 3 本がすべて land した。 ## 「実装完了 = WP 完了」ではないことを表で残す コードは全部 master にあるが、**夜間ループはまだ 1 度も走っていない**。この状態を 「実装済」の一語で片付けると、次のセッションが受け入れ基準を満たしたものと誤読する。 残作業を 2 系統に分けて表にした: 1. 実走スモーク (順位 374) — 受け入れ基準の中核 2. prompt injection 対策 4 件 (順位 378-381) — 定常運用開始前に必須 ## スモークの前提が充足したことを記録 受け入れ基準の表は「(a) workflow が master にある (b) 台帳に無人可マークがある」を 未充足として書いていたが、**両方ともマージで解消した**。残る操作は GitHub UI 側の AUTONOMY_ENABLED 設定のみなので、その 1 点へ書き換えた。 ## 依存関係を明示する 378-381 は 1 本の根 (台帳の自由記述が無検証で agent プロンプトへ流入) から出ている。 一方スモークは dry_run で PR を作らないため本件の実害が無い。したがって **スモークは 378-381 を待たずに着手してよい**と明記した。次セッションが順序で 迷わないようにするため。 ## 未 push の改善 3 点の所在を残す #363 の最終 push が security REJECT で止まったため、改ざん検知の red 化 / 決定 10 の 色分け表 / 決定 6 の列挙基準が master に載っていない。ローカル bookmark wp18/unpushed-improvements (fc22403c) に保持していることを記録した。いずれも 可観測性と文書の改善で、fail-closed 自体は master 版でも成立している。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
新セッションでの指摘 (2026-08-07): workflow は vars.NIGHTLY_APP_ID / secrets.NIGHTLY_APP_PRIVATE_KEY を参照するが、App の作成・インストール・登録を 記録した文書がリポジトリ内に無い。 ## 欠けているのは設計根拠ではなく運用実体 ADR-072 決定 8 は「なぜ App token か」「なぜ PAT ではないか (オーナー PAT は Repository admin として ADR-067 の ruleset backstop を素通りする)」「どの権限を 付けるか (Workflows は付けない)」「なぜ publish 直前に発行するか (token 寿命 1 時間)」を厚く残している。 記録が無いのは以下: - App を実際に作成した事実・日付・名称・インストール範囲 - NIGHTLY_APP_ID = variable / NIGHTLY_APP_PRIVATE_KEY = secret という登録先の別 - 既存の Claude GitHub App との区別 (あちらは Workflows を含む広い権限を持つ別物) - 再構築手順 (鍵ローテーション・派生プロジェクト展開) NIGHTLY_APP の文字列はリポジトリ全体で workflow の 2 行と ADR 残課題の 1 行にしか 現れない。 ## これは ADR-051 違反 ADR-051 (クロスシステム設定 coupling) は内部設定と外部 SaaS 設定が論理結合する場合に (1) 両設定ファイルへの相互参照コメント (2) 期待値の組み合わせ表の ADR 必須記載 (3) 変更は両側を同一 PR、の 3 点を規律として定めている。workflow ↔ GitHub App + repository variables/secrets はこの型で、3 点とも未実施。 前例として ADR-067 段 0 は repository ruleset を ruleset 名つきで「設定済み」と 記録している。ADR-072 は同じ扱いをしていない。同型の欠落が AUTONOMY_ENABLED にも あり (ADR-066 は「Actions variable を使う」とは書くが現状値を記録していない)、 本エントリで一緒に扱う。 ## 順位 374 と同時実施にする理由 スモークでは AUTONOMY_ENABLED の設定と App token の実動確認のため GitHub UI を 触るので、その過程で実値がすべて揃う。先行して記録しようとすると値が確定せず 二度手間になる。 ## 教訓を残す App の作成手順・Expire user authorization tokens の扱い・既存 App との違いは 2026-08-07 のセッションでユーザーへ提示したが、リポジトリへ残さなかった。会話は 次のセッションに残らないが workflow は残る。参照だけが残って由来が消える状態を 作った。順位 375 と同じクラスの失敗としてエントリ本文に記録した。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughWP-18 の状態と受け入れ基準を更新し、実走スモーク、運用上の残課題、台帳由来の prompt injection 対策、外部設定の ADR-072 記録計画を追加した。 ChangesWP-18 夜間ループ運用計画
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🤖 PR Monitor 分析 (GitHub Actions バックストップ)
Applicable Findings (Critical / High / Major)該当なし (レビュー未着のため findings 自体が存在しない) Applicable Findings (Medium 以下)該当なし Filtered (not applicable)該当なし 次のアクション
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/adr/adr-072-nightly-todo-loop.md`:
- Line 335: Replace the “実値” wording in the ADR entry with “設定メタデータ” and
explicitly state that secret values, private keys, and tokens must not be
recorded in the ADR or Git history. Document only the secret names, storage
locations, owner, permission scope, rotation policy, missing-value behavior, and
configuration verification result, including the GitHub App settings referenced
by the existing nightly workflow.
In `@docs/harness-improvement-plan.md`:
- Line 223: 拡張「実走スモーク」の受け入れ基準を成功経路だけでなく、AUTONOMY_ENABLED の
true・false・未設定の3状態で検証する内容に更新し、無効状態では workflow、branch、draft PR、App token
が作成されないことを確認して、各 deny 結果を ADR-072 に記録する。docs/harness-improvement-plan.md
の該当項目に3状態 dispatch と記帳手順を追加し、docs/todo20.md の該当作業計画・完了基準にも同じ無効状態の実走確認を追加する。
In `@docs/todo20.md`:
- Around line 521-528: 外部設定の記録計画に秘密値を保存しないルールを明記する。docs/todo20.md
の「記録すべき項目」では、NIGHTLY_APP_PRIVATE_KEY の値自体は記録せず、secret
名・登録先・権限・ローテーション手順のみを記録する旨を追加する。docs/harness-improvement-plan.md
の「実体」の記録対象にも秘密値を含めないことを明示する。
- Around line 478-480: 台帳 fixture と回帰テストに、自然言語の adversarial な prompt injection
payload を追加してください。shell 形式の payload とは分けて、framing、許可された tool scope、公開出力の
screening がその指示を実行・反映せず安全に処理することを検証し、既存の選択結果と prompt 組立の確認も維持してください。
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7c445ba8-1caf-4e21-9913-b1b27edce131
📒 Files selected for processing (4)
docs/adr/adr-072-nightly-todo-loop.mddocs/harness-improvement-plan.mddocs/todo-summary2.mddocs/todo20.md
| ### 残課題 | ||
|
|
||
| - **実走スモークの完走** (§ 検証記録)。本 ADR の受け入れ基準の中核であり、未実施。 | ||
| - **外部設定 (GitHub App / repository variables・secrets) の実体が未記録**。決定 8 は「なぜ App token か」を厚く残す一方、App 名・インストール範囲・付与権限の実際・`NIGHTLY_APP_ID` (variable) / `NIGHTLY_APP_PRIVATE_KEY` (secret) / `AUTONOMY_ENABLED` (variable) の登録先と欠落時の倒れ方を 1 行も書いていない。[ADR-051](adr-051-cross-system-config-coupling.md) が内部設定と外部 SaaS 設定の論理結合に課す 3 点 (相互参照コメント / 期待値の組み合わせ表 / 両側同一 PR) が未実施の状態にあたる。実走スモークで GitHub UI を触る際に実値を確認し、§ 外部設定の実体 として本 ADR へ追記する。 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
秘密値を ADR に記録しないでください。
Line 335 の「実値を確認し、…本 ADR へ追記」は、NIGHTLY_APP_PRIVATE_KEY の秘密値を記録する意味にも読めます。秘密鍵や token を ADR または Git 履歴へ保存すると、認証情報が漏えいします。
ADR には secret 名、保存先、所有者、権限範囲、ローテーション方針、欠落時の挙動、および設定済みであることの確認結果だけを記録してください。「実値」は「設定メタデータ」に置き換え、秘密値を記録しないことを明記してください。
根拠: .github/workflows/nightly-todo.yml は NIGHTLY_APP_PRIVATE_KEY を App token 発行に使用しています。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/adr-072-nightly-todo-loop.md` at line 335, Replace the “実値” wording
in the ADR entry with “設定メタデータ” and explicitly state that secret values, private
keys, and tokens must not be recorded in the ADR or Git history. Document only
the secret names, storage locations, owner, permission scope, rotation policy,
missing-value behavior, and configuration verification result, including the
GitHub App settings referenced by the existing nightly workflow.
| | 背圧の決定論層 drill(12 シナリオ、実 exe) | **充足**(PR 1、[ADR-071](adr/adr-071-draft-pr-backpressure.md) § 検証記録) | | ||
| | タスク選択の境界固定(unit test 25 件 + 実データ選択) | **充足**(PR 3、[ADR-072](adr/adr-072-nightly-todo-loop.md) § 検証記録) | | ||
| | **実走スモーク — 有効時のみ `claude/nightly-*` の draft PR が作られること** | **未実施**。実行には (a) workflow が master にあるか対象 ref へ `workflow_dispatch` できること、(b) 台帳に無人可マークがあること(= PR 2 のマージ)が要る。反復は [ADR-067](adr/adr-067-phase-b-unattended-fix-push.md) 段 2 の知見 2 に従い**マージせず ref 指定の dispatch** で行う(`dry_run` 入力あり) | | ||
| | **実走スモーク — 有効時のみ `claude/nightly-*` の draft PR が作られること** | **未実施**(順位 374)。前提 (a) workflow が master にあること・(b) 台帳に無人可マークがあることは**いずれも 2026-08-07 のマージで充足済み**。加えて GitHub UI 側で `AUTONOMY_ENABLED` を `'true'`(完全一致)に設定する操作と、`dry_run=false` の完走には App(`NIGHTLY_APP_ID` / `NIGHTLY_APP_PRIVATE_KEY`)の登録が要る。**この UI 操作で確認した実値は順位 384 で ADR-072 へ記録する**。反復は [ADR-067](adr/adr-067-phase-b-unattended-fix-push.md) 段 2 の知見 2 に従い**マージせず ref 指定の dispatch** で行う(`dry_run` 入力あり) | |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
「有効時のみ」の受け入れ基準が成功経路だけを検証しています。
AUTONOMY_ENABLED=true の成功確認に加えて、false と未設定で workflow、branch、draft PR、App token が作成されないことを実走で確認してください。
docs/harness-improvement-plan.md#L223-L223: 3 状態の dispatch と deny 結果の ADR-072 記帳を追加する。docs/todo20.md#L293-L304: 無効状態の実走確認を作業計画と完了基準へ追加する。
📍 Affects 2 files
docs/harness-improvement-plan.md#L223-L223(this comment)docs/todo20.md#L293-L304
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/harness-improvement-plan.md` at line 223,
拡張「実走スモーク」の受け入れ基準を成功経路だけでなく、AUTONOMY_ENABLED の
true・false・未設定の3状態で検証する内容に更新し、無効状態では workflow、branch、draft PR、App token
が作成されないことを確認して、各 deny 結果を ADR-072 に記録する。docs/harness-improvement-plan.md
の該当項目に3状態 dispatch と記帳手順を追加し、docs/todo20.md の該当作業計画・完了基準にも同じ無効状態の実走確認を追加する。
| > **対処案**: 台帳 fixture に injection payload (`caution: "; echo PWNED; #"` 等) を含む行を置き、選択結果と prompt 組立が payload を指示として扱わないことを assert する。 | ||
| > | ||
| > **依存**: 順位 380 (framing 実装)。framing 前にテストだけ書いても固定する対象が無い。 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
prompt injection 用の回帰 fixture を追加してください。
"; echo PWNED; #" は shell injection またはコマンド解析の検証です。これは LLM が「以前の指示を無視する」などの prompt injection を実行しないことを検証しません。shell 形式とは別に、自然言語の adversarial payload を追加し、framing、tool scope、公開出力の screening が機能することを確認してください。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/todo20.md` around lines 478 - 480, 台帳 fixture と回帰テストに、自然言語の adversarial
な prompt injection payload を追加してください。shell 形式の payload とは分けて、framing、許可された tool
scope、公開出力の screening がその指示を実行・反映せず安全に処理することを検証し、既存の選択結果と prompt 組立の確認も維持してください。
| > **記録すべき項目**: | ||
| > | ||
| > - App 名 / 作成日 / インストール範囲 (`claude-code-hook-test` のみか) | ||
| > - 付与した権限の実際の一覧 (決定 8 の方針どおり Workflows が**付いていない**ことの確認を含む) | ||
| > - **既存の Claude GitHub App との区別** — あちらは Workflows を含む広い権限を持つ別物。混同すると「もう入っているから不要」と誤判断されうる | ||
| > - `NIGHTLY_APP_ID` = repository **variable** / `NIGHTLY_APP_PRIVATE_KEY` = **secret** / `AUTONOMY_ENABLED` = **variable** という登録先の別 | ||
| > - **期待値の組み合わせ表** (ADR-051 決定 2) — 各値の欠落時にどう倒れるか。`AUTONOMY_ENABLED` 欠落は job ごと起動しない、App 資格情報の欠落は publish step で落ちる、等 | ||
| > - 再構築手順 (鍵ローテーション時・派生プロジェクトへの展開時) |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
外部設定の記録計画に秘密値の非記録ルールを追加してください。
docs/todo20.md#L521-L528: secret 名、登録先、権限、ローテーション手順のみを記録し、NIGHTLY_APP_PRIVATE_KEYの値を保存しないと明記する。docs/harness-improvement-plan.md#L186-L186: 「実体」の記録対象から秘密値を明示的に除外する。
📍 Affects 2 files
docs/todo20.md#L521-L528(this comment)docs/harness-improvement-plan.md#L186-L186
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/todo20.md` around lines 521 - 528,
外部設定の記録計画に秘密値を保存しないルールを明記する。docs/todo20.md の「記録すべき項目」では、NIGHTLY_APP_PRIVATE_KEY
の値自体は記録せず、secret
名・登録先・権限・ローテーション手順のみを記録する旨を追加する。docs/harness-improvement-plan.md
の「実体」の記録対象にも秘密値を含めないことを明示する。
Resolved findings: - [Major] docs/adr/adr-072-nightly-todo-loop.md:335 秘密値を ADR に記録しないでください。 - [Major] docs/harness-improvement-plan.md:223 「有効時のみ」の受け入れ基準が成功経路だけを検証しています。 - [Major] docs/todo20.md:480 prompt injection 用の回帰 fixture を追加してください。 - [Major] docs/todo20.md:528 外部設定の記録計画に秘密値の非記録ルールを追加してください。
自動 fix 経路 (f698d19) が 1 件 (#4 台帳への非記録ルール追加) を対応済みで、 本コミットはその内容を含んだうえで残りを手で対応した結果である。同一ファイルの 近接行のため path 単位で分離できず 1 コミットに畳み込まれている。 ## 妥当性の判定 severity ラベルではなく、プロジェクトの設計方針に照らして 1 件ずつ判定した。 - #1 adr-072:335 (秘密値を ADR に記録しない) — **妥当**。「実走スモークで実値を 確認し ADR へ追記する」は秘密鍵本文まで書くと読める。ADR-051 が記録を課すのは 結合の存在と期待値の組み合わせであって秘密の実値ではない。設定メタデータに 限定し、鍵本文と token は ADR にも git 履歴にも残さないことを明記した - #2 harness-improvement-plan:223 (受け入れ基準が成功経路だけ) — **妥当**。本 プロジェクトは背圧 12 シナリオ・kill-switch 8 シナリオと停止側を drill で 固めてきたが、夜間ループの停止側は実走未観測。WP-17 の残課題 (明示的 false と config 側 deny が実走未観測) と同じ穴。AUTONOMY_ENABLED の 3 状態を受け入れ 基準へ追加した。指摘本文が名指しした 2 箇所 (計画書 L223 / todo20 L293-304) の 両方に反映している - #3 todo20:480 (prompt injection の回帰 fixture) — **妥当**。順位 382 の payload 例 "; echo PWNED; #" は shell injection であって prompt injection ではない。 台帳テキストが流れ込む先は shell ではなく LLM プロンプトなので、テストが目的と 噛み合っていなかった。自然言語 adversarial payload (本命) と shell/パース形式 payload (堅牢性) の 2 系統へ分離した ## 自動 fix の実測確認 f698d19 は 1 ファイル 2 行追加のみで範囲外の編集ゼロ。内容も妥当だったため そのまま採用した (ADR-068 の後退検知の趣旨に沿って diff を実測で確認済み)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
f698d19 to
839589e
Compare
#366) * feat(nightly-todo): 改ざん検知を red 化し決定 10 の色分けと決定 6 の列挙基準を明文化する (ADR-072) #363 の最終 push が pre-push security review の REJECT で止まったため master に 載らなかった 3 点を、master 上に載せ直す。いずれも可観測性と文書の改善で、 fail-closed 自体は master 版でも成立している。 ## 改ざん検知を green から red へ (workflow) ゲート資産の改ざん検知 step から continue-on-error を除去する。 fail-closed は元から成立していた — continue-on-error: true でも下流の `if: steps.integrity.outcome == 'success'` で push は止まる。問題は**色**で、 green で終わるため run 一覧上「何もすることが無かった夜」と区別が付かなかった。 毎晩回る無人ループでは、この 2 つが混ざった時点で run 一覧が読まれなくなる。 改ざん検知は「何かがゲートを無効化しようとした」という、この系が出しうる最も 大きい信号である。red で落ちても後続 step は if: の評価前に skip されるため push には到達せず、Report outcome は if: '!cancelled()' なので診断行は出る。 ## 決定 10 に色分け表を追加 (ADR-072) 「設計された停止」と「インフラ障害」の 2 分類を表にしたところ、**改ざん検知が どちらにも入っていない**ことが露出した。分類を明文化すると分類に入らない結末が 可視になる、の実例として § 静的レビューが捕捉した件 の #10 に記録した。 見落としていたのは安全性ではなく可観測性の側だった。 ## 決定 6 に列挙基準を追加 (ADR-072) 禁止リストの基準は「危険か」ではなく「**将来の無人 run のゲートを緩めるか**」で ある。security review が挙げた Cargo.toml / Cargo.lock の欠落を採らない根拠が これで、通常の diff は人間の PR レビューとマージという既存の防衛線が効く。 基準を持たないと禁止リストは「怪しいもの全部」へ膨らみ正当なタスクを弾き始める。 ## 適用方法 保持していたローカル bookmark (wp18/unpushed-improvements) は #363 マージ前の スタックのため、そのまま復元すると **#364 で入れた ADR-072 § 残課題 の追記 (外部設定の実体が未記録 / 秘密値は記録しない) を巻き戻す**。したがって workflow は ファイル単位で restore し、ADR-072 は追加分 4 箇所のみ手で適用した。適用後に lpzvttwu との差分が #364 の 1 行だけであることを実測確認している。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(nightly-todo): 決定 10 の red 分類を残り 3 step へ適用する (#366 CodeRabbit 指摘) 自動 fix 経路が作った commit を、内容を実測検証したうえで採用したもの。 **push 自体は scope guard (ADR-054) が BLOCK した** — finding の anchor が docs/adr/adr-072 なのに fix が .github/workflows/ を触ったため。指摘の remedy が anchor と別ファイルにある典型で、guard の設計どおりの挙動だが本件は injection では ないため誤検知にあたる (WP-11 の enforce 期間の観測データとして計上すべき)。 ## 指摘の妥当性 同 PR で追加した決定 10 の色分け表は「gh / network / clone の失敗 → red」と 定めているのに、その 3 経路が continue-on-error: true で green に落ちていた。 表を追加した PR 自身が作った不整合であり、妥当と判断して採用する。 - Prepare a clean publish tree — git clone (ネットワーク I/O) - Mint App token — GitHub API 呼び出し (secret 誤設定・GitHub 障害) - Push branch and open draft PR — git push / gh pr create ## 実測検証 (fix の出力を鵜呑みにしない) - 下流の if: はいずれも `steps.<id>.outcome == 'success'` 形式のため、失敗時は 後続が skip され push へ到達しない (fail-closed は維持) - Report outcome は `if: '!cancelled()'` なので red でも診断行は出る - dry_run=true では app-token / publish は if: により **skipped** (failed ではない) ため、dry_run の run は green のまま ## ADR への記帳 表を書いた著者自身は 1 件 (改ざん検知) しか見つけられず、残り 3 件は他者の レビューで出た。**分類の明文化は露出の必要条件であって十分条件ではない**ことの 実例として決定 10 へ追記した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
どちらも妥当と判断して対応。指摘本文はいずれも **anchor 以外の箇所も名指し**して おり、要約 (anchor 1 箇所) だけでは範囲を取り違えるところだった。 ## #1 実走スモークの項目数が両文書で不一致 (adr-072:338) 観測表は 9 行あるのに、計画書の集計は「8 項目 / 5 充足・1 不成立・2 未観測」= 8 件 だった。#364 で受け入れ基準へ停止側 1 件を足した際、ADR の表には行を足したが集計側を 更新していなかった。 母数を 9 件 (起票時の 8 + #364 追加の停止側 1) と ADR 側に明記し、計画書の集計を 5 充足 / 1 不成立 / 1 判定不能 / 2 未観測 へ修正した。allowlist 行は「判定不能」として 独立に数える (除外して 8 件に揃えるのではなく、状態を持つ 1 件として扱う)。 ## #2 WP-18 の実走状態が古い要約に残っていた (harness-improvement-plan:172) 受け入れ基準表は 2026-08-08 の実走を反映済みだったが、同じ文書の別セクションが 「実走スモーク未実施」「まだ 1 度も走っていない」と矛盾したままだった。指摘本文が L157 / L165 / L172 / L198 の 4 箇所を名指ししていたため、すべて更新した。 - 見出し: 「3 PR マージ済 (2026-08-07、実走スモーク未実施)」→「実装 land 済 + allow 経路の実走成立 (2026-08-08)」 - 残作業 2 系統の 1 番目: 「まだ 1 度も走っていない」→ allow 経路成立、残るのは 停止側とトークン露出の 2 項目 - PR 3 の記述: 「実走スモークは未実施」→ 初回実走で allow 経路成立、step 数も 17 → 18 (決定 11 の step 追加を反映) あわせて「allow 経路は workflow_dispatch ではなく schedule の本番 run が先に 消化した」ことを本文にも明記した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(todo): WP-18 セッションの観測を順位 385-388 へ登録し todo21.md を新設 (Phase 2) WP-18 の PR 作業 (#364〜#370) で実測した自動化経路の運用問題を todo へ登録し、 384 完了削除・todo ローテーション・WP-11 記録を 1 バッチにまとめる。 ## todo21.md 新設 (todo20.md が 56KB = 50KB 閾値超過) 新規追加先を todo20.md → todo21.md へ移行。breadcrumb を持つ 5 ファイル (todo.md / todo8 / todo10 / todo13 / todo14) の「現在の追加先」ポインタと、 数詞「22つ/todo2-20」を持つ 8 ファイル (todo3-11) を 23つ/todo2-21 へ更新。 ## 順位 385-388 (2026-08-08 実測、todo21.md) - 385 (T3): cli-pr-monitor lock の liveness check 欠落 (復帰窓 30 分) - 386 (T2): 監視・自動 fix 経路の空コミットで bookmark ずれ → merge/push 失敗。 **本セッションで 7 回観測**、生成元確定、深さ非依存 revset が本命の対処 - 387 (T2): 自動 fix は push が BLOCK されてもローカル作業コピーを書き換える - 388 (T3): post-merge-feedback の完了判定が書き込みと race し誤 failed marker いずれも post-merge feedback には構造的に入らない (feedback の入力は PR diff と レビュー指摘で、ツール自身の運用中の事象は拾わない)。 ## 順位 384 完了・削除 外部設定の実体は ADR-072 § 外部設定の実体 に記録済み (#369/#370)。todo20.md の full エントリと summary2 の行を削除し、完了記録の 1 行に置換。 ## WP-11 記録 (harness-improvement-plan) #366 で enforce 下の scope guard 誤検知を 1 件観測。anchor と remedy が別ファイルの 指摘は構造的に必ず BLOCK される。本採用判定の前に判定基準の再定義が要ることを記録。 ## 検証 pnpm lint:docs OK (preamble + cross-ref + priority-inversion — 数詞 23 整合を含む) / markdownlint 127 files 0 error。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: CodeRabbit 指摘 4 件に対応 — 実装確認のうえ断定を訂正 (#371) いずれも「実コードを確認せず断定していた」箇所で、実装を verify して直した。 ## #1 (harness-plan) WP-11 の「誤検知」→「設計どおりの保守的 deny」 evaluate_scope_guard の allowlist は allowlist_from_paths(findings.map(f.file)) = finding の anchor 位置だけで、remedy が別ファイルなら含まない (ADR-054 も欠点として 明記)。#366 の BLOCK は誤検知ではなく設計どおりの保守的 deny。本採用の判定基準を 「この保守的 deny を誤検知に数えない」よう明確化する、と修正。 ## #2 (todo.md/todo3-7) breadcrumb の todo20/todo2-20 残存 docs バッチで更新し漏れた参照を補完。todo.md 冒頭の使い分けを todo21 + summary2 まで、 todo3-7 の「todo2-20」を todo2-21 へ。全 docs で todo2-20 残存ゼロを確認。 ## #3 (todo21:58) heads(::@ & bookmarks()) の複数返り @ に複数 bookmark が付くと複数コミットを返し clone --head / PR 選択が多対象になる。 trunk 除外 + 単一 bookmark へ絞る (現行 is_trunk_bookmark 除外と同規律) 必要を追記。 ## #4 (todo21:102) 388 の「race」断定を撤回 reconcile_takt_output → copy_feedback_report は find_latest_run_dir で run dir を 選ぶ (mod.rs:147 / takt.rs:84)。単純な write race と断定せず、latest 特定のずれ / パス不一致 / 前後関係を「まず特定する」形へ。#367 では実体が run dir に存在した。 ## 検証 pnpm lint:docs OK / markdownlint 0 error。scope guard・feedback reconcile の実装を 実際に読んで記述と一致させた。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Phase 2 C) WP-18 の prompt injection 対策 PR (#369/#370) の post-merge feedback の採用候補の うち、セッション中に未対応で価値の高い分をユーザー承認 (2026-08-09) のうえ登録する。 ## 新規登録 (todo21.md、389-391) - 389 (T1): Write(path) tool-scope 指定子の no-op を検出する settings validator。 CLI 2.1.218 で Write() は no-op = deny の silent 無効化。順位 379 で実際に踏んだ。 **検知は warning ではなく error (必須 CI 失敗) にする** — silent security failure は ADR-043 の fail-closed 対象 (#372 CodeRabbit 指摘) - 390 (T2): 台帳 framing 区切りの定数 (LEDGER_DATA_FRAME_MARKER) と workflow リテラル (===BEGIN/END_LEDGER_DATA===) の cross-file 一致を CI 検証 - 391 (T3): jj の落とし穴 (squash 方向・空コミットでの bookmark ずれ) を dev-conventions へ。本セッションで複数回踏んだ。**操作例は再現可能な最小の初期状態 つきで書く** (jj バージョン・リモート有無・コミットグラフ・bookmark 位置に依存する ため、断定形でなく前提つきで、#372 CodeRabbit 指摘) ## 順位 375 補強 (todo20.md) narrow-fix が隣接エッジに穴を作る教訓を 5 項目目として追加 (#369/#370 で複数回 再演、memory dont-trust-takt-fix-output と同根)。新規 rank は立てず既存 375 を編集。 ## 見送り (ユーザー非選択) Cf カテゴリ網羅テスト (#369 T1#3) / GITHUB_TOKEN vs App token 挙動差テスト (#364 T2#3) / pre-push warning 対応方針 (#370 T3#4) は今回登録しない。既に セッション中に対応済みの候補も再登録しない。 ## 検証 pnpm lint:docs OK / markdownlint 0 error。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Phase 2 C) (#372) WP-18 の prompt injection 対策 PR (#369/#370) の post-merge feedback の採用候補の うち、セッション中に未対応で価値の高い分をユーザー承認 (2026-08-09) のうえ登録する。 ## 新規登録 (todo21.md、389-391) - 389 (T1): Write(path) tool-scope 指定子の no-op を検出する settings validator。 CLI 2.1.218 で Write() は no-op = deny の silent 無効化。順位 379 で実際に踏んだ。 **検知は warning ではなく error (必須 CI 失敗) にする** — silent security failure は ADR-043 の fail-closed 対象 (#372 CodeRabbit 指摘) - 390 (T2): 台帳 framing 区切りの定数 (LEDGER_DATA_FRAME_MARKER) と workflow リテラル (===BEGIN/END_LEDGER_DATA===) の cross-file 一致を CI 検証 - 391 (T3): jj の落とし穴 (squash 方向・空コミットでの bookmark ずれ) を dev-conventions へ。本セッションで複数回踏んだ。**操作例は再現可能な最小の初期状態 つきで書く** (jj バージョン・リモート有無・コミットグラフ・bookmark 位置に依存する ため、断定形でなく前提つきで、#372 CodeRabbit 指摘) ## 順位 375 補強 (todo20.md) narrow-fix が隣接エッジに穴を作る教訓を 5 項目目として追加 (#369/#370 で複数回 再演、memory dont-trust-takt-fix-output と同根)。新規 rank は立てず既存 375 を編集。 ## 見送り (ユーザー非選択) Cf カテゴリ網羅テスト (#369 T1#3) / GITHUB_TOKEN vs App token 挙動差テスト (#364 T2#3) / pre-push warning 対応方針 (#370 T3#4) は今回登録しない。既に セッション中に対応済みの候補も再登録しない。 ## 検証 pnpm lint:docs OK / markdownlint 0 error。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
Context
Why: #363 のマージで WP-18 の実装 3 本がすべて master に載ったが、夜間ループはまだ 1 度も走っていない。この状態を「実装済」の一語で片付けると、次のセッションが受け入れ基準を満たしたものと誤読する。残作業を台帳化して、どこから再開すべきかを機械的に分かる形にする。
Trigger: #363 の post-merge feedback (Tier 1 に 4 件・Tier 2 に 2 件) と、WP-18 実装中に検出した問題 9 件。加えて新セッションでの指摘 — workflow が
vars.NIGHTLY_APP_ID/secrets.NIGHTLY_APP_PRIVATE_KEYを参照するのに、App の作成・登録を記録した文書がリポジトリ内に 1 つも無い (ADR-051 が定める 3 点が未実施)。Scope decision: docs のみ。実装は一切含まない。順位 374 (実走スモーク) は本 PR のマージ後に着手する。順位 384 は 374 と同時実施 — スモークで GitHub UI を触る過程で実値が揃うため、先行させると値が確定せず二度手間になる。
Validation
pnpm pushpre-push review: verdict=APPROVE (simplicity / security 両 facet、最終 run 58s、1 iteration)lintPASS (1.9s) /testPASS (3.2s) /buildPASS (1.1s)。docs-only routing (ADR-035) によりrust-lint-testは skippnpm lint:docs: OK (preamble + cross-ref + priority-inversion)markdownlint: 126 files / 0 errorReferences
Summary by CodeRabbit