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>
This commit is contained in:
Tom Boucher
2026-08-23 22:38:12 -04:00
committed by GitHub
parent 107eb8c1d9
commit cf15682d1c
74 changed files with 849 additions and 699 deletions

View File

@@ -11,6 +11,7 @@ A narrative companion guide to GSD Core — orient yourself here, then follow th
- [Slash-command forms](#slash-command-forms-hyphen-vs-colon)
- [Namespace routing primer](#namespace-routing-primer-gsd-ns--v140)
- [Reading GSD's output](#reading-gsds-output)
- [Project lifecycle overview](#project-lifecycle-overview)
- [Workflow Diagrams](#workflow-diagrams)
- [UI Design Contract](#ui-design-contract)
@@ -73,6 +74,66 @@ On the seven nesting runtimes listed above, upgrading to v1.40 changes skill inv
---
## Reading GSD's output
GSD marks its sections with Markdown, not with drawn borders. There are exactly
three forms, and every workflow, checkpoint and report uses them:
| You see | It means |
|---|---|
| `### GSD ► {STAGE NAME}` | A major workflow transition — planning, executing a wave, verifying, completing |
| `### CHECKPOINT: {Type}` | GSD is waiting on you. The bolded `**→ …**` line at the bottom tells you what to type |
| `---` | A break between two sections — most often before the **▶ Next Up** block at the end of a completion |
Panels that used to be drawn with box characters are now a heading followed by
their rows as ordinary lines. A checkpoint reads:
```
### CHECKPOINT: Verification Required
Progress: 5/8 tasks complete
Task: Responsive dashboard layout
How to verify:
1. Visit: http://localhost:3000/dashboard
---
**→ YOUR ACTION: Type "approved" or describe issues**
```
### Why there are no drawn borders
Earlier releases framed stage banners between two 53-character runs
of `━`, and checkpoints were a 62-column box drawn with `╔`, `║` and `╚`. Those
runs are ordinary text to whatever renders GSD's output. In a pane narrower than
the run, the rule wraps and the leftover glyphs land on a second line — so the
border comes apart from the heading it was framing, and the output looks broken
rather than merely narrow. Reported against the Codex desktop interface in
[#3028](https://github.com/open-gsd/gsd-core/issues/3028).
A Markdown heading and a thematic break carry the same structure without
committing to a width, so they read correctly in a narrow pane and a wide one.
This is unconditional: every runtime gets the same output. The alternative — a
capability flag that kept line-art for terminal-oriented runtimes — was weighed
and rejected, because it leaves two output conventions to keep in sync forever
for a gain that is aesthetic rather than structural. What a terminal loses is the
drawn frame; what it keeps is the title, the hierarchy and the break, none of
which depended on the frame. The reasoning is recorded in
`gsd-core/references/ui-brand.md § Why this is unconditional, not per-runtime`.
If you run GSD in a host where the heading form reads worse than the old boxes
did, that is worth reporting — it is the evidence that would justify the flag.
Single-cell tokens are unaffected and unchanged: the status symbols
(`✓ ✗ ◆ ○ ⚠`), the `GSD ►` prefix, and the ten-cell progress gauge
(`Progress: ████████░░ 80%`) are not runs and do not wrap.
The convention is specified in `gsd-core/references/ui-brand.md` and enforced
against all shipped content by `tests/responsive-separators.test.cjs`.
---
## Project lifecycle overview
The core GSD loop is: **discuss → plan → execute → verify → ship**, repeated per phase. The full step-by-step walkthrough — including example outputs, what files get created, and all the flags in play — is in the dedicated tutorial.