From 4d460c99af55891acd36000083c9b8fcf8172a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 12:21:32 +0900 Subject: [PATCH 1/9] =?UTF-8?q?check-all.py:=20check-mutation-claims.py=20?= =?UTF-8?q?=E3=82=92=20--jobs=201=20=E3=81=A7=E8=B5=B7=E3=81=93=E3=81=97?= =?UTF-8?q?=E3=80=81=E5=85=A5=E3=82=8C=E5=AD=90=E3=81=AE=E4=B8=A6=E5=88=97?= =?UTF-8?q?=E3=81=A7=20CPU=20=E3=82=92=E5=8F=96=E3=82=8A=E5=90=88=E3=82=8F?= =?UTF-8?q?=E3=81=AA=E3=81=84=EF=BC=88#460=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 85 +++++++++++++++++++++++++++++++++++++++ scripts/check-all.py | 8 +++- scripts/test-check-all.py | 13 ++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 docs/plans/issue-460.md diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md new file mode 100644 index 00000000..bb932680 --- /dev/null +++ b/docs/plans/issue-460.md @@ -0,0 +1,85 @@ +# Issue #460 — check-all.py が check-mutation-claims.py を既定の並列数で起こし、入れ子で N×N になる + +`check-all.py` は既定で CPU の数(N)だけ並列に回し、その中で `check-mutation-claims.py` を**引数なし**で起こす。 +`check-mutation-claims.py` の `--jobs` の既定も CPU の数なので、その中の `red` は親の残り N-1 本と、 +作業者 N 人ぶんの `red`(陽性対照と変異)と CPU を取り合う。#449 で `red` が 300 秒の打ち切りに届いた(3 回中 2 回)。 + +## 変更範囲 + +触る: + +- `scripts/check-all.py` — `check-mutation-claims.py` を起こすときに `--jobs` を渡す(値は親の `--jobs` から決める)。docstring の並列の節 +- `scripts/test-check-all.py` — 渡した `--jobs` を観測するケースと、その変異 +- `docs/plans/issue-460.md` — この計画 + +触らない: + +- `scripts/check-mutation-claims.py`(既定の並列数・`TIMEOUT` は変えない。単独で回すときは CPU の数のままでよい) +- `scripts/test-check-mutation-claims.py`(中で `check-mutation-claims.py` を既定の並列で起こすが、当てる木の `red` は軽い試料だけ) +- CI のワークフロー(CI は `check-mutation-claims.py` を単独のステップとして呼ぶ——入れ子にならない) +- `CLAUDE.md`(`check-all.py` の行は並列の細部を docstring に預けている。`check-mutation-claims.py` の行の「既定は CPU の数」は単独で回すときの話で、偽にならない) + +### 同じことを述べている箇所の数 + +入れ子の並列数を述べる箇所: `check-all.py` の docstring(並列の節)と `GUARDS` の注記の 2 箇所。 +`CLAUDE.md` の 2 行は単独のときの既定を言うだけで、入れ子の値は持たない(上)。同じファイルの中なので分けない。 + +## 乗るデプロイ経路 + +`scripts/` だけ。プラグインの中身は変えないので版は上げない。公開サイトにも載らない——**反映経路なし**。 + +## 周の在り処 + +- ブランチ: `issue/460-nested-mutation-jobs` +- worktree: `/Users/hdknr/Projects/hdknr/claude-code-setup/.claude/worktrees/issue-460` +- 起点: `43b5832`(start-point `origin/main`) +- base: `43b58324945badf38de0c481ebc64e62f44e9339` + +## 受入基準 + +不変条件: + +1. **`check-all.py` の中の `check-mutation-claims.py` は、親の `--jobs` より多い作業者を起こさない**—— + 親の作業者と入れ子の作業者の積が N×N にならない。値は起動の引数で確かめる +2. **`check-all.py --jobs 1` は入れ子まで直列**(`check-mutation-claims.py --jobs 1`)——「`--jobs 1` で直列」が入れ子で破れない +3. **`check-all.py` が全部通る**(`N/N 本を回した(失敗 0)`) +4. **`check-all.py` の wall が大きく悪化しない**——同じツリーで前後を交互に測る +5. **`check-all.py` の既存の観測(並列・直列・中断・収録漏れ)が緑のまま**——`test-check-all.py` が見る + +経路(`check-mutation-claims.py` を起こす入口): + +| 経路 | 入れ子になるか | 守り方 | +| --- | --- | --- | +| `check-all.py` の `GUARDS` | なる | `--jobs` を渡す(この周) | +| CI(`plugins.yml`) | ならない(単独のステップ) | 対象外 | +| 人が直接 | ならない | 既定(CPU の数)のまま | +| `test-check-mutation-claims.py`(`check-all.py` の `TESTS` 経由) | なるが、当てる木は試料だけ | 対象外(上の「触らない」) | +| `check-mutation-claims.py` の `red` が `check-all.py` を起こす | 今の主張には無い | 対象外 | + +検証で証明できるもの: 1・2(`run` に渡る引数を観測するテストと変異)、3・5(`check-all.py` を回す)、 +4(前後を測る。ただし手元の 10 コアの macOS 1 台での値)。 + +この環境では証明できないもの(**未証明**): 遅い機械・コア数の違う機械で打ち切りに届かなくなること +(測れるのはこの 1 台だけ)。 + +生成物: なし(`scripts/` の 2 本は生成物を持たない。図の書き出し・`skill-metrics.py` の生成ブロックは触らない)。 + +## 未解決の判断 + +- 渡す値(`1`/親の一部)は前後を測ってから決める + +## 手順 8 + +- この周の起票: 0 件 + +## 着手前の実測(著者。関門ではない) + +(測定中) + +## 関門の進捗(再開点) + +- 着手: worktree 作成・肯定的な確認済み + +## 既知の限界・決着済みの論点 + +(まだ無い) diff --git a/scripts/check-all.py b/scripts/check-all.py index d86dcf77..8b68c716 100755 --- a/scripts/check-all.py +++ b/scripts/check-all.py @@ -31,6 +31,10 @@ - **既定は CPU の数だけ並列**(`--jobs`)。**`--jobs 1` で直列**になる。 - **起動は宣言順。** いちばん重い `check-mutation-claims.py` を `GUARDS` の先頭に置いてある ——並列のとき、律速になる 1 本が最後に起動されないように。 +- **入れ子は直列**(#460)。`check-mutation-claims.py` は自分も `--jobs`(既定は CPU の数)で並列に当てるので、 + ここからは `--jobs 1` で起こす。既定のままだと親の作業者と入れ子の作業者が CPU を取り合い、 + `test-worktree-scripts.py` の陽性対照が打ち切り(300 秒)に届いた(2026-10-27、10 コアの macOS で wall 678 秒・失敗)。 + 入れ子を `--jobs 1` にすると 441 秒で通り、`--jobs 3` は 520 秒だった(各 1 回)。 - **出力は宣言順**(終わった順ではない)。先頭が最も重いので、最初の行が出るまで待つ。 - **Ctrl-C で、まだ起動していないものは起動せず、走っているものは止める** (親だけに SIGINT が届いた場合も——子を止めるのは親である)。**孫まで止める**—— @@ -68,7 +72,9 @@ GUARDS: list[tuple[str, list[str], bool]] = [ # **他の歯止めを子プロセスで回すので、1 本だけ重い**(直列で 166 秒。#430 の時点)。 # **起動は宣言順なので先頭に置く**——後ろに置くと、並列のとき律速の 1 本が遅れて起動される。 - ("check-mutation-claims.py", [], False), + # **中では直列に当てさせる**(#460)——既定(CPU の数)のままだと、親の作業者と入れ子の作業者が + # 同じ CPU を取り合い、重い `red` が打ち切り(300 秒)に届いた。測った値は docstring の並列の節。 + ("check-mutation-claims.py", ["--jobs", "1"], False), ("check-plugin-versions.py", [], False), ("check-norm-markers.py", [], False), ("check-duplicate-counts.py", [], False), diff --git a/scripts/test-check-all.py b/scripts/test-check-all.py index 716fc383..936b7c09 100755 --- a/scripts/test-check-all.py +++ b/scripts/test-check-all.py @@ -386,6 +386,16 @@ def contract(target: Path, root: Path, tag: str) -> list[tuple[str, bool]]: except Exception: # noqa: BLE001 — 断らずに別の形で落ちたら、それも失格 refused = False got.append(("--jobs 0 を断る", refused)) + + # 9) 入れ子の並列を絞る(#460)——`check-mutation-claims.py` を `--jobs 1` で起こす。 + # **実物の `GUARDS` のまま、起動の引数だけを記録する**(`run` を差し替えるので何も走らない)。 + mod = load(target, f"{tag}_nested") + mod.TESTS = [] + calls: list[tuple[str, list[str]]] = [] + mod.run = lambda name, args: (calls.append((name, list(args))), (True, ""))[1] + rc, out = run_main(mod, ["--base", "no-such-ref-xyz"]) + got.append(("check-mutation-claims.py を --jobs 1 で起こす", + ("check-mutation-claims.py", ["--jobs", "1"]) in calls)) return got @@ -601,6 +611,9 @@ def test_ci_runs_every_registered_script() -> None: "回帰テストを宣言順に出さない": (" for name, fut in test_runs:\n", " for name, fut in reversed(test_runs):\n"), "--jobs 0 を通す": (" if opts.jobs < 1:\n", " if False:\n"), + # 以下は #460(入れ子の並列) + "入れ子を既定の並列で起こす": ('("check-mutation-claims.py", ["--jobs", "1"], False)', + '("check-mutation-claims.py", [], False)'), # **終わった順に出す**本体を写した変異(`as_completed`。#430 の 2 パス目)。`reversed()` だけでは、 # 受入基準 P11 が挙げる「終わった順」を表す変異が無かった。歯止めの側は SKIP(すぐ終わる)が先に出るので # 試料の遅延に依らず崩れる——**遅延を外しても 2 本とも捕まえた**ので、遅延が要るとは言えない。 From dfa754b510028d0167be613aa528b3fd351ed7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 13:05:22 +0900 Subject: [PATCH 2/9] =?UTF-8?q?check-all.py:=20=E5=85=A5=E3=82=8C=E5=AD=90?= =?UTF-8?q?=E3=81=AE=20--jobs=20=E3=82=92=E8=A6=AA=E3=81=AE=E5=8D=8A?= =?UTF-8?q?=E5=88=86=E3=81=AB=E3=81=97=E3=80=81=E5=A5=91=E7=B4=84=E3=81=AF?= =?UTF-8?q?=E5=80=A4=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F=E6=80=A7=E8=B3=AA?= =?UTF-8?q?=E3=81=A7=E8=A6=8B=E3=82=8B=EF=BC=88#460=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- scripts/check-all.py | 23 ++++++++++++++++------- scripts/test-check-all.py | 32 ++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/scripts/check-all.py b/scripts/check-all.py index 8b68c716..2c67c26a 100755 --- a/scripts/check-all.py +++ b/scripts/check-all.py @@ -31,10 +31,8 @@ - **既定は CPU の数だけ並列**(`--jobs`)。**`--jobs 1` で直列**になる。 - **起動は宣言順。** いちばん重い `check-mutation-claims.py` を `GUARDS` の先頭に置いてある ——並列のとき、律速になる 1 本が最後に起動されないように。 -- **入れ子は直列**(#460)。`check-mutation-claims.py` は自分も `--jobs`(既定は CPU の数)で並列に当てるので、 - ここからは `--jobs 1` で起こす。既定のままだと親の作業者と入れ子の作業者が CPU を取り合い、 - `test-worktree-scripts.py` の陽性対照が打ち切り(300 秒)に届いた(2026-10-27、10 コアの macOS で wall 678 秒・失敗)。 - 入れ子を `--jobs 1` にすると 441 秒で通り、`--jobs 3` は 520 秒だった(各 1 回)。 +- **入れ子は親の半分**(#460)。`check-mutation-claims.py` は自分も `--jobs`(既定は CPU の数)で並列に当てるので、 + ここからは `--jobs` を親の半分(少なくとも 1)にして起こす——`--jobs 1` なら入れ子まで直列になる。 - **出力は宣言順**(終わった順ではない)。先頭が最も重いので、最初の行が出るまで待つ。 - **Ctrl-C で、まだ起動していないものは起動せず、走っているものは止める** (親だけに SIGINT が届いた場合も——子を止めるのは親である)。**孫まで止める**—— @@ -72,9 +70,8 @@ GUARDS: list[tuple[str, list[str], bool]] = [ # **他の歯止めを子プロセスで回すので、1 本だけ重い**(直列で 166 秒。#430 の時点)。 # **起動は宣言順なので先頭に置く**——後ろに置くと、並列のとき律速の 1 本が遅れて起動される。 - # **中では直列に当てさせる**(#460)——既定(CPU の数)のままだと、親の作業者と入れ子の作業者が - # 同じ CPU を取り合い、重い `red` が打ち切り(300 秒)に届いた。測った値は docstring の並列の節。 - ("check-mutation-claims.py", ["--jobs", "1"], False), + # **中の並列数は `NESTED` が決める**(#460)。 + ("check-mutation-claims.py", [], False), ("check-plugin-versions.py", [], False), ("check-norm-markers.py", [], False), ("check-duplicate-counts.py", [], False), @@ -88,6 +85,16 @@ ("check-plan-scope.py", [], True), ] +# 中で自分も `--jobs` で並列に回すもの(#460)。親の並列数から決めた `--jobs` を渡す—— +# 渡さないと入れ子の既定(CPU の数)で起き、親の作業者と同じ CPU を取り合う。 +NESTED = "check-mutation-claims.py" + + +def nested_jobs(jobs: int) -> int: + """入れ子に渡す `--jobs`。親の半分で、少なくとも 1(親が 1 なら入れ子も直列)。""" + return max(1, jobs // 2) + + # 回帰テスト(歯止め自体が何も見ていない状態に退化していないかを見る) TESTS: list[str] = [ "test-check-plugin-versions.py", @@ -240,6 +247,8 @@ def main() -> int: guard_runs.append((label, None)) continue args = [*extra, opts.base] if needs_base else extra + if name == NESTED: + args = [*args, "--jobs", str(nested_jobs(opts.jobs))] guard_runs.append((label, pool.submit(run, name, args))) test_runs = ([] if opts.guards_only else [(name, pool.submit(run, name, [])) for name in TESTS]) diff --git a/scripts/test-check-all.py b/scripts/test-check-all.py index 936b7c09..3279fc1b 100755 --- a/scripts/test-check-all.py +++ b/scripts/test-check-all.py @@ -387,15 +387,25 @@ def contract(target: Path, root: Path, tag: str) -> list[tuple[str, bool]]: refused = False got.append(("--jobs 0 を断る", refused)) - # 9) 入れ子の並列を絞る(#460)——`check-mutation-claims.py` を `--jobs 1` で起こす。 + # 9) 入れ子の並列を絞る(#460)——`check-mutation-claims.py` に、親より少ない `--jobs` を渡す。 # **実物の `GUARDS` のまま、起動の引数だけを記録する**(`run` を差し替えるので何も走らない)。 - mod = load(target, f"{tag}_nested") - mod.TESTS = [] - calls: list[tuple[str, list[str]]] = [] - mod.run = lambda name, args: (calls.append((name, list(args))), (True, ""))[1] - rc, out = run_main(mod, ["--base", "no-such-ref-xyz"]) - got.append(("check-mutation-claims.py を --jobs 1 で起こす", - ("check-mutation-claims.py", ["--jobs", "1"]) in calls)) + # **値そのものは見ない**——見るのは「渡すこと」「親が 1 なら 1」「親が 2 以上なら親より少ない」。 + def nested_args(jobs: str) -> list[list[str]]: + mod = load(target, f"{tag}_nested{jobs}") + mod.TESTS = [] + calls: list[tuple[str, list[str]]] = [] + mod.run = lambda name, args: (calls.append((name, list(args))), (True, ""))[1] + run_main(mod, ["--base", "no-such-ref-xyz", "--jobs", jobs]) + return [args for name, args in calls if name == "check-mutation-claims.py"] + + def inner(args: list[list[str]]) -> int | None: + if len(args) != 1 or args[0][:-1] != ["--jobs"] or not args[0][-1].isdigit(): + return None + return int(args[0][-1]) + + one, four = inner(nested_args("1")), inner(nested_args("4")) + got.append(("--jobs 1 なら入れ子も --jobs 1", one == 1)) + got.append(("--jobs 4 なら入れ子は 1 以上 4 未満", four is not None and 1 <= four < 4)) return got @@ -612,8 +622,10 @@ def test_ci_runs_every_registered_script() -> None: " for name, fut in reversed(test_runs):\n"), "--jobs 0 を通す": (" if opts.jobs < 1:\n", " if False:\n"), # 以下は #460(入れ子の並列) - "入れ子を既定の並列で起こす": ('("check-mutation-claims.py", ["--jobs", "1"], False)', - '("check-mutation-claims.py", [], False)'), + "入れ子に --jobs を渡さない": (' args = [*args, "--jobs", str(nested_jobs(opts.jobs))]\n', + " pass\n"), + "入れ子に親と同じ並列数を渡す": (" return max(1, jobs // 2)\n", " return jobs\n"), + "入れ子を 0 にしうる": (" return max(1, jobs // 2)\n", " return jobs // 2\n"), # **終わった順に出す**本体を写した変異(`as_completed`。#430 の 2 パス目)。`reversed()` だけでは、 # 受入基準 P11 が挙げる「終わった順」を表す変異が無かった。歯止めの側は SKIP(すぐ終わる)が先に出るので # 試料の遅延に依らず崩れる——**遅延を外しても 2 本とも捕まえた**ので、遅延が要るとは言えない。 From f95df7b94aa3e7666e645c479e1ea7ec32b8bc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 13:51:38 +0900 Subject: [PATCH 3/9] =?UTF-8?q?check-all.py:=20=E5=85=A5=E3=82=8C=E5=AD=90?= =?UTF-8?q?=E3=82=92=E8=A6=AA=E3=81=AE=E5=8D=8A=E5=88=86=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=81=9F=E6=A0=B9=E6=8B=A0=E3=81=AE=E5=AE=9F=E6=B8=AC=E3=82=92?= =?UTF-8?q?=20docstring=20=E3=81=A8=E8=A8=88=E7=94=BB=E3=81=AB=E6=9B=B8?= =?UTF-8?q?=E3=81=8F=EF=BC=88#460=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 37 ++++++++++++++++++++++++++++++++----- scripts/check-all.py | 4 ++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index bb932680..b9088654 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -66,20 +66,47 @@ ## 未解決の判断 -- 渡す値(`1`/親の一部)は前後を測ってから決める +- 渡す値: **親の半分(少なくとも 1)に決めた**(下の実測)。`1` は wall が延びすぎる ## 手順 8 - この周の起票: 0 件 -## 着手前の実測(著者。関門ではない) +## 実測(著者。関門ではない) -(測定中) +10 コアの macOS 1 台、2026-10-27。**計測は scratchpad のスクリプトで、他の `check-all.py` がいなくなってから起動し、 +走っている間の他の `check-all.py` の数と 1 分平均の負荷を 5 秒ごとに記録した。** `red` の所要は、`PATH` の先頭に +記録だけする `python3` を置いて、退避先(worktree の外)で走った `scripts/test-*.py` を拾った。 + +| 入れ子の `--jobs` | wall(他の `check-all.py` が 0 本の回) | 最長の `red` | +| --- | --- | --- | +| 既定(10。変更前) | 227.2 / 217.0 / 232.4 / 224.0 / 262.2 秒 | 90.4 / 99.1 秒 | +| 親の半分(5) | 237.4 / 252.3 秒 | 77.4 / 79.4 秒 | +| 1 | 373.1 / 368.0 / 388.1 秒 | 約 64 秒 | + +- **変更前でも、他の `check-all.py` が重ならなければ打ち切り(300 秒)には届かなかった**(最長 90 秒)。 + **打ち切りに届いた 1 回(wall 678 秒・`test-worktree-scripts.py` の陽性対照が 300 秒)は、負荷の 15 分平均が 50 の時間帯で、 + 別のセッション(`issue-458`)が `check-all.py` を走らせていた**(その回は重なりを記録していないので、重なっていたとまでは言えない) +- **`--jobs 1` は wall が約 +65%** で、受入基準 4 に反する。**親の半分は wall の中央値で約 +8%(227 → 245 秒)で、 + 最長の `red` が 90〜99 → 77〜79 秒**。標本は半分が 2 回・変更前が 5 回で、負荷の揺れ(1 分平均 41〜71)の中にある +- 半分の回がもう 1 回あったが、途中で他の `check-all.py` が 2 本重なった(1 分平均 216・wall 457 秒)ので捨てた + +捨てた測定(交絡): + +- 入れ子の値だけを変えて、契約(`test-check-all.py`)を新しい版のままにした回——契約が落ちて `test-check-all.py` の主張 4 件が + 陽性対照で止まり、仕事が減った(wall 237 / 227 / 222 秒)。**比べるときは 2 本とも base の版に戻す** +- 最初の数回(678 / 441 / 520 / 459 秒)——他のセッションの `check-all.py` と重なっていたかを記録していなかった +- 1/3 の回——変異の表が式の文字列(`max(1, jobs // 2)`)を名指ししているので契約が崩れ、さらに他の `check-all.py` が 2 本重なった ## 関門の進捗(再開点) -- 着手: worktree 作成・肯定的な確認済み +- 周の在り処は上の節。肯定的な確認済み(再開した 2 セッション目でも `issue/460-nested-mutation-jobs` の上・`dfa754b`) +- 実装: `4d460c9`(入れ子を `--jobs 1`)→ `dfa754b`(親の半分。契約を性質で見る)→ 実測を docstring に書いたコミット。**実装は完了** +- 手順 5 の Verifier: 未着手 / `/code-review`: 未着手 +- 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた ## 既知の限界・決着済みの論点 -(まだ無い) +- **他のセッションの `check-all.py` が重なったときの打ち切りは、この周では止められない**——入れ子を絞るのは 1 本の `check-all.py` の中の + 取り合いだけで、セッションをまたぐ取り合いは見えない。決着: 採らない(範囲外)。理由: Issue の受入基準は入れ子の N×N +- **`--jobs 1` は採らない**——wall が約 +65%(上の表)で、受入基準 4 に反する diff --git a/scripts/check-all.py b/scripts/check-all.py index 2c67c26a..5df63fdf 100755 --- a/scripts/check-all.py +++ b/scripts/check-all.py @@ -33,6 +33,10 @@ ——並列のとき、律速になる 1 本が最後に起動されないように。 - **入れ子は親の半分**(#460)。`check-mutation-claims.py` は自分も `--jobs`(既定は CPU の数)で並列に当てるので、 ここからは `--jobs` を親の半分(少なくとも 1)にして起こす——`--jobs 1` なら入れ子まで直列になる。 + 2026-10-27、10 コアの macOS で、他の `check-all.py` が重ならない回の wall と、入れ子の中で最も長かった `red`: + 既定のまま(10)は 217〜262 秒・90〜99 秒、半分(5)は 237・252 秒・77〜79 秒、`1` は 368〜388 秒・約 64 秒。 + **`1` は打ち切りまでの余裕が最も大きいが wall が 6 割延びる**ので、半分にした。 + **別のセッションの `check-all.py` と重なったときの取り合いは、ここでは絞れない**(#449 の打ち切りはその時間帯に出た)。 - **出力は宣言順**(終わった順ではない)。先頭が最も重いので、最初の行が出るまで待つ。 - **Ctrl-C で、まだ起動していないものは起動せず、走っているものは止める** (親だけに SIGINT が届いた場合も——子を止めるのは親である)。**孫まで止める**—— From 58536be49807f148ddcb3120a47b5496b44f5f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 13:51:57 +0900 Subject: [PATCH 4/9] =?UTF-8?q?docs(plans):=20#460=20=E3=81=AE=E5=86=8D?= =?UTF-8?q?=E9=96=8B=E7=82=B9=E3=82=92=E6=9B=B8=E3=81=8F=EF=BC=88=E6=89=8B?= =?UTF-8?q?=E9=A0=86=204=20=E3=81=AE=E5=89=B2=E3=82=8A=E7=9B=AE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index b9088654..a4d02367 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -101,7 +101,10 @@ ## 関門の進捗(再開点) - 周の在り処は上の節。肯定的な確認済み(再開した 2 セッション目でも `issue/460-nested-mutation-jobs` の上・`dfa754b`) -- 実装: `4d460c9`(入れ子を `--jobs 1`)→ `dfa754b`(親の半分。契約を性質で見る)→ 実測を docstring に書いたコミット。**実装は完了** +- 実装: `4d460c9`(入れ子を `--jobs 1`)→ `dfa754b`(親の半分。契約を性質で見る)→ `f95df7b`(実測を docstring に)。**実装は完了**。 + `f95df7b` で `check-all.py` 51/51 +- 次: 手順 5 の Verifier(1 パス目)から +- 手順 4 の割り目: AskUserQuestion で訊いた → **「ここで割る」が選ばれた**(2026-10-27) - 手順 5 の Verifier: 未着手 / `/code-review`: 未着手 - 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた From b99fc7f8165acffa739a15ebe864766059f42d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 14:15:59 +0900 Subject: [PATCH 5/9] =?UTF-8?q?check-all.py:=20=E6=89=93=E3=81=A1=E5=88=87?= =?UTF-8?q?=E3=82=8A=E3=81=AE=E5=8E=9F=E5=9B=A0=E3=82=92=E3=80=81=E8=A8=98?= =?UTF-8?q?=E9=8C=B2=E3=81=AB=E3=81=82=E3=82=8B=E4=BA=8B=E5=AE=9F=E3=81=A0?= =?UTF-8?q?=E3=81=91=E3=81=A7=E6=9B=B8=E3=81=8F=EF=BC=88#460=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docstring が「#449 の打ち切りはその時間帯に出た」と因果を書いていたが、#449 の打ち切りは重なりを記録していない日の値で、 根拠が無かった(/code-review 1 パス目の CR5)。計画に 1 パス目の採否の表と、交互の測り直しを書く。 Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 33 ++++++++++++++++++++++++++++++++- scripts/check-all.py | 4 +++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index a4d02367..98ccd2f5 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -91,6 +91,19 @@ 最長の `red` が 90〜99 → 77〜79 秒**。標本は半分が 2 回・変更前が 5 回で、負荷の揺れ(1 分平均 41〜71)の中にある - 半分の回がもう 1 回あったが、途中で他の `check-all.py` が 2 本重なった(1 分平均 216・wall 457 秒)ので捨てた +交互の測り直し(3 セッション目。`/code-review` 1 パス目の CR7 への対応): + +同じツリーで `check-all.py` と `test-check-all.py` の 2 本を**両方とも** base の版と HEAD の版に入れ替えて、順に回した。 +走っている間、**自分の子孫を除いた** `check-all.py` の数と 1 分平均の負荷を 5 秒ごとに記録した +(最初の試行は `test-check-all.py` が起こす `check-all.py` の写しまで「他」に数える形だったので、止めて捨てた)。 + +| 順 | 版 | wall | 他の `check-all.py`(最大) | 1 分平均 | 結果 | +| --- | --- | --- | --- | --- | --- | +| 0 | base | 248.8 秒 | 0 | 11〜47 | 51/51(失敗 0) | +| 1 | HEAD | 243.1 秒 | 0 | 15〜46 | 51/51(失敗 0) | + +- 標本は 1 組だけ(残りの 1 組は人間の判断で止めた)。この 1 組では悪化していない。**「悪化しない」は 1 組と、上の交互でない表からの言い方**である + 捨てた測定(交絡): - 入れ子の値だけを変えて、契約(`test-check-all.py`)を新しい版のままにした回——契約が落ちて `test-check-all.py` の主張 4 件が @@ -105,7 +118,10 @@ `f95df7b` で `check-all.py` 51/51 - 次: 手順 5 の Verifier(1 パス目)から - 手順 4 の割り目: AskUserQuestion で訊いた → **「ここで割る」が選ばれた**(2026-10-27) -- 手順 5 の Verifier: 未着手 / `/code-review`: 未着手 +- 手順 5 の Verifier: 1 パス目 **反証 0 件**(3 セッション目・sonnet・`dev-loop:dev-loop-verifier`。`test-check-all.py` 緑・足した変異 3 件は捕まえる・鮮度 2 本緑。 + 基準 3 は回さず、基準 4 は計画の実測を読んで判定)。注意 1 件は下の採否の表 / `/code-review`: 1 パス目 **指摘 9 件**(high)。採否は下の表 +- 1 パス目の指摘対応: CR5 を直した(docstring の 1 文)・CR7 を測り直した。他は残課題。直したあと `check-all.py` 51/51 +- 次: **手順 5 の当て直し(Verifier 2 パス目)**と **`/code-review` 2 パス目**の両方が残っている。base は同じ SHA - 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた ## 既知の限界・決着済みの論点 @@ -113,3 +129,18 @@ - **他のセッションの `check-all.py` が重なったときの打ち切りは、この周では止められない**——入れ子を絞るのは 1 本の `check-all.py` の中の 取り合いだけで、セッションをまたぐ取り合いは見えない。決着: 採らない(範囲外)。理由: Issue の受入基準は入れ子の N×N - **`--jobs 1` は採らない**——wall が約 +65%(上の表)で、受入基準 4 に反する + +### 採否の表(1 パス目) + +| 指摘 | 実物で失敗を示せるか | 破る受入基準 | 採否 | +| --- | --- | --- | --- | +| Verifier: 契約 9 は「親の半分」を固定しない(入れ子を定数 1 にする変異が通るはず。読解のみ) | 示せない(その変異は基準 1・2 を満たし、失敗ではない) | 無し(契約は意図して値ではなく性質を見る——`dfa754b`) | 残課題 | +| CR1: 契約 9 は `--jobs` を明示した起動しか見ず、既定の起動(引数なし)を観測しない(変異 `and "--jobs" in sys.argv` が緑) | 示せない——実物は既定の起動で入れ子に `--jobs 5`(10 コア。scratchpad で `run` を差し替えて記録)。失敗はテストの網の穴で、成果物の失敗ではない | 無し(基準 1 は実物で満たす) | 残課題 | +| CR2: 契約 9 は入れ子以外の歯止めに `--jobs` が渡ることを見ない(変異 `if True:` が緑) | 示せない——実物は他の歯止めに `--jobs` を渡さない(同上の記録で 0 本) | 無し | 残課題 | +| CR3: 契約 9 は親 1 と 4 しか見ない(変異 `1 if jobs < 8 else jobs * 2` が緑) | 示せない——実物は親 1・10・32 で 1・5・16 | 無し | 残課題 | +| CR4: docstring「`--jobs 1` なら入れ子まで直列」は孫(`red` が起こす `test-*.py` の並列)まで直列にしない | 示せない(基準 2 は「`check-mutation-claims.py --jobs 1`」と定義しており、その意味では真) | 無し | 残課題 | +| CR5: docstring「#449 の打ち切りはその時間帯に出た」は根拠が無い | **示せる**——`docs/plans/issue-449.md:46`「#449 の 300 秒超えは 3 回中 2 回で起きた別の日の値」。重なりは記録されていない。この周の 678 秒の回は別の事象で、計画も「重なっていたとまでは言えない」 | 無し(docstring の事実は受入基準に無い) | **直す(人間の判断。2026-10-27)**——根拠の無い因果の 1 文を、記録にある事実だけに直す | +| CR6: 高度——実測では入れ子 N の `red` は打ち切りから遠く(最長 90〜99 秒)、wall +8% を払って原因と裏付けられないものを直している。並列の形も N×N ではなく (N-1)+N | 示せない(打ち切りは重ならない回で再現しない) | 無し(Issue の受入基準は入れ子の並列を絞ること) | 残課題(**決着の理由への反論**なので PR コメントで人間に渡す) | +| CR7: 基準 4 の証拠は「交互に測った」ことを示していない(順序・時刻が無く、変更後は 2 回) | 示せる(計画の表に順序が無い) | 4(証拠の不足) | **測り直した**(コードは変えない)——下の「交互の測り直し」。4 回の予定を 1 組(2 回)で止めた(人間の判断。#464 に CPU を空けるため) | +| CR8: `nested_jobs` を CPU の数で頭打ちにしていない(`--jobs 32` で入れ子 16) | 示せる(親 32 で 16)が、基準 1 は「親より多くない」で、16 < 32 | 無し | 残課題 | +| CR9: FAIL の行・ログの見出しに入れ子に渡した `--jobs` が出ない | 示せない(並列に依る失敗の再現の例は仮定) | 無し | 残課題 | diff --git a/scripts/check-all.py b/scripts/check-all.py index 5df63fdf..cd76c0c8 100755 --- a/scripts/check-all.py +++ b/scripts/check-all.py @@ -36,7 +36,9 @@ 2026-10-27、10 コアの macOS で、他の `check-all.py` が重ならない回の wall と、入れ子の中で最も長かった `red`: 既定のまま(10)は 217〜262 秒・90〜99 秒、半分(5)は 237・252 秒・77〜79 秒、`1` は 368〜388 秒・約 64 秒。 **`1` は打ち切りまでの余裕が最も大きいが wall が 6 割延びる**ので、半分にした。 - **別のセッションの `check-all.py` と重なったときの取り合いは、ここでは絞れない**(#449 の打ち切りはその時間帯に出た)。 + **別のセッションの `check-all.py` と重なったときの取り合いは、ここでは絞れない**。打ち切りの原因は特定していない + ——#449 の打ち切りは重なりを記録していない日の値で、#460 で届いた 1 回は別のセッションが `check-all.py` を走らせていた + 時間帯だが、重なっていたかは記録していない。 - **出力は宣言順**(終わった順ではない)。先頭が最も重いので、最初の行が出るまで待つ。 - **Ctrl-C で、まだ起動していないものは起動せず、走っているものは止める** (親だけに SIGINT が届いた場合も——子を止めるのは親である)。**孫まで止める**—— From f258b08e8fa6690aea3eb5caa6e644aab3d4e82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 14:17:48 +0900 Subject: [PATCH 6/9] =?UTF-8?q?docs(plans):=20#460=20=E3=81=AE=E5=86=8D?= =?UTF-8?q?=E9=96=8B=E7=82=B9=E3=82=92=E6=9B=B8=E3=81=8F=EF=BC=88=E6=89=8B?= =?UTF-8?q?=E9=A0=86=206=20=E3=81=AE=E5=89=B2=E3=82=8A=E7=9B=AE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index 98ccd2f5..3a108ad0 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -122,6 +122,8 @@ 基準 3 は回さず、基準 4 は計画の実測を読んで判定)。注意 1 件は下の採否の表 / `/code-review`: 1 パス目 **指摘 9 件**(high)。採否は下の表 - 1 パス目の指摘対応: CR5 を直した(docstring の 1 文)・CR7 を測り直した。他は残課題。直したあと `check-all.py` 51/51 - 次: **手順 5 の当て直し(Verifier 2 パス目)**と **`/code-review` 2 パス目**の両方が残っている。base は同じ SHA + (2 パス目で見るのは主に `b99fc7f` の docstring の 1 文と、計画の測り直し) +- 手順 6 の割り目(2 パス目の前): AskUserQuestion で訊いた → **「ここで割る」が選ばれた**(2026-10-27) - 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた ## 既知の限界・決着済みの論点 From bba67c944cbcbe43fac996f3f2ac30736efea4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 14:32:37 +0900 Subject: [PATCH 7/9] =?UTF-8?q?test-worktree-scripts.py:=20=E6=89=93?= =?UTF-8?q?=E3=81=A1=E5=88=87=E3=82=8A=E3=81=AE=E5=8E=9F=E5=9B=A0=E3=82=92?= =?UTF-8?q?=E3=80=81=E8=A8=98=E9=8C=B2=E3=81=AB=E3=81=82=E3=82=8B=E4=BA=8B?= =?UTF-8?q?=E5=AE=9F=E3=81=A0=E3=81=91=E3=81=A7=E6=9B=B8=E3=81=8F=EF=BC=88?= =?UTF-8?q?#460=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CR5 で check-all.py から消したのと同じ根拠の無い因果(並列が重なったときに届いた)が、 このコメントに残っていた(/code-review 2 パス目の R5)。計画に 2 パス目の採否の表と、広げた範囲・基準 6 を書く。 Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 24 ++++++++++++++++++++++++ scripts/test-worktree-scripts.py | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index 3a108ad0..fcdf8ead 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -11,6 +11,8 @@ - `scripts/check-all.py` — `check-mutation-claims.py` を起こすときに `--jobs` を渡す(値は親の `--jobs` から決める)。docstring の並列の節 - `scripts/test-check-all.py` — 渡した `--jobs` を観測するケースと、その変異 - `docs/plans/issue-460.md` — この計画 +- `scripts/test-worktree-scripts.py` — 197〜199 行のコメントの 1 文だけ(2 パス目の R5。CR5 と同じ根拠の無い因果が残っていた。 + 広げたのは人間の判断、2026-10-27。挙動は変えない) 触らない: @@ -45,6 +47,9 @@ 3. **`check-all.py` が全部通る**(`N/N 本を回した(失敗 0)`) 4. **`check-all.py` の wall が大きく悪化しない**——同じツリーで前後を交互に測る 5. **`check-all.py` の既存の観測(並列・直列・中断・収録漏れ)が緑のまま**——`test-check-all.py` が見る +6. (2 パス目に範囲を広げた分)**`test-worktree-scripts.py` はコメントの 1 文しか変わらず、挙動が変わらない**—— + `test-worktree-scripts.py` が緑で、差分がコメント行だけ。**直した文は記録(`docs/plans/issue-449.md:46`)にある事実だけを言い、 + `check-all.py` の docstring と食い違わない** 経路(`check-mutation-claims.py` を起こす入口): @@ -124,6 +129,10 @@ - 次: **手順 5 の当て直し(Verifier 2 パス目)**と **`/code-review` 2 パス目**の両方が残っている。base は同じ SHA (2 パス目で見るのは主に `b99fc7f` の docstring の 1 文と、計画の測り直し) - 手順 6 の割り目(2 パス目の前): AskUserQuestion で訊いた → **「ここで割る」が選ばれた**(2026-10-27) +- 手順 5 の当て直し(Verifier 2 パス目): **反証 0 件**(4 セッション目・sonnet・`dev-loop:dev-loop-verifier`。注意 2 件は基準 4 の証拠の弱さ) + / `/code-review` 2 パス目: **指摘 10 件**(high)。採否は下の「採否の表(2 パス目)」 +- 2 パス目の指摘対応: R5 だけ直す(人間の判断)。**狭いパスの起点: `f258b08e8fa6690aea3eb5caa6e644aab3d4e82b`**(指摘対応を始める直前の HEAD) +- 範囲を広げた分の受入基準: 6(下) - 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた ## 既知の限界・決着済みの論点 @@ -146,3 +155,18 @@ | CR7: 基準 4 の証拠は「交互に測った」ことを示していない(順序・時刻が無く、変更後は 2 回) | 示せる(計画の表に順序が無い) | 4(証拠の不足) | **測り直した**(コードは変えない)——下の「交互の測り直し」。4 回の予定を 1 組(2 回)で止めた(人間の判断。#464 に CPU を空けるため) | | CR8: `nested_jobs` を CPU の数で頭打ちにしていない(`--jobs 32` で入れ子 16) | 示せる(親 32 で 16)が、基準 1 は「親より多くない」で、16 < 32 | 無し | 残課題 | | CR9: FAIL の行・ログの見出しに入れ子に渡した `--jobs` が出ない | 示せない(並列に依る失敗の再現の例は仮定) | 無し | 残課題 | + +### 採否の表(2 パス目) + +| 指摘 | 実物で失敗を示せるか | 破る受入基準 | 採否 | +| --- | --- | --- | --- | +| Verifier 注意 1・R1: 交互の測り直しは 1 組(248.8 / 243.1 秒)で、予想の +8%(約 19 秒)を判別できない。基準 4 には閾値が無く落ちようがない | 示せる(計画の表のばらつき 217〜262 秒) | 4(証拠の不足。成果物の失敗ではない) | 残課題——**PR コメントに「基準 4 は証拠が弱い」と名指し**(人間の判断。2026-10-27) | +| Verifier 注意 2・R2: 1 分平均 11〜47 で、他の `check-all.py` 以外の負荷は統制していない。順序も固定 | 示せる(計画の記録) | 4(同上) | 残課題(R1 と同じ扱い) | +| R3: 経路表の「`red` が `check-all.py` を起こす——今の主張には無い」は偽。`red` が `test-check-all.py` の主張が 4 件ある | 示せる(`grep` で 4 件)。ただし `test-check-all.py` は `run` を偽物に差し替えて `main()` を回す(`test-check-all.py:281`)ので、重い入れ子にはならない | 無し | 残課題(経路表の言い方の誤り) | +| R4: 孫の `test-check-mutation-claims.py` は既定の `--jobs` で `main()` を回すので、`check-all.py --jobs 1` でも孫は直列でない | 示せる(主張 3 件) | 無し(基準 2 は「`check-mutation-claims.py --jobs 1`」と定義。1 パス目の CR4 と同じ) | 残課題 | +| R5: `test-worktree-scripts.py:197-199` に CR5 と同じ根拠の無い因果が残り、`check-all.py` の docstring と食い違う | 示せる(ファイル:行) | 無し(範囲外だった) | **直す(人間の判断。2026-10-27)**——範囲を広げ、基準 6 を足した | +| R6: 「未証明」が狭い——打ち切りはこの機械でも重ならない回で再現しておらず、「打ち切りを防ぐ」はこの機械でも未証明 | 示せる(計画の実測節) | 無し | 残課題——PR コメントの未証明に足す | +| R7: CR8 の理由「16 < 32」は base との比較を見ていない——10 コアで `--jobs 32` なら入れ子は変更前の 10 から 16 に増える | 示せる(式から) | 無し(基準 1 は「親より多くない」) | 残課題(**決着の理由への反論**なので PR コメントで人間に渡す) | +| R8: 捨てた測定(237 / 227 / 222 秒)と残した表の値(227.2・237.4)が近く、混ざったかもしれない | 示せない(1 セッション目の記録は残っていない) | 無し | 残課題 | +| R9: 高度——名前で 1 段だけ絞っており、下の段は既定の並列のまま。環境変数で継ぐ上限なら全段に効く | 示せない(設計の提案) | 無し | 残課題 | +| R10: 半分の固定は、軽い歯止めが終わった後の尾で約 N/2 コアを空ける | 示せない(wall +8% の原因という推測) | 無し | 残課題 | diff --git a/scripts/test-worktree-scripts.py b/scripts/test-worktree-scripts.py index 4df667d2..1c35d350 100644 --- a/scripts/test-worktree-scripts.py +++ b/scripts/test-worktree-scripts.py @@ -196,8 +196,8 @@ def _build_dangling_origin_head(base: Path) -> Path: # **足場は 1 度だけ作り、使うたびに複製する**(#449)。**`observe()` は 21 回走る** # (正しい版 1 + 変異 20)ので、足場を毎回 `git init`・`commit`・`clone`・`push` で -# 組み直すと、**それだけで子プロセスが 1 回に 50 本ほど増える**——`check-all.py` の並列と -# `check-mutation-claims.py` の並列が重なったとき、この 1 本が打ち切り(300 秒)に届いた。 +# 組み直すと、**それだけで子プロセスが 1 回に 50 本ほど増える**——`check-all.py` の中の +# `check-mutation-claims.py` で、この 1 本が打ち切り(300 秒)に届いたことがある(3 回中 2 回。原因は特定していない)。 # **複製は使い捨てで、観測どうしは今までどおり足場を共有しない。** _templates: dict[str, tuple[Path, object]] = {} _template_root: tempfile.TemporaryDirectory | None = None From 7c0f8e2c78658acdebbdf0b2dd7f736fa1455401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 14:34:21 +0900 Subject: [PATCH 8/9] =?UTF-8?q?docs(plans):=20#460=20=E3=81=AE=202=20?= =?UTF-8?q?=E3=83=91=E3=82=B9=E7=9B=AE=E3=81=A8=E7=8B=AD=E3=81=84=E3=83=91?= =?UTF-8?q?=E3=82=B9=E3=81=AE=E7=B5=90=E6=9E=9C=E3=82=92=E6=9B=B8=E3=81=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index fcdf8ead..5820a330 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -133,6 +133,10 @@ / `/code-review` 2 パス目: **指摘 10 件**(high)。採否は下の「採否の表(2 パス目)」 - 2 パス目の指摘対応: R5 だけ直す(人間の判断)。**狭いパスの起点: `f258b08e8fa6690aea3eb5caa6e644aab3d4e82b`**(指摘対応を始める直前の HEAD) - 範囲を広げた分の受入基準: 6(下) +- R5 の修正 `bba67c9` のあと `check-all.py` 51/51(失敗 0) +- 狭いパス(R5): **反証 0 件**(sonnet・`dev-loop:dev-loop-verifier`。コメント以外の差分が空・`test-worktree-scripts.py` 緑・ + 直した文は #449 の記録と一致)。**Verifier は変異を設計しなかった**(コメントだけの変更なので、変異は前後で同じ結果になるとして)。素通りした変異: なし(当てていない) +- 関門はここで打ち切り(2 パス)。次: PR を作り、残課題・未証明・基準 4 の証拠の弱さを PR コメントに書く - 交絡を潰した手順: 上の「捨てた測定」。他の `check-all.py` の重なりを記録し、比べる 2 本を base の版に揃えた ## 既知の限界・決着済みの論点 From cef71e0aa57d1b8a586b690de6ea4b36ee311cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A5=88=E8=89=AF=20=E8=8B=B1=E6=A8=B9?= Date: Tue, 27 Oct 2026 14:44:24 +0900 Subject: [PATCH 9/9] =?UTF-8?q?docs(plans):=20#460=20=E3=81=AE=E6=89=8B?= =?UTF-8?q?=E9=A0=86=207=E3=83=BB8=20=E3=82=92=E6=9B=B8=E3=81=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- docs/plans/issue-460.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/plans/issue-460.md b/docs/plans/issue-460.md index 5820a330..8b7f1dad 100644 --- a/docs/plans/issue-460.md +++ b/docs/plans/issue-460.md @@ -76,6 +76,9 @@ ## 手順 8 - この周の起票: 0 件 +- 焼き戻す学び: リポジトリには無し(CR5 の直し残し(R5)は、手順 3 の「同じことを述べている箇所の数」で、 + `check-all.py` の外にある同じ主張を数えていなかったため。規定はもうあるので、足すものは無い) +- 手順 7: PR #467 は CI 緑。マージは人間の承認待ち。反映経路なし ## 実測(著者。関門ではない)