create-anpunkit 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,21 @@
1
1
  {
2
- "version": "2.1.0",
2
+ "version": "2.2.0",
3
3
  "files": [
4
4
  {
5
5
  "path": "AGENTS.md",
6
- "sha256": "e33c8290f6a5aa15a744721d435944d49552b08428c91f83be4cf02b2a4fbda4"
6
+ "sha256": "0e4bdc92e8e33355fdfca8d7c3f644bd5f6b91d8b11b1837c65241c25a8dd695"
7
7
  },
8
8
  {
9
9
  "path": "CLAUDE.md",
10
- "sha256": "e9d84381044c68d1b7289708de20bc6d2202eca3f39a2f63e7824a36fa18e299"
10
+ "sha256": "132e64b4a9a5a178deb4db810324f79338c2af65d598fd5e26f183225c2a4d98"
11
11
  },
12
12
  {
13
13
  "path": "README.md",
14
- "sha256": "bd33dd8be4b1b20ab4ea9444f60094a8ee125681e6f1073e3ed7f06c1f5a5f4c"
14
+ "sha256": "ca353eea88978b65dab78355ec304de0b8fb5d8ecb54d4316ee493de4459f002"
15
15
  },
16
16
  {
17
17
  "path": ".gitattributes",
18
- "sha256": "51ca20efd556b51644b3fd938cd07ff86a17170edd09f7c9caf718911a56b0a2"
18
+ "sha256": "5362db7bc5f0639f80bb191f5d6436a2c54b1ca8a398362fba14136eca4014bf"
19
19
  },
20
20
  {
21
21
  "path": "setup.sh",
@@ -27,19 +27,23 @@
27
27
  },
28
28
  {
29
29
  "path": ".claude/agents/e2e-runner.md",
30
- "sha256": "4e914d20022be58f3915526f91ac6df54cb5efd4836c12b97fd042cce90e8ddc"
30
+ "sha256": "c454ad3217d6adc21e0e6cda5746e3094ea299cd7e71f761e1f417a7d6a2391e"
31
31
  },
32
32
  {
33
33
  "path": ".claude/agents/implementer.md",
34
- "sha256": "9c2d5e166bac94bfff31a775766094a4275c5a8d1da9bae7823e824f5c307fe6"
34
+ "sha256": "e6598fdb77657616f821695323653cfdded44db85a428597d1c8074a56bbf816"
35
35
  },
36
36
  {
37
37
  "path": ".claude/agents/infra-provisioner.md",
38
38
  "sha256": "52a54a2aaaf7e53d28e261f5e01f2693fd0a4883fd93f844a112a742a91f9149"
39
39
  },
40
+ {
41
+ "path": ".claude/agents/spec-author.md",
42
+ "sha256": "3e352514bfd5eb32f966cfa12014d706d17b3a12ad2155e2f826243c03fb7d0c"
43
+ },
40
44
  {
41
45
  "path": ".claude/agents/planner.md",
42
- "sha256": "b74951f53ddfebba5d2255d164ef4b1b6fa8544f3e8d9ae3ff7d23e2f3198650"
46
+ "sha256": "a1a2b86aa5a88d8b9fee9af3a8d10c7f1f09e5a2fb32f831dce38b010c507771"
43
47
  },
44
48
  {
45
49
  "path": ".claude/agents/researcher.md",
@@ -51,7 +55,7 @@
51
55
  },
52
56
  {
53
57
  "path": ".claude/agents/test-author.md",
54
- "sha256": "d8ccd98ced9a77c7da6c40c12b7b3108f302f4cc5956ea8b516f6384203c9c13"
58
+ "sha256": "adc53adb326424dcb215a5f074c7df3dfcb6644f2c63ce1e9ed68d2810dc8398"
55
59
  },
56
60
  {
57
61
  "path": ".claude/hooks/cursor-session-start.sh",
@@ -95,11 +99,11 @@
95
99
  },
96
100
  {
97
101
  "path": "commands.src/overview.md",
98
- "sha256": "841dad7d2765f4240900d18cd57a6c5a4cbc6c1f19f0568f5e14d4e098f60ab8"
102
+ "sha256": "85a300dcdd94d95c87c25c84d06619a38b5b3679631f68b511da11d7010e5cb8"
99
103
  },
100
104
  {
101
105
  "path": "commands.src/phase.md",
102
- "sha256": "de910c499acf6f3d27353b2594a4ff8d7b650ee90b35ceb8dabf1e3244f4851b"
106
+ "sha256": "60a0e6442c2a3945afc4aec991cd44d48705eb8c142f3c2284db7095bb5441d9"
103
107
  },
104
108
  {
105
109
  "path": "commands.src/quick.md",
@@ -135,11 +139,11 @@
135
139
  },
136
140
  {
137
141
  "path": ".claude/commands/overview.md",
138
- "sha256": "841dad7d2765f4240900d18cd57a6c5a4cbc6c1f19f0568f5e14d4e098f60ab8"
142
+ "sha256": "85a300dcdd94d95c87c25c84d06619a38b5b3679631f68b511da11d7010e5cb8"
139
143
  },
140
144
  {
141
145
  "path": ".claude/commands/phase.md",
142
- "sha256": "de910c499acf6f3d27353b2594a4ff8d7b650ee90b35ceb8dabf1e3244f4851b"
146
+ "sha256": "60a0e6442c2a3945afc4aec991cd44d48705eb8c142f3c2284db7095bb5441d9"
143
147
  },
144
148
  {
145
149
  "path": ".claude/commands/quick.md",
@@ -175,11 +179,11 @@
175
179
  },
176
180
  {
177
181
  "path": ".cursor/commands/overview.md",
178
- "sha256": "8cd54af27fa63ccfa714c7ecfa48476664fa3407b46cb708ddbc4ad2ebbb0a58"
182
+ "sha256": "9ee65f44d44362aaa37e5df7ed95eb7d386cec6e2045a2f87a81b80da343ac00"
179
183
  },
180
184
  {
181
185
  "path": ".cursor/commands/phase.md",
182
- "sha256": "693e4edca20374441c876ac58994863949fb8f364e72e8a0dc32670d4550fc69"
186
+ "sha256": "5a2bac0d8dc36892256e49ddfd6bccac36e1d71dbc4cc0602ac337e398a0733e"
183
187
  },
184
188
  {
185
189
  "path": ".cursor/commands/quick.md",
@@ -229,17 +233,33 @@
229
233
  "path": "scripts/regression.sh",
230
234
  "sha256": "711bf59c9a1aa66846e1efd4a2127476edd8d92010207807e11e4080d430006e"
231
235
  },
236
+ {
237
+ "path": "scripts/spec-staleness.sh",
238
+ "sha256": "1a2b2cad55ba0500c84ce8c2e582ccc4b735bb2fc7d7152969e37c6653297de4"
239
+ },
240
+ {
241
+ "path": "scripts/spec-conformance.sh",
242
+ "sha256": "932be0e02c47dba0d56bc3600cc8ad80031e54a13e65ba4e474fd957bab9f9fa"
243
+ },
244
+ {
245
+ "path": "tests/helpers/spec-assert.py",
246
+ "sha256": "dd63f979cecdfa54e808ace01da038f44acb3a29ea65c928bf0458fd2d44c8d8"
247
+ },
248
+ {
249
+ "path": "tests/helpers/spec-assert.ts",
250
+ "sha256": "feda86755bb58af7f75323e182136eb4e5d43e813358ed1a3d712bbc4e069069"
251
+ },
232
252
  {
233
253
  "path": "create-anpunkit/package.json",
234
- "sha256": "4b16cdfd4d9a22379147338664530fd7ce7f0e7566bf63d097f7b8f8f76dcdd8"
254
+ "sha256": "e283531b788e94cf9ca604a119e9d581e9cede3e1276770087f2c4874927e567"
235
255
  },
236
256
  {
237
257
  "path": "create-anpunkit/bin/cli.js",
238
- "sha256": "129dae04923b6d380d3ca4601b5dcd2baa6ad4c51c827dddae3e43ea6a9c50e2"
258
+ "sha256": "f96460757110e6a0f81cef750c5b39442ea5589f53ae83b69951555632cce7ec"
239
259
  },
240
260
  {
241
261
  "path": "create-anpunkit/build.sh",
242
- "sha256": "01fb6d1bb8866db54b0942d341b43e3f0ef96b97f7904909d77393fec49dbb58"
262
+ "sha256": "3a5062e46ba09ff23736de08545cefd1c0f30b216c3820bd2ada22e3d0db5b79"
243
263
  },
244
264
  {
245
265
  "path": "create-anpunkit/README.md",
@@ -119,6 +119,18 @@ Store the round-1 answers as working context — do NOT write OVERVIEW.md yet.
119
119
  interactive element the phase introduces (not "page renders 200").
120
120
  - Map each phase to the DATAFLOW transitions it is expected to make reachable.
121
121
 
122
+ The planner ALSO writes the up-front SKELETON spec files (v2.2, §5.44/§5.51):
123
+ one `docs/spec-phase-<n>.md` per public-surface phase (skip Phase 0 + pure
124
+ infra/config/doc phases), enumerating the case NAMES — happy path, each named
125
+ edge, each named failure + error code — for every `dataflow:` transition and
126
+ every `acceptance` criterion, with `TBD` values. The generated header transcludes
127
+ that phase's `acceptance:` line + in-scope `DATAFLOW.md` transition rows verbatim.
128
+
129
+ 8b. STAMP each skeleton's staleness hash: for every `docs/spec-phase-<n>.md` the
130
+ planner wrote, run `bash scripts/spec-staleness.sh stamp <n>`. This embeds the
131
+ hash of the transcluded acceptance line + transition rows so phase-time
132
+ `/phase` can detect upstream drift. (Values are filled per phase by `spec-author`.)
133
+
122
134
  9. Create docs/STATE.md:
123
135
  ```
124
136
 
@@ -144,6 +156,11 @@ blocker: none
144
156
  ```
145
157
 
146
158
  Then stop and show me PLAN.md + DATAFLOW.md for approval before any phase starts.
159
+ EXTEND the approval surface (v2.2, §5.51 — one confirmation, no new gate): for each
160
+ public-surface phase, list the transition/acceptance ids it covers and the enumerated
161
+ case NAMES (no values). I confirm the case-name set is COMPLETE here — these names
162
+ are the up-front behavioral contract; values get filled + reviewed per phase at
163
+ `/phase` SPEC REVIEW.
147
164
 
148
165
  Remind me: "Run `/infra` next to provision the Azure environment (Phase 0) and
149
166
  run the one-time AUTH PROOF before starting Phase 1."
@@ -1,10 +1,10 @@
1
1
  ---
2
- description: Run one phase end-to-end. TDD phases run SCAFFOLD -> RED -> TEST REVIEW -> GREEN; non-TDD phases run IMPLEMENT -> TEST. Both with the debug circuit breaker and the regression + dataflow + evidence guards at CLOSE.
2
+ description: Run one phase end-to-end. TDD phases run SPEC fill -> SPEC REVIEW -> SCAFFOLD -> RED -> conformance -> GREEN -> boundary/E2E; non-TDD phases run IMPLEMENT -> TEST. Both with the debug circuit breaker and the regression + dataflow + evidence guards at CLOSE.
3
3
  argument-hint: [phase number]
4
4
  ---
5
5
 
6
6
  Caveman ULTRA mode. You are the ORCHESTRATOR. Route work to subagents —
7
- you do NOT implement or debug yourself.
7
+ you do NOT implement, fill specs, or debug yourself.
8
8
 
9
9
  Note: subagents cannot talk to the user. Only YOU can.
10
10
 
@@ -29,20 +29,21 @@ b. PHASE STATE CHECK: Read docs/STATE.md and docs/PLAN.md.
29
29
  c. FINAL PHASE CHECK: Read docs/PLAN.md. Is this the last phase (no further
30
30
  pending phases after this one)? Record this as IS_FINAL_PHASE=true/false.
31
31
 
32
- d. AUTH LIVENESS GATE (hard rule 16 replaces the old soft nudge): if this phase
33
- will run a real/E2E suite, confirm every credential it needs is live NOW.
32
+ d. AUTH LIVENESS GATE (hard rule 16): if this phase will run a boundary/E2E suite,
33
+ confirm every credential it needs is live NOW.
34
34
  - If INFRA.md has no `AUTH PROOF: PASS` marker -> STOP: "Auth never proven
35
35
  reusable. Run `/infra` first."
36
36
  - Run `scripts/auth-setup.sh --check` (Entra token obtainable + not expired)
37
37
  and, for each external system this phase touches (docs/DATAFLOW.md external
38
38
  rows + docs/ENDPOINTS.md auth column), confirm its credential is obtainable
39
- headlessly. Any failure -> real/E2E is BLOCKED; tell me what to run; the
39
+ headlessly. Any failure -> boundary/E2E is BLOCKED; tell me what to run; the
40
40
  MOCK suite may still proceed.
41
41
 
42
42
  e. FRONTEND TRIGGER (hard rule 13): read docs/OVERVIEW.md `has_frontend` + the
43
43
  frontend root. Set FRONTEND_PHASE=true iff `has_frontend: true` AND this
44
44
  phase's `changes` (docs/PLAN.md) include any path under the frontend root.
45
- This is a PATH MATCH, not a judgment call. Record FRONTEND_PHASE for the GATE.
45
+ This is a PATH MATCH, not a judgment call. Record FRONTEND_PHASE it gates the
46
+ `ui` boundary run + evidence at CLOSE.
46
47
 
47
48
  ---
48
49
 
@@ -57,8 +58,9 @@ datasource, compare what it touches to the confirmed BASELINE in
57
58
  docs/research/datasource-<name>.md. If it touches a NEW table/column beyond the
58
59
  baseline -> surface my understanding of just that delta as a falsifiable claim;
59
60
  WAIT for confirm; append it to datasource-<name>.md. If it touches only confirmed
60
- data -> proceed with a one-line note, no stop. Real/E2E against an UNCONFIRMED
61
- datasource is HARD-BLOCKED (mock still runs).
61
+ data -> proceed with a one-line note, no stop. Boundary/E2E against an UNCONFIRMED
62
+ datasource is HARD-BLOCKED (mock still runs). The confirmed baseline is what
63
+ `spec-author` grounds fixtures in.
62
64
 
63
65
  Then classify the phase:
64
66
 
@@ -66,63 +68,105 @@ Then classify the phase:
66
68
  exported function/class, CLI command, message contract) assertable from the
67
69
  acceptance spec. Size is NOT the criterion.
68
70
 
69
- - Clear public surface -> `TDD_PHASE=true` -> run the TDD path (§2 → §3a → §3r → §3b).
71
+ - Clear public surface -> `TDD_PHASE=true` -> run the TDD path (§2 → §3 → §4 → §5 → §6 → §7).
70
72
  - Pure infra/config/doc, no public surface -> `TDD_PHASE=false` -> run the
71
73
  non-TDD path (§2N → §3N).
72
74
  - AMBIGUOUS -> default `TDD_PHASE=true`, but STATE the classification + the reason
73
- to me, so I can override to non-TDD BEFORE SCAFFOLD fires. (Hard rule 11: never
74
- downgrade a TDD phase just to dodge the RED gate.)
75
+ to me, so I can override to non-TDD BEFORE SPEC fill fires. (Hard rule 11: never
76
+ downgrade a TDD phase just to dodge the gates.)
75
77
 
76
78
  =====================================================================
77
79
  ## TDD PATH (TDD_PHASE=true)
78
80
  =====================================================================
79
81
 
80
- ## 2. SCAFFOLD
82
+ ## 2. SPEC FILL + STALENESS
83
+
84
+ a. SKELETON CHECK: confirm docs/spec-phase-<n>.md exists (planner generated it at
85
+ /overview). If MISSING (planner classified it non-TDD, or it's a new phase from
86
+ /replan): generate the skeleton NOW from this phase's PLAN.md `acceptance` +
87
+ `dataflow:` transitions in the planner skeleton format (generated header + named
88
+ `TBD` rows), then `bash scripts/spec-staleness.sh stamp <n>` to stamp its hash.
89
+
90
+ b. Dispatch `spec-author`. It fills each case row with a real input payload
91
+ (`fixtures/<case-id>-input.json`), concrete expected output
92
+ (`fixtures/<case-id>-expected.json`), matcher tokens for volatile fields,
93
+ `error-code` for failures, and `selector/assert/value` `ui` descriptors —
94
+ grounded in the RESEARCH findings + the confirmed datasource baseline.
95
+
96
+ c. CASE-SET-DIVERGENCE (hard re-entry, hard rule 12 / §5.52): if `spec-author`
97
+ returns `CASE-SET-DIVERGENCE` (a required case can't be filled from real facts,
98
+ or research revealed an unlisted/contradicted case) -> STOP. Surface the finding.
99
+ I amend the up-front case-name contract in the skeleton; you re-stamp
100
+ (`bash scripts/spec-staleness.sh stamp <n>`); then re-dispatch `spec-author` to
101
+ re-fill from scratch. AI never amends the case-name set — I own the contract.
102
+
103
+ d. STALENESS (hard rule 17): run `bash scripts/spec-staleness.sh <n>`. Nonzero
104
+ (upstream PLAN acceptance line / DATAFLOW rows drifted since the skeleton was
105
+ stamped, e.g. via /replan) -> regenerate the skeleton header from current
106
+ PLAN/DATAFLOW, re-stamp, re-dispatch `spec-author`. Do NOT hand-edit the hash.
107
+
108
+ ## 3. SPEC REVIEW — human gate (hard rule 12)
109
+
110
+ STOP. Surface the FILLED cases to me as FALSIFIABLE CLAIMS in plain language, e.g.:
111
+ - "POST /orders/submit with an empty line-item list → 422 EMPTY_ORDER."
112
+ - "Successful submit of a 3-line order → 201; order.id is a UUID; order.status is
113
+ 'submitted'."
114
+ Re-run `bash scripts/spec-staleness.sh <n>` at entry (nonzero -> back to §2d).
115
+ SCAFFOLD cannot begin until I confirm. Classify any rejection WITH me (§5.50):
116
+ - WRONG EXPECTED -> fix the case row + `fixtures/<case-id>-expected.json`; no
117
+ re-research. (You may patch the fixture directly per my correction.)
118
+ - WRONG INPUT SHAPE -> re-dispatch `spec-author` with the correction.
119
+ - NEW CASE or CONTRADICTED CASE -> hard re-entry (§2c): I amend the skeleton, you
120
+ re-stamp, re-confirm the amended case(s) + any case sharing their `covers` id
121
+ (the staleness hash certifies the unchanged remainder — not re-read), re-fill.
122
+ Loop until I approve. Unskippable on TDD phases.
123
+
124
+ ## 4. SCAFFOLD
81
125
 
82
126
  Dispatch `implementer` in SCAFFOLD mode: interface stubs only (signatures +
83
- types; bodies raise NotImplementedError / return 501); NO logic, NO tests.
84
- Returns the stub files + the interface surface.
127
+ types; bodies raise NotImplementedError / return 501); NO logic, NO tests, NO
128
+ edits to the spec or fixtures. Returns the stub files + the interface surface.
85
129
 
86
- ## 3a. RED
130
+ ## 5. RED
87
131
 
88
- Dispatch `test-author` to write the REAL API suite (+ mock) BLIND against the
89
- stubs + acceptance, AND emit docs/test-plan-phase-<n>.md (acceptance criteria →
90
- test names, plus a mandatory "NOT covered / assumptions" section). Place
91
- contract/ENDPOINTS/DATAFLOW-transition tests in `tests/regression/`, phase-local
92
- tests in `tests/phase-<n>/`. Run the suite.
132
+ Dispatch `test-author` to EMIT the boundary harness from the locked spec `data`
133
+ rows: one deep-equality assertion per case against `fixtures/<case-id>-expected.json`
134
+ via the kit comparator `tests/helpers/spec-assert.*`, each citing its case with a
135
+ `# spec: <case-id>` comment. It does NOT author assertions — it generates them from
136
+ the spec. Place contract/ENDPOINTS/transition tests in `tests/regression/`,
137
+ phase-local in `tests/phase-<n>/`.
93
138
 
94
- RED GATE = every acceptance test COLLECTS cleanly AND FAILS (assertion /
95
- NotImplemented).
96
- - Any test PASSES on stubs -> STOP (spec trivial or test wrong); show me.
139
+ If FRONTEND_PHASE (and the phase has `ui` cases): also dispatch `e2e-runner` to EMIT
140
+ Playwright assertions from each `ui` case's `fixtures/<case-id>-ui.json` descriptor,
141
+ each citing `// spec: <case-id>`. Run the suites.
142
+
143
+ RED GATE = every case test COLLECTS cleanly AND FAILS (assertion / NotImplemented).
144
+ - Any test PASSES on stubs -> STOP (spec trivial or emitter wrong); show me.
97
145
  - Collection / import / syntax error -> stub mismatch; re-dispatch SCAFFOLD to
98
146
  fix SIGNATURES (not logic); re-run.
99
- - UNDERSPEC -> STOP; ask me to sharpen the acceptance spec.
100
147
 
101
- ## 3r. TEST REVIEWhuman gate (hard rule 12)
148
+ ## 6. CONFORMANCE GATE (hard rule 18) replaces the v2.1 human TEST REVIEW
102
149
 
103
- STOP. Surface docs/test-plan-phase-<n>.md to me: what each acceptance criterion
104
- maps to, and the "NOT covered / assumptions" section. GREEN cannot begin until I
105
- approve. On rejection, classify with me:
106
- - MISREAD of an adequate spec -> re-dispatch `test-author` with my feedback as
107
- added constraint; re-run RED; re-present the test plan.
108
- - UNDERSPEC (the acceptance spec itself is too vague) -> sharpen the acceptance
109
- spec in docs/PLAN.md, then re-dispatch `test-author` fresh.
110
- Loop until I approve. This gate is unskippable on TDD phases.
150
+ Run `bash scripts/spec-conformance.sh <n>`. It loud-fails (and BLOCKS GREEN) if:
151
+ - any `TBD` marker remains in docs/spec-phase-<n>.md or a referenced fixture, OR
152
+ - any case-id in the spec table has no boundary test citing it (`# spec: <case-id>`).
153
+ Nonzero -> fix the gap (re-dispatch `spec-author` for a stray TBD, or `test-author`/
154
+ `e2e-runner` for a missing citation) and re-run. GREEN cannot start until it passes.
111
155
 
112
- ## 3b. GREEN
156
+ ## 7. GREEN + BOUNDARY/E2E
113
157
 
114
- Dispatch `implementer` in FILL mode with the phase spec + research + the test
115
- file paths (it MAY read the tests — frozen before logic, no overfit — but must
116
- NOT edit them). Fill to green. Budget 3, WARN@2, STUCK@3.
158
+ Dispatch `implementer` in FILL mode with the FILLED docs/spec-phase-<n>.md + its
159
+ fixtures + research + the generated test file paths (it MAY read the tests — frozen
160
+ before logic, no overfit but must NOT edit tests, spec, or fixtures). Fill to
161
+ green against the spec. Budget 3, WARN@2, STUCK@3.
117
162
 
118
- If FRONTEND_PHASE (from PRE-FLIGHT e): dispatch `e2e-runner` MANDATORY, not
119
- optional (hard rule 13). It reads INFRA.md target, runs `scripts/e2e-stack.sh up`
120
- / Playwright / `down`, and captures a screenshot at EACH UI-existence assertion
121
- regardless of pass/fail to docs/evidence/e2e-phase-<n>/, with a summary in
122
- docs/research/e2e-<slug>.md. Acceptance spec has no UI-existence criterion ->
123
- e2e-runner returns UNDERSPEC -> STOP, sharpen the spec.
163
+ Run the BOUNDARY suite (real HTTP/CLI/message; `TEST_MODE=real`). If FRONTEND_PHASE,
164
+ `e2e-runner` runs its emitted `ui` specs — MANDATORY (hard rule 13) reads INFRA.md
165
+ target, runs `scripts/e2e-stack.sh up` / Playwright / `down`, and captures a
166
+ screenshot at EACH UI-existence assertion regardless of pass/fail to
167
+ docs/evidence/e2e-phase-<n>/, with a summary in docs/research/e2e-<slug>.md.
124
168
 
125
- PHASE GATE (rule 5) -> go to §456 (see GATE below).
169
+ PHASE GATE (rule 5) -> go to §8910 (see GATE below).
126
170
 
127
171
  =====================================================================
128
172
  ## NON-TDD PATH (TDD_PHASE=false)
@@ -137,18 +181,19 @@ includes "deployed URL" before proceeding.
137
181
 
138
182
  ## 3N. TEST (blind)
139
183
 
140
- Dispatch `test-author`. It writes MOCK + REAL API suites from the acceptance
141
- spec — never reads the logic. (No TEST REVIEW gate on the non-TDD path — no
142
- public surface to mis-test. e2e-runner only if FRONTEND_PHASE.)
184
+ Dispatch `test-author`. It writes MOCK + boundary suites from the acceptance
185
+ spec — never reads the logic. (No spec file, SPEC REVIEW, or conformance gate on
186
+ the non-TDD path — no public surface to contract. e2e-runner only if FRONTEND_PHASE.)
143
187
 
144
188
  =====================================================================
145
189
 
146
190
  ## GATE (both paths)
147
191
 
148
- PHASE GATE = current-phase REAL API suite passes AND (FRONTEND_PHASE) E2E passes
149
- WITH evidence captured AND the accumulated mock regression corpus stays green AND
150
- every docs/ENDPOINTS.md entry has a regression test AND every REACHABLE
151
- docs/DATAFLOW.md transition has a regression test (all checked at CLOSE).
192
+ PHASE GATE = current-phase BOUNDARY suite passes AND (FRONTEND_PHASE) the `ui`
193
+ boundary passes WITH evidence captured AND the accumulated mock regression corpus
194
+ stays green AND every docs/ENDPOINTS.md entry has a regression test AND (TDD)
195
+ `spec-conformance.sh` passed AND every REACHABLE docs/DATAFLOW.md transition has a
196
+ filled case in the phase spec (all checked at CLOSE).
152
197
  - GATE PASS -> go to CLOSE.
153
198
  - GATE BLOCKED (SERVICE UNAVAILABLE, STACK NOT READY, AZURE UNAVAILABLE, FLAKE)
154
199
  -> tell me, wait. Not a code bug. For AZURE UNAVAILABLE: suggest `/infra verify`.
@@ -156,17 +201,17 @@ docs/DATAFLOW.md transition has a regression test (all checked at CLOSE).
156
201
 
157
202
  ---
158
203
 
159
- ## 4. FIX
204
+ ## 8. FIX
160
205
 
161
206
  Dispatch `debugger` (isolated context) on the specific failure.
162
- - FIXED -> re-run TEST (and the regression corpus).
207
+ - FIXED -> re-run the boundary suite (and the regression corpus).
163
208
  - SERVICE UNAVAILABLE -> tell me, wait. Suggest `/infra verify` if Azure.
164
209
  - WARN (2 attempts failed) -> relay immediately, then let debugger finish attempt 3.
165
210
  - STUCK -> go to ESCALATE.
166
211
 
167
212
  ---
168
213
 
169
- ## 5. ESCALATE — circuit breaker. Mode B.
214
+ ## 9. ESCALATE — circuit breaker. Mode B.
170
215
 
171
216
  FIRST STUCK: STOP. Present to me: the problem, 3 failed hypotheses, the
172
217
  debugger's recommendation, the debug file path. Ask what to do. Wait. Options:
@@ -179,20 +224,22 @@ what to try next. Hand control to me.
179
224
 
180
225
  ---
181
226
 
182
- ## 6. CLOSE
227
+ ## 10. CLOSE
183
228
 
184
229
  REGRESSION + COVERAGE GATES (before closing — all FAIL HARD, do not close):
185
- - Run `scripts/regression.sh` (mock corpus). A failure BLOCKS close -> route to FIX.
230
+ - Run `bash scripts/regression.sh` (mock corpus). A failure BLOCKS close -> route to FIX.
186
231
  - ENDPOINTS COVERAGE: every `docs/ENDPOINTS.md` entry MUST have >=1 test in
187
232
  `tests/regression/`. Zero coverage -> FAIL HARD.
188
- - DATAFLOW COVERAGE (hard rule 14): every `docs/DATAFLOW.md` transition whose
189
- trigger is REACHABLE in the code shipped so far MUST have >=1 test in
190
- `tests/regression/`. Zero coverage on a reachable transition -> FAIL HARD.
191
- Unreachable transitions list as PENDING (not failed). IF IS_FINAL_PHASE: any
192
- transition still PENDING -> FAIL HARD (everything must be live by the last phase).
233
+ - DATAFLOW COVERAGE (hard rule 14, re-seamed v2.2): every `docs/DATAFLOW.md`
234
+ transition whose trigger is REACHABLE in the code shipped so far MUST have >=1
235
+ FILLED CASE in docs/spec-phase-<n>.md. Zero coverage on a reachable transition ->
236
+ FAIL HARD. Unreachable transitions list as PENDING (not failed). IF
237
+ IS_FINAL_PHASE: any transition still PENDING -> FAIL HARD. (The case→test half is
238
+ already enforced by `spec-conformance.sh` at §6 — every case-id is cited by a
239
+ boundary test, which by placement lands in tests/regression/.)
193
240
  - EVIDENCE (FRONTEND_PHASE only, hard rule 13): docs/evidence/e2e-phase-<n>/ must
194
241
  contain at least the per-UI-existence-assertion screenshots. Empty -> FAIL HARD.
195
- - IF IS_FINAL_PHASE: additionally run `scripts/regression.sh --real` (full real
242
+ - IF IS_FINAL_PHASE: additionally run `bash scripts/regression.sh --real` (full real
196
243
  corpus). A failure blocks close.
197
244
 
198
245
  Mark phase `done` in docs/PLAN.md.
@@ -202,7 +249,7 @@ ARCHITECTURE / DATAFLOW SELF-CHECK:
202
249
  workflow rule? YES -> run `/log-decision`. NO -> state why not.
203
250
  - Did this phase add/change an object's STATE LIFECYCLE? YES -> update
204
251
  docs/DATAFLOW.md (hard rule 9) in this CLOSE, and confirm new reachable
205
- transitions are covered. NO -> state why not.
252
+ transitions are covered by a filled case. NO -> state why not.
206
253
 
207
254
  IF IS_FINAL_PHASE — FINAL CLOSE sequence:
208
255
 
@@ -115,6 +115,18 @@ Store the round-1 answers as working context — do NOT write OVERVIEW.md yet.
115
115
  interactive element the phase introduces (not "page renders 200").
116
116
  - Map each phase to the DATAFLOW transitions it is expected to make reachable.
117
117
 
118
+ The planner ALSO writes the up-front SKELETON spec files (v2.2, §5.44/§5.51):
119
+ one `docs/spec-phase-<n>.md` per public-surface phase (skip Phase 0 + pure
120
+ infra/config/doc phases), enumerating the case NAMES — happy path, each named
121
+ edge, each named failure + error code — for every `dataflow:` transition and
122
+ every `acceptance` criterion, with `TBD` values. The generated header transcludes
123
+ that phase's `acceptance:` line + in-scope `DATAFLOW.md` transition rows verbatim.
124
+
125
+ 8b. STAMP each skeleton's staleness hash: for every `docs/spec-phase-<n>.md` the
126
+ planner wrote, run `bash scripts/spec-staleness.sh stamp <n>`. This embeds the
127
+ hash of the transcluded acceptance line + transition rows so phase-time
128
+ `/phase` can detect upstream drift. (Values are filled per phase by `spec-author`.)
129
+
118
130
  9. Create docs/STATE.md:
119
131
  ```
120
132
 
@@ -140,6 +152,11 @@ blocker: none
140
152
  ```
141
153
 
142
154
  Then stop and show me PLAN.md + DATAFLOW.md for approval before any phase starts.
155
+ EXTEND the approval surface (v2.2, §5.51 — one confirmation, no new gate): for each
156
+ public-surface phase, list the transition/acceptance ids it covers and the enumerated
157
+ case NAMES (no values). I confirm the case-name set is COMPLETE here — these names
158
+ are the up-front behavioral contract; values get filled + reviewed per phase at
159
+ `/phase` SPEC REVIEW.
143
160
 
144
161
  Remind me: "Run `/infra` next to provision the Azure environment (Phase 0) and
145
162
  run the one-time AUTH PROOF before starting Phase 1."