docs(web-tasks): タスク台帳を定期更新台帳へ改訂し無人可マークと weekly-review 接続を追加 (WP-18 PR 2) - #362
Conversation
WP-18 PR 2 (1/4)。台帳を夜間ループの選択元に転用する前に、現状の鮮度を確認した。 ## 削除した 2 件 docs-only の採用タスク(順位 120 / 134)はどちらも既に land しており、 docs/todo-summary.md / todo-summary2.md の順位 table から消えていた。実体も確認した: - 順位 120: ADR-007 に negation by enumeration の case study(Rust regex の lookahead 非対応と代替案 3 択の比較)が存在する - 順位 134: ADR-035 に docs-only PR の適用外基準リスト(mutation / DRY / YAGNI 等)が 存在する これで docs-only の採用枠は 0 件になったが、本ファイルは retire しない。lifecycle の 改訂は 3/4 で行う。 ## 棚卸し履歴 section の新設 台帳の鮮度は「行が消えていること」でしか表現されず、削除の根拠が残らない。後から 「なぜこのタスクは消えたのか」を再調査する羽目になるため、削除の判定と根拠を残す section を設けた。今後の定期棚卸し(3/4 で weekly-review に接続)もここに追記する。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 2 (2/4)。夜間ループ (WP-18 PR 3) がタスクを機械選択できるよう、台帳に 「無人可」の軸を追加する。マークはユーザー承認済み (2026-08-06)。 ## なぜ 2 段階か 本ファイルは元々「Claude Code Web セッションの pickup scope」で、人間が対話で補助 できる前提だった。夜間ループは補助なしで完結する必要があるため、同じ表に載っている ことが即「無人で回せる」を意味しない。Web 実行可 / 無人可の 2 段階に分ける。 ## 無人可の判定条件 3 つ 1. 着手時の判断が要らない (「再選定」「着手時判断」「見積り」「検討」が注意欄に無い) 2. 実装内容が一意 (設計の選択肢が複数残っていない) 3. 重複の恐れがない (未マージブランチや進行中 PR に同一実装が無い) 条件 3 は台帳だけでは判定できないため定期棚卸しで確認する。**判定に迷ったら無人可に しない** — 誤検出の損失は「夜間ループが人間の意図と違う実装で draft PR を作る」だが、 見送りの損失は「Web セッションで人間が着手する」だけで、非対称に軽い。 マークは人間が付ける (ADR-022 の責務分離)。夜間ループはマークの有無を機械的に読む だけで、自分でこの判定をしない。 ## マーク結果: 14 件中 7 件 無人可: 203 / 240 / 228 / 339 / 163 / 239 / 216。 いずれも実装内容が台帳と対象ファイルの現物から一意に決まり、設計判断を含まない。 見送り 7 件は理由を表で残した。条件 1 違反が 178 / 334 / 179、条件 2 違反が 180 / 340 / 272、条件 3 違反が 284 (未マージの claude/select-next-task-a9aiam に同タスクの 実装が乗っており、ブランチが決着したら昇格しうる)。 判断の根拠を残すのは、将来この分類を見直す際に注意欄の再読解からやり直さずに済ませる ため。台帳は行の増減でしか状態を表せないので、判定の痕跡は別に書く必要がある。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 2 (3/4)。着手前決定 3 (2026-08-05 ユーザー確認) の実装。 ## 旧 lifecycle が成り立たなくなる理由 旧規定は「採用タスクが全て land したら retire」。本ファイルが Claude Code Web セッションの pickup scope を切り出しただけの作業表だった頃の想定である。 夜間 todo 消化ループ (WP-18 PR 3) がここをタスク選択元として読むようになると、台帳が 空になった瞬間にファイルごと消え、ループの入力が消滅する。そもそも todo-summary に新しい タスクが登録され続ける以上「全部 land して終わり」という状態は来ない。 よって**空になっても retire しない**。空は「今は無人で回せるタスクが無い」という正常な 状態で、夜間ループはその場合に何も作らずに終わる (fail-closed)。 ## 定期更新の周期と接続先 weekly-review と同じ週次にする。専用スケジュールを増やさないのは、台帳の鮮度が落ちる 速度が todo corpus の decay と同じ周期だから。接続は 4/4 で .takt/facets/instructions/review-todo-whole.md (weekly-review workflow の観点⑤) に実装する。 棚卸しで見るのは (1) land 済み行の削除と棚卸し履歴への記帳、(2) todo-summary からの新規 候補の昇格、(3) 無人可マークの見直し。特に (3) の条件 3 (重複の恐れ) は台帳の外にある 未マージブランチ・進行中 PR を見ないと判定できず、この棚卸しでしか確認できない。 実行と採否は人間が決める (ADR-022)。facet は read-only で findings を上げるだけ。 ## retire 条件の再定義 「タスクが尽きたら」ではなく「本ファイルを読む自動化が撤去されたら」に変えた。あわせて permanent value の有無も見直した — 旧規定は「移管不要 (永続価値となる decision はない)」 だったが、2/4 で追加した無人可の判定条件は自律実行の境界判断そのもので永続価値がある。 retire 時に ADR へ移す旨を明記した。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 2 (4/4)。3/4 で定めた「台帳は weekly-review と同じ週次で棚卸しする」を、 実際にパイプラインへ接続する。 ## なぜ既存 facet に相乗りするか 新しい step / スケジュールを増やさない。台帳の decay は todo corpus の decay と同種 (経年・横断的で、編集時の決定論層からは見えない) で、観点⑤ が既にその領域を担当して いる。専用機構を足すと weekly-review の step 数と実行時間だけが増える。 ## Criterion 3 の 3 検査 1. land 済みなのに台帳に残る行 — 順位 table (todo-summary*.md) から消えた行を検出 2. 昇格候補 — 採用タスク (2) の基準を満たすのに台帳に無い 順位 3. **成立しなくなった 無人可 マーク** — 台帳の外の状態に依存するため、ここでしか検査 できない。jj log と remote bookmark を見て、同一タスクの未マージ実装ブランチ / 進行中 PR が無いことを確認する severity は 3 が high (無人 agent の重複・競合実装を招く)、1・2 が low〜medium。 ## 権限境界 facet は read-only のまま。台帳を編集せず findings を上げるだけで、特に 無人可 マークの 増減は人間の決定 (ADR-022) として /weekly-review の採否ステップへ回す。この点を output contract にも明記した。 ## 既知のリスク (初回 run で観測する) 本 step は model: haiku で、Criterion 3 は他の criterion より重い (順位のクロス参照 + bookmark 検査)。現在の台帳は 14 行なので追跡可能な規模だが、台帳が育つか検出漏れが 出るようなら model の見直しか検査の決定論層への切り出しを検討する。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 2 (5/5)。pre-push simplicity review の非 blocking warning への対応。 ## 指摘 Criterion 3 の item 3 (無人可 マークの重複検査) だけが、他の criterion と違って **リポジトリ外の状態** (remote bookmark / PR status) を根拠にする。到達不能なケース (ネットワーク無し / gh 未認証 / shallow・非 colocated clone、ADR-070 の cloud routine 実行下 では現実的にありうる) の扱いが書かれておらず、「検査できなかった」が「検査したが重複なし」 として報告されうる。 これは本リポジトリの fail-closed 規律 (ADR-043) と整合しない。指摘は妥当。 ## 対応 「証拠が無いことは不在の証拠ではない」旨を明記し、remote/PR 状態を実際に観測できなかった 場合は当該行の条件 3 を **unverified** として、どの lookup が失敗したかとともに報告させる。 「重複なし」とは書かせない。 severity ガイダンスにも unverified = medium (マーク自体は妥当かもしれないが、今サイクルでは 誰も確認していない) を追加した。 本 facet は何も block しないので、unverified と書くコストはレポート 1 行にすぎない。助言層に fail-open が正しい (ADR-043) のと、検査結果を実際より良く見せることは別問題である。 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:
📝 WalkthroughWalkthrough自律実行タスク台帳を管理台帳へ変更しました。 Changes台帳鮮度検査と自律実行基準
Estimated code review effort: 3 (Moderate) | ~20 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 |
|
@coderabbitai review |
✅ Action performedReview finished.
|
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 @.takt/facets/instructions/review-todo-whole.md:
- Around line 57-59: Update the “Landed-but-listed rows” procedure to inspect
only the current ledger tables under “### Batch 1” and “### Batch 2”, excluding
the “§ 棚卸し履歴” and reason tables. Require exact table-cell matching using the
pattern “| <順位> |” when checking docs/todo-summary.md and docs/todo-summary2.md,
so historical entries such as 120 and 134 are not flagged.
- Line 78: Criterion 3 の判定手順に、remote bookmark と in-flight PR を確認するための gh または同等の
remote/PR lookup を追加してください。lookup に失敗または利用できない場合は Criterion 3 を判定せず、必ず
unverified と出力するよう明記してください。
In `@docs/claude-code-web-tasks.md`:
- Around line 168-169: Update the promotion criteria in
docs/claude-code-web-tasks.md lines 168-169 so candidates qualify when they meet
either the §採用タスク (2) cargo-test criteria or all three docs-only criteria
permitted by Line 36. Update .takt/facets/instructions/review-todo-whole.md line
60 so Criterion 3 promotion candidates uses the same combined criteria, ensuring
docs-only candidates are included in both the ledger and freshness-facet
workflows.
- Line 180: Update the repository-reference search command in the documented
workflow to include the repository root as its search path, ensuring grep
recursively scans tracked files instead of reading standard input.
🪄 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: b6ed1e95-8a2d-4faa-82f9-21459d87273e
📒 Files selected for processing (3)
.takt/facets/instructions/review-todo-whole.md.takt/workflows/weekly-review.yamldocs/claude-code-web-tasks.md
| Check three things, in this order: | ||
|
|
||
| 1. **Landed-but-listed rows** — for each 順位 in the ledger's tables, `Grep` the same 順位 in `docs/todo-summary.md` / `docs/todo-summary2.md`. A row present in the ledger but **absent from both 順位 tables** has landed and should be removed (with the evidence recorded in the ledger's § 棚卸し履歴). Verify the task really landed (grep the artifact it claims to produce) before raising — a 順位 can also disappear because it was deprioritized. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
現行タスク表だけを抽出し、順位を表セルとして照合してください。
Line 59 の「ledger's tables」は、§ 棚卸し履歴も含む表現です。docs/claude-code-web-tasks.md の Line 145-146 は、削除済みの順位 120 と 134 を履歴として意図的に保持しています。これらは summary table には存在しないため、現在の手順では毎週「landed-but-listed」と誤判定します。Grep も順位の裸の数字ではなく、| <順位> | の表セルを検索してください。対象を ### Batch 1 と ### Batch 2 の現行表に限定し、理由表と棚卸し履歴を除外してください。
修正例
-For each 順位 in the ledger's tables, ...
+For each 順位 in the active task tables under `### Batch 1` and `### Batch 2`, excluding the reason table and `§ 棚卸し履歴`, ...
-`Grep` the same 順位 in `docs/todo-summary.md` / `docs/todo-summary2.md`.
+Match the exact summary-table cell `| <順位> |` in `docs/todo-summary.md` / `docs/todo-summary2.md`.台帳の現行表と棚卸し履歴の関係に基づく指摘です。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Check three things, in this order: | |
| 1. **Landed-but-listed rows** — for each 順位 in the ledger's tables, `Grep` the same 順位 in `docs/todo-summary.md` / `docs/todo-summary2.md`. A row present in the ledger but **absent from both 順位 tables** has landed and should be removed (with the evidence recorded in the ledger's § 棚卸し履歴). Verify the task really landed (grep the artifact it claims to produce) before raising — a 順位 can also disappear because it was deprioritized. | |
| Check three things, in this order: | |
| 1. **Landed-but-listed rows** — for each 順位 in the active task tables under `### Batch 1` and `### Batch 2`, excluding the reason table and `§ 棚卸し履歴`, match the exact summary-table cell `| <順位> |` in `docs/todo-summary.md` / `docs/todo-summary2.md`. A row present in the ledger but **absent from both 順位 tables** has landed and should be removed (with the evidence recorded in the ledger's § 棚卸し履歴). Verify the task really landed (grep the artifact it claims to produce) before raising — a 順位 can also disappear because it was deprioritized. |
🤖 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 @.takt/facets/instructions/review-todo-whole.md around lines 57 - 59, Update
the “Landed-but-listed rows” procedure to inspect only the current ledger tables
under “### Batch 1” and “### Batch 2”, excluding the “§ 棚卸し履歴” and reason
tables. Require exact table-cell matching using the pattern “| <順位> |” when
checking docs/todo-summary.md and docs/todo-summary2.md, so historical entries
such as 120 and 134 are not flagged.
|
|
||
| 1. Glob the corpus + read the `docs/todo.md` preamble (routing contract). | ||
| 2. For Criterion 0/1/2, gather evidence with `Grep` / `jj log` — never raise a corpus-decay finding without a verified pointer. | ||
| 2. For Criterion 0/1/2/3, gather evidence with `Grep` / `jj log` — never raise a corpus-decay finding without a verified pointer. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".takt/facets/instructions/review-todo-whole.md"
if [ -f "$file" ]; then
wc -l "$file"
sed -n '1,120p' "$file"
else
echo "missing: $file"
fd -a 'review-todo-whole.md|review-todo|instructions' .
fi
echo '--- searches ---'
rg -n "Criterion 3|remote bookmark|in-flight|gh|Grep|jj log|unverified|unverified" "$file" || trueRepository: aloekun/claude-code-hook-test
Length of output: 14024
Criterion 3 の外部状態確認を判定手順に明記してください。
Line 61 は remote bookmark と in-flight PR の確認を求めています。Line 78 の証拠収集では Grep / jj log だけが列挙されているため、remote state の確認を省略して Criterion 3 を判定する可能性があります。gh または同等の remote/PR lookup を明記し、lookup できない場合は unverified を出力してください。
修正例
-For Criterion 0/1/2/3, gather evidence with `Grep` / `jj log` ...
+For Criterion 0/1/2, gather evidence with `Grep` / `jj log`; for Criterion 3, also inspect remote bookmarks and in-flight PRs. If unavailable, report `unverified` ...📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 2. For Criterion 0/1/2/3, gather evidence with `Grep` / `jj log` — never raise a corpus-decay finding without a verified pointer. | |
| 2. For Criterion 0/1/2, gather evidence with `Grep` / `jj log`; for Criterion 3, also inspect remote bookmarks and in-flight PRs. If unavailable, report `unverified` rather than raising a corpus-decay finding. |
🤖 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 @.takt/facets/instructions/review-todo-whole.md at line 78, Criterion 3
の判定手順に、remote bookmark と in-flight PR を確認するための gh または同等の remote/PR lookup
を追加してください。lookup に失敗または利用できない場合は Criterion 3 を判定せず、必ず unverified
と出力するよう明記してください。
| 1. **land 済み行の削除** — `docs/todo-summary.md` / `todo-summary2.md` の順位 table から消えた行を削除し、根拠を [§棚卸し履歴](#棚卸し履歴) に記帳する | ||
| 2. **新規候補の昇格** — todo-summary 側に増えたタスクのうち [§採用タスク (2) の判定基準](#採用タスク-2-cargo-test-検証タスククロスプラットフォーム対応後2026-07-23)を満たすものを表へ追加する |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
docs-only 候補を、台帳と鮮度 facet の両方で昇格対象にしてください。
両方の手順が §採用タスク (2) の cargo-test 基準だけを参照しています。docs/claude-code-web-tasks.md の Line 36 は docs-only 候補の再追加を許可しているため、現在のままでは週次棚卸しがその候補を取りこぼします。
docs/claude-code-web-tasks.md#L168-L169: docs-only の3基準または cargo-test 基準を満たす候補を昇格対象にする。.takt/facets/instructions/review-todo-whole.md#L60-L60: Criterion 3 の promotion candidates に docs-only の3基準を追加する。
📍 Affects 2 files
docs/claude-code-web-tasks.md#L168-L169(this comment).takt/facets/instructions/review-todo-whole.md#L60-L60
🤖 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/claude-code-web-tasks.md` around lines 168 - 169, Update the promotion
criteria in docs/claude-code-web-tasks.md lines 168-169 so candidates qualify
when they meet either the §採用タスク (2) cargo-test criteria or all three docs-only
criteria permitted by Line 36. Update
.takt/facets/instructions/review-todo-whole.md line 60 so Criterion 3 promotion
candidates uses the same combined criteria, ensuring docs-only candidates are
included in both the ledger and freshness-facet workflows.
|
|
||
| 1. 本ファイルを読む自動化(夜間 workflow / weekly-review facet)が撤去済みであることを確認 | ||
| 2. permanent value の移管を確認 — 現時点で永続価値を持つのは [§自律実行可否の 2 段階分類](#自律実行可否の-2-段階分類)の判定条件のみ。retire 時に ADR へ移す | ||
| 3. リポ内で本ファイルを参照する箇所を `grep -rn "claude-code-web-tasks.md"` で洗い出し、参照を除去 |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Repository files matching docs/claude-code-web-tasks.md"
if [ -f docs/claude-code-web-tasks.md ]; then
echo "exists"
sed -n '165,190p' docs/claude-code-web-tasks.md | cat -n
else
echo "not found"
fi
echo
echo "All grep -rn references to claude-code-web-tasks.md in tracked files"
rg -n "grep -rn \"claude-code-web-tasks\.md\"|claude-code-web-tasks\.md" -S --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' . || true
echo
echo "Behavior probe: command without file operand reads stdin"
python3 - <<'PY'
import subprocess, tempfile, textwrap, shlex, os, pathlib, sys, signal
cmd = shlex.split('grep -rn "claude-code-web-tasks.md"')
with tempfile.TemporaryDirectory() as td:
pass_no_stdin = subprocess.Popen(
cmd,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
cwd=td
)
try:
out, err = pass_no_stdin.communicate(input=b'', timeout=2)
except subprocess.TimeoutExpired:
pass_no_stdin.kill()
out, err = pass_no_stdin.communicate()
behavior = "stdin-blocking"
else:
behavior = f"returns-rc-{pass_no_stdin.returncode}"
pass_real_dir = subprocess.run(cmd, text=True,
stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=td,
timeout=3)
if pass_real_dir.returncode == 2:
behavior = "no-file-operand-error"
print("grep_no_file_operand_error_msg:", pass_real_dir.stderr.strip())
print({
"cmd": " ".join(cmd),
"without_stdin_behavior": behavior,
"output": out.decode(errors="replace"),
"stderr_with_no_stdin": decode := b"\n".join(err[:128]),
})
PYRepository: aloekun/claude-code-hook-test
Length of output: 2799
grep に検索対象パスを指定してください。
Line 180 の grep -rn "claude-code-web-tasks.md" には file operand がありません。このコマンドは標準入力を読み、リポジトリを再帰検索しません。参照を見落とすと、weekly-review facet または workflow が台帳を読む状態でファイルを削除できます。リポジトリ root を検索対象に追加してください。
修正例
-`grep -rn "claude-code-web-tasks.md"`
+`grep -rn "claude-code-web-tasks.md" .`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 3. リポ内で本ファイルを参照する箇所を `grep -rn "claude-code-web-tasks.md"` で洗い出し、参照を除去 | |
| 3. リポ内で本ファイルを参照する箇所を `grep -rn "claude-code-web-tasks.md" .` で洗い出し、参照を除去 |
🤖 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/claude-code-web-tasks.md` at line 180, Update the repository-reference
search command in the documented workflow to include the repository root as its
search path, ensuring grep recursively scans tracked files instead of reading
standard input.
🤖 PR Monitor 分析 (GitHub Actions バックストップ)
Applicable Findings (Critical / High / Major)
Applicable Findings (Medium 以下)
Filtered (not applicable)該当なし(4件とも本 PR が新規追加した内容自体の自己整合性・正確性に関する指摘であり、ADR に矛盾する意図的設計や scope 外・sensitive-file 該当は無いと判断) 次のアクション
|
PR #362 への CodeRabbit レビュー (Major 3 / Minor 1) の反映。4 件とも妥当。 ## 1. [Major] 棚卸し履歴を landed-but-listed 検査から除外する 本 PR が同じ diff 内で作り込んだ恒久的な誤検知だった。commit 1 で新設した § 棚卸し履歴 は 削除済み順位 (120 / 134) を「なぜ消したか」の記録として意図的に残す。一方 Criterion 3 item 1 は「台帳の表の各順位」を対象にしていたため、この 2 件を**毎週** landed-but-listed として上げ続ける。 検査対象を現行タスク表 (Batch 1 / Batch 2 と非空時の § 採用タスク) に限定し、§ 棚卸し履歴 と § 無人可としなかった…理由 (どちらも順位列を持つ) を除外した。台帳側の § ライフサイクル にも同じ scope を明記している。 あわせて照合を裸の数値ではなく表セル `| <順位> |` の完全一致に変えた。裸の `120` は行数・ バイト数・その数字を含む別順位にも当たる。 ## 2. [Major] docs-only 候補を昇格経路に含める 台帳と facet の両方が § 採用タスク (2) の cargo-test 基準だけを参照していた。commit 1 で 「docs-only の候補が再び出た場合は上記 3 基準で本表へ追加する」と書いた以上、週次棚卸しは docs-only 経路も見ないと候補を取りこぼす。 両ファイルの昇格手順を「cargo-test 基準 **または** docs-only 3 基準」へ改めた。docs-only 枠が 現在 0 件であることと、それでも経路を開いてある理由も明記した。 ## 3. [Minor] Criterion 3 の外部状態確認を判定手順にも書く Judgment procedure step 2 が Criterion 0/1/2/3 を一括で「Grep / jj log で証拠収集」と していたため、Criterion 3 の remote/PR 確認を省いたまま判定できてしまう。step 2 を 0/1/2 と 3 に分け、3 では remote bookmark / in-flight PR の lookup を必須とし、 lookup 不能時は unverified を出すことを明記した (5/5 で入れた方針を手順側にも通した)。 ## 4. [Major] retire 手順の grep に検索対象パスを与える `grep -rn "claude-code-web-tasks.md"` はファイル operand が無く標準入力待ちになる。 参照を 1 件も見つけないまま「参照なし」と誤認して物理削除しうる。`.` を追加し、 省いた場合に何が起きるかも併記した。 この行は元ファイルからの引き継ぎだが、3/4 で lifecycle 節ごと書き直した際に自分の変更 範囲に入っているため本 PR で直す。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 3 (1/5)。夜間ループの「何を実装するか」を決める層。ユーザー確認済みの設計 (2026-08-06): 選択ロジックは workflow の shell ではなく Rust exe に置く。 ## なぜ LLM でも shell でもないのか ADR-052 は「分類ロジックを Rust 分類関数を用意せず自律 actor の実行時 LLM 判断に委ねる」 ことをアンチパターンとして挙げている。夜間ループで何を実装するかは自律動作の起点であり、 ここが揺れると下流のゲートがいくら堅くても「意図しないタスクを正しく実装した draft PR」が 出てくる。 shell (awk/grep) 案を採らなかったのは、markdown table の境界 (列ずれ・全角・エスケープ されたパイプ・無関係な表の混在) に回帰テストを書く場がないため。本 crate は 25 件の unit test でその境界を固定している。 ## 毎晩同じタスクを実装し直す問題 台帳の行はタスクが**マージされるまで**残る。素朴に「無人可の先頭行」を選ぶと毎晩同じ タスクを実装する。ブランチ名に順位を埋め (claude/nightly-<順位>)、open な同名ブランチの 順位を --exclude-ranks で除外する形で決定論のまま解いた。 --exclude-ranks は空でも省略できない。空文字は「数えた結果 0 件」、フラグ欠落は 「数えられなかった」で意味が違う。省略可能にすると gh api が失敗した run が「開いている draft は無い」と解釈して同じタスクを二重実装する (PR 1 の --open-draft-prs と同じ設計)。 ## 曖昧さはすべて停止側へ 台帳は人間が手で編集する markdown なので、列ずれ・順位の重複・未知のマーク表記が起こる。 これらは読み飛ばさず **エラー (exit 2)** にする。読み飛ばした行が本来の選択対象だった場合、 ループは黙って別のタスクを実装するため。 「対象ファイル」列の解決も同じ方針を採る。実表記が「対象ファイル」と「対象ファイル (実パス)」 の 2 種あるため前方一致で探すが、**複数ヒットしたら先頭を黙って採らずエラーにする**。将来 「対象ファイル案」のような列が先に追加されると、誤った列を agent への指示に使ってしまう (pre-push simplicity review の指摘 SIM-NEW-ledger-rs-L865 を反映)。 「✅ (条件付き)」のような書き足しもエラーにする。無人可でない側へ倒すと人間の意図と判定が ずれたまま静かに進む。 exit コードは 0 = 選択 / 2 = 入力不正・台帳破損 / 3 = 該当なし (正常な no-op)。3 と 2 を 分けるのは run log で「何もすることが無かった」と「台帳が壊れている」を切り分けるためで、 後続を動かさない点は同じ。 ## 実データ検証 PR 2 (#362) マージ後の master 台帳で実走した: - 除外なし → rank=203 branch=claude/nightly-203 (Batch 1 の先頭 ✅ 行) - 203 除外 → rank=240 - 無人可 7 件すべて除外 → exit 3 (no-op) - 棚卸し履歴 / 無人可としなかった理由 の 2 表 (順位 列を持つが 無人可 列を持たない) は 正しく無視された - **PR 2 未マージの旧台帳 → exit 2** で loud に停止。台帳が旧構成のままなら夜間ループは 黙って no-op せず、理由を出して止まる 依存 crate ゼロ。本 exe は夜間ループで唯一「何を実装するか」を決める存在なので、供給元を 増やさないこと自体を設計制約とした。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 3 (5/5)。 ## 記帳 - WP-18 節の見出しと全体像表を「着手中」→「実装済(実走スモーク待ち)」へ - PR 2 / PR 3 の項目を実装内容付きで確定記録。PR 3 は 16 step 構成 (選択 → 実装 → コストフィルタ → clean publish tree → 禁止リスト → 改ざん検知 → gate → App token → draft PR 作成) と、決定 7 / 8 / 9 の由来を残した - 受け入れ基準を表へ変え、充足 3 件と**未実施 2 件**を分けた ## 件数記載を実測と一致させた CodeRabbit が ADR 側で指摘した「件数が実装と一致しない」型の不整合が、計画書側にも 同型で存在していた: - unit test 23 件 → **25 件** (fix step が追加した 2 件を反映していなかった) - workflow 15 step → **16 step** (clean publish tree 段の追加を反映していなかった) - スモークの同梱観測 7 項目 → **8 項目** 観測項目については件数だけ直さず、**内訳の列挙をやめて ADR-072 の表を指す形**に変えた。 同じ一覧を 2 箇所に持つ限り再び drift するため (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ## 受け入れ基準の状態を正直に書く 実走スモークは本 WP の受け入れ基準の中核だが**未実施**である。「実装が全部 land した = WP 完了」と書ける状態ではないため表で未実施を明示した。 採用率 50% が統計的な意味を持たない点 (2 週間・最大 14 件) も併記した。 ## chain 宣言 PR 1 が導入した 3 点の消費側を実装済みの step 名で具体化した。PR 2 → PR 3 の**実行時** 依存も明記した (PR 2 未マージだと選択 exe が exit 2 で止まるが、これは設計どおりの fail-closed で静かな no-op にはならない)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 3 (5/5)。 ## 記帳 - WP-18 節の見出しと全体像表を「着手中」→「実装済(実走スモーク待ち)」へ - PR 2 / PR 3 の項目を実装内容付きで確定記録。PR 3 は 16 step 構成 (選択 → 実装 → コストフィルタ → clean publish tree → 禁止リスト → 改ざん検知 → gate → App token → draft PR 作成) と、決定 7 / 8 / 9 の由来を残した - 受け入れ基準を表へ変え、充足 3 件と**未実施 2 件**を分けた ## 件数記載を実測と一致させた CodeRabbit が ADR 側で指摘した「件数が実装と一致しない」型の不整合が、計画書側にも 同型で存在していた: - unit test 23 件 → **25 件** (fix step が追加した 2 件を反映していなかった) - workflow 15 step → **16 step** (clean publish tree 段の追加を反映していなかった) - スモークの同梱観測 7 項目 → **8 項目** 観測項目については件数だけ直さず、**内訳の列挙をやめて ADR-072 の表を指す形**に変えた。 同じ一覧を 2 箇所に持つ限り再び drift するため (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ## 受け入れ基準の状態を正直に書く 実走スモークは本 WP の受け入れ基準の中核だが**未実施**である。「実装が全部 land した = WP 完了」と書ける状態ではないため表で未実施を明示した。 採用率 50% が統計的な意味を持たない点 (2 週間・最大 14 件) も併記した。 ## chain 宣言 PR 1 が導入した 3 点の消費側を実装済みの step 名で具体化した。PR 2 → PR 3 の**実行時** 依存も明記した (PR 2 未マージだと選択 exe が exit 2 で止まるが、これは設計どおりの fail-closed で静かな no-op にはならない)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 3 (5/5)。 ## 記帳 - WP-18 節の見出しと全体像表を「着手中」→「実装済(実走スモーク待ち)」へ - PR 2 / PR 3 の項目を実装内容付きで確定記録。PR 3 は 16 step 構成 (選択 → 実装 → コストフィルタ → clean publish tree → 禁止リスト → 改ざん検知 → gate → App token → draft PR 作成) と、決定 7 / 8 / 9 の由来を残した - 受け入れ基準を表へ変え、充足 3 件と**未実施 2 件**を分けた ## 件数記載を実測と一致させた CodeRabbit が ADR 側で指摘した「件数が実装と一致しない」型の不整合が、計画書側にも 同型で存在していた: - unit test 23 件 → **25 件** (fix step が追加した 2 件を反映していなかった) - workflow 15 step → **16 step** (clean publish tree 段の追加を反映していなかった) - スモークの同梱観測 7 項目 → **8 項目** 観測項目については件数だけ直さず、**内訳の列挙をやめて ADR-072 の表を指す形**に変えた。 同じ一覧を 2 箇所に持つ限り再び drift するため (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ## 受け入れ基準の状態を正直に書く 実走スモークは本 WP の受け入れ基準の中核だが**未実施**である。「実装が全部 land した = WP 完了」と書ける状態ではないため表で未実施を明示した。 採用率 50% が統計的な意味を持たない点 (2 週間・最大 14 件) も併記した。 ## chain 宣言 PR 1 が導入した 3 点の消費側を実装済みの step 名で具体化した。PR 2 → PR 3 の**実行時** 依存も明記した (PR 2 未マージだと選択 exe が exit 2 で止まるが、これは設計どおりの fail-closed で静かな no-op にはならない)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
WP-18 PR 3 (5/5)。 ## 記帳 - WP-18 節の見出しと全体像表を「着手中」→「実装済(実走スモーク待ち)」へ - PR 2 / PR 3 の項目を実装内容付きで確定記録。PR 3 は 16 step 構成 (選択 → 実装 → コストフィルタ → clean publish tree → 禁止リスト → 改ざん検知 → gate → App token → draft PR 作成) と、決定 7 / 8 / 9 の由来を残した - 受け入れ基準を表へ変え、充足 3 件と**未実施 2 件**を分けた ## 件数記載を実測と一致させた CodeRabbit が ADR 側で指摘した「件数が実装と一致しない」型の不整合が、計画書側にも 同型で存在していた: - unit test 23 件 → **25 件** (fix step が追加した 2 件を反映していなかった) - workflow 15 step → **16 step** (clean publish tree 段の追加を反映していなかった) - スモークの同梱観測 7 項目 → **8 項目** 観測項目については件数だけ直さず、**内訳の列挙をやめて ADR-072 の表を指す形**に変えた。 同じ一覧を 2 箇所に持つ限り再び drift するため (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ## 受け入れ基準の状態を正直に書く 実走スモークは本 WP の受け入れ基準の中核だが**未実施**である。「実装が全部 land した = WP 完了」と書ける状態ではないため表で未実施を明示した。 採用率 50% が統計的な意味を持たない点 (2 週間・最大 14 件) も併記した。 ## chain 宣言 PR 1 が導入した 3 点の消費側を実装済みの step 名で具体化した。PR 2 → PR 3 の**実行時** 依存も明記した (PR 2 未マージだと選択 exe が exit 2 で止まるが、これは設計どおりの fail-closed で静かな no-op にはならない)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…R-072) (#363) * feat(nightly-task-select): 台帳から無人可タスクを決定論的に選ぶ exe を新設する WP-18 PR 3 (1/5)。夜間ループの「何を実装するか」を決める層。ユーザー確認済みの設計 (2026-08-06): 選択ロジックは workflow の shell ではなく Rust exe に置く。 ## なぜ LLM でも shell でもないのか ADR-052 は「分類ロジックを Rust 分類関数を用意せず自律 actor の実行時 LLM 判断に委ねる」 ことをアンチパターンとして挙げている。夜間ループで何を実装するかは自律動作の起点であり、 ここが揺れると下流のゲートがいくら堅くても「意図しないタスクを正しく実装した draft PR」が 出てくる。 shell (awk/grep) 案を採らなかったのは、markdown table の境界 (列ずれ・全角・エスケープ されたパイプ・無関係な表の混在) に回帰テストを書く場がないため。本 crate は 25 件の unit test でその境界を固定している。 ## 毎晩同じタスクを実装し直す問題 台帳の行はタスクが**マージされるまで**残る。素朴に「無人可の先頭行」を選ぶと毎晩同じ タスクを実装する。ブランチ名に順位を埋め (claude/nightly-<順位>)、open な同名ブランチの 順位を --exclude-ranks で除外する形で決定論のまま解いた。 --exclude-ranks は空でも省略できない。空文字は「数えた結果 0 件」、フラグ欠落は 「数えられなかった」で意味が違う。省略可能にすると gh api が失敗した run が「開いている draft は無い」と解釈して同じタスクを二重実装する (PR 1 の --open-draft-prs と同じ設計)。 ## 曖昧さはすべて停止側へ 台帳は人間が手で編集する markdown なので、列ずれ・順位の重複・未知のマーク表記が起こる。 これらは読み飛ばさず **エラー (exit 2)** にする。読み飛ばした行が本来の選択対象だった場合、 ループは黙って別のタスクを実装するため。 「対象ファイル」列の解決も同じ方針を採る。実表記が「対象ファイル」と「対象ファイル (実パス)」 の 2 種あるため前方一致で探すが、**複数ヒットしたら先頭を黙って採らずエラーにする**。将来 「対象ファイル案」のような列が先に追加されると、誤った列を agent への指示に使ってしまう (pre-push simplicity review の指摘 SIM-NEW-ledger-rs-L865 を反映)。 「✅ (条件付き)」のような書き足しもエラーにする。無人可でない側へ倒すと人間の意図と判定が ずれたまま静かに進む。 exit コードは 0 = 選択 / 2 = 入力不正・台帳破損 / 3 = 該当なし (正常な no-op)。3 と 2 を 分けるのは run log で「何もすることが無かった」と「台帳が壊れている」を切り分けるためで、 後続を動かさない点は同じ。 ## 実データ検証 PR 2 (#362) マージ後の master 台帳で実走した: - 除外なし → rank=203 branch=claude/nightly-203 (Batch 1 の先頭 ✅ 行) - 203 除外 → rank=240 - 無人可 7 件すべて除外 → exit 3 (no-op) - 棚卸し履歴 / 無人可としなかった理由 の 2 表 (順位 列を持つが 無人可 列を持たない) は 正しく無視された - **PR 2 未マージの旧台帳 → exit 2** で loud に停止。台帳が旧構成のままなら夜間ループは 黙って no-op せず、理由を出して止まる 依存 crate ゼロ。本 exe は夜間ループで唯一「何を実装するか」を決める存在なので、供給元を 増やさないこと自体を設計制約とした。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(build): cli-nightly-task-select を build script と build:all へ配線する WP-18 PR 3 (2/5)。他の cli-* と同じ形 (cargo build --release + deploy-artifacts) を踏襲する。 CI 経路 (夜間 workflow) は master ref から cargo build するため deploy 先の .claude/*.exe を 使わないが、cli-fix-push-gate も同じく CI 専用でありながら build script + deploy を持つ。 形を揃えることで、ローカル drill が他の exe と同じ `node scripts/run-artifact.mjs` 経由で 実行できる。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(nightly-todo): 夜間 todo 消化 workflow を新設する (schedule 03:00 JST) WP-18 PR 3 (3/5)。台帳の無人可タスクを 1 件無人実装し **draft PR 作成で停止**する 15 step の workflow。マージ判断は人間 (ADR-052 の commitment 点の手前で止まる操作)。 schedule は毎日 1 回 18:00 UTC = 03:00 JST。反復検証のため workflow_dispatch も持たせた (ADR-067 段 2 の知見 2)。dry_run 入力でゲート通過まで走らせて push を止められる。 ## 信頼境界 (ADR-066 決定 3 / ADR-067 と同型) 台帳・ゲート exe・autonomy-config.toml はすべて master ref の写しから調達する。schedule イベントは GitHub の仕様上 default branch の workflow 定義で実行されるため、本ファイル自体も PR ブランチからは差し替えられない。push / PR 作成は workflow step が行い agent には gh / git を 与えない。 ## 背圧ゲートを 2 回呼ぶ pre-flight (agent 起動前) は Max 枠の節約、authority (push 直前) は push の権威。pre-flight は continue-on-error で受け Select task に if を付けて deny 後は後続を走らせない。背圧 deny は 設計上の正常動作なので job failure にはしない。 ## agent には Bash を与えない --allowedTools は Read/Edit/Write/Glob/Grep のみ。cargo を許さないのは、cargo test が build.rs と テストバイナリ = agent 自身が直前に書いたコードを実行するため。agent のターン中はプロセス env に action の資格情報が載るので、cargo を与えることは「自分で書いたコードを資格情報のある環境で、 いかなるゲートより前に実行させる」ことに等しい。詳細は ADR-072 決定 5。 ## CI を draft PR へ紐づける App token (ADR-072 決定 8) GITHUB_TOKEN で作成した PR の pull_request イベントは**承認待ちの run** になり、人間が Approve を押すまで ci.yml が動かない。Windows を主開発環境とする本プロジェクトで 2 OS 検証を 人間の操作待ちにする設計は採れないため、push と PR 作成に App installation token を使う。 PAT ではなく App を選ぶのは、オーナーの PAT が Repository admin として動き ADR-067 の ruleset backstop を bypass するため。App installation は独立 actor で admin ではない。 App 権限は Contents / Pull requests の write のみで **Workflows は付けない** — .github/workflows/** を含む push が権限側でも通らず Guard step の禁止リストと二重になる。token 発行は publish 直前 (寿命 1 時間に対し実装 agent が最大 60 ターン走るため)。背圧の計数は GITHUB_TOKEN のままで、 読み取りに triggering の含意が無い以上 App token の露出面を広げない。 ## 内部 Verify はコストフィルタであって品質保証ではない ubuntu 単独・--ignored 無し・hooks smoke 無しで ci.yml の真部分集合。目的は「コンパイルも 通らない変更で draft PR を作り背圧の枠と人間のレビュー時間を浪費しない」ことに限る。品質の 保証は PR に紐づく ci.yml (2 OS matrix) が担う。2 OS matrix をここへ複製しないのは検証の定義が 2 箇所へ分かれて drift するため。この区別は step 名・コメント・PR 本文の 3 箇所に明記した。 ## ガードレールの保護 (2 層) - **禁止リスト**: work/ の diff が autonomy-config.toml / .github/workflows/ / 各ゲート crate に 触れていたら push しない。空 diff も deny - **改ざん検知**: agent の file tools は $GITHUB_WORKSPACE 全体に届き master-ref/ を書き換え られる。Build 段で採った sha256 と authority gate の直前で照合する。基準値は $RUNNER_TEMP = ワークスペース外に置く ## 停止段の切り分けを 1 行で完結させる Report outcome が全 step の outcome を 1 行に出す (implement / app_token 含む)。 「Stop when there is nothing to implement」は 2 経路 (select 非ゼロ / pre-flight deny で select 自体が skip) で発火するため、経路ごとに参照すべきログ行を出し分ける。 ## その他の fail-closed - open PR の取得が上限 100 件に張り付いたら停止する (背圧の過小評価を防ぐ) - 着手済み順位の除外は draft かどうかに依らない (ready 化された claude/nightly-N も再実装しない) ## 禁止リストに台帳自身を追加 (ADR-072 決定 6) docs/claude-code-web-tasks.md は「次に何を実装するか」を決める仕組みであり、config や gate exe と同じく **agent を縛る側**にある。ここが draft PR 経由で書き換わると、以後の タスク選択が静かに汚染される。初版はここを落としていた。 ## Count open drafts に continue-on-error を付けない理由をコメント化 設計上の停止点 (背圧 deny / タスク無し / guard deny) は green + NIGHTLY_SKIP、インフラ 障害は red、という色分けは意図的。ADR に書いていなかったため pre-push review に再指摘 された。決定 10 として明文化し、workflow 側にも根拠を残す。 ## timeout-minutes: 60 を明示 他 workflow は例外なく明示済み (ci.yml=60 / pr-monitor.yml=15, 20 / release-binaries.yml=30) で、本 job だけ無指定 = 既定 360 分だった。無人・毎日回る job で ハングを 6 時間放置すると Max 枠を焼き続ける (ADR-072 決定 4 が節約のためにゲートを 二重に呼ぶ設計と矛盾する)。Implement 60 turns + 後続 step を見込んだ上限。 js-yaml で構文検証済み (17 step)。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(adr-072): 決定 8 (App token) / 決定 9 (clean publish tree) を新設し件数記載を実装と一致させる WP-18 PR 3。pre-push review が計 8 サイクルで返した REJECT と warning、および CodeRabbit の 指摘 2 件を ADR へ反映する。fix step は毎回 workflow を直すが ADR を一度も更新しないため、 設計根拠を追いつかせる。 ## 決定 8 — Windows CI が走らない問題への対処 GITHUB_TOKEN で作成した PR の pull_request イベントは **承認待ちの run** になり、人間が Approve を押すまで ci.yml が動かない。Windows を主開発環境とする本プロジェクトで 2 OS 検証を 人間の操作待ちにする設計は採れない (2026-08-07 ユーザー判断)。 公式は App installation token または PAT を回避策として挙げるが **PAT は採れない** — ADR-067 段 0 の ruleset は bypass を Repository admin ロールに与えており、オーナーの PAT は その admin として動くため 5 層目の防波堤を素通りする。 副次効果として job の GITHUB_TOKEN から write を落とせた。GITHUB_TOKEN は claude-code-action の github_token 入力として agent (未信頼) が触れる唯一の GitHub 資格情報であり、write のままだと 決定 6/7 の前提を token 側から崩しうる。App token の導入で Phase B より弱い権限で同じことが できる構成になった。 ## 決定 9 — git 操作は agent が触れていない作業ツリーで行う 決定 6 の禁止リストは staged path の列挙で .git 内部を構造的に見ない。一方 add/commit/push は core.hooksPath / filter.* / core.fsmonitor / credential.helper / core.sshCommand / *.textconv 等 多数の設定経路から外部プログラムを起動する。刺さる先は決定 8 の App token を持つ publish step。 最初は deny-list で対処したが **2 回連続でレビュアーが漏れを見つけた**。列挙で追随する限り 往復は終わらない。publish/ を Implement 終了後に新規 clone し、作業ツリーのファイルだけを rsync --delete --exclude '.git/' で運ぶ。agent はターン終了後に何も書けないので、その後に 作られた .git は定義上手が届かず、クラスごと消える。 決定 7 とは非対称。master-ref は作り直せないので検知にとどまるが、publish は作り直せるので 排除する。 ## 決定 3 — 除外判定を PR 状態からブランチ存在へ クローズされた draft の順位が再選択され push が non-fast-forward で失敗する無駄ループを塞ぐ。 ls-remote は一致なしでも exit 0 + 空出力なので「0 件」と「取得失敗」を取り違えない。 ## CodeRabbit 指摘 2 件への対応 1. **unit test 件数が実装と不一致** — 23 件 (内訳 17/6) と書いていたが実測は 25 件 (17/8)。 fix step が追加した 2 件を反映していなかった。実測して修正 2. **見出しと本文の件数が不一致** — 見出しと表は 6 件へ更新済みだったが、**本文が「2 件」の まま**残っていた。指摘の要約 (「見出しと表の件数」) だけを見ると解消済みに見えるが、 コメント本文が本文側も名指ししていた。本文を 6 件へ更新し、うち 2 件は指摘の具体例自体が 誤っていたこと (#3 は誤りに気づかず設計を動かし、#6 は誤りの中の正しい構造を拾った) も 併記した ## その他 内部 Verify はコストフィルタであって品質保証ではない (ubuntu 単独・--ignored 無し・ hooks smoke 無しで ci.yml の真部分集合)。品質の保証は draft PR に紐づく ci.yml が担う。 ## 決定 6 — 禁止リストに台帳自身を追加 「自分を縛る仕組み」として config と gate exe は列挙したのに、**選択元である台帳** (docs/claude-code-web-tasks.md) を同じクラスだと認識していなかった。決定 1 で「台帳は master ref から読む」と信頼境界を引きながら、台帳への書き込み経路を塞いでいない。 agent が台帳を書き換えた diff が draft PR に紛れ、人間が見落としてマージすると、以後の タスク選択が静かに汚染される。禁止リストへ 1 エントリ追加して塞いだ。 ## 決定 10 — 停止の色分けを決定として明文化する pre-push simplicity review が「Count open drafts に continue-on-error が無く、他の停止点の ように graceful degradation しない」と指摘した。**現状を維持し、理由を決定として残す。** 設計上の正常な結末 (背圧 deny / タスク無し / guard deny / 空 diff) は green + NIGHTLY_SKIP、 インフラ障害 (gh / network / clone の失敗) は red。両者を同じ扱いにすると、run 一覧から 「本当に壊れた夜」と「何もすることが無かった夜」の区別が消える。毎晩回る無人ループでは、 この 2 つが混ざった時点で run 一覧が読まれなくなる。 Report outcome は if: '!cancelled()' なので red でも 1 行サマリは出る。診断は失われない。 ## 件数 ## 捕捉 9 — job の実行時間に上限が無かった 同リポジトリの他 workflow は例外なく timeout-minutes を明示している (ci.yml=60 / pr-monitor.yml=15, 20 / release-binaries.yml=30) のに、本 job だけ無指定 = 既定 360 分。 同じ claude-code-action を使う pr-monitor.yml の fix job が 30 turns に対し 20 分を課す のに対し、本 job は turns 2 倍 (60) で上限なしだった。 決定 4 で Max 枠の節約のためにゲートを二重に呼ぶ設計にしておきながら、**ハングした run が 枠を焼き続ける経路**を空けていた。timeout-minutes: 60 を明示。 スモーク観測 8 項目 / 静的レビューの捕捉実績 9 件 / js-yaml 17 step / 決定 10 件 — 数値の 記載はすべて実測と突き合わせて一致を確認した。 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(harness-plan): WP-18 の記帳を最終構成へ更新し件数記載を実測と一致させる WP-18 PR 3 (5/5)。 ## 記帳 - WP-18 節の見出しと全体像表を「着手中」→「実装済(実走スモーク待ち)」へ - PR 2 / PR 3 の項目を実装内容付きで確定記録。PR 3 は 16 step 構成 (選択 → 実装 → コストフィルタ → clean publish tree → 禁止リスト → 改ざん検知 → gate → App token → draft PR 作成) と、決定 7 / 8 / 9 の由来を残した - 受け入れ基準を表へ変え、充足 3 件と**未実施 2 件**を分けた ## 件数記載を実測と一致させた CodeRabbit が ADR 側で指摘した「件数が実装と一致しない」型の不整合が、計画書側にも 同型で存在していた: - unit test 23 件 → **25 件** (fix step が追加した 2 件を反映していなかった) - workflow 15 step → **16 step** (clean publish tree 段の追加を反映していなかった) - スモークの同梱観測 7 項目 → **8 項目** 観測項目については件数だけ直さず、**内訳の列挙をやめて ADR-072 の表を指す形**に変えた。 同じ一覧を 2 箇所に持つ限り再び drift するため (#362 の post-merge feedback が指摘した single source-of-truth 問題と同型)。 ## 受け入れ基準の状態を正直に書く 実走スモークは本 WP の受け入れ基準の中核だが**未実施**である。「実装が全部 land した = WP 完了」と書ける状態ではないため表で未実施を明示した。 採用率 50% が統計的な意味を持たない点 (2 週間・最大 14 件) も併記した。 ## chain 宣言 PR 1 が導入した 3 点の消費側を実装済みの step 名で具体化した。PR 2 → PR 3 の**実行時** 依存も明記した (PR 2 未マージだと選択 exe が exit 2 で止まるが、これは設計どおりの fail-closed で静かな no-op にはならない)。 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>
概要
WP-18(夜間 todo 消化ループ)の PR 2 / 3 本。docs-only + takt facet の変更で、Rust コードは含まない。
夜間ループがタスクを機械選択できるよう、docs/claude-code-web-tasks.md を「Claude Code Web セッションの pickup scope」から定期更新される管理台帳へ改訂する。着手前決定 3(2026-08-05 ユーザー確認)の実装。
PR 1(#361)とは独立で、master から分岐している。順序依存はない。
変更内容(5 コミット)
docs(web-tasks)docs(web-tasks)docs(web-tasks)feat(weekly-review)review-todo-wholefacet に台帳の鮮度検査(Criterion 3)を追加docs(weekly-review)unverifiedとして報告させる(pre-push review 指摘対応)1. stale 行の削除
docs-only の採用タスク(順位 120 / 134)はどちらも既に land しており、
docs/todo-summary.md/todo-summary2.mdの順位 table から消えていた。実体も確認した:あわせて 棚卸し履歴 section を新設した。台帳の鮮度は「行が消えていること」でしか表現されず、削除の根拠が残らない。後から「なぜこのタスクは消えたのか」を再調査する羽目になる。
2. 無人可の 2 段階分類
本ファイルは元々「人間が対話で補助できる」前提の pickup scope だった。夜間ループは補助なしで完結する必要があるため、表に載っていることが即「無人で回せる」を意味しない。
判定条件 3 つ:
判定に迷ったら無人可にしない。誤検出の損失は「夜間ループが人間の意図と違う実装で draft PR を作る」だが、見送りの損失は「Web セッションで人間が着手する」だけで、非対称に軽い。
マークは人間が付ける(ADR-022 の責務分離)。夜間ループはマークの有無を機械的に読むだけで、自分でこの判定をしない。
結果: 14 件中 7 件(順位 203 / 240 / 228 / 339 / 163 / 239 / 216、ユーザー承認済み)。見送り 7 件も理由を表で残した — 条件 1 違反が 178 / 334 / 179、条件 2 違反が 180 / 340 / 272、条件 3 違反が 284。
順位 284 は未マージの
claude/select-next-task-a9aiamに同タスクの実装が乗っているための見送りで、ブランチが決着すれば昇格しうる。3. lifecycle の改訂
旧規定は「採用タスクが全て land したら retire」。夜間ループがここをタスク選択元として読むと、台帳が空になった瞬間にファイルごと消えてループの入力が消滅する。そもそも todo-summary に新しいタスクが登録され続ける以上「全部 land して終わり」という状態は来ない。
よって空になっても retire しない。空は「今は無人で回せるタスクが無い」という正常な状態で、夜間ループはその場合に何も作らずに終わる(fail-closed)。
retire 条件も「タスクが尽きたら」→「本ファイルを読む自動化が撤去されたら」に変えた。permanent value の有無も見直し、無人可の判定条件は自律実行の境界判断そのもので永続価値があるため retire 時に ADR へ移す旨を明記した。
4. weekly-review パイプラインへの接続
新しい step / スケジュールを増やさず、既存の観点⑤(
review-todo-whole)に相乗りさせた。台帳の decay は todo corpus の decay と同種(経年・横断的で編集時の決定論層から見えない)で、専用機構を足すと weekly-review の step 数と実行時間だけが増える。Criterion 3 の 3 検査:
severity は 3 が
high(無人 agent の重複・競合実装を招く)、1・2 がlow〜medium。facet は read-only のままで、無人可マークの増減は人間の決定として/weekly-reviewの採否ステップへ回す。5. pre-push review 指摘への対応
初回レビューで simplicity が非 blocking warning を 1 件出した。Criterion 3 の item 3 だけがリポジトリ外の状態(remote bookmark / PR status)を根拠にしており、到達不能なケース(ネットワーク無し /
gh未認証 / shallow・非 colocated clone)の扱いが未定義で、「検査できなかった」が「検査したが重複なし」として報告されうる、という指摘。妥当な指摘のため修正した。remote/PR 状態を実際に観測できなかった場合は当該行の条件 3 を
unverifiedとして、どの lookup が失敗したかとともに報告させる。「重複なし」とは書かせない。severity ガイダンスにもunverified=mediumを追加した。本 facet は何も block しないので、
unverifiedと書くコストはレポート 1 行にすぎない。助言層に fail-open が正しい(ADR-043)のと、検査結果を実際より良く見せることは別問題である。既知のリスク(初回 weekly-review run で観測する)
本 step は
model: haikuで、Criterion 3 は他の criterion より重い(順位のクロス参照 + bookmark 検査)。現在の台帳は 14 行なので追跡可能な規模だが、台帳が育つか検出漏れが出るようなら model の見直しか検査の決定論層への切り出しを検討する。計画書を触っていない理由
docs/harness-improvement-plan.mdの WP-18 節は PR 1(#361)が既に編集している。master から分岐した本 PR が同じ箇所を書くとマージ時に衝突するため、PR 2 の完了記帳は PR 3 側でまとめて行う。検証
pnpm lint:docs(preamble + cross-ref + priority-inversion)green.takt/workflows/weekly-review.yamlの変更はコメント 3 行の追加のみ(インデントは周辺コメントと同一)Summary by CodeRabbit
ドキュメント
改善