create-anpunkit 2.0.3 → 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.
- package/bin/cli.js +3 -2
- package/package.json +1 -1
- package/template/.claude/agents/e2e-runner.md +44 -13
- package/template/.claude/agents/implementer.md +13 -7
- package/template/.claude/agents/infra-provisioner.md +33 -2
- package/template/.claude/agents/planner.md +79 -6
- package/template/.claude/agents/researcher.md +19 -8
- package/template/.claude/agents/spec-author.md +118 -0
- package/template/.claude/agents/test-author.md +76 -43
- package/template/.claude/anpunkit-manifest.json +47 -27
- package/template/.claude/commands/infra.md +28 -3
- package/template/.claude/commands/overview.md +84 -24
- package/template/.claude/commands/phase.md +139 -40
- package/template/.claude/commands/replan.md +23 -9
- package/template/.cursor/commands/infra.md +26 -1
- package/template/.cursor/commands/overview.md +83 -23
- package/template/.cursor/commands/phase.md +138 -39
- package/template/.cursor/commands/replan.md +22 -8
- package/template/.gitattributes +1 -0
- package/template/AGENTS.md +215 -36
- package/template/CLAUDE.md +1 -0
- package/template/README.md +59 -23
- package/template/anpunkit.png +0 -0
- package/template/commands.src/infra.md +28 -3
- package/template/commands.src/overview.md +84 -24
- package/template/commands.src/phase.md +139 -40
- package/template/commands.src/replan.md +23 -9
- package/template/docs/DESIGN_LOG.md +192 -1
- package/template/index.html +339 -0
- package/template/scripts/spec-conformance.sh +93 -0
- package/template/scripts/spec-staleness.sh +115 -0
- package/template/setup.sh +110 -47
- package/template/tests/helpers/spec-assert.py +162 -0
- package/template/tests/helpers/spec-assert.ts +158 -0
package/template/AGENTS.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# anpunkit — portable agent methodology (single source of truth)
|
|
2
2
|
|
|
3
|
-
<!-- ANPUNKIT-AGENTS-SENTINEL-v2.
|
|
4
|
-
> **SENTINEL.** The HTML comment above (`ANPUNKIT-AGENTS-SENTINEL-v2.
|
|
5
|
-
> load-bearing marker. `setup.sh` greps for
|
|
6
|
-
> disk and was not clobbered. Do not remove or
|
|
3
|
+
<!-- ANPUNKIT-AGENTS-SENTINEL-v2.2 -->
|
|
4
|
+
> **SENTINEL.** The HTML comment above (`ANPUNKIT-AGENTS-SENTINEL-v2.2`) is a
|
|
5
|
+
> load-bearing marker. `setup.sh` greps for the bare prefix `ANPUNKIT-AGENTS-SENTINEL`
|
|
6
|
+
> to confirm this file resolved on disk and was not clobbered. Do not remove or
|
|
7
|
+
> rename it.
|
|
7
8
|
|
|
8
9
|
> **What this file is.** The complete, tool-agnostic methodology for the anpunkit
|
|
9
10
|
> workflow: the loop, the roles, the procedures, the rituals, and the hard rules.
|
|
@@ -31,7 +32,7 @@ A phase runs in one of two orders, chosen at RESEARCH time by the TDD
|
|
|
31
32
|
APPLICABILITY check (see Procedures → `phase`):
|
|
32
33
|
|
|
33
34
|
- **TDD phase** (`TDD_PHASE=true`):
|
|
34
|
-
`RESEARCH -> SCAFFOLD -> RED -> GREEN ->
|
|
35
|
+
`RESEARCH -> SPEC fill -> spec-staleness -> SPEC REVIEW -> SCAFFOLD -> RED -> spec-conformance -> GREEN -> boundary/E2E -> FIX -> CLOSE`
|
|
35
36
|
- **Non-TDD phase** (pure infra / config / doc — `TDD_PHASE=false`):
|
|
36
37
|
`RESEARCH -> IMPLEMENT -> TEST -> FIX -> CLOSE`
|
|
37
38
|
|
|
@@ -39,7 +40,44 @@ APPLICABILITY check (see Procedures → `phase`):
|
|
|
39
40
|
exported function/class, CLI command, or message contract) that is assertable
|
|
40
41
|
from the acceptance spec." Size is NOT the criterion. On ambiguity, default
|
|
41
42
|
`TDD_PHASE=true` AND state the classification + reason so a human can override to
|
|
42
|
-
non-TDD before
|
|
43
|
+
non-TDD before SPEC fill fires.
|
|
44
|
+
|
|
45
|
+
**SPEC REVIEW (v2.2)** is the mandatory human gate on every TDD phase, sitting
|
|
46
|
+
UPSTREAM — between RESEARCH and SCAFFOLD, before any code. The reviewable,
|
|
47
|
+
authoritative artifact is the SPEC, not the test. After RESEARCH, `spec-author`
|
|
48
|
+
fills `docs/spec-phase-<n>.md` (skeleton case-names generated at `/overview`) with
|
|
49
|
+
concrete observable behavior — real input payloads, real expected outputs, matcher
|
|
50
|
+
tokens for volatile fields — grounded in fresh per-phase research and the confirmed
|
|
51
|
+
datasource baseline. `scripts/spec-staleness.sh` then loud-fails if the upstream
|
|
52
|
+
`acceptance:` line or `DATAFLOW.md` transition rows drifted since the skeleton was
|
|
53
|
+
generated. The orchestrator surfaces the filled cases as FALSIFIABLE CLAIMS
|
|
54
|
+
("POST /orders/submit with an empty line-item list → 422 EMPTY_ORDER"); SCAFFOLD
|
|
55
|
+
cannot fire until the human confirms. Rejection is classified at the gate (§5.50):
|
|
56
|
+
wrong expected → fix the case row + fixture; wrong input shape → re-dispatch
|
|
57
|
+
`spec-author`; a new or contradicted case → hard re-entry to amend the up-front
|
|
58
|
+
case-name contract (§5.52). Tests are then GENERATED from the locked spec rows
|
|
59
|
+
(deep-equality + matcher tokens for `data`; Playwright from the descriptor for
|
|
60
|
+
`ui`) — humans never review test code. This is the fix for "both agents
|
|
61
|
+
independently fabricated the same wrong contract from a one-line acceptance and the
|
|
62
|
+
suite went green on a broken core." (§5.43–§5.50)
|
|
63
|
+
|
|
64
|
+
**Boundary test is the system-of-record per case (v2.2).** Every spec case has
|
|
65
|
+
exactly one OUTER-BOUNDARY test — `data` cases: a real HTTP call / CLI invocation /
|
|
66
|
+
real message against the running backend + real services (v2.1's "real API suite");
|
|
67
|
+
`ui` cases: a Playwright assertion against the deployed (or local-docker) target
|
|
68
|
+
(v2.1's "E2E"). The boundary test is the phase gate; green mock alone never closes a
|
|
69
|
+
phase. A mock mirror is optional and shares the SAME fixture + comparator via a
|
|
70
|
+
`TEST_MODE` flag, so it cannot assert different values than the boundary test. (§5.47)
|
|
71
|
+
|
|
72
|
+
**E2E is mandatory, not a judgment call.** If the project is frontend-bearing
|
|
73
|
+
(`has_frontend: true` in `docs/OVERVIEW.md`) AND the phase's `changes` touch the
|
|
74
|
+
frontend root recorded in OVERVIEW.md, `ui` boundary cases MUST run before CLOSE.
|
|
75
|
+
The trigger is a deterministic path match, not "does this phase feel frontend-y." A
|
|
76
|
+
frontend file changed with no `ui` boundary run is a loud CLOSE failure. `e2e-runner`
|
|
77
|
+
EMITS the Playwright assertion from each case's `ui` descriptor (it no longer authors
|
|
78
|
+
blind) and retains screenshot-on-each-UI-existence-assertion as the visual backstop.
|
|
79
|
+
On `has_frontend: false` projects there is no browser: `ui` case rows are invalid and
|
|
80
|
+
all cases are `data` boundary. (§5.34, §5.54)
|
|
43
81
|
|
|
44
82
|
-----
|
|
45
83
|
|
|
@@ -53,21 +91,58 @@ terse summary + path. Workers cannot address the user — only the orchestrator
|
|
|
53
91
|
can. Escalation is at most two hops.
|
|
54
92
|
|
|
55
93
|
- **researcher** — two modes. DESIGN: domain/constraint research before planning
|
|
56
|
-
(service limits, API contracts, architectural constraints, cost surprises)
|
|
57
|
-
|
|
58
|
-
|
|
94
|
+
(service limits, API contracts, architectural constraints, cost surprises);
|
|
95
|
+
for any external datasource, drafts a falsifiable DATA UNDERSTANDING (grain,
|
|
96
|
+
fields-under-test with meaning + real nullability/range, sample-fixture shape,
|
|
97
|
+
the assumption that if wrong makes a test meaningless) to `docs/research/
|
|
98
|
+
datasource-<name>.md`. IMPL: per-phase codebase + service investigation. Checks
|
|
99
|
+
the shared KB snapshot first (step 0). Writes findings to `docs/research/`;
|
|
100
|
+
returns terse summary + path.
|
|
59
101
|
- **planner** — research → vertical-slice `docs/PLAN.md`. Phase 0 (infra) always
|
|
60
|
-
first; the last phase always contains the deploy task.
|
|
102
|
+
first; the last phase always contains the deploy task. For any phase whose
|
|
103
|
+
`changes` touch the frontend root, the `acceptance` MUST include ≥1 UI-existence
|
|
104
|
+
criterion naming the specific user-visible interactive element introduced (not
|
|
105
|
+
"page renders 200"). Populates each phase's expected `DATAFLOW.md` transitions.
|
|
106
|
+
At `/overview` it ALSO enumerates the up-front CASE-NAME contract (§5.44): for
|
|
107
|
+
every `DATAFLOW.md` transition and every `acceptance:` criterion in a TDD phase,
|
|
108
|
+
the case *names* that must exist (happy path, each named edge, each named failure
|
|
109
|
+
+ error code) — no fixture values yet — written as skeleton `docs/spec-phase-<n>.md`
|
|
110
|
+
files (generated header + named rows, values `TBD`).
|
|
111
|
+
- **spec-author** — fills the per-phase spec. Runs AFTER RESEARCH, BEFORE SPEC
|
|
112
|
+
REVIEW. Reads the skeleton `spec-phase-<n>.md`, the confirmed
|
|
113
|
+
`datasource-<name>.md` baseline, and per-phase RESEARCH for the real API shape;
|
|
114
|
+
fills each case row with a real input payload (`fixtures/<case-id>-input.json`),
|
|
115
|
+
concrete expected output (`fixtures/<case-id>-expected.json`), matcher tokens for
|
|
116
|
+
volatile fields, `error-code` for failures, and `selector/assert/value` for `ui`
|
|
117
|
+
cases. Returns `CASE-SET-DIVERGENCE` if a required case cannot be filled from real
|
|
118
|
+
facts, or research reveals an unlisted branch/failure-mode. `spec-author` is NOT
|
|
119
|
+
`implementer` (author ≠ implementer invariant, §5.53) and never reads
|
|
120
|
+
implementation logic.
|
|
61
121
|
- **infra-provisioner** — generates Bicep, runs `az deployment what-if`, applies
|
|
62
|
-
only on human approval, writes `docs/INFRA.md` + `.env.test`.
|
|
122
|
+
only on human approval, writes `docs/INFRA.md` + `.env.test`. Runs the one-time
|
|
123
|
+
AUTH PROOF (§5.37): proves every credential the project's real tests will use is
|
|
124
|
+
obtainable headlessly twice in a row (prime + reuse) with zero prompts.
|
|
63
125
|
- **implementer** — builds ONE phase. Two MODES for TDD phases (SCAFFOLD: stubs
|
|
64
126
|
only; FILL: logic to green) plus a legacy full-build mode for non-TDD phases.
|
|
65
|
-
Writes code, never tests.
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
|
|
127
|
+
Writes code, never tests. On TDD phases it reads the human-approved filled
|
|
128
|
+
`docs/spec-phase-<n>.md` as its behavioral contract (normal spec-driven
|
|
129
|
+
development) — it never authors spec fixtures (author ≠ implementer, §5.53).
|
|
130
|
+
Maintains `docs/ENDPOINTS.md` each phase.
|
|
131
|
+
- **test-author** — now a HARNESS EMITTER, not a blind assertion author (§5.53). On
|
|
132
|
+
TDD phases it reads the locked spec rows and GENERATES the assertion harness: one
|
|
133
|
+
deep-equality assertion against `fixtures/<case-id>-expected.json` per `data` case,
|
|
134
|
+
citing the case with a `# spec: <case-id>` comment, using the kit-versioned
|
|
135
|
+
comparator `tests/helpers/spec-assert.*` (which honors matcher tokens). It does
|
|
136
|
+
not invent assertions — there is nothing for a human to review at the test layer.
|
|
137
|
+
Places contract/transition tests in `tests/regression/`, phase-local in
|
|
138
|
+
`tests/phase-<n>/`; mock-vs-boundary is a `TEST_MODE` flag on the SAME test.
|
|
139
|
+
- **e2e-runner** — now a Playwright EMITTER for `ui` boundary cases, not a blind
|
|
140
|
+
author (§5.54). Reads `docs/INFRA.md` for the target and each `ui` case's
|
|
141
|
+
`fixtures/<case-id>-ui.json` descriptor (`selector / assert / value`, closed
|
|
142
|
+
vocabulary: `visible | text-equals | enabled | count`), and emits the assertion.
|
|
143
|
+
Captures a screenshot at EACH UI-existence assertion regardless of pass/fail
|
|
144
|
+
(capture-on-success) to `docs/evidence/e2e-phase-<n>/`, plus a summary in
|
|
145
|
+
`docs/research/e2e-<slug>.md`.
|
|
71
146
|
- **debugger** — debugs in an ISOLATED context. Writes a trace to
|
|
72
147
|
`docs/research/debug-<slug>.md`; returns a summary.
|
|
73
148
|
- **synthesizer** — compresses `docs/STATE.md` / `docs/ISSUES.md`, prunes
|
|
@@ -83,12 +158,21 @@ Named procedures, each with a canonical body in `commands.src/<name>.md` and a
|
|
|
83
158
|
generated copy per tool (`.claude/commands/`, `.cursor/commands/`).
|
|
84
159
|
|
|
85
160
|
- **overview** — bootstrap a project: design-research → grill r1 → design-research
|
|
86
|
-
→ re-grill r2
|
|
161
|
+
→ RESEARCH REVIEW → re-grill r2 (covers data structures, dataflow, and object
|
|
162
|
+
state flow) → `OVERVIEW.md` (+ `has_frontend`/frontend-root, `DATAFLOW.md`,
|
|
163
|
+
confirmed datasource understanding) → planner → `PLAN.md` (Phase 0 always first)
|
|
164
|
+
+ skeleton `docs/spec-phase-<n>.md` case-name files. The end-of-`/overview` human
|
|
165
|
+
approval is EXTENDED to confirm the cross-phase skeleton case-name set in the same
|
|
166
|
+
surface (no new gate, §5.51).
|
|
87
167
|
- **infra** — provision/verify Azure infra: Bicep → what-if → human review → apply
|
|
88
|
-
→ `INFRA.md` + `.env.test`.
|
|
168
|
+
→ `INFRA.md` + `.env.test`. Runs the one-time AUTH PROOF.
|
|
89
169
|
- **phase [n]** — run one phase end-to-end with the circuit breaker. Chooses the
|
|
90
|
-
TDD or non-TDD order at RESEARCH.
|
|
91
|
-
|
|
170
|
+
TDD or non-TDD order at RESEARCH. PRE-FLIGHT runs the auth liveness check. TDD
|
|
171
|
+
phases: `spec-author` fills the spec → `spec-staleness.sh` → SPEC REVIEW (human,
|
|
172
|
+
before SCAFFOLD) → SCAFFOLD → RED (generated harness) → `spec-conformance.sh` →
|
|
173
|
+
GREEN → boundary/E2E. Frontend phases run mandatory `ui` boundary with screenshot
|
|
174
|
+
evidence. CLOSE runs the regression guard + ENDPOINTS coverage gate + DATAFLOW
|
|
175
|
+
transition→case coverage gate + evidence-present check.
|
|
92
176
|
- **quick [change]** — small, obvious, non-phase change; no agent chain. Stays
|
|
93
177
|
non-TDD. Runs the mock regression corpus after the change.
|
|
94
178
|
- **unstuck** — deep re-research after a circuit breaker (human-triggered).
|
|
@@ -126,7 +210,7 @@ recover: current phase, next action, open blocker.
|
|
|
126
210
|
|
|
127
211
|
-----
|
|
128
212
|
|
|
129
|
-
## Hard rules (1–
|
|
213
|
+
## Hard rules (1–19)
|
|
130
214
|
|
|
131
215
|
1. Before debugging ANY error: grep `docs/ISSUES.md` AND `docs/research/INDEX.md`.
|
|
132
216
|
The SESSION-OPEN ritual surfaces ISSUES.md — there is no excuse to miss it.
|
|
@@ -135,26 +219,94 @@ recover: current phase, next action, open blocker.
|
|
|
135
219
|
3. Every resolved error -> logged to `docs/ISSUES.md` with root cause + failed
|
|
136
220
|
attempts.
|
|
137
221
|
4. End of phase -> synthesize -> context reset -> next phase.
|
|
138
|
-
5. **PHASE GATE** =
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
(
|
|
222
|
+
5. **PHASE GATE** = every current-phase spec case's BOUNDARY test passes (`data`:
|
|
223
|
+
real HTTP/CLI/message; `ui`: Playwright with screenshot evidence) AND the
|
|
224
|
+
accumulated mock regression corpus stays green AND every `docs/ENDPOINTS.md`
|
|
225
|
+
entry has at least one test in `tests/regression/` AND `spec-conformance.sh`
|
|
226
|
+
passed (no TBD, every case-id cited by a boundary test) AND every REACHABLE
|
|
227
|
+
`docs/DATAFLOW.md` transition has at least one filled case in the phase spec
|
|
228
|
+
(rule 14). The final phase additionally runs the full REAL regression corpus and
|
|
229
|
+
requires zero PENDING transitions. A green mock suite alone can never close a phase.
|
|
230
|
+
6. On TDD phases the behavioral contract is the human-approved
|
|
231
|
+
`docs/spec-phase-<n>.md`; tests are GENERATED from its case rows (not authored):
|
|
232
|
+
`test-author` emits a deep-equality harness against the shared fixtures for
|
|
233
|
+
`data` cases, `e2e-runner` emits Playwright from the `ui` descriptor. Because the
|
|
234
|
+
spec row and the test load the SAME fixture, a test physically cannot assert
|
|
235
|
+
different values than the locked spec. Humans review the spec (SPEC REVIEW), never
|
|
236
|
+
the tests.
|
|
145
237
|
7. Service outage is not a bug — `SERVICE UNAVAILABLE` / `AZURE UNAVAILABLE` /
|
|
146
238
|
`STACK NOT READY` / `FLAKE` do not spend the debug budget. Only `LOGIC FAIL`
|
|
147
239
|
reaches the debugger.
|
|
148
240
|
8. E2E auth = ROPC with a dedicated MFA-excluded test account. NEVER script the
|
|
149
241
|
Microsoft login UI.
|
|
150
242
|
9. Architectural change (new/removed agent, hook, command, or a changed workflow
|
|
151
|
-
rule)? -> run `log-decision` before closing.
|
|
243
|
+
rule)? -> run `log-decision` before closing. A phase that changes an object's
|
|
244
|
+
state lifecycle MUST update `docs/DATAFLOW.md` in the same CLOSE.
|
|
152
245
|
10. Azure project? Run `scripts/auth-setup.sh` ONCE per session before any Azure
|
|
153
246
|
work. Never debug an auth error without checking this first.
|
|
154
|
-
11. **No-rationalization (scoped).** Do not
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
247
|
+
11. **No-rationalization (scoped).** Do not, in order to dodge a gate:
|
|
248
|
+
downgrade a TDD phase to non-TDD or route phase-worthy work through `quick`
|
|
249
|
+
(RED gate); set `has_frontend: false` or keep a touched element out of the
|
|
250
|
+
acceptance spec (E2E / UI-existence gate); fabricate a fixture value or leave a
|
|
251
|
+
`TBD` to slip past SPEC REVIEW / conformance instead of escalating UNDERSPEC or
|
|
252
|
+
`CASE-SET-DIVERGENCE`; mark a reachable transition PENDING (DATAFLOW gate); or
|
|
253
|
+
skip evidence capture. (Scoped deliberately to these named seams; this is not a
|
|
254
|
+
broad "never make excuses" rule.)
|
|
255
|
+
12. **SPEC REVIEW (TDD phases).** SCAFFOLD cannot begin until the human confirms the
|
|
256
|
+
filled `docs/spec-phase-<n>.md` cases, surfaced as falsifiable claims. Rejection
|
|
257
|
+
is classified at the gate (§5.50): wrong expected → fix case row + fixture; wrong
|
|
258
|
+
input shape → re-dispatch `spec-author`; new or contradicted case → hard re-entry
|
|
259
|
+
to amend the up-front case-name contract, re-confirm the amended + same-`covers`
|
|
260
|
+
neighbor cases (staleness-hash certifies the unchanged remainder), then re-fill
|
|
261
|
+
(§5.52). Unskippable on TDD phases; absent on the non-TDD path (no behavioral
|
|
262
|
+
contract to review). Replaces the v2.1 human TEST REVIEW gate (removed — humans
|
|
263
|
+
no longer review tests).
|
|
264
|
+
13. **Mandatory frontend E2E + evidence.** When `has_frontend: true` and the
|
|
265
|
+
phase's `changes` touch the frontend root recorded in OVERVIEW.md, E2E MUST
|
|
266
|
+
run. Each UI-existence assertion captures a screenshot (on success too) to
|
|
267
|
+
`docs/evidence/e2e-phase-<n>/`. Frontend files changed with no E2E run, or a
|
|
268
|
+
closed frontend phase with no evidence on disk, fails CLOSE hard. (Evidence is
|
|
269
|
+
gitignored — present-on-disk at CLOSE is the check, not committed history.)
|
|
270
|
+
14. **DATAFLOW transition coverage (re-seamed v2.2, §5.56).** Every transition in
|
|
271
|
+
`docs/DATAFLOW.md` whose trigger is reachable in the code shipped so far MUST
|
|
272
|
+
have ≥1 FILLED CASE in `docs/spec-phase-<n>.md` (was: ≥1 test in
|
|
273
|
+
`tests/regression/`); zero coverage on a reachable transition fails CLOSE hard.
|
|
274
|
+
Unreachable transitions list as PENDING. Any transition still PENDING at the
|
|
275
|
+
final phase fails hard. The case→test half of the old guarantee now lives in
|
|
276
|
+
`spec-conformance.sh` (rule 18: every case-id is cited by a boundary test, which
|
|
277
|
+
by placement convention lands in `tests/regression/`). Peer to the ENDPOINTS
|
|
278
|
+
coverage gate, which is unchanged and orthogonal (endpoint-keyed, not
|
|
279
|
+
behavior-keyed).
|
|
280
|
+
15. **Datasource data understanding.** Real-suite / E2E tests against an external
|
|
281
|
+
datasource are HARD-BLOCKED until that datasource's DATA UNDERSTANDING is
|
|
282
|
+
confirmed (baseline at `/overview`; per-phase delta-confirm for any
|
|
283
|
+
new table/column). The mock suite still runs. No testing against data you
|
|
284
|
+
never confirmed understanding of.
|
|
285
|
+
16. **Auth proof + liveness.** A one-time AUTH PROOF at `/infra` proves every
|
|
286
|
+
credential the real tests use — Entra/MSAL app login AND external datasource
|
|
287
|
+
credentials — is obtainable headlessly twice in a row (prime + reuse) with
|
|
288
|
+
zero prompts; "reusable without interaction" means exactly this. Each `/phase`
|
|
289
|
+
PRE-FLIGHT runs a cheap liveness check (token obtainable, not expired) before
|
|
290
|
+
dispatching real/E2E. Both fail loud; the mock suite proceeds regardless.
|
|
291
|
+
17. **Spec staleness (§5.55).** `scripts/spec-staleness.sh <n>` runs immediately
|
|
292
|
+
after `spec-author` fills the spec AND again at SPEC REVIEW entry. It re-hashes
|
|
293
|
+
the current `PLAN.md` `acceptance:` line + the in-scope `DATAFLOW.md` transition
|
|
294
|
+
rows and compares to the hash embedded in the spec's generated header. A
|
|
295
|
+
mismatch (upstream drifted since the skeleton was generated) exits nonzero and
|
|
296
|
+
blocks SPEC REVIEW — the spec must be regenerated/re-filled. The generated
|
|
297
|
+
header is never hand-edited.
|
|
298
|
+
18. **Spec conformance (§5.55).** `scripts/spec-conformance.sh <n>` runs between RED
|
|
299
|
+
and GREEN, replacing the removed human TEST REVIEW gate. It loud-fails (blocks
|
|
300
|
+
GREEN) if any `TBD` marker remains in the spec or its fixtures, or if any case-id
|
|
301
|
+
in the spec table has no boundary test citing it via the `# spec: <case-id>`
|
|
302
|
+
convention.
|
|
303
|
+
19. **Author ≠ implementer (§5.53).** `spec-author` and `implementer` are distinct
|
|
304
|
+
roles. `spec-author` fills the spec + fixtures and NEVER reads implementation
|
|
305
|
+
logic; `implementer` reads the filled spec as its contract and NEVER authors spec
|
|
306
|
+
fixtures. `test-author` / `e2e-runner` are harness EMITTERS, not assertion
|
|
307
|
+
authors. This replaces the v2.1 test-author RED-first blindness invariant: spec
|
|
308
|
+
fixtures are written before code, so the contract cannot be shaped toward an
|
|
309
|
+
implementation.
|
|
158
310
|
|
|
159
311
|
-----
|
|
160
312
|
|
|
@@ -176,13 +328,36 @@ the KB. The kit works normally without a KB.
|
|
|
176
328
|
- `docs/HISTORY.md` — one line per finished phase.
|
|
177
329
|
- `docs/DESIGN_LOG.md` — kit architectural rationale (§5.x decision log).
|
|
178
330
|
- `docs/OVERVIEW.md` — project scope. Written after the double-grill in `overview`.
|
|
331
|
+
Carries `has_frontend` + the frontend root path, and the data/state-flow summary.
|
|
332
|
+
- `docs/DATAFLOW.md` — state-transition table per key object (`object | states |
|
|
333
|
+
transition (from→to) | trigger | who writes | external system`). Living doc,
|
|
334
|
+
grill-driven; drives the CLOSE transition-coverage gate. The data-side analogue
|
|
335
|
+
of `ENDPOINTS.md`. (v2.1)
|
|
336
|
+
- `docs/spec-phase-<n>.md` — the per-phase behavioral contract (v2.2). Skeleton
|
|
337
|
+
(case names + `TBD` values) generated at `/overview`; filled by `spec-author` per
|
|
338
|
+
phase. Generated self-correlating header transcludes the phase's `PLAN.md`
|
|
339
|
+
`acceptance:` line + in-scope `DATAFLOW.md` transition rows and embeds a staleness
|
|
340
|
+
hash (never hand-edited). The only human-authored region is the example-case table.
|
|
341
|
+
Human-approved at SPEC REVIEW before SCAFFOLD. (Committed.)
|
|
342
|
+
- `fixtures/<case-id>-input.json` / `-expected.json` / `-ui.json` — the shared
|
|
343
|
+
fixtures a spec row references AND the generated test harness loads (transcription
|
|
344
|
+
is structural, not honor-system). `-expected.json` carries matcher tokens for
|
|
345
|
+
volatile fields; `-ui.json` is the `[{selector,assert,value}]` UI descriptor.
|
|
346
|
+
(Committed — part of the contract.) (v2.2)
|
|
347
|
+
- `tests/helpers/spec-assert.*` — the kit-versioned per-language comparator that
|
|
348
|
+
honors matcher tokens (`<UUID>`, `<ISO8601>`, `<ANY_STRING>`, `<ANY_NUMBER>`,
|
|
349
|
+
`<UNORDERED>`, `<MATCHES:regex>`). One implementation per supported test language;
|
|
350
|
+
NO per-project comparator code. (v2.2)
|
|
351
|
+
- `docs/evidence/e2e-phase-<n>/` — screenshot evidence captured at each UI-existence
|
|
352
|
+
assertion (gitignored; present-on-disk at CLOSE is the gate). (v2.1)
|
|
179
353
|
- `docs/INFRA.md` — Azure infra manifest: resource IDs, endpoints, cost estimates,
|
|
180
|
-
E2E target.
|
|
354
|
+
E2E target, AUTH PROOF result.
|
|
181
355
|
- `docs/ENDPOINTS.md` — API/service endpoint catalogue. Maintained by implementer
|
|
182
356
|
each phase. Drives the CLOSE coverage gate.
|
|
183
357
|
- `docs/research/` — full research + debug files. `INDEX.md` is the searchable map.
|
|
184
358
|
`design-<slug>.md` (design research), `<slug>.md` (impl research),
|
|
185
|
-
`debug-<slug>.md` (debugger traces)
|
|
359
|
+
`debug-<slug>.md` (debugger traces), `datasource-<name>.md` (confirmed data
|
|
360
|
+
understanding, referenced from DATAFLOW.md external rows).
|
|
186
361
|
- `docs/.snapshots/` — pre-compact recovery markers (auto-pruned, gitignored).
|
|
187
362
|
- `infra/` — Bicep templates. Committed (IaC audit trail). `infra/params.json`
|
|
188
363
|
holds no secrets.
|
|
@@ -191,6 +366,10 @@ the KB. The kit works normally without a KB.
|
|
|
191
366
|
- `tests/phase-<n>/` — phase-local test suites.
|
|
192
367
|
- `tests/regression/` — cross-phase contract tests (the regression corpus). Run by
|
|
193
368
|
`scripts/regression.sh` (default mock; `--real` runs the real corpus).
|
|
369
|
+
- `scripts/spec-staleness.sh <n>` — loud-fails if the spec's generated header drifted
|
|
370
|
+
from the current `PLAN.md` acceptance line + `DATAFLOW.md` rows (rule 17). (v2.2)
|
|
371
|
+
- `scripts/spec-conformance.sh <n>` — loud-fails on any remaining `TBD` or any
|
|
372
|
+
case-id with no citing boundary test (rule 18). Runs between RED and GREEN. (v2.2)
|
|
194
373
|
- `scripts/auth-setup.sh` — session Azure credential check. Run once per session.
|
|
195
374
|
- `.claude/kb-config.json` — shared KB path + remote (optional, written by setup.sh).
|
|
196
375
|
- `docs/.kb-snapshot.md` — KB INDEX loaded this session (auto-generated, gitignored).
|
package/template/CLAUDE.md
CHANGED
|
@@ -17,6 +17,7 @@ The roles defined in AGENTS.md map to these Claude Code subagent files:
|
|
|
17
17
|
|researcher |`.claude/agents/researcher.md` |haiku |
|
|
18
18
|
|planner |`.claude/agents/planner.md` |opus |
|
|
19
19
|
|infra-provisioner |`.claude/agents/infra-provisioner.md` |opus |
|
|
20
|
+
|spec-author |`.claude/agents/spec-author.md` |opus |
|
|
20
21
|
|implementer |`.claude/agents/implementer.md` |opus |
|
|
21
22
|
|test-author |`.claude/agents/test-author.md` |opus |
|
|
22
23
|
|e2e-runner |`.claude/agents/e2e-runner.md` |opus |
|
package/template/README.md
CHANGED
|
@@ -25,8 +25,12 @@ npx create-anpunkit # non-destructive: never clobbers your files
|
|
|
25
25
|
# then open Claude Code or Cursor — the session-start hook fires automatically
|
|
26
26
|
/overview # bootstrap the project (includes Phase 0 infra)
|
|
27
27
|
```
|
|
28
|
-
Useful flags: `--dry-run` (print the plan, write nothing), `--force`
|
|
29
|
-
user-modified kit files), `--
|
|
28
|
+
Useful flags: `--dry-run` (print the per-tool plan, write nothing), `--force`
|
|
29
|
+
(overwrite user-modified kit files), `--tools <claude,cursor>` (install only the
|
|
30
|
+
selected tools' files; interactive menu if omitted on a fresh TTY install),
|
|
31
|
+
`--add-tool <name>` (lay down an additional tool's files into an existing
|
|
32
|
+
project), `--kb-path <dir>` (your pre-cloned KB repo; remote auto-recorded from
|
|
33
|
+
its origin) / `--no-kb`.
|
|
30
34
|
|
|
31
35
|
Upgrading an existing anpunkit project? Re-run `npx create-anpunkit`. It refreshes
|
|
32
36
|
kit-owned files, preserves anything you modified as `<file>.anpunkit-new`, merges
|
|
@@ -46,38 +50,63 @@ cd my-project && bash setup.sh
|
|
|
46
50
|
|
|
47
51
|
|Command |Does |
|
|
48
52
|
|-----------------|------------------------------------------------------------------------------|
|
|
49
|
-
|`/overview` |design-research → grill (×2) → OVERVIEW → PLAN (Phase 0
|
|
50
|
-
|`/infra` |provision Azure infra: Bicep → what-if → review → apply → INFRA.md + .env.test|
|
|
51
|
-
|`/phase [n]` |run one phase: research →
|
|
53
|
+
|`/overview` |design-research → RESEARCH REVIEW → grill (×2, incl. data/state flow) → OVERVIEW + DATAFLOW → PLAN (Phase 0 first) → STATE|
|
|
54
|
+
|`/infra` |provision Azure infra: Bicep → what-if → review → apply → INFRA.md + .env.test → AUTH PROOF|
|
|
55
|
+
|`/phase [n]` |run one phase: research → SPEC fill → SPEC REVIEW → SCAFFOLD → RED → conformance → GREEN → boundary/E2E, with circuit breaker|
|
|
52
56
|
|`/quick [change]`|small obvious change, direct, no agent chain |
|
|
53
57
|
|`/unstuck` |deep re-research after a circuit breaker (you trigger it) |
|
|
54
58
|
|`/synthesize` |compress STATE.md, dedup ISSUES.md, prune snapshots |
|
|
55
|
-
|`/replan` |revise PLAN.md when it drifts
|
|
59
|
+
|`/replan` |revise PLAN.md when it drifts (reconciles regression corpus + DATAFLOW) |
|
|
56
60
|
|`/log-issue` |append an error with root cause + failed attempts |
|
|
57
61
|
|`/log-decision` |record an architectural change in DESIGN_LOG.md |
|
|
58
62
|
|`/store-wisdom` |promote resolved issues + research findings to shared KB |
|
|
59
63
|
|
|
60
64
|
## Subagents
|
|
61
65
|
|
|
62
|
-
`researcher` (Haiku, two modes: design + impl) · `planner` (Opus
|
|
63
|
-
`
|
|
64
|
-
`
|
|
66
|
+
`researcher` (Haiku, two modes: design + impl) · `planner` (Opus, also writes skeleton specs) ·
|
|
67
|
+
`infra-provisioner` (Opus) · `spec-author` (Opus, fills per-phase spec + fixtures) ·
|
|
68
|
+
`implementer` (Opus, SCAFFOLD/FILL modes) · `test-author` (Opus, harness emitter) · `debugger` (Opus, isolated) ·
|
|
69
|
+
`e2e-runner` (Opus, Playwright emitter) · `synthesizer` (Haiku)
|
|
65
70
|
|
|
66
71
|
The main session is the orchestrator — it routes, it does not implement.
|
|
67
72
|
|
|
68
|
-
## The loop (v2.
|
|
69
|
-
|
|
70
|
-
Phases that add a public callable surface run
|
|
71
|
-
`RESEARCH -> SCAFFOLD -> RED -> GREEN ->
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
## The loop (v2.2: spec-driven contract + upstream human gate + generated tests)
|
|
74
|
+
|
|
75
|
+
Phases that add a public callable surface run spec-first:
|
|
76
|
+
`RESEARCH -> SPEC fill -> spec-staleness -> SPEC REVIEW -> SCAFFOLD -> RED -> spec-conformance -> GREEN -> boundary/E2E -> FIX -> CLOSE`.
|
|
77
|
+
The reviewable, authoritative artifact is the **spec**, not the test. At `/overview`
|
|
78
|
+
the planner enumerates the case *names* per phase (skeleton `docs/spec-phase-<n>.md`).
|
|
79
|
+
At phase start the new `spec-author` fills them with concrete cases — real inputs,
|
|
80
|
+
real expected outputs, matcher tokens for volatile fields — written to shared
|
|
81
|
+
`fixtures/` files. **SPEC REVIEW** is a human gate that sits *upstream* (before any
|
|
82
|
+
code): you confirm falsifiable claims in plain language ("empty order → 422
|
|
83
|
+
EMPTY_ORDER"). Tests are then GENERATED from the locked spec rows (deep-equality +
|
|
84
|
+
matcher tokens for `data`; Playwright from the descriptor for `ui`) loading the
|
|
85
|
+
*same* fixtures — so a test physically cannot assert different values than the spec.
|
|
86
|
+
`spec-conformance.sh` blocks GREEN until no `TBD` remains and every case-id is cited
|
|
87
|
+
by a boundary test. This is the v2.2 fix for "both agents independently fabricated
|
|
88
|
+
the same wrong contract from a one-line acceptance and the suite went green on a
|
|
89
|
+
broken core." Pure infra/config/doc phases keep the direct
|
|
90
|
+
`RESEARCH -> IMPLEMENT -> TEST` order (no spec, no SPEC REVIEW — no public surface).
|
|
91
|
+
|
|
92
|
+
Frontend phases are detected by a **deterministic path match** (`has_frontend` +
|
|
93
|
+
the frontend root, both set in `docs/OVERVIEW.md`): if a phase changes a file
|
|
94
|
+
under the frontend root, **E2E is mandatory**, the acceptance spec must name the
|
|
95
|
+
specific user-visible element it introduces (not "page renders 200"), and the
|
|
96
|
+
`e2e-runner` captures a screenshot at each such assertion — on success too — to a
|
|
97
|
+
gitignored `docs/evidence/` dir. That's the fix for shipping a missing sign-in button.
|
|
76
98
|
|
|
77
99
|
Every phase CLOSE runs the accumulated **mock regression corpus**
|
|
78
|
-
(`tests/regression/`, via `scripts/regression.sh`)
|
|
79
|
-
gate
|
|
80
|
-
|
|
100
|
+
(`tests/regression/`, via `scripts/regression.sh`) plus a hard ENDPOINTS coverage
|
|
101
|
+
gate AND a **DATAFLOW transition-coverage gate** — every reachable state
|
|
102
|
+
transition in `docs/DATAFLOW.md` (the data-side analogue of `ENDPOINTS.md`,
|
|
103
|
+
grilled out at `/overview`) must have a regression test. The final phase
|
|
104
|
+
additionally runs the full real corpus and allows zero PENDING transitions.
|
|
105
|
+
|
|
106
|
+
External datasources get a confirmed, falsifiable **DATA UNDERSTANDING** (grain,
|
|
107
|
+
fields, sample shape, meaning-breaking assumption) before real tests run, and auth
|
|
108
|
+
is proven reusable once at `/infra` (obtainable headlessly twice in a row) with a
|
|
109
|
+
cheap liveness check each phase.
|
|
81
110
|
|
|
82
111
|
Methodology lives in one place: the portable **`AGENTS.md`** at the repo root.
|
|
83
112
|
`CLAUDE.md` is a thin `@AGENTS.md` shim with Claude-native wiring only.
|
|
@@ -142,6 +171,10 @@ home-dir custom-prompts with a divergent UX).
|
|
|
142
171
|
- `docs/PLAN.md` — vertical-slice phase plan (Phase 0 always first)
|
|
143
172
|
- `docs/HISTORY.md` — one line per finished phase
|
|
144
173
|
- `docs/OVERVIEW.md` — project scope, written after double-grill
|
|
174
|
+
- `docs/DATAFLOW.md` — state-transition table per key object (grilled at /overview; drives CLOSE coverage gate)
|
|
175
|
+
- `docs/spec-phase-<n>.md` — per-phase behavioral contract (skeleton at /overview, filled by spec-author; human-reviewed at SPEC REVIEW)
|
|
176
|
+
- `fixtures/<case-id>-{input,expected,ui}.json` — shared by the spec row and the generated test harness (committed; part of the contract)
|
|
177
|
+
- `tests/helpers/spec-assert.{py,ts}` — kit-versioned matcher-aware comparator (honors `<UUID>`, `<ISO8601>`, … tokens)
|
|
145
178
|
- `docs/INFRA.md` — Azure resource manifest + cost estimates (written by infra-provisioner)
|
|
146
179
|
- `docs/ENDPOINTS.md` — API/service endpoint catalogue (maintained by implementer)
|
|
147
180
|
- `docs/.snapshots/` — pre-compact recovery markers (auto-pruned, gitignored)
|
|
@@ -206,6 +239,7 @@ phase starts, owned by the `infra-provisioner` subagent.
|
|
|
206
239
|
/infra # generates Bicep -> what-if diff -> you review -> "go" -> apply
|
|
207
240
|
# writes docs/INFRA.md (resource manifest + cost estimates)
|
|
208
241
|
# writes .env.test (generated, never fill manually)
|
|
242
|
+
# runs AUTH PROOF (every credential proven reusable headlessly)
|
|
209
243
|
/phase 1 # PRE-FLIGHT checks Phase 0 is done before starting
|
|
210
244
|
```
|
|
211
245
|
|
|
@@ -225,13 +259,15 @@ Prompts `az login` only if stale. No credential storage — your account only.
|
|
|
225
259
|
1. `infra-provisioner` reads `docs/OVERVIEW.md` for the system design
|
|
226
260
|
1. Generates `infra/main.bicep` + per-service modules under `infra/modules/`
|
|
227
261
|
1. Runs `az deployment what-if` — shows exactly what will be created
|
|
228
|
-
1. **Stops and waits for your
|
|
262
|
+
1. **Stops and waits for your "go"** — nothing applied without your review
|
|
229
263
|
1. Applies the deployment
|
|
230
264
|
1. Writes `docs/INFRA.md` — resource IDs, endpoints, cost estimates (THB, SEA region)
|
|
231
265
|
1. Generates `.env.test` from the manifest
|
|
266
|
+
1. Runs the **AUTH PROOF** — proves every credential (Entra/MSAL + datasources) is obtainable headlessly twice in a row
|
|
232
267
|
|
|
233
268
|
Re-run `/infra` any time infra drifts or a new resource is needed.
|
|
234
269
|
Re-run `/infra regenerate-env` to refresh `.env.test` only.
|
|
270
|
+
Re-run `/infra auth-proof` to re-prove credentials on demand.
|
|
235
271
|
|
|
236
272
|
### Cost awareness
|
|
237
273
|
|
|
@@ -257,7 +293,7 @@ Three layers: unit/integration (mock suite), real API (`test-author`), and
|
|
|
257
293
|
functional browser E2E (`e2e-runner`, Playwright).
|
|
258
294
|
|
|
259
295
|
**Phase gate:** a frontend-touching phase closes only when the real API suite
|
|
260
|
-
AND the browser E2E suite pass. Mock-green alone never closes a phase.
|
|
296
|
+
AND the browser E2E suite pass with screenshot evidence. Mock-green alone never closes a phase.
|
|
261
297
|
|
|
262
298
|
**MSAL / Entra ID auth.** Browser E2E never drives the Microsoft login UI.
|
|
263
299
|
`e2e/global-setup.ts` uses ROPC flow with a dedicated test account (MFA excluded
|
|
@@ -265,7 +301,7 @@ via Conditional Access) to fetch a real token and inject it into the MSAL cache.
|
|
|
265
301
|
|
|
266
302
|
**E2E setup (one-time per project):**
|
|
267
303
|
|
|
268
|
-
1. Run `/infra` — it generates `.env.test` automatically.
|
|
304
|
+
1. Run `/infra` — it generates `.env.test` automatically and runs the AUTH PROOF.
|
|
269
305
|
1. Provision the Entra test user + Conditional Access MFA exclusion.
|
|
270
306
|
1. `npm i -D @playwright/test && npx playwright install chromium`
|
|
271
307
|
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Provision or verify Azure infrastructure. Generates Bicep, shows what-if diff for your review, applies only after your approval, writes docs/INFRA.md and .env.test.
|
|
3
|
-
argument-hint: [provision | verify | update <what changed> | regenerate-env]
|
|
2
|
+
description: Provision or verify Azure infrastructure. Generates Bicep, shows what-if diff for your review, applies only after your approval, writes docs/INFRA.md and .env.test. Runs the one-time AUTH PROOF.
|
|
3
|
+
argument-hint: [provision | verify | update <what changed> | regenerate-env | auth-proof]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Caveman ULTRA mode. You are the ORCHESTRATOR.
|
|
@@ -36,6 +36,31 @@ Action: $ARGUMENTS (default: "provision" if INFRA.md missing, "verify" if presen
|
|
|
36
36
|
4. On "make changes": dispatch UPDATE with feedback. Loop to step 2.
|
|
37
37
|
|
|
38
38
|
5. On APPLIED: tell me INFRA.md ✓, .env.test ✓, and any manual steps remaining.
|
|
39
|
+
Then run AUTH PROOF (below) before declaring Phase 0 complete.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## AUTH PROOF (one-time, hard rule 16)
|
|
44
|
+
|
|
45
|
+
Runs after a successful PROVISION (and on demand via `/infra auth-proof`). Proves
|
|
46
|
+
every credential the project's real tests will use is reusable WITHOUT interaction.
|
|
47
|
+
"Reusable" is defined falsifiably: obtainable headlessly TWICE IN A ROW.
|
|
48
|
+
|
|
49
|
+
1. Enumerate the credentials in scope: the Entra/MSAL app login, plus every
|
|
50
|
+
external datasource credential referenced in docs/DATAFLOW.md (external rows)
|
|
51
|
+
and docs/ENDPOINTS.md (auth column) — Azure SQL, Tableau, etc.
|
|
52
|
+
|
|
53
|
+
2. Dispatch `infra-provisioner` to run, for EACH credential, a headless obtain
|
|
54
|
+
twice in a row: first call primes (token fetch / connect), second call must
|
|
55
|
+
succeed from cache/refresh with ZERO prompts. The Microsoft login UI is never
|
|
56
|
+
driven (ROPC + dedicated MFA-excluded test account; hard rule 8).
|
|
57
|
+
|
|
58
|
+
3. Result:
|
|
59
|
+
- All credentials pass twice headlessly -> write `AUTH PROOF: PASS <timestamp>`
|
|
60
|
+
to docs/INFRA.md with the per-credential list. Phase 0 may complete.
|
|
61
|
+
- Any credential prompts or fails the second obtain -> NOT reusable. Write
|
|
62
|
+
`AUTH PROOF: FAIL` + which credential, STOP, tell me what to fix. Phase 0 is
|
|
63
|
+
not complete until the proof passes.
|
|
39
64
|
|
|
40
65
|
---
|
|
41
66
|
|
|
@@ -43,7 +68,7 @@ Action: $ARGUMENTS (default: "provision" if INFRA.md missing, "verify" if presen
|
|
|
43
68
|
|
|
44
69
|
1. Check INFRA.md exists. If missing: tell me to run `/infra provision` first.
|
|
45
70
|
2. Dispatch `infra-provisioner` VERIFY mode.
|
|
46
|
-
3. Return drift report.
|
|
71
|
+
3. Return drift report. If the AUTH PROOF marker is missing or stale, re-run AUTH PROOF.
|
|
47
72
|
|
|
48
73
|
---
|
|
49
74
|
|