diff --git a/skills/super-board/references/run.md b/skills/super-board/references/run.md index 81eb4bf2..d91021ad 100644 --- a/skills/super-board/references/run.md +++ b/skills/super-board/references/run.md @@ -158,7 +158,7 @@ read it — re-read, then redo the edit. Builder opens the PR with every block f | `ac` (checklist + one proof line each) | writes all unchecked | ticks with proof, or leaves unchecked with the reason | unticks one it disproved | | `history` (Lane · Done · Time · Details) | appends a row | appends a row | appends a row | | `visual` (Before \| After, UI only) | — | writes | — | -| `risk` (🟢/🟡/🔴 + one line) | writes | — | adjusts | +| `risk` (🟢/🟡/🔴 + one line, Door, Blast radius) | writes | — | adjusts | | `redcheck` (only when merged with a failing check) | — | — | writes | ```markdown @@ -202,6 +202,8 @@ read it — re-read, then redo the edit. Builder opens the PR with every block f ## Risk 🟢 **Low** · +- **Door:** · +- **Blast radius:** · ``` diff --git a/skills/super-board/references/writing-standard.md b/skills/super-board/references/writing-standard.md index 41ec2433..c9bc552d 100644 --- a/skills/super-board/references/writing-standard.md +++ b/skills/super-board/references/writing-standard.md @@ -142,12 +142,14 @@ A partial PR writes `Refs #N`, never `Closes #N`. ``` **Acceptance criteria** — a checklist, one proof line under each. Unchecked = not verified, -and the proof line says why in one line. +and the proof line says why in one line. A proof line shows before and after where it can: +the test that failed before the change and passes now, or the output that changed. UI proof +goes in Before | After. ``` ## Acceptance criteria - [x] 12 MB file shows the size message in 1 s\ - ↳ `e2e/upload-size.spec.ts:14` + ↳ `e2e/upload-size.spec.ts:14` · failed on `5a2363b`, passes on `3f9c2a1` - [x] No request over 10 MB\ ↳ spec asserts 0 calls · HAR in `runs/issue-790-qa-v2/` - [ ] No new Sentry events after deploy\ @@ -178,15 +180,20 @@ committed on the branch; raw URLs are pinned to the commit that holds them. | Mobile | | | ``` -**Risk** — level plus one line. If it merged red, name the check here too. +**Risk** — level plus one line, then Door and Blast radius. If it merged red, name the check +here too. ``` ## Risk 🟢 **Low** · limit read from one constant; no plan differences. +- **Door:** two-way · revert the PR and the old check returns +- **Blast radius:** upload form · users with files over 10 MB see a new error ``` -Levels: 🟢 Low · 🟡 Medium · 🔴 High. A `needs-you: ` line (merge gate reads it) goes -under Risk. +Levels: 🟢 Low · 🟡 Medium · 🔴 High. **Door** is two-way (a revert undoes it) or one-way +(hard to undo: DROP, rename, data rewrite, public API, sent email); a one-way door is never 🟢. +**Blast radius** is a short label (`none`, `page`, `billing`, `all users`) and one line on who +breaks. A `needs-you: ` line (merge gate reads it) goes under Risk. ## 3 · Ticket diff --git a/skills/super-build/SKILL.md b/skills/super-build/SKILL.md index 16c7f017..715f6d72 100644 --- a/skills/super-build/SKILL.md +++ b/skills/super-build/SKILL.md @@ -133,7 +133,7 @@ handoff complete. Add file summaries and critical inline notes on the PR, not in **On dispatcher exit 0 (success):** - `git -C .claude/worktrees/issue-N push -u origin loop/issue-N` -- `gh pr create --draft --base --head loop/issue-N --title " [] : " --body-file ` — title in commit-subject format, body = the marker-block template from `skills/super-board/references/run.md` (writing-standard.md § 2), `Closes #N` in the status card, `Docs:` bullets in Solution +- `gh pr create --draft --base --head loop/issue-N --title " [] : " --body-file ` — title in commit-subject format, body = the marker-block template from `skills/super-board/references/run.md` (writing-standard.md § 2), `Closes #N` in the status card, `Docs:` bullets in Solution, Door + Blast radius in Risk - `gh issue edit N --remove-label loop:in-progress` - `gh issue comment N --body "[builder] [report] ✅ built · PR "` (Next line: `qa`) - Move the project card to `QA`. The Tester and Reviewer take it from there; the issue closes when the Reviewer merges through the merge gate. @@ -243,7 +243,7 @@ Follow spec `.claude/skills/super-board/references/run.md` → Builder (first pa 3. Docs check (section below) — if the ticket touches a third-party surface, an upgrade, or auth/billing, read the current official docs first. 4. Implement smallest safe change covering ACs — under the PR size cap (section below). 5. Commit + push (always). -6. Open **draft PR** with the PR description template from `run.md` — title in commit-subject format, every marker block filled, `Docs:` bullets in Solution. +6. Open **draft PR** with the PR description template from `run.md` — title in commit-subject format, every marker block filled, `Docs:` bullets in Solution, Door + Blast radius in Risk. 7. Follow [PR author notes](../super-board/references/pr-author-notes.md), then post the `[builder] [report]` PR comment + the short issue comment with the PR URL (writing-standard.md § 4). 8. Move card Ready/Building → QA. diff --git a/skills/super-qa/references/iteration-preamble.md b/skills/super-qa/references/iteration-preamble.md index a8efc2f0..687f97ff 100644 --- a/skills/super-qa/references/iteration-preamble.md +++ b/skills/super-qa/references/iteration-preamble.md @@ -320,7 +320,8 @@ acceptable; a fix can silently disable a feature to make a wrong spec pass. (`.claude/bin/super-board-pr-body.sh --skeleton`): status card with `Closes #${ISSUE_N}`, Problem (the failing assertion / signal type, lettered steps, screenshot), Solution (plain bullets), Acceptance criteria with proof - lines, Iteration history, Risk (🟢/🟡/🔴 — subjective signals are never 🟢). + lines, Iteration history, Risk (🟢/🟡/🔴 + Door + Blast radius — subjective + signals are never 🟢). Forensics excerpts go in the proof lines, not as file lists. After opening the PR and after each later push, follow `.claude/skills/super-board/references/pr-author-notes.md`: one file-level review diff --git a/skills/super-review/SKILL.md b/skills/super-review/SKILL.md index 01c4e227..8be99776 100644 --- a/skills/super-review/SKILL.md +++ b/skills/super-review/SKILL.md @@ -315,6 +315,7 @@ See `.claude/skills/super-board/references/run.md` → Reviewer. Summary of the - Both open → bounce to whichever is older. - Clean up worktree, exit. 3. Read PR + spot-check Tester evidence + read CLAUDE.md / AGENTS.md. + Check the Risk block against the diff: is the Door right (one-way: DROP, rename, data rewrite, public API, sent email) and the Blast radius honest? Fix it with `super-board-pr-body.sh --block risk`; a one-way door is never 🟢. **3b. Prior-report check** — load `prior_report` (see "Review remembers"); if present, round 1 checks each prior finding; any `not fixed` → re-open its thread, bounce by prefix, post the report, exit. 4. Review code + tests. 5. **Reviewer-side test rerun (always — closes Tester self-verification gap):** diff --git a/tests/test_writing_format.py b/tests/test_writing_format.py index 4a171aa4..889d2a90 100644 --- a/tests/test_writing_format.py +++ b/tests/test_writing_format.py @@ -227,6 +227,17 @@ def test_pr_body_markers(): assert "## Not verified" not in run_md and "**Status:**" not in run_md +def test_risk_names_door_and_blast_radius(): + """Risk carries the merge danger: a two-way or one-way door and a blast radius.""" + run_md = (REF / "run.md").read_text(encoding="utf-8") + std_risk = next(b for b in fenced(STANDARD) if b.startswith("## Risk\n🟢")) + run_risk = run_md[run_md.index("\n## Risk"):run_md.index("")] + for name, risk in (("writing-standard.md", std_risk), ("run.md", run_risk)): + assert "**Door:**" in risk, f"{name} Risk lacks Door" + assert "**Blast radius:**" in risk, f"{name} Risk lacks Blast radius" + assert "one-way door is never 🟢" in STANDARD + + def test_status_alerts(): for alert in ("> [!NOTE]", "> [!TIP]", "> [!WARNING]"): assert alert in STANDARD, f"writing-standard.md lacks {alert}"