feat(hooks): push 前パイプラインハーネスの実装 - #8
Conversation
📝 Walkthrough🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
.claude/hooks-pre-tool-validate/src/main.rs (1)
234-265: 環境変数プレフィックスによるバイパスの可能性
preset_git()(line 125) では(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+|command\s+|env\s+)*を含めて環境変数プレフィックスやcommand/envビルトイン経由の実行をブロックしています。しかしpreset_jj_push_guard()にはこの対策がありません。以下のコマンドがバイパスできる可能性があります:
JJ_TRACE=1 jj git pushcommand jj git pushenv jj git push♻️ 環境変数プレフィックス対策の追加
BlockedPattern { - pattern: Regex::new(r#"(?im)(^|&&|;|\|\||\||&)\s*jj\s+git\s+push(\s|$)"#).unwrap(), + pattern: Regex::new(r#"(?im)(^|&&|;|\|\||\||&)\s*(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+|command\s+|env\s+)*jj\s+git\s+push(\s|$)"#).unwrap(), message: r#"**jj git push がブロックされました**同様に
jj pushのパターンにも適用してください。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks-pre-tool-validate/src/main.rs around lines 234 - 265, The jj push guard patterns in preset_jj_push_guard() lack the environment-variable/command/env prefix protection present in preset_git(); update both Regex::new(...) patterns (the ones matching `jj\s+git\s+push` and `jj\s+push`) to include the same prefix group `(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+|command\s+|env\s+)*` at the start of the pattern so invocations like `JJ_TRACE=1 jj git push`, `command jj git push`, or `env jj push` are blocked the same way as in preset_git().docs/adr/adr-008-push-pipeline-harness.md (1)
35-53: コードブロックに言語指定を追加してください。markdownlint により、fenced code block に言語指定がないことが検出されています(MD040)。アーキテクチャ図として
textまたは明示的な指定を追加してください。📝 言語指定の追加
-``` +```text Claude が "jj git push" を実行しようとする🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/adr/adr-008-push-pipeline-harness.md` around lines 35 - 53, The fenced code block in adr-008-push-pipeline-harness.md that contains the architecture diagram (the block beginning with the line "Claude が \"jj git push\" を実行しようとする") must include a language spec to satisfy markdownlint MD040; update the opening triple-backtick to include a language such as text (e.g., ```text) so the diagram block is explicitly marked and the linter error is resolved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/hooks-push-pipeline/src/main.rs:
- Around line 196-197: The current unwrap_or_else on pipeline.push_cmd accepts
empty or whitespace-only strings; update the logic that builds push_cmd (and the
similar cmd handling at the other block) to trim whitespace and treat an empty
result as missing so the DEFAULT_PUSH_CMD is used: when reading
pipeline.push_cmd, trim() the string and if the trimmed string is non-empty use
it, otherwise fall back to DEFAULT_PUSH_CMD (same change for the other variable
named cmd/ pipeline.cmd), ensuring both whitespace-only and empty strings are
replaced by the default.
In `@package.json`:
- Line 16: The "push" npm script currently uses Windows-only backslash and .exe
(".\\.claude\\hooks-push-pipeline.exe"), which breaks on Unix; update the "push"
script in package.json to invoke a cross-platform path or wrapper (for example
"./.claude/hooks-push-pipeline" without backslashes/extension) or implement
platform-specific scripts like "push:win" and "push:unix" and have "push"
dispatch to the correct one (or use a small Node wrapper that selects the
correct binary), referencing the "push" script name and the
".claude/hooks-push-pipeline" binary to locate the change.
---
Nitpick comments:
In @.claude/hooks-pre-tool-validate/src/main.rs:
- Around line 234-265: The jj push guard patterns in preset_jj_push_guard() lack
the environment-variable/command/env prefix protection present in preset_git();
update both Regex::new(...) patterns (the ones matching `jj\s+git\s+push` and
`jj\s+push`) to include the same prefix group
`(?:[A-Za-z_][A-Za-z0-9_]*=\S+\s+|command\s+|env\s+)*` at the start of the
pattern so invocations like `JJ_TRACE=1 jj git push`, `command jj git push`, or
`env jj push` are blocked the same way as in preset_git().
In `@docs/adr/adr-008-push-pipeline-harness.md`:
- Around line 35-53: The fenced code block in adr-008-push-pipeline-harness.md
that contains the architecture diagram (the block beginning with the line
"Claude が \"jj git push\" を実行しようとする") must include a language spec to satisfy
markdownlint MD040; update the opening triple-backtick to include a language
such as text (e.g., ```text) so the diagram block is explicitly marked and the
linter error is resolved.
🪄 Autofix (Beta)
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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8eefad1c-2540-404e-b3ed-db1abdc1742f
⛔ Files ignored due to path filters (1)
.claude/hooks-push-pipeline/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
.claude/hooks-config.toml.claude/hooks-pre-tool-validate/src/main.rs.claude/hooks-push-pipeline/Cargo.toml.claude/hooks-push-pipeline/src/main.rs.gitignoreCLAUDE.mddocs/adr/adr-008-push-pipeline-harness.mdpackage.jsonscripts/deploy-hooks.ts
| "build:hooks-settings": "node -e \"const fs=require('fs');const t=fs.readFileSync('.claude/settings.local.json.template','utf8');const p=process.cwd().replace(/\\\\/g,'\\\\\\\\');fs.writeFileSync('.claude/settings.local.json',t.replace(/\\{\\{PROJECT_DIR\\}\\}/g,p))\" && echo settings.local.json generated", | ||
| "build:hooks": "pnpm build:hooks-pre-tool-validate && pnpm build:hooks-post-tool-linter && pnpm build:hooks-stop-quality && pnpm build:hooks-settings", | ||
| "build:hooks": "pnpm build:hooks-pre-tool-validate && pnpm build:hooks-post-tool-linter && pnpm build:hooks-stop-quality && pnpm build:hooks-push-pipeline && pnpm build:hooks-settings", | ||
| "push": ".\\.claude\\hooks-push-pipeline.exe", |
There was a problem hiding this comment.
クロスプラットフォーム互換性の確認が必要です。
push スクリプトで Windows 固有のパス構文 (.\) を使用しています。Unix 系システム(Linux/macOS)では ./ が必要であり、現在の構文では動作しません。
.exe 拡張子から Windows 専用を意図している可能性がありますが、クロスプラットフォーム対応が必要な場合は以下の修正を検討してください:
🔧 クロスプラットフォーム対応の提案
- "push": ".\\.claude\\hooks-push-pipeline.exe",
+ "push": "node -e \"require('child_process').execSync(process.platform === 'win32' ? '.\\\\.claude\\\\hooks-push-pipeline.exe' : './.claude/hooks-push-pipeline', {stdio: 'inherit'})\"",または、Unix 用にはシンボリックリンクや拡張子なしのバイナリを用意する方法もあります。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` at line 16, The "push" npm script currently uses Windows-only
backslash and .exe (".\\.claude\\hooks-push-pipeline.exe"), which breaks on
Unix; update the "push" script in package.json to invoke a cross-platform path
or wrapper (for example "./.claude/hooks-push-pipeline" without
backslashes/extension) or implement platform-specific scripts like "push:win"
and "push:unix" and have "push" dispatch to the correct one (or use a small Node
wrapper that selects the correct binary), referencing the "push" script name and
the ".claude/hooks-push-pipeline" binary to locate the change.
PreToolUse の jj-push-guard プリセットで直接の push をブロックし、 hooks-push-pipeline (スタンドアロン Rust exe) で push 前パイプラインを 実行する2段構成で、Claude Code hooks に存在しない push hook を補完する。 - PreToolUse: jj-push-guard プリセット追加 - hooks-push-pipeline: command 型/ai 型ステップの順次実行 + 最終 push - hooks-config.toml: [push_pipeline] セクション追加 - ビルド・配布統合: package.json, .gitignore, deploy-hooks.ts 更新 - ADR-008: 設計判断を記録 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> fix: CodeRabbit レビュー指摘4件を修正 - push_cmd/cmd の空文字バリデーション追加 (#1 Major) - jj-push-guard に環境変数プレフィックスバイパス対策 (#3 Nitpick) - ADR-008 コードブロックに言語指定追加 (#4 Nitpick) - hooks-push-pipeline 全関数に docstring 追加 (#5 Pre-merge)
9d9bcb9 to
9150913
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.claude/hooks-push-pipeline/src/main.rs (1)
106-114: Windows 固有のcmd /cを使用しているため、Linux/macOS では動作しません
Command::new("cmd").args(["/c", cmd])は Windows 専用です。クロスプラットフォーム対応が必要な場合は、OS に応じてシェルを切り替える必要があります。現在の設計が Windows 専用で意図的であれば問題ありませんが、将来的な移植性を考慮する場合は修正を検討してください。
♻️ クロスプラットフォーム対応案
- let mut child = match Command::new("cmd") - .args(["/c", cmd]) + #[cfg(windows)] + let mut child = match Command::new("cmd") + .args(["/c", cmd]) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .spawn() + { + Ok(c) => c, + Err(e) => return (false, format!("Failed to execute {}: {}", cmd, e)), + }; + + #[cfg(not(windows))] + let mut child = match Command::new("sh") + .args(["-c", cmd]) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) .spawn()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks-push-pipeline/src/main.rs around lines 106 - 114, The code currently spawns a process with Windows-only Command::new("cmd").args(["/c", cmd]) which breaks on Linux/macOS; change the spawn logic to choose the shell based on the target OS (e.g., if cfg!(windows) use Command::new("cmd").args(&["/c", cmd]) else use Command::new("sh").args(&["-c", cmd])) and then call .stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() the same way; keep the same error handling (the Err(e) => return ...) and the variable names (child, cmd) so the rest of the function remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.claude/hooks-push-pipeline/src/main.rs:
- Around line 106-114: The code currently spawns a process with Windows-only
Command::new("cmd").args(["/c", cmd]) which breaks on Linux/macOS; change the
spawn logic to choose the shell based on the target OS (e.g., if cfg!(windows)
use Command::new("cmd").args(&["/c", cmd]) else use
Command::new("sh").args(&["-c", cmd])) and then call
.stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() the same way; keep the
same error handling (the Err(e) => return ...) and the variable names (child,
cmd) so the rest of the function remains unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b2e6b497-f318-43af-8055-f6b0e1b1abc3
⛔ Files ignored due to path filters (1)
.claude/hooks-push-pipeline/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
.claude/hooks-config.toml.claude/hooks-pre-tool-validate/src/main.rs.claude/hooks-push-pipeline/Cargo.toml.claude/hooks-push-pipeline/src/main.rs.gitignoreCLAUDE.mddocs/adr/adr-008-push-pipeline-harness.mdpackage.jsonscripts/deploy-hooks.ts
✅ Files skipped from review due to trivial changes (3)
- CLAUDE.md
- .claude/hooks-push-pipeline/Cargo.toml
- .gitignore
🚧 Files skipped from review as they are similar to previous changes (4)
- scripts/deploy-hooks.ts
- package.json
- .claude/hooks-config.toml
- docs/adr/adr-008-push-pipeline-harness.md
…プト化 + prepare-pr-body helper 新設 (PR-B) ADR-028 の二次防衛層を実装。`permissions.ask` の "ask > allow" precedence により、auto mode でも毎回確認プロンプトが発火するようになる。 - `.claude/settings.json`: `permissions.ask` に 4 パターン追加 - `Bash(pnpm create-pr*)`, `Bash(pnpm merge-pr*)` - `Bash(*cli-pr-monitor.exe*)`, `Bash(*cli-merge-pipeline.exe*)` - `.claude/settings.local.json.template`: `pnpm create-pr` / `merge-pr` の allow 登録を削除 (ADR-028 の二層防衛と矛盾する誤解を招くため) - `scripts/prepare-pr-body.ps1` 新規: stdin から PR body を受け取り `.tmp-pr-body.md` に UTF-8 (BOM なし) で書き出す helper。`-Cleanup` で削除 - `package.json`: `prepare-pr-body` / `prepare-pr-body:cleanup` スクリプト追加 - `.gitignore`: `.tmp-pr-body.md` を除外 (一時ファイル) - `docs/adr/adr-028-pnpm-create-pr-gate.md`: PR-B 実装済みに反映、PR-D 参照番号を更新 - `docs/todo.md`: PR-B タスク削除 + 後続リナンバー (PR-C → #7, PR-D → #8) smoke test: - `echo "日本語" | pnpm prepare-pr-body` で UTF-8 が保持されることを確認 - `pnpm prepare-pr-body:cleanup` で `.tmp-pr-body.md` 削除動作を確認 refs: ADR-028, PR #56 (PR-A, ADR 集約)
…プト化 + prepare-pr-body helper 新設 (PR-B) ADR-028 の二次防衛層を実装。`permissions.ask` の "ask > allow" precedence により、auto mode でも毎回確認プロンプトが発火するようになる。 - `.claude/settings.json`: `permissions.ask` に 4 パターン追加 - `Bash(pnpm create-pr*)`, `Bash(pnpm merge-pr*)` - `Bash(*cli-pr-monitor.exe*)`, `Bash(*cli-merge-pipeline.exe*)` - `.claude/settings.local.json.template`: `pnpm create-pr` / `merge-pr` の allow 登録を削除 (ADR-028 の二層防衛と矛盾する誤解を招くため) - `scripts/prepare-pr-body.ps1` 新規: stdin から PR body を受け取り `.tmp-pr-body.md` に UTF-8 (BOM なし) で書き出す helper。`-Cleanup` で削除 - `package.json`: `prepare-pr-body` / `prepare-pr-body:cleanup` スクリプト追加 - `.gitignore`: `.tmp-pr-body.md` を除外 (一時ファイル) - `docs/adr/adr-028-pnpm-create-pr-gate.md`: PR-B 実装済みに反映、PR-D 参照番号を更新 - `docs/todo.md`: PR-B タスク削除 + 後続リナンバー (PR-C → #7, PR-D → #8) smoke test: - `echo "日本語" | pnpm prepare-pr-body` で UTF-8 が保持されることを確認 - `pnpm prepare-pr-body:cleanup` で `.tmp-pr-body.md` 削除動作を確認 refs: ADR-028, PR #56 (PR-A, ADR 集約)
…プト化 + prepare-pr-body helper 新設 (PR-B) (#57) ADR-028 の二次防衛層を実装。`permissions.ask` の "ask > allow" precedence により、auto mode でも毎回確認プロンプトが発火するようになる。 - `.claude/settings.json`: `permissions.ask` に 4 パターン追加 - `Bash(pnpm create-pr*)`, `Bash(pnpm merge-pr*)` - `Bash(*cli-pr-monitor.exe*)`, `Bash(*cli-merge-pipeline.exe*)` - `.claude/settings.local.json.template`: `pnpm create-pr` / `merge-pr` の allow 登録を削除 (ADR-028 の二層防衛と矛盾する誤解を招くため) - `scripts/prepare-pr-body.ps1` 新規: stdin から PR body を受け取り `.tmp-pr-body.md` に UTF-8 (BOM なし) で書き出す helper。`-Cleanup` で削除 - `package.json`: `prepare-pr-body` / `prepare-pr-body:cleanup` スクリプト追加 - `.gitignore`: `.tmp-pr-body.md` を除外 (一時ファイル) - `docs/adr/adr-028-pnpm-create-pr-gate.md`: PR-B 実装済みに反映、PR-D 参照番号を更新 - `docs/todo.md`: PR-B タスク削除 + 後続リナンバー (PR-C → #7, PR-D → #8) smoke test: - `echo "日本語" | pnpm prepare-pr-body` で UTF-8 が保持されることを確認 - `pnpm prepare-pr-body:cleanup` で `.tmp-pr-body.md` 削除動作を確認 refs: ADR-028, PR #56 (PR-A, ADR 集約)
ADR-028 (外部可視成果物の生成コマンドの実行ゲート) の運用フローを skill として明文化。 `pnpm push` 完了後の PR 作成で以下の 7 ステップを標準化する: 1. jj status + jj log -r master..@ で差分/bookmark 確認 2. commit description から PR title 初稿生成 (70 文字超は短縮、conventional prefix 維持) 3. diff + commit log から PR body 初稿生成 (Summary/Context/Validation/References) 4. Claude が提示 → AskUserQuestion で明示承認 (auto mode でも必須) 5. `pnpm prepare-pr-body` 経由で `.tmp-pr-body.md` に書き出し 6. `pnpm create-pr --title ... --body-file ...` foreground 実行 (permissions.ask で再確認) 7. `pnpm prepare-pr-body:cleanup` で一時ファイル削除 ## 設計ハイライト - **ADR-028 二層防衛の活用**: skill 内の AskUserQuestion (一次) + permissions.ask (二次) - **user-supplied text の尊重** (ADR-022): 承認済 draft の二重書き換えを禁止 - **body は必ず一時ファイル経由**: `--body "..."` 引数経由の切り詰めリスク回避 (PR #51 / memory `feedback_pnpm_create_pr_body.md`) - **automated actor から独立**: takt / cli-* の自律ループはこの skill を呼ばない ## ステータス 試験運用 (2026-04-19〜)。発火頻度・UX を半年観察して正式採用 / 改良 / 廃止を判断する。 ## ファイル - `.claude/skills/prepare-pr/SKILL.md` 新設 (178 行) ## docs/todo.md - PR-D 完了に伴い「セッション 247510ea 由来: 整備タスク群」ブロック全体を削除 - 雑務 task をリナンバー (#8 → #7) refs: ADR-028, ADR-022, PR #57 (PR-B body helper), memory `feedback_bookmark_auto_naming.md`
ADR-028 (外部可視成果物の生成コマンドの実行ゲート) の運用フローを skill として明文化。 `pnpm push` 完了後の PR 作成で以下の 7 ステップを標準化する: 1. jj status + jj log -r master..@ で差分/bookmark 確認 2. commit description から PR title 初稿生成 (70 文字超は短縮、conventional prefix 維持) 3. diff + commit log から PR body 初稿生成 (Summary/Context/Validation/References) 4. Claude が提示 → AskUserQuestion で明示承認 (auto mode でも必須) 5. `pnpm prepare-pr-body` 経由で `.tmp-pr-body.md` に書き出し 6. `pnpm create-pr --title ... --body-file ...` foreground 実行 (permissions.ask で再確認) 7. `pnpm prepare-pr-body:cleanup` で一時ファイル削除 ## 設計ハイライト - **ADR-028 二層防衛の活用**: skill 内の AskUserQuestion (一次) + permissions.ask (二次) - **user-supplied text の尊重** (ADR-022): 承認済 draft の二重書き換えを禁止 - **body は必ず一時ファイル経由**: `--body "..."` 引数経由の切り詰めリスク回避 (PR #51 / memory `feedback_pnpm_create_pr_body.md`) - **automated actor から独立**: takt / cli-* の自律ループはこの skill を呼ばない ## ステータス 試験運用 (2026-04-19〜)。発火頻度・UX を半年観察して正式採用 / 改良 / 廃止を判断する。 ## ファイル - `.claude/skills/prepare-pr/SKILL.md` 新設 (178 行) ## docs/todo.md - PR-D 完了に伴い「セッション 247510ea 由来: 整備タスク群」ブロック全体を削除 - 雑務 task をリナンバー (#8 → #7) refs: ADR-028, ADR-022, PR #57 (PR-B body helper), memory `feedback_bookmark_auto_naming.md`
ADR-028 (外部可視成果物の生成コマンドの実行ゲート) の運用フローを skill として明文化。 `pnpm push` 完了後の PR 作成で以下の 7 ステップを標準化する: 1. jj status + jj log -r master..@ で差分/bookmark 確認 2. commit description から PR title 初稿生成 (70 文字超は短縮、conventional prefix 維持) 3. diff + commit log から PR body 初稿生成 (Summary/Context/Validation/References) 4. Claude が提示 → AskUserQuestion で明示承認 (auto mode でも必須) 5. `pnpm prepare-pr-body` 経由で `.tmp-pr-body.md` に書き出し 6. `pnpm create-pr --title ... --body-file ...` foreground 実行 (permissions.ask で再確認) 7. `pnpm prepare-pr-body:cleanup` で一時ファイル削除 ## 設計ハイライト - **ADR-028 二層防衛の活用**: skill 内の AskUserQuestion (一次) + permissions.ask (二次) - **user-supplied text の尊重** (ADR-022): 承認済 draft の二重書き換えを禁止 - **body は必ず一時ファイル経由**: `--body "..."` 引数経由の切り詰めリスク回避 (PR #51 / memory `feedback_pnpm_create_pr_body.md`) - **automated actor から独立**: takt / cli-* の自律ループはこの skill を呼ばない ## ステータス 試験運用 (2026-04-19〜)。発火頻度・UX を半年観察して正式採用 / 改良 / 廃止を判断する。 ## ファイル - `.claude/skills/prepare-pr/SKILL.md` 新設 (178 行) ## docs/todo.md - PR-D 完了に伴い「セッション 247510ea 由来: 整備タスク群」ブロック全体を削除 - 雑務 task をリナンバー (#8 → #7) refs: ADR-028, ADR-022, PR #57 (PR-B body helper), memory `feedback_bookmark_auto_naming.md`
ADR-028 (外部可視成果物の生成コマンドの実行ゲート) の運用フローを skill として明文化。 `pnpm push` 完了後の PR 作成で以下の 7 ステップを標準化する: 1. jj status + jj log -r master..@ で差分/bookmark 確認 2. commit description から PR title 初稿生成 (70 文字超は短縮、conventional prefix 維持) 3. diff + commit log から PR body 初稿生成 (Summary/Context/Validation/References) 4. Claude が提示 → AskUserQuestion で明示承認 (auto mode でも必須) 5. `pnpm prepare-pr-body` 経由で `.tmp-pr-body.md` に書き出し 6. `pnpm create-pr --title ... --body-file ...` foreground 実行 (permissions.ask で再確認) 7. `pnpm prepare-pr-body:cleanup` で一時ファイル削除 ## 設計ハイライト - **ADR-028 二層防衛の活用**: skill 内の AskUserQuestion (一次) + permissions.ask (二次) - **user-supplied text の尊重** (ADR-022): 承認済 draft の二重書き換えを禁止 - **body は必ず一時ファイル経由**: `--body "..."` 引数経由の切り詰めリスク回避 (PR #51 / memory `feedback_pnpm_create_pr_body.md`) - **automated actor から独立**: takt / cli-* の自律ループはこの skill を呼ばない ## ステータス 試験運用 (2026-04-19〜)。発火頻度・UX を半年観察して正式採用 / 改良 / 廃止を判断する。 ## ファイル - `.claude/skills/prepare-pr/SKILL.md` 新設 (178 行) ## docs/todo.md - PR-D 完了に伴い「セッション 247510ea 由来: 整備タスク群」ブロック全体を削除 - 雑務 task をリナンバー (#8 → #7) refs: ADR-028, ADR-022, PR #57 (PR-B body helper), memory `feedback_bookmark_auto_naming.md`
…必須 follow-up (順位 91 + 92 + 93) (#135) * feat(cli-finding-classifier, cli-push-runner): Bundle i — Phase d 着手前必須 follow-up (順位 91 + 92 + 93) PR #132 (Phase c MVP land) の post-merge-feedback で採用された 3 件を 1 PR にまとめて land。 ## 順位 91 (Tier 2 #4): [lint_screen] config parse test - src/cli-push-runner/src/config.rs に 5 tests を追加 - silent field rename / 追加で None fallback する failure mode を unit test で防止 - full fields / minimal only enabled / absent yields None / numeric defaults / string defaults の 5 軸独立検証 ## 順位 92 (Tier 2 #5): scale-aware eval fixtures (200+ 行) - eval13-large-refactor-real.diff (5 file / 280 行) — context 限界 + JSON 完全性 - eval14-mid-mixed.diff (3 file / 153 行) — mid-scale recall 安定性 - eval15-syntax-stress.diff (1 file / 208 行) — 単 file 長尺の schema 完全性 - lint-screen-evals.json に id 13/14/15 baseline (auto_fix lane × 13 findings 合計) 追加 - count test を rename + 上限緩和 (eval_set_loads_and_has_at_least_phase_b_prime_baseline_count) - Bundle i 実体スモーク test (eval_set_includes_bundle_i_scale_aware_fixtures) 追加 ### dogfood 結果 (mistral:7b / temperature=0) agreement = 11/15 = 73.3% (Phase b' 75% から marginal 劣化 = fixture が設計通り failure mode を再現) eval13 (280 行): JSON parse error 'missing field screen_decision' → fallback path 作動 = PR #132 smoke (868 行 diff) で観測した failure mode を decisive に再現 eval15 (208 行): JSON parse error 'missing field severity at line 38' = nested field omission の別 failure mode を新規捕捉 eval14 (153 行): JSON 完全だが recall 33% (3 baseline 中 1 件のみ TP) aggregate precision=76.2% recall=51.6% latency p50=4591ms p95=8370ms verdict CONDITIONAL-GO agreement < 75% 未達理由は eval13/15 の fallback (= fixture が設計通り作動した結果) で mechanical に説明可能。Phase d 投入前の必須 measurement を取得 (todo6.md L164 「未達理由が 文書化される」branch を満たす)。§8.D v4 prompt 改訂は別 bundle に切り出し。 ## 順位 93 (Tier 3 #8): coding-style.md partial fix anti-pattern codify - ~/.claude/rules/common/coding-style.md § Cross-File Reference Lifecycle に 「変更差分外への partial fix 再発」anti-pattern を追加 - PR #94 / #111 / #132 を inline cite (実証ベース) - family_tag を grep -rn で全 path 検索する対処手順、partial fix の意図的切り出しを明記 ## Phase d 着手の前提条件 update Bundle i land で以下が揃った: - (a) [lint_screen] config silent failure 防止 (順位 91) - (b) scale-aware fixtures による failure mode の reproducible measurement (順位 92) - (c) cross-file partial fix anti-pattern の global rule 化 (順位 93) 次は §8.D v4 prompt 改訂で大規模 diff の JSON 完全性を改善するループ (Phase d 着手前の最終 gate)。 * fix(cli-finding-classifier): CodeRabbit Major #r3213115045 — eval count 下限を Bundle i baseline 15 に固定 >=12 だと既存 fixture 削除を検出できないため >= 15 に変更し regression 防止。 将来の fixture 追加 (>15) は許容。
…jj split の -m 必須化 (順位 144) (#172) * docs(todo): 順位 143 + 144 新規追加 — PR #171 post-merge-feedback 採用 2 件 (Bundle 171: T2-#4 fixture helper + T3-#8 jj hook) * refactor(hooks-pre-tool-validate): BlockedPattern に exception field 追加 (順位 144 Phase 1) * feat(hooks-pre-tool-validate): jj-message-required preset 追加 (順位 144 Phase 2) * test(hooks-pre-tool-validate): block/allow/non-regression test 拡充 (順位 144 Phase 3) * chore(hooks): build + deploy hooks-pre-tool-validate exe + 順位 144 entry 削除 (Phase 4)
…DR-071) (#361) * feat(autonomy-policy): 未マージ draft 数の背圧を判定コアの入力にする WP-18 PR 1 (1/5)。ADR-052 原則 5 が自動実行可クラスの前提条件とする背圧を、 判定コア `lib-autonomy-policy` が入力として受け取れるようにする。 ## 変更の要点 `Operation::backpressure_connected()` の `DraftPr => false` 固定を廃し、背圧の **指標の要求**と**指標の実測値**を別の層へ分けた: - `Operation::requires_draft_backpressure()` — 操作クラスが「未マージ draft 数」を 要求するかだけを持つ静的分類。状態は持たない - `GateInputs::open_draft_prs` / `max_open_draft_prs` — 実測値と閾値。どちらか一方でも `None` なら `backpressure-unavailable` で deny (fail-closed) 背圧の状態を enum 側にも持たせると `GateInputs` と二重管理になり判定経路が分岐するため、 状態の保持先は `GateInputs` 1 箇所に限定した (計画書 WP-18 PR 1 の明示要件)。 `FixPush` が draft 数を要求しないのは背圧が無いからではなく、その背圧が cli-pr-monitor の 有界 retry (`max_retries`) で、呼び出しごとに gate へ渡す状態を持たないため。この非対称を doc コメントとテスト (`fix_push_is_unaffected_by_draft_backpressure_inputs`) の両方で固定した。 ## 追加した deny 理由 `DenyReason::BackpressureSaturated { open, limit }` (code = `backpressure-saturated`)。 飽和判定は `>=`。閾値は「これ以上は積まない」上限であり、`limit = 0` は「draft を 1 件も 作らない」= 実質停止を意味する。 `describe_sources` の背圧表記は `structural` / `ok(N/M)` / `saturated(N/M)` / `unavailable` の 4 状態で、実数を必ず併記する。run log 1 行で「数え損ねて止まった」と「積み過ぎて 止まった」を切り分けられるようにするため。 ## テスト 判定コアのテストを 16 → 22 件へ。網羅走査テストは背圧 4 パターンを軸に加えて 54 → 216 組合せになり、許可される組合せ数も式で固定した (truthy 表記数 × (fix-push 4 + draft-pr 1))。 境界 (`open == limit` で止まる)、`limit = 0`、kill-switch が背圧より先に効くこと、 背圧入力の欠落 3 パターンをそれぞれ独立に pin している。 ## 本コミットの範囲 呼び手 2 件 (`cli-autonomy-gate` / `cli-fix-push-gate`) は本コミットでは `None` を渡す。 `draft-pr` は従来どおり deny のままで、運用挙動は変わらない。config からの閾値読み取りは 2/5、実測 draft 数の受け口は 3/5 で接続する。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(autonomy-policy): 背圧閾値 max_open_draft_prs を config から 1 回の read で取り込む WP-18 PR 1 (2/5)。背圧の閾値を `autonomy-config.toml` の `[autonomy] max_open_draft_prs` に置き、kill-switch フラグと同じ信頼境界 (master ref の写し) と 同じ「欠損 → 停止」極性に乗せる。 ## read を 1 回に集約した理由 `read_repo_config_enabled(path) -> Option<bool>` を `read_repo_config(path) -> RepoConfig` へ置き換えた。キーごとに読み取り関数を生やすとファイルを 2 回読むことになり、2 回の read の 間に config が差し替わると「kill-switch は旧世代・閾値は新世代」という混成状態で判定しうる。 1 回の read から派生した値だけを使う。 ## 半壊 config は全フィールドが停止側へ倒れる toml の parse はファイル単位なので、`max_open_draft_prs` が型違い (文字列 / 負値 / 小数) だと `enabled` も含めて全フィールドが `None` になる。これは意図した挙動で、config の一部が壊れた 状態を「kill-switch だけ有効」で運転させない (ADR-043 fail-closed)。テストで明示的に固定した。 閾値キー欠落時に既定値 (3 など) へ倒さないのも同じ理由。書き忘れが「勝手に 3 件まで作る」 という fail-open にならないよう、欠落は背圧未接続 = draft PR deny とする。 一方で未知キーは無視する (`unknown_keys_are_ignored`)。config に新しい設定を足したときに、 未更新のバイナリが parse 失敗で全停止するのは安全側に振りすぎるため。 ## テスト sources のテストを 6 → 11 件へ。閾値の正常読み取り (0 を含む)、キー欠落が既定値でないこと、 型違い 3 種が kill-switch フラグごと停止側へ倒すこと、未知キー無視を追加した。 ## 本コミットの範囲 `cli-autonomy-gate` は閾値を `GateInputs` へ渡すようになったが、実測 draft 数の受け口 (`--open-draft-prs`) はまだ無いため `draft-pr` は `backpressure-unavailable` で deny のまま。 接続は 3/5 で行う。`cli-fix-push-gate` は `enabled` しか使わないため呼び出し形の追従のみ。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(autonomy-gate): --open-draft-prs で実測 draft 数を受け取り背圧を接続する WP-18 PR 1 (3/5)。判定コア (1/5) と閾値 (2/5) に続き、背圧の残り 1 入力である **実測件数**の受け口を CLI に開ける。これで `draft-pr` が構造的 deny を脱し、 ADR-052 原則 5 の契約を満たした状態でのみ許可されるようになる。 ## 引数の扱い `--open-draft-prs <count>` は省略可能。`fix-push` では判定に使わないためで、`draft-pr` で 省略した場合は `None` = 背圧未接続として deny に倒れる。**省略が許可へ倒れる経路は無い**。 値のパースは `u32` で、空文字 / 負値 / 小数 / 非数値 / 末尾空白は引数不正 (exit 2) として 弾く。呼び手の `gh api` が失敗したときの出力 (空文字など) を 0 件と読み違えて「draft が 1 件も無いので作ってよい」に倒れるのが最悪の failure mode なので、ここは黙って `None` へ 潰さず loud に落とす。 `--config` / `--operation` の必須性は従来どおり。引数ループは値取得を各 arm へ寄せ、 未知フラグの判定を値の有無より先に行う既存の順序を保った。 ## テスト 引数解析のテストを 4 → 7 件へ。省略時が `None` であること、`0` が正しく `Some(0)` として 読まれること (「0 件」と「数えられなかった」を型で区別する契約)、不正値 5 種が引数不正で あることを固定した。 ## 本コミットの範囲 exe 単体では背圧が接続された。実測値を渡す呼び手 (夜間 workflow の `gh api` step) は **本 PR には含まれず PR 3 で追加する** (ADR-069 chain 宣言 → 計画書 § WP-18 と ADR-071 を 5/5 で更新)。実 exe による drill は 4/5。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr-071): 未マージ draft PR 数による背圧を起票し drill 12 シナリオを記録 WP-18 PR 1 (4/5)。1/5〜3/5 で実装した背圧の設計判断・試験運用条件・実測を永続化する。 ## 記録した決定 5 件 1. 指標は「未マージ draft PR 数 (claude/ prefix)」。run 回数や経過時間のような代理指標 ではなく、止めたい事象 (人間が捌けない量の未処理成果物) を直接数える 2. 背圧の状態は GateInputs だけが持つ。enum 側にも状態を置くと判定経路が二股に分かれ、 「テストは通るが実運用では別の枝を通る」drift を生む 3. 閾値は autonomy-config.toml の max_open_draft_prs、判定は >=。0 は draft-pr クラス だけの停止、キー欠落は既定値ではなく deny 4. 数えるのは呼び手 (workflow step の gh api)、判断するのは gate。exe が gh に依存すると ローカル drill が GitHub 到達性に依存し、安全装置の再現可能な検証ができなくなる 5. 数えられなかったことは 0 件ではない。不正値は exit 2 で loud に落とす 決定 4 の「呼び手が数を偽れる」問題は、schedule イベントが default branch の workflow 定義を 使うという GitHub の仕様で担保される (ADR-066 の config master ref 契約と同じ信頼境界)。 ## 外部 SaaS の課金・上限事実を移管 (計画書 § 2 の退役条件 2) 2026-08-06 に最新値を再確認して永続化した。 - public リポジトリ + standard runner の Actions 実行は無料・分数無制限 (GitHub 公式 docs で 原文確認)。GitHub Free の 2,000 分/月は private のみ - claude-code-action@v1 は claude_code_oauth_token で Max 枠を消費。OAuth token は個人 サブスクに紐づき、自動化の消費が対話作業のレート枠を圧迫しうる 要約: Actions の実行時間は無料だが Max 枠は有限。背圧の経済的根拠はここにある。 ## 検証記録 release build の実 exe で drill 12 シナリオを実施し全て設計どおりを確認した。#6/#7 の対で >= 境界、#8 で limit=0 の停止、#9 で fix push が draft 数から独立していること、#10 で 半壊 config が enabled ごと停止することを実バイナリ上で確認している。 unit test は判定コア 22 / sources 11 / 引数解析 7 件。網羅走査 1 件が 216 組合せを走査する。 ## bounded lifetime decision trigger (b)「閾値到達で実際に次の run が止まること」は本 ADR 固有の観測点で、 exe 単体 drill では作れない状態 (夜間ループが実際に 3 件積む必要がある)。期限は 2026-11-06。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(harness-plan): WP-18 PR 1 の完了を記帳し PR 3 への chain 宣言と SaaS 事実の移管を行う WP-18 PR 1 (5/5)。計画書側の 3 種類の更新。 ## 1. PR 1 完了の記帳 - WP-18 節の見出しと全体像表を「着手可」→「着手中(PR 1 実装済み)」へ - PR 構成 1 に実装時の設計判断を確定記録: 閾値判定の層は (a) gate 内を採用。 backpressure_connected() は廃し requires_draft_backpressure()(指標の要求のみ)と GateInputs の 2 フィールド(状態)へ分離した - 着手前決定 2 の記述を過去形へ(backpressure_connected() は既に存在しない名前のため、 現在形のまま残すと ADR-069 決定 1 の「名前一致」要件に反する) - WP-19 ステップ 2 を「前倒し済み」→「land 済み」へ ## 2. PR chain 宣言(ADR-069 決定 1) PR 1 が導入した 3 点(--open-draft-prs フラグ / max_open_draft_prs キー / DraftPr の許可 経路)は PR 3 まで呼び手を持たない。抽出↔呼び手のペアリングを表で具体名指定した。 順序を逆にできない根拠も明記した — ADR-052 原則 5 が背圧の接続を draft-pr クラス有効化の 前提条件としているため、背圧が先に land する必要がある(WP-17 の kill-switch 先行と同構造)。 なお PR 1 単体では draft-pr は deny のままで運用挙動は変わらない。 ## 3. SaaS 課金・上限事実の移管(退役条件 2 / 順位 117 の 3 ステップ原則) permanent 側(ADR-071 § 外部 SaaS の課金・上限事実)を先に作成 → 本ファイルの § 2 から GitHub Actions 課金 2 点と claude-code-action の OAuth 認証を削除し ADR-071 への参照へ 置き換えた。cloud routines の事実群は WP-19 / ADR-070 の担当範囲のため本節に残している。 runner 単価の相対比も private 化時のみ関係するため移管対象外とした。 pnpm lint:docs / markdownlint ともに green。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: CodeRabbit 指摘 2 件に対応 (主張の適用範囲を限定 / 移管済み方針の更新) PR #361 への CodeRabbit レビュー (Minor 2 件) の反映。どちらも「書いた内容が実態より 広い/古い」型の指摘で、妥当。 ## 1. 「draft-pr は deny のまま」の適用範囲を限定 (2 箇所) 指摘は「**両文書**が PR 3 まで draft-pr に許可経路が無いように読める」というもの。実際には ADR-071 § 検証記録の drill #6 が示すとおり、--open-draft-prs と有効な config を渡せば exe は allow になる。 正確には**リポジトリ内の自動化経路に --open-draft-prs を渡す呼び手が 1 つも無いため** deny に なる、が正しい。「運用挙動は変わらない」の根拠を exe の挙動ではなく呼び手の不在へ置き直した。 根拠を取り違えたまま PR 3 で呼び手が入ると、主張だけが stale に残る。 修正箇所は 2 つ: - docs/adr/adr-071-*.md § 残課題 - docs/harness-improvement-plan.md § WP-18 の PR chain 宣言 計画書側から ADR-071 § 残課題への参照も付け、同じ限定が 1 箇所に集約されるようにした。 ## 2. 計画書 § 2 preamble: 移管済みの事実と矛盾する旧方針を更新 旧文は「現時点では ADR 化せず本ファイルに保持する」と書いていたが、同じ blockquote の 次の行で「ADR-071 へ移管済み」と述べており矛盾していた。 方針文を「担当 WP の ADR 起票時に移管し本節から削除する」という恒常ルールへ書き換え、 移管済み / 未移管を別項目に分けた。未移管の内訳 (cloud routines の daily cap / webhook 上限 / GitHub App 必須 / 緑ステータスの意味) も具体名で列挙し、次の担当 WP が何を移管 すべきか読み取れるようにした。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(todo): WP-18 で検出した問題を 4 エントリへ登録 (順位 374-377) 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> * docs(todo): #363 post-merge feedback の採用 6 件を登録 (順位 378-383) 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> * docs(harness-plan): WP-18 を 3 PR マージ済へ更新し残作業 2 系統を明示する #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> * docs(todo): 外部設定 (GitHub App / variables / secrets) の実体記録を登録 (順位 384) 新セッションでの指摘 (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> * fix(review): CodeRabbit Major 4 件を妥当性判定のうえ 3 件へ対応する (#364) 自動 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> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
jj-push-guardプリセットで直接の push をブロックし、pnpm pushに誘導hooks-push-pipeline(Rust exe) がhooks-config.tomlの[push_pipeline]セクションからステップを読み込み、順次実行type = "command"ステップ(テスト等)は即時実行、type = "ai"ステップ(レビュー、コミット整理)は将来実装のプレースホルダーChanges
.claude/hooks-push-pipeline/.claude/hooks-pre-tool-validate/src/main.rsjj-push-guardプリセット追加.claude/hooks-config.toml[push_pipeline]セクション追加package.jsonbuild:hooks-push-pipeline,pushスクリプト追加docs/adr/adr-008-push-pipeline-harness.mdTest plan
cargo test(hooks-push-pipeline): 9/9 passcargo test(hooks-pre-tool-validate): 93/93 passpnpm pushでパイプライン実行を確認 (test pass → AI skip → push 完了)pnpm build:hooksで全 hooks の一括ビルドを確認🤖 Generated with Claude Code
Summary by CodeRabbit
新機能
pnpm pushによるプッシュ前パイプラインを追加(テスト実行とレビューステップを順に実行)。pnpm pushを促す保護機構を導入。ドキュメント
その他