Files
msd-core/gsd-core/references/execute-mvp-tdd.md
Tom Boucher cf15682d1c enhance(#3028): responsive Markdown separators instead of fixed-width rules (#3789)
* feat(#3028): responsive Markdown separators instead of fixed-width rules

Stage banners, checkpoints, completion and error panels used fixed-width
runs of box-drawing characters -- a 53-column heavy rule and a 62-column
double-line box. Those runs are ordinary text to a Markdown-rendering
host, so in a narrower pane they wrap and the border comes apart from
the heading it framed.

Shipped content now emits an ATX heading for a titled section and a
blank-line-delimited --- for a break between sections, both of which
adapt to the available width. The same convention is applied to the
three code sites that built these strings at runtime: the UAT
checkpoint renderer, the milestone-close audit report, and the TDD
review checkpoint table.

Removing the box also removes its only reason to exist -- the
east-asian-width padding helpers that kept its right border aligned
(checkpointBoxLine, displayWidth, isWideCodePoint, ZERO_WIDTH_MARK_RE,
CHECKPOINT_BOX_WIDTH). RTL directional isolation is unchanged.

The convention is specified in gsd-core/references/ui-brand.md and
enforced across all shipped content by tests/responsive-separators.test.cjs.

Refs #3028

* test(#3028): pin the heading form in checkpoint and audit-report assertions

These suites asserted the exact box borders and the 62-column padded
banner interior. With the box gone they assert the ### heading form,
the --- break and the bolded instruction line, and each now carries a
positive assertion that no box character remains -- which is what pins
the fix rather than merely tolerating it.

Language coverage is converted, not dropped: Japanese, Chinese, Korean,
Hindi and Arabic all still assert their rendered banner, and the Arabic
case still asserts the RTL directional isolates the box removal must
not disturb. Adds a case for a banner longer than the old inner width,
which previously produced a ragged border and now has none.

Refs #3028

* chore(#3028): acknowledge execute-plan.md growth from the checkpoint display spec

The checkpoint_protocol display spec described the drawn box; it now
describes the heading, the --- break and the bolded action prompt,
which costs 22 bytes (40111 -> 40133, 827 under the cap).

Appended to the existing #3370 fragment rather than filed as a new one:
a growth ack keys on the bare filename and #3370 already declares
execute-plan.md, so a second source naming it would be a hard
duplicate-key error. Same supersede-by-append route #3370 took for the
spent #2652 fragment.

Refs #3028

* docs(#3028): state the load-bearing half of the separator rule, and amend the zh-CN reference

Review found three things.

The rule as first written demanded a blank line above AND below every
---. Only the one above is load-bearing: it is what stops CommonMark
reading the rule as a setext underline for the line above. The one below
is cosmetic, because a thematic break is a leaf block. The rule now says
that, with the reason, instead of asserting a stricter form the content
does not keep.

The zh-CN reference had received the mechanical box-to-heading swap but
none of the prose behind it: it still claimed a 62-character checkpoint
width and still listed --- among forbidden mixed banner styles, so it
contradicted the convention it was translating. It now carries the
separator section, the setext reasoning, the unconditional-vs-per-runtime
rationale and a corrected anti-pattern list, in Chinese.

The user guide asserted that a heading is not a degradation anywhere.
That is an assertion, not a demonstration. It now says what was actually
traded away in a plain terminal, points at the recorded rationale, and
invites the report that would justify the capability flag instead.

Refs #3028

* chore(#3028): backfill changeset PR number

Refs #3028

---------

Co-authored-by: sim <sim@local>
2026-08-23 22:38:12 -04:00

4.4 KiB

Execute-Phase — MVP+TDD Gate (Runtime Enforcement)

Loaded by execute-phase workflow and gsd-executor agent only when both MVP_MODE=true AND TDD_MODE=true for the phase. Defines the runtime gate that blocks behavior-adding tasks until a failing-test commit exists.

When this gate fires

  • MVP_MODE is true (resolved from CLI flag → ROADMAP **Mode:** field → config; see gsd-core/references/planner-mvp-mode.md).
  • TDD_MODE is true (resolved from --tdd flag → workflow.tdd_mode config).
  • The current task being executed has tdd="true" in its <task> frontmatter (set by the planner per Phase 1).
  • The task's <behavior> block lists at least one expected behavior.

If any of these is false, the gate is inactive — execution proceeds normally.

What the gate checks

For each task gated by MVP+TDD, the executor MUST verify (before running the implementation step):

  1. A failing-test commit exists. Search git log on the current branch for a commit matching test({phase}-{plan}) whose subject mentions the same plan as the current task. The commit must touch a test file (*.test.*, *.spec.*, tests/**).
  2. The test was actually red. The commit message body or the executor's recent shell history must show the test failed when first run. Acceptable evidence:
    • Commit message contains RED: prefix or (RED) tag
    • Recent terminal output shows FAIL or non-zero exit on the new test before any implementation commit
  3. No implementation commit yet. No feat({phase}-{plan}) commit may exist for the same plan ID before the failing-test commit.

If any check fails, the gate trips.

What "behavior-adding task" means

A task is behavior-adding when:

  • Its frontmatter has tdd="true" AND
  • Its <behavior> block names at least one user-visible outcome (not a config-only or doc-only task) AND
  • Its <files> list includes at least one source file (not exclusively docs/tests/config files such as *.md, *.json, *.test.*, *.spec.*, *.yml, *.yaml, *.toml, *.ini, .env*)

Pure documentation, configuration, or test-only tasks are skipped by this gate even when both modes are active.

What happens when the gate trips

The executor MUST:

  1. Halt before running the task's implementation step.

  2. Emit a structured halt report:

MVP+TDD GATE TRIPPED — Plan {plan_id}, Task {task_id}

Reason: {missing_red_commit | red_commit_not_failing | feat_before_test}

Behavior expected to be tested:

  • {first behavior bullet}

Required next step:

  1. Write a failing test for the behavior above.
  2. Commit it as: test({phase}-{plan}): {short description}
  3. Re-run /gsd execute-phase

3. Exit the current execution wave cleanly. Do NOT roll back any prior commits in the same wave.
4. Update `STATE.md` with `last_gate_trip: {plan_id}/{task_id}` so the user can resume after writing the test.

## Escalation: end-of-phase TDD review under MVP+TDD

The existing end-of-phase TDD review (in `workflows/execute-phase.md`'s `tdd_review_checkpoint` step) is normally **advisory** — it surfaces gate violations but does not block phase completion.

Under MVP+TDD, escalate this to **blocking**:
- If any TDD plan is missing a RED or GREEN commit, the executor MUST refuse to mark the phase complete.
- The user is shown the same review table, but the verdict line reads:
> "Phase blocked: {N} TDD plan(s) violate the RED→GREEN gate sequence under MVP+TDD. Resolve and re-run /gsd execute-phase, or override with `/gsd execute-phase {phase} --force-mvp-gate` to ship anyway."

The `--force-mvp-gate` flag is documented but not introduced by this plan — it is the escape hatch the spec mentions; if the user later builds it, the workflow already references the contract.

## What this gate does NOT do

- It does not enforce REFACTOR commits. REFACTOR remains optional (per `gsd-core/references/tdd.md`).
- It does not check test quality (the test could be trivially passing). That's the planner's job.
- It does not run tests. The executor only inspects git log + file system. Running tests is the implementation step's job.
- It does not gate config-only or doc-only tasks (see "behavior-adding task" definition).

## Compatibility with existing TDD discipline

This gate is additive to `gsd-core/references/tdd.md`. Tasks not under MVP+TDD continue to use the existing advisory TDD discipline (RED/GREEN/REFACTOR commits with end-of-phase review checkpoint). Only the runtime gate and the blocking escalation are new.