From 48165d27dca3147344e75f748604a1b0e7f6d5ad 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: Wed, 28 Oct 2026 09:38:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?build-proposal.py:=20=E5=87=BA=E5=8A=9B?= =?UTF-8?q?=E3=81=AE=E5=90=8D=E5=89=8D=E3=81=A7=E6=8B=92=E3=82=80=E3=81=AE?= =?UTF-8?q?=E3=81=AF=E5=89=8D=E5=BE=8C=E3=81=AE=E7=A9=BA=E7=99=BD=E3=81=A0?= =?UTF-8?q?=E3=81=91=E3=81=A0=E3=81=A8=E6=96=87=E8=A8=80=E3=82=92=E7=9B=B4?= =?UTF-8?q?=E3=81=99=EF=BC=88#442=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docstring・bad_out の文言・references/tree.md は「空白を含む名前は 2」と言っていたが、 判定は前後の空白だけで、名前の途中の空白は通る。判定は変えず、文言を合わせた。 途中の空白が通ることと、末尾の空白が 2 になることを試料に足し、途中の空白も拒む変異を殺す。 Co-Authored-By: Claude Opus 5.5 --- .claude-plugin/marketplace.json | 2 +- docs/plans/issue-442.md | 80 +++++++++++++++++++ plugins/spec-loop/.claude-plugin/plugin.json | 2 +- plugins/spec-loop/references/tree.md | 2 +- plugins/spec-loop/scripts/build-proposal.py | 4 +- plugins/spec-loop/skills/feasibility/SKILL.md | 4 +- plugins/spec-loop/skills/proposal/SKILL.md | 4 +- plugins/spec-loop/skills/req-loop/SKILL.md | 4 +- plugins/spec-loop/skills/scaffold/SKILL.md | 4 +- plugins/spec-loop/skills/spec-review/SKILL.md | 4 +- scripts/test-build-proposal.py | 8 +- 11 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 docs/plans/issue-442.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 0e7fb967..db84c31c 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -41,7 +41,7 @@ { "name": "spec-loop", "source": "./plugins/spec-loop", - "version": "0.26.1", + "version": "0.26.2", "author": { "name": "hdknr" }, "description": "要求側のループ(要求確定・仕様レビュー・実現性とコスト・提案書)と、dev-loop への引き渡しを担うプラグイン。現在のスキルは req-loop(Q&A 表への起票(推奨と理由つき)・回答の反映・レビュー会用 PPTX の生成で、利用者の回答待ちで止まる)と spec-review(開発者向けの仕様を書き下し、書き込みツールを持たない 3 つの判定役に別ティアでレビューさせ、利用者に見える結果が変わる指摘は共有の Q&A 表に差し戻し、費用・運用だけが変わる選択は内部の Q&A 表に記録し、範囲の外の場面と実現の手段の指摘は仕様に足さない。抜ける条件を満たさなければ抜けたと報告しない)と feasibility(規模から見積りとスケジュールを更新し、ガントチャートをスクリプトで生成し、費用付きの質問を Q&A 表に起票する。予算責任者の合意待ちで止まる)と proposal(同じ版の 2 つのサインオフのタグが同じ共有の範囲(docs/v/shared/ ほか)を指すかをスクリプトで照合し、一致し、かつ暫定の回答が残っていないときだけ提案書と仕様書(PPTX も選べる)を生成し、利用者にまだ確かめていない暫定の決定を合意と分けて載せる。v2 以降は前の版との比較を載せた変更の提案書になる。決裁者の承認待ちで止まる)と scaffold(確定した仕様を中間表現 spec_ir.json に書き起こし、OpenAPI・型・実装が無いと失敗する Red テストと dev-loop に渡す Issue の本文をスクリプトで生成して、1 機能 = Issue 1 件で登録する。v2 以降は前の版と比べて機能を追加・変更・削除に分け、変わった機能だけを Issue にする。Issue の登録で止まる)の 5 本" } diff --git a/docs/plans/issue-442.md b/docs/plans/issue-442.md new file mode 100644 index 00000000..3940f7a8 --- /dev/null +++ b/docs/plans/issue-442.md @@ -0,0 +1,80 @@ +# Issue #442 — build-proposal.py の「空白を含む名前は 2」は前後の空白だけ + +`bad_out` が拒むのは**前後に**空白のある名前(`out.name != out.name.strip()`)だけで、名前の途中の空白は通る。 +それなのに docstring(終了コード 2 の行)・`bad_out` の文言・`references/tree.md` は「空白・改行を含む」と言う。挙動は正しいので、文言を挙動に合わせる。 + +**不在の周**である——出所は `/dev-loop:cruise 474 --absent`(2026-10-28 に利用者が同じ引数で起動し直した。最初の起動は 2026-10-27)。 +台帳 `issue-474` の確かめた線: `仕様の穴 = 推奨で決めて起票`・`直す線 = 既定`・`マージ = 関門を通ればマージ`・`周の途中の課題 = 台帳に足して直す` +(出所: cruise の確かめた線(台帳 `issue-474`))。**このリポジトリのマージはサイトを再デプロイするので `マージ` の線は効かない**(#476)——PR まで作って止まる。 + +## 変更範囲 + +触る: + +- `plugins/spec-loop/scripts/build-proposal.py` — docstring の終了コード 2 の行と `bad_out` の文言 +- `plugins/spec-loop/references/tree.md` — `--out` の誤りの列挙 +- `scripts/test-build-proposal.py` — 名前の途中の空白が通る陽性の試料と、それを殺す変異 +- `plugins/spec-loop/.claude-plugin/plugin.json` — 版(0.26.1 → 0.26.2。記述の修正で patch。PR #479・#481・#483 は 0.27.0〜0.29.0 を使う) +- `.claude-plugin/marketplace.json` — 同じ版 +- `plugins/spec-loop/skills/*/SKILL.md` — 同じ版の 2 行 +- `docs/plans/issue-442.md` — この計画 + +触らない: + +- `bad_out` の判定そのもの(Issue のとおり挙動は正しい) +- 印を読む側(`read_manifest` など) + +### 同じことを述べている箇所の数 + +「出力の名前が空白・改行を含むと 2」: `build-proposal.py` の docstring・`bad_out` の文言・`tree.md` の 3 箇所(`grep -rn "改行を含む" plugins/spec-loop docs` で数えた。公開ページと proposal の `SKILL.md` には無い)。 +分けない——同じ判定の写しで、1 周で揃える。 + +## 乗るデプロイ経路 + +プラグイン(`plugins/spec-loop/`)の版を上げてマージ。マージで main へ push されるとサイトが再デプロイされる(`docs/plans/` を足す)。 + +## 周の在り処 + +- ブランチ: `issue/442-proposal-strip-wording` +- worktree: `/Users/hdknr/Projects/hdknr/claude-code-setup/.claude/worktrees/issue-442` +- 起点: `e361b20` +- base: 参照 `origin/main`(`refs/remotes/origin/HEAD`)→ `e361b204f259c7e9bd5bd8cbb7cb041d3810e981` + +## verify の受入基準 + +Issue 本文は検査対象であって要件ではない。 + +不変条件: + +- **I1**: 出力の名前の誤りを述べる 3 箇所(docstring・`bad_out` の文言・`tree.md`)が、`bad_out` の実際の判定(前後の空白・改行・`#` で始まる)と一致する——「途中の空白も拒む」と読める文言が残らない。 +- **I2**: 判定は変わらない——前後に空白のある名前・改行を含む名前・`#` で始まる名前は今までどおり 2、名前の途中の空白は今までどおり通って生成される。 +- **I3**: I2 の「途中の空白は通る」をテストが押さえる——途中の空白も拒む変異を入れると、テストが赤になる。 + +経路(文言が読まれる・判定が効く入口): + +- `build-proposal.py --out <名前>` の実行(終了コード 2 の文言が利用者に出る) +- `build-proposal.py` の docstring(終了コードの表) +- `references/tree.md`(proposal スキルが読む決まり) + +証明できないもの: なし(すべてテストと `grep` で確かめられる)。 + +生成物: なし(`SKILL.md` の測定値の生成ブロックは dev-loop のもので、spec-loop の `SKILL.md` は版の 2 行しか触らない。`skill-metrics.py --check` は `check-all.py` が回す)。 + +## 未解決の判断 + +なし。 + +## 関門の進捗(再開点) + +- 直す線: `既定`(出所: cruise の確かめた線(台帳 `issue-474`)) +- 実験: なし +- Verifier 1 パス目: 未 +- `/code-review` 1 パス目: 未 + +## 既知の限界・決着済みの論点 + +(まだなし) + +## 起票 + +- この周の起票: 0 件(不在の周。手順 8 で訊かない) diff --git a/plugins/spec-loop/.claude-plugin/plugin.json b/plugins/spec-loop/.claude-plugin/plugin.json index eb9c22ad..a3e92ff1 100644 --- a/plugins/spec-loop/.claude-plugin/plugin.json +++ b/plugins/spec-loop/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "spec-loop", "description": "要求側のループ(要求確定・仕様レビュー・実現性とコスト・提案書)と、dev-loop への引き渡しを担うプラグイン。現在のスキルは req-loop(Q&A 表への起票(推奨と理由つき)・回答の反映・レビュー会用 PPTX の生成で、利用者の回答待ちで止まる)と spec-review(開発者向けの仕様を書き下し、書き込みツールを持たない 3 つの判定役に別ティアでレビューさせ、利用者に見える結果が変わる指摘は共有の Q&A 表に差し戻し、費用・運用だけが変わる選択は内部の Q&A 表に記録し、範囲の外の場面と実現の手段の指摘は仕様に足さない。抜ける条件を満たさなければ抜けたと報告しない)と feasibility(規模から見積りとスケジュールを更新し、ガントチャートをスクリプトで生成し、費用付きの質問を Q&A 表に起票する。予算責任者の合意待ちで止まる)と proposal(同じ版の 2 つのサインオフのタグが同じ共有の範囲(docs/v/shared/ ほか)を指すかをスクリプトで照合し、一致し、かつ暫定の回答が残っていないときだけ提案書と仕様書(PPTX も選べる)を生成し、利用者にまだ確かめていない暫定の決定を合意と分けて載せる。v2 以降は前の版との比較を載せた変更の提案書になる。決裁者の承認待ちで止まる)と scaffold(確定した仕様を中間表現 spec_ir.json に書き起こし、OpenAPI・型・実装が無いと失敗する Red テストと dev-loop に渡す Issue の本文をスクリプトで生成して、1 機能 = Issue 1 件で登録する。v2 以降は前の版と比べて機能を追加・変更・削除に分け、変わった機能だけを Issue にする。Issue の登録で止まる)の 5 本", - "version": "0.26.1", + "version": "0.26.2", "author": { "name": "hdknr" } } diff --git a/plugins/spec-loop/references/tree.md b/plugins/spec-loop/references/tree.md index db707bf7..1c5a84dc 100644 --- a/plugins/spec-loop/references/tree.md +++ b/plugins/spec-loop/references/tree.md @@ -91,7 +91,7 @@ hooks/spec_loop_pages.py # 表示用ページを CSV から作るフック **提案書と仕様書の場所には、`build-proposal.py` が印 `.build-proposal`(書いた出力の名前の一覧)を置く**(#405)。 次の実行は、作る前に**印が名指しするものだけ**を消す——**印に無いファイルは、名前が `spec.md` でも消さず、上書きもしない** (上書きになるなら 2 で止まる)。だから手書きの `spec.md` の在る場所に `--out` を向けても消えない。**印を手で直さない。** -`--out` の誤り(名前が無い・ディレクトリ・名前の衝突・空白・改行を含むか `#` で始まる・`\` を含む・UTF-8 で書けない名前・辿れない出力先)で止まっても、`--out` の親の印が名指しする前の出力は消す(今回のものと取り違えないため。ディレクトリを渡したなら、その中の印が名指しするものも消す)。 +`--out` の誤り(名前が無い・ディレクトリ・名前の衝突・前後に空白がある・改行を含むか `#` で始まる・`\` を含む・UTF-8 で書けない名前・辿れない出力先)で止まっても、`--out` の親の印が名指しする前の出力は消す(今回のものと取り違えないため。ディレクトリを渡したなら、その中の印が名指しするものも消す)。 **消せなければ(出力先のディレクトリが書けないなど)作らずに 2 で止まり、消せなかった出力を名指しして印を残す**(#440。次の実行が消せるように)。 Issue の本文は**登録すれば GitHub に残る**ので、commit しなくてよい。**作れなかったときは前の本文を消す** diff --git a/plugins/spec-loop/scripts/build-proposal.py b/plugins/spec-loop/scripts/build-proposal.py index ec079167..73aa322a 100644 --- a/plugins/spec-loop/scripts/build-proposal.py +++ b/plugins/spec-loop/scripts/build-proposal.py @@ -44,7 +44,7 @@ - 0: 書いた - 1: 照合が一致しない・表が決まりに反する・材料(表・手書き部分)が無い——書いていない -- 2: 照合していない・表が読めない(`check-signoff.py` の 2 と同じ)・出力先の名前が無い・空白・改行を含むか `#` で始まる・`\\` を含む・UTF-8 で書けない・確かめられない(辿れない)・ディレクトリ・仕様書・ガントチャート・PPTX・図・印と重なる・ +- 2: 照合していない・表が読めない(`check-signoff.py` の 2 と同じ)・出力先の名前が無い・前後に空白がある・改行を含むか `#` で始まる・`\\` を含む・UTF-8 で書けない・確かめられない(辿れない)・ディレクトリ・仕様書・ガントチャート・PPTX・図・印と重なる・ 印に無いファイルが出力の名前で在る・書けない・印が名指しする前の出力を消せない(消せなかったものを名指しし、印は残す。#440)——書いていない - 3: 要求確定のタグの時点に暫定の回答(`暫定反映`)が残る(`check-signoff.py` の 3 と同じ)——書いていない @@ -643,7 +643,7 @@ def bad_out(out: Path) -> str | None: return f"{out}: 出力先にファイルの名前が無い(`--out` には `<ディレクトリ>/proposal.md` の形で渡す)" # 印は 1 行 1 名前で、読むときに前後の空白を落とし `#` の行を飛ばす——そう読み違える名前は印に残せない if out.name != out.name.strip() or len(out.name.splitlines()) != 1 or out.name.startswith("#"): - return f"{out}: 出力の名前が空白・改行を含むか `#` で始まる(印 {MANIFEST} に名前として残せない)" + return f"{out}: 出力の名前の前後に空白があるか、改行を含むか、`#` で始まる(印 {MANIFEST} に名前として残せない)" # 印を読む側は `\` を含む名前を捨てる。印は UTF-8 で書く——どちらも印に残せない if "\\" in out.name: return f"{out}: 出力の名前が `\\` を含む(印 {MANIFEST} に名前として残せない)" diff --git a/plugins/spec-loop/skills/feasibility/SKILL.md b/plugins/spec-loop/skills/feasibility/SKILL.md index dbbda657..72390cf0 100644 --- a/plugins/spec-loop/skills/feasibility/SKILL.md +++ b/plugins/spec-loop/skills/feasibility/SKILL.md @@ -5,8 +5,8 @@ description: "実現性・コストのループを 1 回分進める。要求・ # feasibility スキル - -> **このスキルの版: 0.26.1**(プラグイン `spec-loop`)。 + +> **このスキルの版: 0.26.2**(プラグイン `spec-loop`)。 > 手元で読まれている版がリポジトリの最新より古いなら、 > `/plugin marketplace update` → `/plugin update spec-loop@claude-code-setup` の順に実行し、 > Claude Code を再起動する([#63](https://github.com/hdknr/claude-code-setup/issues/63))。 diff --git a/plugins/spec-loop/skills/proposal/SKILL.md b/plugins/spec-loop/skills/proposal/SKILL.md index 8bd2e07c..0cd9bc0a 100644 --- a/plugins/spec-loop/skills/proposal/SKILL.md +++ b/plugins/spec-loop/skills/proposal/SKILL.md @@ -5,8 +5,8 @@ description: "提案書のループを 1 回分進める。利用者の要求確 # proposal スキル - -> **このスキルの版: 0.26.1**(プラグイン `spec-loop`)。 + +> **このスキルの版: 0.26.2**(プラグイン `spec-loop`)。 > 手元で読まれている版がリポジトリの最新より古いなら、 > `/plugin marketplace update` → `/plugin update spec-loop@claude-code-setup` の順に実行し、 > Claude Code を再起動する([#63](https://github.com/hdknr/claude-code-setup/issues/63))。 diff --git a/plugins/spec-loop/skills/req-loop/SKILL.md b/plugins/spec-loop/skills/req-loop/SKILL.md index 2537f5ab..0fc0ca97 100644 --- a/plugins/spec-loop/skills/req-loop/SKILL.md +++ b/plugins/spec-loop/skills/req-loop/SKILL.md @@ -5,8 +5,8 @@ description: "要求確定のループを 1 周(= レビュー会 1 回分) # req-loop スキル - -> **このスキルの版: 0.26.1**(プラグイン `spec-loop`)。 + +> **このスキルの版: 0.26.2**(プラグイン `spec-loop`)。 > 手元で読まれている版がリポジトリの最新より古いなら、 > `/plugin marketplace update` → `/plugin update spec-loop@claude-code-setup` の順に実行し、 > Claude Code を再起動する([#63](https://github.com/hdknr/claude-code-setup/issues/63))。 diff --git a/plugins/spec-loop/skills/scaffold/SKILL.md b/plugins/spec-loop/skills/scaffold/SKILL.md index 2204748e..5ac0694c 100644 --- a/plugins/spec-loop/skills/scaffold/SKILL.md +++ b/plugins/spec-loop/skills/scaffold/SKILL.md @@ -5,8 +5,8 @@ description: "確定した仕様を dev-loop の入力(Issue)に変える引 # scaffold スキル - -> **このスキルの版: 0.26.1**(プラグイン `spec-loop`)。 + +> **このスキルの版: 0.26.2**(プラグイン `spec-loop`)。 > 手元で読まれている版がリポジトリの最新より古いなら、 > `/plugin marketplace update` → `/plugin update spec-loop@claude-code-setup` の順に実行し、 > Claude Code を再起動する([#63](https://github.com/hdknr/claude-code-setup/issues/63))。 diff --git a/plugins/spec-loop/skills/spec-review/SKILL.md b/plugins/spec-loop/skills/spec-review/SKILL.md index 58439cb0..a2b066b3 100644 --- a/plugins/spec-loop/skills/spec-review/SKILL.md +++ b/plugins/spec-loop/skills/spec-review/SKILL.md @@ -5,8 +5,8 @@ description: "仕様レビューのループを 1 回分進める。確定した # spec-review スキル - -> **このスキルの版: 0.26.1**(プラグイン `spec-loop`)。 + +> **このスキルの版: 0.26.2**(プラグイン `spec-loop`)。 > 手元で読まれている版がリポジトリの最新より古いなら、 > `/plugin marketplace update` → `/plugin update spec-loop@claude-code-setup` の順に実行し、 > Claude Code を再起動する([#63](https://github.com/hdknr/claude-code-setup/issues/63))。 diff --git a/scripts/test-build-proposal.py b/scripts/test-build-proposal.py index b9d79e95..cd52dd6f 100644 --- a/scripts/test-build-proposal.py +++ b/scripts/test-build-proposal.py @@ -411,6 +411,10 @@ def pptx_ok(parts: dict) -> bool: lambda r: bad_out("ディレクトリ")(r) and r.output.count("前に作った出力を消した") == len(STALE) and not r.files), # 印は 1 行 1 名前で前後の空白を落とし `#` の行を飛ばすので、そう読み違える名前では作らない(#405 の 1 パス目) ("出力の名前が空白で始まると 2", SIGNED + [("out", " notes.md")], False, bad_out("空白")), + ("出力の名前が空白で終わると 2", SIGNED + [("out", "notes.md ")], False, bad_out("空白")), + # 落とすのは前後だけなので、名前の途中の空白は読み違えない——拒まずに作る(#442) + ("出力の名前の途中の空白は通る", SIGNED + [("out", "my proposal.md")], False, + lambda r: made(r) and "my proposal.md" in r.files.get(MANIFEST, b"").decode("utf-8")), ("出力の名前が改行を含むと 2", SIGNED + [("out", "x\nY.md")], False, bad_out("改行")), ("出力の名前が # で始まると 2", SIGNED + [("out", "#draft.md")], False, bad_out("`#`")), # 印を読む側は `\` を含む名前を捨て、印は UTF-8 で書く——どちらも印に残せない(#405 の 2 パス目) @@ -550,7 +554,9 @@ def pptx_ok(parts: dict) -> bool: ("ディレクトリの出力先の中を消さない", " left += remove_owned(out) # ディレクトリを", " pass # ディレクトリを", "出力先がディレクトリならその中の前の出力を消す"), ("前後に空白のある名前を見ない", " if out.name != out.name.strip() or ", " if ", "出力の名前が空白で始まると 2"), - ("改行を含む名前を見ない", "len(out.name.splitlines()) != 1 or ", "", "出力の名前が改行を含むと 2"), + ("名前の途中の空白も拒む", " if out.name != out.name.strip() or ", ' if " " in out.name or ', + "出力の名前の途中の空白は通る"), + ("改行を含む名前を見ない","len(out.name.splitlines()) != 1 or ", "", "出力の名前が改行を含むと 2"), ("# で始まる名前を見ない", ' or out.name.startswith("#"):\n', ":\n", "出力の名前が # で始まると 2"), ("親を作るのを try の外に置く", " try:\n directory.mkdir(parents=True, exist_ok=True) # 親が普通のファイルでも traceback にしない\n", From 7c81fb7e33ab99a5c8a32d1cf1cf23e4bf818937 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: Wed, 28 Oct 2026 09:48:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?issue-442:=201=20=E3=83=91=E3=82=B9?= =?UTF-8?q?=E7=9B=AE=E3=81=AE=E7=B5=90=E6=9E=9C=EF=BC=882=20=E3=83=91?= =?UTF-8?q?=E3=82=B9=E7=9B=AE=E3=81=AF=E8=A9=B2=E5=BD=93=E3=81=AA=E3=81=97?= =?UTF-8?q?=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-442.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/plans/issue-442.md b/docs/plans/issue-442.md index 3940f7a8..739280f2 100644 --- a/docs/plans/issue-442.md +++ b/docs/plans/issue-442.md @@ -22,7 +22,7 @@ 触らない: - `bad_out` の判定そのもの(Issue のとおり挙動は正しい) -- 印を読む側(`read_manifest` など) +- 印を読む側(`owned_names`。1 パス目の `/code-review` の指摘で、無い関数名 `read_manifest` を直した——計画ファイルは成果物ではない) ### 同じことを述べている箇所の数 @@ -68,12 +68,26 @@ Issue 本文は検査対象であって要件ではない。 - 直す線: `既定`(出所: cruise の確かめた線(台帳 `issue-474`)) - 実験: なし -- Verifier 1 パス目: 未 -- `/code-review` 1 パス目: 未 +- 1 パス目の指摘対応の起点: `48165d2`(1 パス目の 2 つの関門に渡した時点の HEAD) +- Verifier 1 パス目(`dev-loop:dev-loop-verifier`・sonnet): 通した。反証 0 件(軽微な点 1 件——下の表の V1) +- `/code-review` 1 パス目(high): 通した。不具合 0 件・指摘 6 件(テストの網羅と文言。下の表の CR1〜CR6) +- 手順 4 への差し戻し: なし(「直す」の行が 0 件) +- 2 パス目: 該当なし——1 パス目の指摘対応で成果物の差分 0 行。起点 `48165d2`。`git diff 48165d2 -- ':(top)' ':(top,exclude)docs/plans/issue-442.md'` が空、`git status --porcelain` は計画ファイルだけ +- 狭いパス: 該当なし +- 割り目: 不在の周なので訊いていない(`absent-lines.md` の「訊く場面」) ## 既知の限界・決着済みの論点 -(まだなし) +### 1 パス目の採否 + +| 指摘 | 実物で失敗を示せるか | 破る受入基準 | 採否 | +| --- | --- | --- | --- | +| V1 / CR6: 既存の変異の行(`改行を含む名前を見ない`)のカンマの後ろの空白が落ちた | 示せる——`git diff e361b20 -- scripts/test-build-proposal.py` の `-`/`+` 行(著者の編集で入った) | 無し(見た目だけ) | 残課題 | +| CR1: 新しい試料は印に名前が残るかだけを見て、次の実行がその名前を読み戻して前の出力を消すかは見ない(`owned_names` を空白で割る変異が残る) | 示せない(著者は走らせていない。関門の想定の変異) | 無し(I1〜I3 は読み戻しを含まない) | 残課題 | +| CR2: 「空白で終わると 2」の試料に専用の変異が無い(`strip` → `lstrip` が変異の一覧に無い) | 示せない(著者は走らせていない。関門のプローブ) | 無し(I3 は途中の空白だけ) | 残課題 | +| CR3: 変異「名前の途中の空白も拒む」は `strip` の検査も外す 2 つの変更になっている | 示せない(関門が狭い変異を手で当てて同じ試料で赤を確かめた——I3 は成り立つ) | 無し | 残課題 | +| CR4: `strip`・`splitlines` は `\x0b`・`\x1c`・`
` などにも効き、「空白」「改行」の語が覆いきらない | 示せない(著者は走らせていない。この周より前からの挙動) | 無し(I1 が見るのは「途中の空白も拒む」と読める文言) | 残課題 | +| CR5: 計画ファイルの「触らない」が無い関数名 `read_manifest` を挙げている | 示せる——`grep -n "def owned_names\|def read_manifest"` が `owned_names` だけを返す | 無し(計画ファイルは成果物ではない) | 残課題(計画ファイルの記述は直した) | ## 起票