From 0271ad6b45000fc5fd39f48343b20db0b49100bf Mon Sep 17 00:00:00 2001 From: Adrian Theopold <83468052+AdrianTheopold@users.noreply.github.com> Date: Tue, 4 Aug 2026 06:46:22 +0000 Subject: [PATCH] fix(bridge): give plan.md a reader, and close six more one-instance-named gaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up audit of 1.2.0 for the defect shape that produced the plan.md bug: an instruction naming ONE instance where it means a CLASS, so the rule is honored for the thing it names and silently ignored for its siblings. Seven findings, all verified on disk. The 1.2.0 fix was itself incomplete, in exactly this shape — it amended one of the two places the §7 rule lives: - templates/verify.md carried the same unqualified "blank = PASS" sentence that schema.yaml was corrected to qualify. The template is what the verifier writes into, so the schema's caveat was defeated by its own template. Now qualified in both. - 1.2.0 added prose, not a reader. Nothing mechanically detected an unmaintained plan.md, so the new caveat was unenforced: PRECHECK grepped tasks.md alone. A ledger nobody reads is a ledger nobody maintains — that is why plan.md rotted while tasks.md never did. PRECHECK gains command 3 over plan.md (`[x]` or `[~]`, so an all-deferred plan still passes), and verify §2 now reports both files separately, because a ticked tasks.md beside an empty plan.md is the signature of a bookkeeping miss rather than unfinished work. Retroactively tested: command 3 returns 20 on a maintained plan.md, and 0 on both known instances of the bug — the pristine template and the 2026-07-02 correctness-pass plan, whose 53 boxes were never ticked while its work shipped. Also fixed, same shape: - The front-door leak detector watched `docs/superpowers/specs/` while the schema redirects `docs/superpowers/plans/` too, and both READMEs and both adopter fragments list both paths as leaks. A plans/ leak was invisible; observed live in a real cycle, where §6 reported one of the two files present. Both paths now checked (schema + template + prose). - The `` substitution note sat on the verify PRECHECK only, while the retrospective PRECHECK has identical literal placeholders — an agent runs `test -f ...//verify.md`, fails, and STOPs a passing cycle. Note added there. - retrospective §4's skill table omitted `openspec-verify-change`, the one skill with a documented manual fallback, so the skipped-skill discipline could never fire for the skip most likely to happen. Added to the table, and to apply step 0 as a WARNING (not a STOP, since the fallback exists). - Both READMEs still quoted the pre-fix indent-blind `grep -c '^- \[x\]'`, and now also carry the plan.md gate. - Both READMEs cited schema.yaml by line number (35-39 / 180-182; actual 38-41 / 181-183). Replaced with named blocks — line numbers are the same rot in miniature. VERSION 1.2.0 → 1.3.0 (new mechanical gate). Validated: `openspec schema validate superpowers-bridge` passes. Co-Authored-By: Claude Opus 5 (1M context) --- superpowers-bridge/README.md | 8 +-- superpowers-bridge/README.zh-TW.md | 8 +-- superpowers-bridge/VERSION | 2 +- superpowers-bridge/schema.yaml | 59 ++++++++++++++----- superpowers-bridge/templates/retrospective.md | 1 + superpowers-bridge/templates/verify.md | 24 ++++++-- 6 files changed, 73 insertions(+), 29 deletions(-) diff --git a/superpowers-bridge/README.md b/superpowers-bridge/README.md index f28c8a9..c4f154e 100644 --- a/superpowers-bridge/README.md +++ b/superpowers-bridge/README.md @@ -187,8 +187,8 @@ If any condition is missing, keep brainstorming. When all five hold: | Anti-pattern | Why it's wrong | |---|---| -| Letting brainstorming write to `docs/superpowers/specs/` after the schema is installed | Bypasses redirection at [schema.yaml](./schema.yaml) lines 35-39; produces orphan artifacts | -| Letting writing-plans write to `docs/superpowers/plans/` | Same reason (schema.yaml lines 180-182) | +| Letting brainstorming write to `docs/superpowers/specs/` after the schema is installed | Bypasses the `IMPORTANT output redirection` block in the **brainstorm** artifact's instruction ([schema.yaml](./schema.yaml)); produces orphan artifacts. Verify §6 detects it. | +| Letting writing-plans write to `docs/superpowers/plans/` | Same reason — the equivalent block in the **plan** artifact's instruction. Verify §6 detects it. | | Promoting to opsx with unresolved blocking TBDs | Those TBDs will block apply phase too — promotion just defers the same problem | | Opening a change for bug fix / typo / config tweak | Process ceremony exceeds actual risk; slows delivery without value | @@ -454,7 +454,7 @@ This schema requires a subagent-capable platform (Claude Code, Codex, etc.). The Each timing-sensitive artifact runs concrete shell evidence checks at the start of its instruction: -- **verify**: `git log ..HEAD | wc -l > 0` AND `grep -c '^- \[x\]' tasks.md > 0` +- **verify**: `git log ..HEAD | wc -l > 0` AND `grep -cE '^\s*- \[x\]' tasks.md > 0` AND `grep -cE '^\s*- \[[x~]\]' plan.md > 0` - **retrospective**: `test -f verify.md` AND `! grep -q '^- \[x\] ❌ FAIL' verify.md` The LLM does not need to interpret timing prose — it runs commands and reads results. This is layer 2 of concern #1 / mitigation for concern #2. @@ -482,7 +482,7 @@ A bundle release `1.x.y` is a published cut of schema major `v1`. A future schem Baseline versions this schema was authored against. This is a **historical snapshot, not an end-to-end compatibility guarantee** — CI cannot run the full prompt-layer workflow in headless mode, so behavioral compatibility relies on human review when drift fires. -Current bundle release: **`1.2.0`** (see [VERSION](./VERSION)). +Current bundle release: **`1.3.0`** (see [VERSION](./VERSION)). | superpowers-bridge | OpenSpec CLI | Superpowers plugin | Baseline as of | |---|---|---|---| diff --git a/superpowers-bridge/README.zh-TW.md b/superpowers-bridge/README.zh-TW.md index adf2b70..5cc39a7 100644 --- a/superpowers-bridge/README.zh-TW.md +++ b/superpowers-bridge/README.zh-TW.md @@ -187,8 +187,8 @@ OpenSpec 管 **「做什麼」**(artifact 生命週期:proposal / specs / tasks | 反模式 | 為什麼錯 | |---|---| -| schema 已安裝後仍讓 brainstorming 寫到 `docs/superpowers/specs/` | 繞過 [schema.yaml](./schema.yaml) line 35-39 的 redirection,留下 orphan artifact | -| 讓 writing-plans 寫到 `docs/superpowers/plans/` | 同理(schema.yaml line 180-182) | +| schema 已安裝後仍讓 brainstorming 寫到 `docs/superpowers/specs/` | 繞過 [schema.yaml](./schema.yaml) 中 **brainstorm** artifact instruction 的 `IMPORTANT output redirection` 段,留下 orphan artifact。verify §6 會偵測到 | +| 讓 writing-plans 寫到 `docs/superpowers/plans/` | 同理 —— 對應的是 **plan** artifact instruction 裡的同一段。verify §6 會偵測到 | | TBD 還沒收斂就升級到 opsx | 那些 TBD 在 apply phase 一樣會擋住進度,只是把問題往後挪 | | 對 bug fix / typo 也建 change | 流程儀式 > 實質風險,反而拖慢交付 | @@ -454,7 +454,7 @@ TDD 與 code-review 平常藏在 `subagent-driven-development` 的 SKILL.md 裡 時序敏感的 artifact 在 instruction 開頭跑具體 shell 證據檢查: -- **verify**:`git log ..HEAD | wc -l > 0` 且 `grep -c '^- \[x\]' tasks.md > 0` +- **verify**:`git log ..HEAD | wc -l > 0` 且 `grep -cE '^\s*- \[x\]' tasks.md > 0` 且 `grep -cE '^\s*- \[[x~]\]' plan.md > 0` - **retrospective**:`test -f verify.md` 且 `! grep -q '^- \[x\] ❌ FAIL' verify.md` LLM 不必解讀 timing 文字 —— 跑指令、看結果即可。這是顧慮 #1 第 2 層,以及顧慮 #2 的緩解。 @@ -482,7 +482,7 @@ LLM 不必解讀 timing 文字 —— 跑指令、看結果即可。這是顧慮 本 schema 撰寫時所對齊的 upstream 基準版本。這是**歷史快照,不是端對端相容性承諾** — CI 無法在 headless 環境跑完整的 prompt-layer workflow,行為相容性依賴 drift 觸發人類檢核。 -目前 bundle release: **`1.2.0`**(見 [VERSION](./VERSION))。 +目前 bundle release: **`1.3.0`**(見 [VERSION](./VERSION))。 | superpowers-bridge | OpenSpec CLI | Superpowers plugin | 基準日期 | |---|---|---|---| diff --git a/superpowers-bridge/VERSION b/superpowers-bridge/VERSION index 26aaba0..f0bb29e 100644 --- a/superpowers-bridge/VERSION +++ b/superpowers-bridge/VERSION @@ -1 +1 @@ -1.2.0 +1.3.0 diff --git a/superpowers-bridge/schema.yaml b/superpowers-bridge/schema.yaml index eaf2881..82c26d9 100644 --- a/superpowers-bridge/schema.yaml +++ b/superpowers-bridge/schema.yaml @@ -215,10 +215,20 @@ artifacts: 2. Task progress (must return > 0): grep -cE '^\s*- \[x\]' openspec/changes//tasks.md - (This returns 0 only if the apply executor failed to tick - tasks.md as tasks cleared — see apply step 2's ticking rule; - a 0 here on a genuinely-complete apply is a bookkeeping miss, - not incomplete work. Tick the boxes, then re-run.) + + 3. Step progress (must return > 0): + grep -cE '^\s*- \[[x~]\]' openspec/changes//plan.md + + A 0 from either means the apply executor failed to maintain that + ledger as tasks cleared — see apply step 2's ticking rule. On a + genuinely-complete apply, a 0 is a bookkeeping miss, not + incomplete work: tick the boxes, then re-run. Both files are + gated because a rule that names one of them gets followed for + that one and missed for the other, and an unmaintained plan.md + silently disarms check 7 below (it counts `[~]` rows that were + never written). Command 3 accepts `[x]` or `[~]`, so a plan whose + steps were all deferred still passes — deferral is a recorded + outcome, not a missing one. Only after BOTH return positive numbers, proceed to invoke the verification skill below. @@ -240,10 +250,15 @@ artifacts: `"valid": true`. If any item fails, record the issues and return to fix the underlying artifact before proceeding. - 2. **Task completion**: Confirm every checkbox in tasks.md is - `- [x]`. For any `- [ ]` remaining, document the reason - (e.g. manual / out-of-scope / blocked) and whether it blocks - archive. + 2. **Task completion**: Confirm every checkbox in BOTH committed + ledgers — tasks.md and plan.md — is `- [x]` (or `- [~]` for a + deliberately deferred plan.md step). For any `- [ ]` + remaining in either file, document the reason (e.g. manual / + out-of-scope / blocked) and whether it blocks archive. Report + the two files separately: an all-unchecked plan.md beside a + fully-ticked tasks.md is the signature of a bookkeeping miss + rather than unfinished work, and it means check 7's `[~]` + count cannot be trusted. 3. **Delta spec sync state**: For each directory under `openspec/changes//specs/`, compare against the @@ -263,13 +278,17 @@ artifacts: 6. **Front-door routing leak detector** (warning, non-blocking): - For projects using superpowers-bridge, design output - should never land in `docs/superpowers/specs/` — the - brainstorm artifact's output redirection (see this - schema's brainstorm.instruction) routes it to - `openspec/changes//brainstorm.md`. Run: + For projects using superpowers-bridge, neither design nor + plan output should land under `docs/superpowers/` — the + brainstorm artifact's output redirection (see this schema's + brainstorm.instruction) routes design output to + `openspec/changes//brainstorm.md`, and the plan + artifact's redirection routes the plan to + `openspec/changes//plan.md`. Check BOTH redirected + paths: a detector watching only one reports clean while the + other leaks. Run: - ls docs/superpowers/specs/*.md 2>/dev/null + ls docs/superpowers/specs/*.md docs/superpowers/plans/*.md 2>/dev/null If any files exist, record a WARNING: "Front-door routing leak — design output found at docs/superpowers/specs/...; @@ -330,6 +349,10 @@ artifacts: Before producing retrospective.md, run these commands. If either fails, STOP and tell the user verify must pass first. + (Substitute in the commands below with this + change's directory name before running them — pasted verbatim + they match nothing and the PRECHECK fails on a passing cycle.) + 1. verify.md exists: test -f openspec/changes//verify.md @@ -506,6 +529,14 @@ apply: or explicitly opt into the manual fallback path described at the end of this instruction. + One further skill is consumed later in this phase and is NOT a + STOP: `openspec-verify-change` at step 3, which has a documented + manual fallback (run verify's numbered checks by hand). Note its + absence as a WARNING at apply start rather than discovering it at + step 3, and record the fallback in the retrospective's + skipped-skill section — it is listed in that table precisely + because it is the skip most likely to actually happen. + Additionally, confirm the project's expected CLI tools are on PATH. The exact list depends on the project — read plan.md and surface any tool mentioned (e.g., `mvn`/`mvnw`, diff --git a/superpowers-bridge/templates/retrospective.md b/superpowers-bridge/templates/retrospective.md index 6cadabc..ecc504d 100644 --- a/superpowers-bridge/templates/retrospective.md +++ b/superpowers-bridge/templates/retrospective.md @@ -60,6 +60,7 @@ Commit chain (chronological): | superpowers:subagent-driven-development | | | (transitive) superpowers:test-driven-development | | | (transitive) superpowers:requesting-code-review | | +| openspec-verify-change | | | superpowers:finishing-a-development-branch | | > **Default expectation**: all ✓. Every skill is part of the schema's design; diff --git a/superpowers-bridge/templates/verify.md b/superpowers-bridge/templates/verify.md index d359988..62306c5 100644 --- a/superpowers-bridge/templates/verify.md +++ b/superpowers-bridge/templates/verify.md @@ -29,9 +29,14 @@ If any items fail, list id + issues: --- -## 2. Task Completion (`tasks.md`) +## 2. Task Completion (`tasks.md` + `plan.md`) -- [ ] All `- [ ]` have become `- [x]` +- [ ] `tasks.md` — all `- [ ]` have become `- [x]` +- [ ] `plan.md` — all step boxes are `- [x]`, or `- [~]` where deliberately deferred + +> Report the two separately. An all-unchecked `plan.md` beside a fully-ticked `tasks.md` is the +> signature of a bookkeeping miss rather than unfinished work — and it makes §7's `[~]` count +> meaningless, since the rows it reads were never written. **Incomplete tasks** (if any): @@ -78,14 +83,16 @@ and Scenarios of `specs/*.md`: ## 6. Front-Door Routing Leak Detector (warning, non-blocking) -Design output should not land in `docs/superpowers/specs/` (the brainstorm -artifact's output redirection routes it to -`openspec/changes//brainstorm.md`). +Neither design nor plan output should land under `docs/superpowers/` — the brainstorm artifact's +output redirection routes design output to `openspec/changes//brainstorm.md`, and the plan +artifact's routes the plan to `openspec/changes//plan.md`. Both directories are checked, +because a detector watching only one of the two redirected paths reports clean while the other +leaks. Detection: ```bash -ls docs/superpowers/specs/*.md 2>/dev/null +ls docs/superpowers/specs/*.md docs/superpowers/plans/*.md 2>/dev/null ``` - [ ] No files, or any present are legitimate pre-schema-install holdovers @@ -121,6 +128,11 @@ it in the retrospective's Misses. > **When this section may be left blank**: if plan.md has no `[~]`-marked rows at all, this section need not be filled (blank = PASS). > As soon as plan.md contains any `[~]`, this section must enumerate each one, otherwise the Overall Decision should be downgraded to FAIL. +> +> **But first confirm plan.md was maintained** (§2). A blank §7 means "nothing was deferred" only +> if the step ledger reflects the work. An all-unchecked plan.md means nobody maintained it, so the +> absence of `[~]` rows says nothing about whether steps were deferred — reconstruct the deferral +> state from the SDD ledger and the commits, tick plan.md to match, and re-run verify. ---