fix(#4130): parse phase-prefixed decision IDs (D4-01) (#4357)

* test(#4130): failing-first regression for phase-prefixed decision IDs

Add the #4130 matrix: D4-01/D12-01 across all three bullet forms, tags,
discretion, wrapped lead-ins, gate-level plan/verify end-to-end rows, and
parity properties (well-formed digit-prefixed ids parse to their exact id;
a non-digit injected into the prefix fails loud). Update the #2347
non-D-prefix fixture from D5-NN (now a legal grammar) to DEC-NN, and
graduate the representative d5-prefix corpus fixture from could-not-parse
to parsed-but-uncovered.

All new rows are RED against origin/next; they go green with the parser
fix in the next commit.

* fix(#4130): parse phase-prefixed decision IDs (D4-01)

The three declaration grammars, the parse-miss guard, the #3939 join
regexes, and the token evidence all anchored on the literal 'D-' (or
'**D-'), so an ID carrying a digit-run phase prefix between the leading
letter and the hyphen matched nothing — while the #2347 shape detector
correctly called those bullets decision-shaped, collapsing the whole
CONTEXT.md to could-not-parse with 0 extracted instead of a coverage
verdict.

Derive the extractor ID grammar from one shared DECISION_ID_SOURCE
('D[0-9]*-' + the existing alnum tail, full id captured), widen the
guard/join anchors to ID_ATTEMPT_SOURCE (bare 'D-' or a digit-initial
prefix run, so a typo'd 'D4x-01' fails loud while letter-initial prose
like 'Deferred-until' stays none-present), and align the bare-token
evidence. Both gates and the gap-checker share the parser, so all three
surfaces read phase-prefixed decisions now; the gate messages name the
accepted forms including the phase-prefixed one.

* docs(#4130): document the phase-prefixed decision identifier form

The canonical CONTEXT.md reference said decisions carry 'a sequential
D-NN identifier' with no mention of the optional phase-number prefix the
parser now accepts (D4-01) or the alphanumeric tail it always accepted
(D-INFRA-01). Name both in the Decision identifier format section, EN
and ja-JP.

* chore(#4130): changeset

* chore(#4130): backfill PR number in changeset

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-05 21:05:19 -04:00
committed by GitHub
parent 48789fe9a9
commit 06eba5fdb0
9 changed files with 480 additions and 67 deletions

View File

@@ -51,15 +51,24 @@ The body is divided into named XML-style blocks. The blocks appear in a fixed or
## Decision identifier format
Every decision in `<decisions>` carries a sequential `D-NN` identifier:
Every decision in `<decisions>` carries a sequential `D-NN` identifier. An optional
phase-number prefix may sit between the `D` and the hyphen (`D4-01`) — useful on
multi-phase projects where bare `D-01` collides across phases; the digits are read
as part of the identifier (#4130):
```markdown
### Layout style
- **D-01:** Card-based layout, not timeline or list
- **D-02:** Each card shows: author avatar, name, timestamp, full post content, reaction counts
### Phase-4 decisions
- **D4-01:** Phase-scoped identifier, distinct from any other phase's D-01
```
Identifiers are scoped to the phase. `D-01` in Phase 3 is unrelated to `D-01` in Phase 7. The plan-checker (Dimension 7) verifies that every `D-NN` is addressed by at least one task action in the generated plans.
Alphanumeric tails (`D-INFRA-01`) are also accepted. Identifiers are scoped to the
phase. `D-01` in Phase 3 is unrelated to `D-01` in Phase 7. The plan-checker
(Dimension 7) verifies that every decision identifier is addressed by at least one
task action in the generated plans.
---