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
32 changes: 30 additions & 2 deletions .github/workflows/nightly-todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ jobs:
制約 (逸脱すると後続の決定論ゲートが push を拒否します):
- **自律動作のガードレール自体を変更しないこと**: `autonomy-config.toml`、
`.github/workflows/**`、`src/cli-autonomy-gate/**`、`src/lib-autonomy-policy/**`、
`src/cli-fix-push-gate/**`、`src/cli-nightly-task-select/**`、`src/lib-ledger/**`
`src/cli-fix-push-gate/**`、`src/cli-nightly-task-select/**`、`src/lib-ledger/**`、
`src/cli-ledger-cleanup/**`
- コミット・push・ブランチ操作・PR 操作は行わないこと (あなたの権限外)
- タスクに関係しないファイルを整形・修正しないこと
# tool scope (ADR-072 決定 12、順位 379)。
Expand Down Expand Up @@ -402,12 +403,39 @@ jobs:
# 決める仕組みであり、config や gate exe と同じく **自分を縛る側**にある。agent が
# 台帳を書き換えた diff が PR に紛れ、人間が見落としてマージすると、以後の
# タスク選択が静かに汚染される (ADR-072 決定 6)。
if grep -Eq '^(autonomy-config\.toml|\.github/workflows/|docs/claude-code-web-tasks\.md|src/cli-autonomy-gate/|src/lib-autonomy-policy/|src/cli-fix-push-gate/|src/cli-nightly-task-select/|src/lib-ledger/)' \
if grep -Eq '^(autonomy-config\.toml|\.github/workflows/|docs/claude-code-web-tasks\.md|src/cli-autonomy-gate/|src/lib-autonomy-policy/|src/cli-fix-push-gate/|src/cli-nightly-task-select/|src/lib-ledger/|src/cli-ledger-cleanup/)' \
"$RUNNER_TEMP/changed.txt"; then
echo "[NIGHTLY_DENY] 自律動作のガードレールを変更しているため push しません"
exit 1
fi

# 台帳が宣言した成果物がすべて揃っているかを決定論的に検証する。
#
# 由来: PR #394 は lint rule の 5 成果物のうち fixture 2 件だけを追加して CI green で
# マージされた。Guard step は「触ってはいけない物を触っていないか」しか見ず、
# 「実装すべき物を実装したか」は誰も見ていなかった。
#
# Guard の後に置くのは、禁止リスト違反を先に落とすため (改ざんされた台帳で
# 完了判定させない)。exe と台帳はどちらも master-ref/ から取る — work/ 側は agent が
# 書き換えられるので、自分の成績表を自分で書ける状態にしない (決定 1 と同じ信頼境界)。
- name: Verify the declared artifacts are complete
id: ledger-completion
continue-on-error: true
if: steps.guard.outcome == 'success'
run: |
set -euo pipefail
cargo build --release -p cli-ledger-cleanup --manifest-path master-ref/Cargo.toml
master-ref/target/release/cli-ledger-cleanup \
--ledger master-ref/docs/claude-code-web-tasks.md \
--ranks "${{ steps.select.outputs.rank }}" \
--changed-files "$RUNNER_TEMP/changed.txt"

- name: Stop when the implementation is incomplete
if: steps.guard.outcome == 'success' && steps.ledger-completion.outcome != 'success'
run: |
echo "::error::台帳が宣言する成果物に未変更のものがあります (直前の [LEDGER_CLEANUP_BLOCK] を参照)。実装が不完全な draft PR を作らないため、ここで停止します。" >&2
exit 1

# Implement ステップ (agent) は $GITHUB_WORKSPACE 全体に Read/Edit/Write/Glob/Grep を持ち、
# master-ref/ 側のゲート exe/config も技術的には書き換え可能 (プロンプト上の「対象は work/」は
# 強制力を持たない)。Guard step は work/ の diff しか見ないためこの改ざんを検知できず、後段の
Expand Down
7 changes: 7 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 @@ -23,6 +23,7 @@ members = [
"src/cli-autonomy-gate",
"src/cli-docs-lint",
"src/cli-finding-classifier",
"src/cli-ledger-cleanup",
"src/cli-fix-push-gate",
"src/cli-merge-pipeline",
"src/cli-nightly-task-select",
Expand Down
4 changes: 2 additions & 2 deletions docs/adr/adr-072-nightly-todo-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ security review の主張は「**`--allowedTools` の `Bash(cmd:*)` は文字列

draft PR は commitment 点の手前なので人間のレビューが最終防衛になるが、「自分を縛る仕組みを自分で書き換えた diff」だけは例外とし、決定論的な path 禁止リストで push を止める。

対象: `autonomy-config.toml` / `.github/workflows/**` / **`docs/claude-code-web-tasks.md`** / `src/cli-autonomy-gate/**` / `src/lib-autonomy-policy/**` / `src/cli-fix-push-gate/**` / `src/cli-nightly-task-select/**` / `src/lib-ledger/**`。
対象: `autonomy-config.toml` / `.github/workflows/**` / **`docs/claude-code-web-tasks.md`** / `src/cli-autonomy-gate/**` / `src/lib-autonomy-policy/**` / `src/cli-fix-push-gate/**` / `src/cli-nightly-task-select/**` / `src/lib-ledger/**` / `src/cli-ledger-cleanup/**`

**`src/lib-ledger/**` は 2026-08-14 に追加した。** 台帳パーサを `cli-nightly-task-select` から共有 lib へ抽出した際、パースの実体だけが禁止リストの外へ出た。exe 名で列挙していたため、**中身を別 crate へ動かすと保護が自動では追随しない**。禁止リストは「どの exe か」ではなく「どのロジックが自分を縛るか」で決まる — 台帳の解釈は agent が読む指示そのものを組み立てる位置にあり、exe 側に残った CLI 面と同じ保護が要る。

**台帳 (`docs/claude-code-web-tasks.md`) を含めるのは、それが「次に何を実装するか」を決める仕組みだから。** config や gate exe と同じく*自分を縛る側*にある。agent が台帳を書き換えた diff が draft PR に紛れ、人間が見落としてマージすると、以後のタスク選択が静かに汚染される。初版はここを落としていた (§ 静的レビューが捕捉した件)。

**列挙の基準は「危険か」ではなく「将来の無人 run のゲートを緩めるか」である。** security review は `Cargo.toml` / `Cargo.lock` の欠落を warning として挙げたが(agent が追加した build-script 依存が Guard を素通りする)、**採らない** — これらは通常の diff であり、人間の PR レビューとマージという既存の防衛線が効く。一方リストに載せた 8 つは、書き換わると*それ以降の run*がゲートを経ずに走るようになる。この基準を持たないと禁止リストは「怪しいもの全部」へ膨らみ、正当なタスクを弾き始める。
**列挙の基準は「危険か」ではなく「将来の無人 run のゲートを緩めるか」である。** security review は `Cargo.toml` / `Cargo.lock` の欠落を warning として挙げたが(agent が追加した build-script 依存が Guard を素通りする)、**採らない** — これらは通常の diff であり、人間の PR レビューとマージという既存の防衛線が効く。一方リストに載せた 9 つは、書き換わると*それ以降の run*がゲートを経ずに走るようになる。この基準を持たないと禁止リストは「怪しいもの全部」へ膨らみ、正当なタスクを弾き始める。

**許可リストではなく禁止リストにした**のは、台帳の「対象ファイル」列が自由記述の markdown (バッククォート・括弧・複数パスの列挙) で、path allowlist に落とすと正当なタスクまで弾くため。allowlist 化は台帳を機械可読にしてからの課題とする (§ 残課題)。

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
"build:cli-fix-push-gate": "cargo build --release -p cli-fix-push-gate && node scripts/deploy-artifacts.mjs cli-fix-push-gate",
"build:cli-nightly-task-select": "cargo build --release -p cli-nightly-task-select && node scripts/deploy-artifacts.mjs cli-nightly-task-select",
"build:cli-stale-branch-scan": "cargo build --release -p cli-stale-branch-scan && node scripts/deploy-artifacts.mjs cli-stale-branch-scan",
"build:cli-ledger-cleanup": "cargo build --release -p cli-ledger-cleanup && node scripts/deploy-artifacts.mjs cli-ledger-cleanup",
"build:hooks-settings": "node scripts/build-hooks-settings.mjs",
"build:all": "pnpm build:hooks-session-start && pnpm build:hooks-pre-tool-validate && pnpm build:hooks-post-tool-linter && pnpm build:hooks-post-tool-comment-lint-rust && pnpm build:hooks-post-tool-jj-op-verify && pnpm build:hooks-stop-quality && pnpm build:hooks-stop-feedback-dispatch && pnpm build:hooks-stop-tool-call-leak && pnpm build:hooks-user-prompt-feedback-recovery && pnpm build:cli-push-runner && pnpm build:cli-pr-monitor && pnpm build:cli-merge-pipeline && pnpm build:check-ci-coderabbit && pnpm build:cli-finding-classifier && pnpm build:cli-docs-lint && pnpm build:cli-takt-timings && pnpm build:cli-telemetry-report && pnpm build:cli-autonomy-gate && pnpm build:cli-fix-push-gate && pnpm build:cli-nightly-task-select && pnpm build:cli-stale-branch-scan && pnpm build:hooks-settings",
"build:all": "pnpm build:hooks-session-start && pnpm build:hooks-pre-tool-validate && pnpm build:hooks-post-tool-linter && pnpm build:hooks-post-tool-comment-lint-rust && pnpm build:hooks-post-tool-jj-op-verify && pnpm build:hooks-stop-quality && pnpm build:hooks-stop-feedback-dispatch && pnpm build:hooks-stop-tool-call-leak && pnpm build:hooks-user-prompt-feedback-recovery && pnpm build:cli-push-runner && pnpm build:cli-pr-monitor && pnpm build:cli-merge-pipeline && pnpm build:check-ci-coderabbit && pnpm build:cli-finding-classifier && pnpm build:cli-docs-lint && pnpm build:cli-takt-timings && pnpm build:cli-telemetry-report && pnpm build:cli-autonomy-gate && pnpm build:cli-fix-push-gate && pnpm build:cli-nightly-task-select && pnpm build:cli-stale-branch-scan && pnpm build:cli-ledger-cleanup && pnpm build:hooks-settings",
"push": "node scripts/run-artifact.mjs cli-push-runner && node scripts/run-artifact.mjs cli-pr-monitor --monitor-only",
"create-pr": "node scripts/run-artifact.mjs cli-pr-monitor",
"mark-notified": "node scripts/run-artifact.mjs cli-pr-monitor --mark-notified",
Expand Down
22 changes: 22 additions & 0 deletions push-runner-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,28 @@
enabled = true
patterns = ["__*", "_tmp_*"]

# ---------------------------------------------------------------------------
# [ledger_completion] — 台帳タスクの実装完了検証 (2026-08-15 追加)。
# commit description に `Ledger-Rank: N` trailer を書くと、台帳
# (docs/claude-code-web-tasks.md) の「対象ファイル」列が挙げる成果物すべてが
# PR 範囲で変更されているかを cli-ledger-cleanup が判定し、未完了なら push を止める。
#
# 由来: 夜間 PR #394 が lint rule の 5 成果物のうち fixture 2 件だけを追加して
# CI green でマージされた。CI は「壊れていないか」を見るが「宣言した成果物が揃ったか」は
# 見ない。両者を突き合わせる機構がどこにも無かった。
#
# ADR-039 3 点セット:
# - **Config opt-in**: default OFF。本リポジトリで dogfood のため enabled = true。
# - **Kill-switch**: `enabled = false` で完全停止。trailer を書かない push は常に skip される
# ため、止まるのは「宣言した人」だけ。
# - **Bounded lifetime**: trailer を使った push を数回観測し、誤検出の有無と
# 「宣言し忘れ」の頻度を見てから default-ON 昇格 or 却下を判定する。
# ---------------------------------------------------------------------------
[ledger_completion]
enabled = true
exe = ".claude/cli-ledger-cleanup.exe"
ledger = "docs/claude-code-web-tasks.md"

# ---------------------------------------------------------------------------
# [pr_size_check] — 順位 151 (Bundle "既存ルール仕組み化"): PR diff サイズ検査。
# `jj diff --stat -r '<default_branch>..@'` で PR 範囲の insertions + deletions を計測し、
Expand Down
17 changes: 17 additions & 0 deletions src/cli-ledger-cleanup/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "cli-ledger-cleanup"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "cli-ledger-cleanup"
path = "src/main.rs"

[dependencies]
# 台帳の解釈は lib-ledger に集約する (ADR-024)。本 exe は CLI 面 (引数・出力・exit コード) だけを担う。
lib-ledger = { path = "../lib-ledger" }

# 外部 crate 依存は足さない。本 exe は「実装が完了したか」を判定して後始末の可否を決める
# ゲートであり、供給元が増えるほど判定を曲げられる面が広がる (lib-ledger と同じ論理)。

# [profile.release] は workspace root (Cargo.toml) に集約 (ADR-026)
Loading
Loading