From f239060e87e4b167a62a68624902dab4f501dfa5 Mon Sep 17 00:00:00 2001 From: jfk Date: Thu, 4 Jun 2026 18:49:14 +0900 Subject: [PATCH 1/3] docs(spec): TDD as default implementation discipline in /start and /goal Two-layer model: orchestration chosen by size/risk; TDD (superpowers:test-driven-development) is the default discipline applied during implementation wherever there is a test surface. Reconciles the /start 17c<->18 routing mismatch and aligns /start with /goal 5b. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...4-tdd-default-discipline-routing-design.md | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md diff --git a/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md b/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md new file mode 100644 index 0000000..5075afb --- /dev/null +++ b/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md @@ -0,0 +1,88 @@ +# TDD as a default implementation discipline in `/start` and `/goal` + +**Date:** 2026-06-04 +**Status:** Approved design — ready for implementation plan +**Scope:** `commands/start.md` (steps 17b/17c/18), `commands/goal.md` (step 5b wording + cross-reference), docs (README sync) + +## Problem + +`superpowers:test-driven-development` is a **discipline skill** (an inner red→green→refactor loop applied while writing code), not an orchestration skill like `feature-dev:feature-dev`, `superpowers:writing-plans`, or `superpowers:subagent-driven-development`. Today the two are conflated in `/start`: + +- **Step 17c** prints TDD as if it were a fourth selectable tier (`(横断的) test-first where it fits ← only if detected`), alongside the orchestration tiers (Trivial / Moderate / Large). +- **Step 18** never actually routes to TDD. Its continue-target precedence (18b) resolves only to `feature-dev` (when detected) or a plan/conversational draft. The `Large → subagent` tier auto-launches **only** under `--parallel`; the `test-first → TDD` tier **never** auto-launches. + +Result: a menu that advertises four tiers but wires roughly two, and TDD — the one discipline the TDD skill says applies *always* — has no real place. Meanwhile `/goal` step 5b already treats TDD correctly ("TDD as an invariant, not a forced march"), so `/start` and `/goal` are asymmetric. + +## Goal + +Formalize a **two-layer model** and make it consistent across `/start` and `/goal`: + +- **Orchestration layer** (chosen by size/risk): direct edits / `feature-dev` / `writing-plans → subagent-driven-development`. +- **Discipline layer** (default-on): `superpowers:test-driven-development` runs *inside* the implementation of whichever orchestration is chosen, wherever the change has a test surface. + +Concretely: TDD becomes the **default implementation discipline**, not a selectable route. The only "choice" is orchestration; TDD is on by default where there is real logic to assert, and opted out only for pure docs / rename / config. + +### Non-goals (YAGNI) + +- No TDD on/off toggle UI (a toggle invites the "skip just this once" rationalization the TDD skill explicitly warns against). +- TDD is **not** promoted to a standalone mutually-exclusive route. +- The Q2 "green stops under `/goal`" harness-hardening (autonomous-flag threading) is a **separate issue**, out of scope here. + +## Design + +### Two-layer model (the invariant being encoded) + +``` +Orchestration (pick by size/risk) Discipline (default during implementation) +───────────────────────────────── ────────────────────────────────────────── +Trivial (docs / rename / config) → direct (no test surface → no TDD) +Moderate → feature-dev ┐ +Large / plan-driven → writing-plans ├─→ implement test-first via + → subagent ┘ superpowers:test-driven-development +``` + +The TDD opt-out condition is the **same** wording `/goal` 5b already uses: skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / mechanical rename / config). Never manufacture a token test to satisfy the ritual. + +### Change 1 — `/start` step 17b/17c (Suggested workflow display) + +- **17b (detection):** keep detecting the orchestration skills and `/code-review` as today. Detect `superpowers:test-driven-development` separately — it is the discipline, not a tier. +- **17c (printed workflow):** present the orchestration tiers as *the choice* (Trivial→direct / Moderate→feature-dev / Large→writing-plans→subagent), each shown only when its skill is detected (the "direct edits" tier is always shown). Then state TDD **once**, as the default discipline that applies to whichever tier touches real logic — not as a tier bullet. Show the TDD line only when `superpowers:test-driven-development` is detected. Mirror `/goal` 5b's "test surface → test-first; docs/rename/config → opt-out" language so the two commands read identically. +- The detection-gated "omit silently when not installed" rule (existing 17b behavior) still applies to every skill named, TDD included. + +### Change 2 — `/start` step 18 (continue-target action) + +- **18b (pick continue target):** unchanged in *which orchestration* it resolves to (parallel→subagent / batch→plan / feature-dev→feature-dev / else→draft). TDD is **not** added as a new continue target. +- **18e (perform the action):** the action that actually implements — launching `feature-dev`, drafting-and-implementing a plan, or direct conversational implementation — is instructed to proceed **test-first via `superpowers:test-driven-development` when the change has a test surface** (same opt-out as 17c/5b). TDD is wired as a *property of the continue action*, not a menu item. +- **Honesty fix (17c ↔ 18 mismatch):** reconcile what 17c advertises with what 18 can launch. Specifically, the `Large → subagent` tier is only auto-launched under `--parallel`; without `--parallel` the continue target falls to a plan draft. 17c's text must not imply step 18 will auto-launch a tier it cannot. Either (a) annotate the `Large` tier in 17c to note it auto-launches only with `--parallel` (otherwise step 18 drafts a plan the operator runs), or (b) equivalent wording — chosen during implementation, but the printed menu and the actual 18b behavior must agree. + +### Change 3 — `/goal` step 5b (already implemented; align + cross-reference) + +- 5b already drives TDD as an invariant. No behavior change. **Align the wording** with `/start` 17c so the opt-out condition is phrased identically, and add a one-line note that TDD is the default discipline in **both** `/start` and `/goal` (cross-reference), so a reader of either command sees the same contract. + +### Change 4 — docs + +- Sync `README.md` / `README.ja.md` where they describe the `/start` implementation-guidance / suggested-workflow step, so the documented behavior matches: orchestration is chosen by size; TDD is the default discipline. + +## Affected files + +| File | Change | +|---|---| +| `commands/start.md` | 17b detect TDD as discipline; 17c reframe tiers + TDD-as-default line; 18e make continue action test-first; reconcile 17c↔18 mismatch | +| `commands/goal.md` | 5b wording alignment + cross-reference note (no behavior change) | +| `README.md`, `README.ja.md` | sync the `/start` workflow description | +| `CHANGELOG.md` | entry under the next release | + +## Testing / verification + +This repo's "tests" are documentation-consistency checks (markdown command files, no runtime). Verification: + +- `/gh-issue-driven:doctor` still passes (no schema/flag changes introduced). +- Manual dogf-read: confirm 17c's printed tiers and 18b's actual continue-target resolution agree (no tier advertised that 18 cannot launch). +- Confirm `/start` 17c and `/goal` 5b state the same TDD opt-out condition (string-level consistency). +- Confirm the TDD line in 17c is detection-gated (absent when `superpowers:test-driven-development` is not installed). +- No config schema change → no `config.md` default additions required. + +## Risks + +- **Over-application of TDD** to changes with no real test surface. Mitigated by carrying `/goal` 5b's exact opt-out wording ("nothing to assert → skip; do not manufacture a token test"). +- **Wording drift** between `/start` and `/goal`. Mitigated by making 5b the canonical source and cross-referencing rather than duplicating divergent prose. From 634e0bda912d91d6e17d0ba174b349db69e8fbcb Mon Sep 17 00:00:00 2001 From: jfk Date: Thu, 4 Jun 2026 19:18:13 +0900 Subject: [PATCH 2/3] feat(start): wire TDD as default implementation discipline (#79) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reframe /start step 17b/17c into two orthogonal layers — orchestration (direct / feature-dev / writing-plans→subagent, chosen by size/risk) and a default-on test-first discipline (superpowers:test-driven-development) applied inside whichever orchestration runs. TDD is no longer a never-routed 4th menu tier. - 17b: split orchestration skills from the implementation discipline; the test-first default applies even when the TDD skill is not installed (only the skill's name is detection-gated, never the default). - 17c: present orchestration tiers as the choice + a test-first discipline sub-line; document the 17c<->18 contract so the menu never advertises an auto-launch step 18 cannot perform. - 18e: the one-tap continue drives implementation test-first in-line (parent adopts the TDD discipline, not a spawned process), composing inside the orchestration rather than replacing it. - goal 5b: name the two layers + cross-reference that TDD is the default in both /start and /goal (no behavior change). - README.md / README.ja.md: document the two-layer implementation handoff. Closes #79 Co-Authored-By: Claude Opus 4.8 (1M context) --- README.ja.md | 5 +++++ README.md | 5 +++++ commands/goal.md | 6 +++--- commands/start.md | 26 ++++++++++++++++++-------- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/README.ja.md b/README.ja.md index 93b3937..f46c6a3 100644 --- a/README.ja.md +++ b/README.ja.md @@ -111,6 +111,11 @@ issue 取得と recall の **後**、ブランチ作成の **前** に走りま 3. レビュアの応答末尾の `## Verdict: green|yellow|red` 行から verdict を解析する。構造化行が canonical で last-wins、case は正規化、末尾の句読点は許容。キーワードヒューリスティックは構造化行が無い場合の **fallback のみ** で、warn ログを emit して soft-deprecation の追跡が可能。 4. **green** → HITL 確認ゲート(ブランチ作成前にユーザー確認。`gate1.green_continue_requires_confirm` で設定可、デフォルト `true`) / **yellow** → ユーザー確認 / **red** → abort(`force` で override 可) +ブランチ作成後、`/start` は **suggested workflow** を表示し、ワンタップの continue を提示します。実装は **直交する2層** で構成されます: + +- **オーケストレーション** — 変更の規模/リスクで選ぶ: 直接編集(trivial / docs / rename / config)・`/feature-dev:feature-dev`(moderate)・`superpowers:writing-plans → subagent-driven-development`(large / plan-driven)。**overkill を避け**、選ぶのは最大1つ。 +- **テストファースト規律** — `superpowers:test-driven-development` は、テスト面がある変更(実ロジックを含むもの)では **デフォルト** で適用される規律。選んだオーケストレーションの **内側** で red→green→refactor を回すものであり、独立したルートでは **ない**。opt-out は純粋な docs / formatting / rename / config のみ。スキル未インストールでもデフォルトは維持(手動で test-first)。これは `/goal` step 5b と対称 — TDD は **両コマンド** でデフォルトの実装規律。ワンタップの *continue* が自動起動するのはオーケストレーション(`/feature-dev` か plan 起案)のみで、テストファースト規律はその内側で適用されます。 + ### Phase 2 — `/gh-issue-driven:ship`(Gate 2: PR 作成直前のレビューバッテリー + Copilot ループ) 実装の **後**、PR 作成の **前** に走ります。デフォルトでは **3つの advisor reviewer** が 1ターン内で並列発火 (advisor-only mode): diff --git a/README.md b/README.md index 9521337..69cc9b8 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,11 @@ Runs **after** the issue is fetched and recall is done, **before** the branch is 3. Parse the verdict from a `## Verdict: green|yellow|red` line at the end of the reviewer's response. The structured line is canonical and last-wins; case is normalized; trailing punctuation is tolerated. A keyword heuristic is the **fallback only** when no structured line is present, and emits a warn-level log so soft-deprecation can be tracked. 4. **green** → HITL confirmation gate (asks the user to confirm before creating the branch; configurable via `gate1.green_continue_requires_confirm`, default `true`). **yellow** → ask the user to confirm. **red** → abort unless `force`. +After the branch is created, `/start` prints a **suggested workflow** and offers a one-tap continue. Implementation has **two orthogonal layers**: + +- **Orchestration** — chosen by the change's size/risk: direct edits (trivial / docs / rename / config) · `/feature-dev:feature-dev` (moderate) · `superpowers:writing-plans → subagent-driven-development` (large / plan-driven). Pick at most one — **avoid overkill**. +- **Test-first discipline** — `superpowers:test-driven-development` is the **default** wherever the change has a test surface (any real logic), applied *inside* the chosen orchestration (red→green→refactor), **not** as a separate route. Opt out only for pure docs / formatting / rename / config. The default holds even when the skill isn't installed (drive it test-first manually). This mirrors `/goal` step 5b — TDD is the default implementation discipline in **both** commands. The one-tap *continue* only auto-launches an orchestration (`/feature-dev`, or a plan draft); the test-first discipline is applied within whatever it runs. + ### Phase 2 — `/gh-issue-driven:ship` (Gate 2: pre-PR review battery + Copilot loop) Runs **after** the implementation, **before** the PR is created. By default, **3 advisor reviewers** fire in parallel in a single Claude turn (advisor-only mode): diff --git a/commands/goal.md b/commands/goal.md index 003a983..d8fc13d 100644 --- a/commands/goal.md +++ b/commands/goal.md @@ -142,12 +142,12 @@ Apply the verdict policy (Autonomy model table). On `green`/`yellow` → continu #### 5b. Implement (size-aware — avoid overkill) -Choose the implementation approach by the change's size/risk, exactly as `/start` step 17b/17c describes — **avoid overkill**: -- Trivial (docs / one-liner / rename) → direct edits, no orchestration skill. +Implementation has **two orthogonal layers**, exactly as `/start` step 17b/17c describes. Choose **one orchestration** by the change's size/risk (**avoid overkill**), then apply the **test-first discipline** inside it: +- Trivial (docs / one-liner / rename / config) → direct edits, no orchestration skill. - Moderate feature → `/feature-dev:feature-dev` (if installed). - Large / plan-driven / independent sub-tasks → `/superpowers:subagent-driven-development` (or `/superpowers:executing-plans`), if installed. -**TDD as an invariant, not a forced march.** Where the change has a test surface (any real logic — not pure docs/config/rename), drive it test-first via `/superpowers:test-driven-development`: write a failing test that pins an acceptance criterion → write the minimum code to pass → refactor while green. Keep the cycle **tight** — small red→green→refactor steps, not one big test bolted on at the end. Skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / mechanical rename); do **not** manufacture a token test to satisfy the ritual, and do **not** mechanically "refactor" a diff that does not need it. The Definition of Done is green tests + green checks on the issue's acceptance criteria — not "every numbered step was performed". +**TDD as an invariant, not a forced march.** Where the change has a test surface (any real logic — not pure docs/config/rename), drive it test-first via `/superpowers:test-driven-development`: write a failing test that pins an acceptance criterion → write the minimum code to pass → refactor while green. Keep the cycle **tight** — small red→green→refactor steps, not one big test bolted on at the end. Skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / mechanical rename); do **not** manufacture a token test to satisfy the ritual, and do **not** mechanically "refactor" a diff that does not need it. The Definition of Done is green tests + green checks on the issue's acceptance criteria — not "every numbered step was performed". This test-first default is the **same contract `/start` encodes** (step 17b/17c discipline layer, applied in step 18e) — TDD is the default implementation discipline in **both** `/start` and `/goal`; the two are deliberately symmetric, and the default holds even when the TDD skill is not installed (drive it test-first manually). Run the change to green on the issue's acceptance criteria, then run the repo's relevant checks (tests, plus lint/typecheck/build scaled to what the change touches). diff --git a/commands/start.md b/commands/start.md index 04a253c..fd47baa 100644 --- a/commands/start.md +++ b/commands/start.md @@ -969,35 +969,43 @@ If `GATE1_VERDICT` is `unknown` (reviewer skills not installed), omit this sub-s Check the current conversation's system-reminder skill list for the presence of these skills. -**Implementation skills** — pick the one that fits the change's size/risk; **avoid overkill** (a trivial change needs none of these — edit directly): +Implementation has **two orthogonal layers**: pick **one orchestration** skill by the change's size/risk (**avoid overkill** — a trivial change needs none, edit directly), and apply the **test-first discipline** *inside* whichever orchestration you pick, wherever the change has a test surface. + +**Orchestration skills** (choose at most one, by scope): - `/feature-dev:feature-dev` — guided feature development for **moderate** features (7-phase: discovery → exploration → questions → architecture → implementation → quality review → summary) - `/superpowers:subagent-driven-development` — execute an implementation plan's independent tasks for **large / plan-driven** work - `/superpowers:executing-plans` — execute a written plan with review checkpoints (alternative to the above for large work) -- `/superpowers:test-driven-development` — test-first cycle, layered in wherever a test-first approach fits -`/feature-dev:feature-dev` is **not** the only implementation skill — choose by scope. +`/feature-dev:feature-dev` is **not** the only orchestration — choose by scope. + +**Implementation discipline** (default-on — a discipline, *not* a fourth orchestration tier): + +- `/superpowers:test-driven-development` — test-first red→green→refactor. This is the **default discipline** wherever the change has a test surface (any real logic), mirroring `/goal` step 5b's "TDD as an invariant, not a forced march". Opt out only for pure docs / formatting / rename / config. The test-first **default applies even when this skill is not installed** (drive it test-first manually) — the skill is just the formalized helper, so **only the skill's name is detection-gated**, never the default itself. **Review skill** (run before shipping): - `/code-review` — the Claude Code skill for reviewing the **working-tree diff** before `/ship` (no PR required yet; effort levels low/medium/high/max, `--fix`). -For each detected skill, include it in the suggested workflow below. For skills not detected, omit them silently — do not mention unavailable skills. +For each detected skill, include it in the suggested workflow below. For skills not detected, omit them silently — do not mention unavailable skills. **Exception — the test-first discipline:** the test-first sub-line in 17c is *always* shown because the default applies with or without the skill (it is a discipline, not a launchable tier); when `/superpowers:test-driven-development` is not detected, show the discipline but drop the skill name (phrase it as "drive it test-first manually") rather than omitting the line. This is the one carve-out from the "omit unavailable skills" rule. #### 17c. Print the suggested workflow ``` Suggested workflow: - 1. Implement the change on this branch — pick the approach that fits its size/risk (avoid overkill): - • Trivial (docs / one-liner / rename) → direct edits, no orchestration skill + 1. Implement the change on this branch — pick the orchestration that fits its size/risk (avoid overkill): + • Trivial (docs / one-liner / rename / config) → direct edits, no orchestration skill • Moderate feature → /feature-dev:feature-dev ← only if detected • Large / plan-driven / independent sub-tasks → /superpowers:subagent-driven-development (or /superpowers:executing-plans) ← only if detected - • (cross-cutting) test-first where it fits → /superpowers:test-driven-development ← only if detected + Discipline (runs inside whichever orchestration above — not a separate option): + • Test-first by default → write the failing test first, then the code, unless pure docs/rename/config ← drive via /superpowers:test-driven-development when detected 2. Run /code-review to review the working diff before shipping. ← only if detected 3. /gh-issue-driven:ship ← when implementation is ready ``` -Renumber the steps to be contiguous (no gaps if a skill is omitted). Step 1 ("Implement") and the final step (`/ship`) are always present regardless of skill detection. Under step 1, list only the size tiers whose skill was detected — the "direct edits" tier is always shown (it needs no skill). +Renumber the steps to be contiguous (no gaps if a skill is omitted). Step 1 ("Implement") and the final step (`/ship`) are always present regardless of skill detection. Under step 1, list only the **orchestration** tiers whose skill was detected — the "direct edits" tier is always shown (it needs no skill). The **test-first discipline sub-line is always shown** (the default applies with or without the skill); name `/superpowers:test-driven-development` only when detected, otherwise phrase it as "drive it test-first manually". The discipline applies *across* the tiers — it is **not** a fourth orchestration option. + +This is the **17c↔18 contract**: 17c is the *manual* menu (you can run any detected skill yourself). Step 18's one-tap *continue* only ever auto-launches an **orchestration** — `/feature-dev:feature-dev` (moderate) or a plan draft; the Large→subagent path auto-launches only under `--parallel` (otherwise step 18 drafts a plan you run). Step 18 never launches TDD as a standalone route — the test-first discipline is applied *within* whatever the continue action runs (see 18b/18e). So the menu never advertises an auto-launch that step 18 cannot perform. #### 17d. Respect `lang` setting @@ -1070,6 +1078,8 @@ Invoke the AskUserQuestion tool with this question and these three **fixed** opt - **Stop here** → print a one-line acknowledgement (`OK — returning to prompt. Run /gh-issue-driven:ship when implementation is ready.`) and stop. Equivalent to the legacy behavior. - **Continue (option 2)** → print a one-line acknowledgement naming the action, then immediately perform `CONTINUE_TARGET_ACTION`. For the `--parallel` case, this means invoking the `/superpowers:subagent-driven-development` skill via the Skill tool with the plan content (from step 14.5's `plan.path`) as its working input. For the `/feature-dev` case this means invoking the `/feature-dev:feature-dev` skill via the Skill tool. For the "draft a plan" case, begin a normal conversational turn that summarizes the issue, lists the gate1 key suggestions extracted in step 17a, and proposes a concrete implementation outline grounded in files you have read or will read. + + **Apply the test-first discipline within whichever orchestration runs.** Regardless of the continue target, when the change has a test surface (any real logic — not pure docs / formatting / rename / config), drive the implementation **test-first**: adopt the `/superpowers:test-driven-development` discipline **in-line** — write the failing test, watch it fail, write the minimal code to pass, refactor while green. This is the same in-line execution model as every other Skill invocation in this command (the parent adopts the role in this same conversation — it is **not** a spawned process), and it composes *inside* the orchestration rather than replacing it (e.g. `/feature-dev`'s implementation phase runs test-first; a plan draft is implemented test-first). The default holds even when `/superpowers:test-driven-development` is not installed — drive it test-first manually. Skip the discipline only for the pure docs/rename/config opt-out. - **Feedback / different direction (option 3)** → print a one-line acknowledgement that invites the operator to type their note, e.g. `Got it — what would you like to change or discuss?`. Then **stop and wait** for the operator's next message. When that next message arrives, treat it as the feedback and respond to it conversationally. Do **not** invoke any skill. Do not assume the feedback overrides gate1 — if it implies a design change large enough to invalidate gate1, say so explicitly and suggest re-running `/gh-issue-driven:start` once the new direction is settled. After step 18 completes (regardless of which branch), `/start` is done. The state file written in step 14 is the source of truth for `/ship` and `/status`; step 18's choice is **not** persisted (it only affects the in-conversation flow). From 4a058118943d58959214039909a3b9e9da08c978 Mon Sep 17 00:00:00 2001 From: jfk Date: Thu, 4 Jun 2026 19:29:14 +0900 Subject: [PATCH 3/3] fix: address Copilot review (loop 1) - Reconcile spec + AC with the implemented carve-out: the test-first discipline sub-line in 17c is always shown; only the skill NAME is detection-gated (per gate1's DX-Lead suggestion). Updates the design spec's Change 1 bullet and the verification checklist accordingly. - Normalize the TDD opt-out condition to one canonical string, 'pure docs / formatting / rename / config', across /start 17c/18e and /goal 5b (was drifting: missing 'formatting', 'mechanical rename' vs 'config' ordering). Co-Authored-By: Claude Opus 4.8 (1M context) --- commands/goal.md | 2 +- commands/start.md | 4 ++-- .../2026-06-04-tdd-default-discipline-routing-design.md | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/commands/goal.md b/commands/goal.md index d8fc13d..3efb996 100644 --- a/commands/goal.md +++ b/commands/goal.md @@ -147,7 +147,7 @@ Implementation has **two orthogonal layers**, exactly as `/start` step 17b/17c d - Moderate feature → `/feature-dev:feature-dev` (if installed). - Large / plan-driven / independent sub-tasks → `/superpowers:subagent-driven-development` (or `/superpowers:executing-plans`), if installed. -**TDD as an invariant, not a forced march.** Where the change has a test surface (any real logic — not pure docs/config/rename), drive it test-first via `/superpowers:test-driven-development`: write a failing test that pins an acceptance criterion → write the minimum code to pass → refactor while green. Keep the cycle **tight** — small red→green→refactor steps, not one big test bolted on at the end. Skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / mechanical rename); do **not** manufacture a token test to satisfy the ritual, and do **not** mechanically "refactor" a diff that does not need it. The Definition of Done is green tests + green checks on the issue's acceptance criteria — not "every numbered step was performed". This test-first default is the **same contract `/start` encodes** (step 17b/17c discipline layer, applied in step 18e) — TDD is the default implementation discipline in **both** `/start` and `/goal`; the two are deliberately symmetric, and the default holds even when the TDD skill is not installed (drive it test-first manually). +**TDD as an invariant, not a forced march.** Where the change has a test surface (any real logic — not pure docs / formatting / rename / config), drive it test-first via `/superpowers:test-driven-development`: write a failing test that pins an acceptance criterion → write the minimum code to pass → refactor while green. Keep the cycle **tight** — small red→green→refactor steps, not one big test bolted on at the end. Skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / rename / config); do **not** manufacture a token test to satisfy the ritual, and do **not** mechanically "refactor" a diff that does not need it. The Definition of Done is green tests + green checks on the issue's acceptance criteria — not "every numbered step was performed". This test-first default is the **same contract `/start` encodes** (step 17b/17c discipline layer, applied in step 18e) — TDD is the default implementation discipline in **both** `/start` and `/goal`; the two are deliberately symmetric, and the default holds even when the TDD skill is not installed (drive it test-first manually). Run the change to green on the issue's acceptance criteria, then run the repo's relevant checks (tests, plus lint/typecheck/build scaled to what the change touches). diff --git a/commands/start.md b/commands/start.md index fd47baa..94e81b3 100644 --- a/commands/start.md +++ b/commands/start.md @@ -998,7 +998,7 @@ Suggested workflow: • Moderate feature → /feature-dev:feature-dev ← only if detected • Large / plan-driven / independent sub-tasks → /superpowers:subagent-driven-development (or /superpowers:executing-plans) ← only if detected Discipline (runs inside whichever orchestration above — not a separate option): - • Test-first by default → write the failing test first, then the code, unless pure docs/rename/config ← drive via /superpowers:test-driven-development when detected + • Test-first by default → write the failing test first, then the code, unless pure docs / formatting / rename / config ← drive via /superpowers:test-driven-development when detected 2. Run /code-review to review the working diff before shipping. ← only if detected 3. /gh-issue-driven:ship ← when implementation is ready ``` @@ -1079,7 +1079,7 @@ Invoke the AskUserQuestion tool with this question and these three **fixed** opt - **Stop here** → print a one-line acknowledgement (`OK — returning to prompt. Run /gh-issue-driven:ship when implementation is ready.`) and stop. Equivalent to the legacy behavior. - **Continue (option 2)** → print a one-line acknowledgement naming the action, then immediately perform `CONTINUE_TARGET_ACTION`. For the `--parallel` case, this means invoking the `/superpowers:subagent-driven-development` skill via the Skill tool with the plan content (from step 14.5's `plan.path`) as its working input. For the `/feature-dev` case this means invoking the `/feature-dev:feature-dev` skill via the Skill tool. For the "draft a plan" case, begin a normal conversational turn that summarizes the issue, lists the gate1 key suggestions extracted in step 17a, and proposes a concrete implementation outline grounded in files you have read or will read. - **Apply the test-first discipline within whichever orchestration runs.** Regardless of the continue target, when the change has a test surface (any real logic — not pure docs / formatting / rename / config), drive the implementation **test-first**: adopt the `/superpowers:test-driven-development` discipline **in-line** — write the failing test, watch it fail, write the minimal code to pass, refactor while green. This is the same in-line execution model as every other Skill invocation in this command (the parent adopts the role in this same conversation — it is **not** a spawned process), and it composes *inside* the orchestration rather than replacing it (e.g. `/feature-dev`'s implementation phase runs test-first; a plan draft is implemented test-first). The default holds even when `/superpowers:test-driven-development` is not installed — drive it test-first manually. Skip the discipline only for the pure docs/rename/config opt-out. + **Apply the test-first discipline within whichever orchestration runs.** Regardless of the continue target, when the change has a test surface (any real logic — not pure docs / formatting / rename / config), drive the implementation **test-first**: adopt the `/superpowers:test-driven-development` discipline **in-line** — write the failing test, watch it fail, write the minimal code to pass, refactor while green. This is the same in-line execution model as every other Skill invocation in this command (the parent adopts the role in this same conversation — it is **not** a spawned process), and it composes *inside* the orchestration rather than replacing it (e.g. `/feature-dev`'s implementation phase runs test-first; a plan draft is implemented test-first). The default holds even when `/superpowers:test-driven-development` is not installed — drive it test-first manually. Skip the discipline only for the pure docs / formatting / rename / config opt-out. - **Feedback / different direction (option 3)** → print a one-line acknowledgement that invites the operator to type their note, e.g. `Got it — what would you like to change or discuss?`. Then **stop and wait** for the operator's next message. When that next message arrives, treat it as the feedback and respond to it conversationally. Do **not** invoke any skill. Do not assume the feedback overrides gate1 — if it implies a design change large enough to invalidate gate1, say so explicitly and suggest re-running `/gh-issue-driven:start` once the new direction is settled. After step 18 completes (regardless of which branch), `/start` is done. The state file written in step 14 is the source of truth for `/ship` and `/status`; step 18's choice is **not** persisted (it only affects the in-conversation flow). diff --git a/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md b/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md index 5075afb..d48dbbb 100644 --- a/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md +++ b/docs/superpowers/specs/2026-06-04-tdd-default-discipline-routing-design.md @@ -41,13 +41,13 @@ Large / plan-driven → writing-plans ├─→ implement test-fir → subagent ┘ superpowers:test-driven-development ``` -The TDD opt-out condition is the **same** wording `/goal` 5b already uses: skip the cycle only when there is genuinely nothing to assert (pure docs / formatting / mechanical rename / config). Never manufacture a token test to satisfy the ritual. +The TDD opt-out condition is one **canonical string** used verbatim in `/start` 17b/17c/18e and `/goal` 5b: skip the cycle only when there is genuinely nothing to assert — **"pure docs / formatting / rename / config"**. Never manufacture a token test to satisfy the ritual. ### Change 1 — `/start` step 17b/17c (Suggested workflow display) - **17b (detection):** keep detecting the orchestration skills and `/code-review` as today. Detect `superpowers:test-driven-development` separately — it is the discipline, not a tier. -- **17c (printed workflow):** present the orchestration tiers as *the choice* (Trivial→direct / Moderate→feature-dev / Large→writing-plans→subagent), each shown only when its skill is detected (the "direct edits" tier is always shown). Then state TDD **once**, as the default discipline that applies to whichever tier touches real logic — not as a tier bullet. Show the TDD line only when `superpowers:test-driven-development` is detected. Mirror `/goal` 5b's "test surface → test-first; docs/rename/config → opt-out" language so the two commands read identically. -- The detection-gated "omit silently when not installed" rule (existing 17b behavior) still applies to every skill named, TDD included. +- **17c (printed workflow):** present the orchestration tiers as *the choice* (Trivial→direct / Moderate→feature-dev / Large→writing-plans→subagent), each shown only when its skill is detected (the "direct edits" tier is always shown). Then state TDD **once**, as the default discipline that applies to whichever tier touches real logic — not as a tier bullet. The test-first **discipline sub-line is always shown** because the default applies with or without the skill; only the skill *name* (`superpowers:test-driven-development`) is detection-gated — when undetected, the line drops the name and reads "drive it test-first manually". Use the canonical opt-out string so `/start` 17c and `/goal` 5b read identically. +- The "omit silently when not installed" rule (existing 17b behavior) still applies to every **orchestration/review** skill named. The test-first discipline is the **one carve-out**: its sub-line is always shown (it is a discipline, not a launchable tier), and only the skill name is gated. (This refines the original AC's "TDD line is detection-gated": per gate1's DX-Lead suggestion, the test-first *default* must hold even when the skill is absent — otherwise a machine without superpowers silently loses the discipline. Only the skill *name* is gated, not the discipline line.) ### Change 2 — `/start` step 18 (continue-target action) @@ -79,7 +79,7 @@ This repo's "tests" are documentation-consistency checks (markdown command files - `/gh-issue-driven:doctor` still passes (no schema/flag changes introduced). - Manual dogf-read: confirm 17c's printed tiers and 18b's actual continue-target resolution agree (no tier advertised that 18 cannot launch). - Confirm `/start` 17c and `/goal` 5b state the same TDD opt-out condition (string-level consistency). -- Confirm the TDD line in 17c is detection-gated (absent when `superpowers:test-driven-development` is not installed). +- Confirm the test-first sub-line in 17c is **always shown**, with only the skill *name* detection-gated (the line reads "drive it test-first manually" when `superpowers:test-driven-development` is not installed). - No config schema change → no `config.md` default additions required. ## Risks