create-anpunkit 2.1.0 → 2.3.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 +2 -2
- package/package.json +2 -3
- package/template/.claude/agents/debugger.md +1 -1
- package/template/.claude/agents/e2e-runner.md +56 -29
- package/template/.claude/agents/implementer.md +14 -8
- package/template/.claude/agents/infra-provisioner.md +53 -59
- package/template/.claude/agents/planner.md +99 -30
- package/template/.claude/agents/researcher.md +16 -1
- package/template/.claude/agents/spec-author.md +126 -0
- package/template/.claude/agents/synthesizer.md +1 -1
- package/template/.claude/agents/test-author.md +81 -63
- package/template/.claude/anpunkit-manifest.json +66 -107
- package/template/.claude/commands/infra.md +7 -3
- package/template/.claude/commands/log-decision.md +1 -1
- package/template/.claude/commands/log-issue.md +1 -1
- package/template/.claude/commands/overview.md +55 -13
- package/template/.claude/commands/phase.md +153 -81
- package/template/.claude/commands/quick.md +1 -1
- package/template/.claude/commands/replan.md +1 -1
- package/template/.claude/commands/store-wisdom.md +1 -1
- package/template/.claude/commands/synthesize.md +1 -1
- package/template/.claude/commands/unstuck.md +1 -1
- package/template/.claude/hooks/session-start.sh +5 -11
- package/template/.claude/ref/compression.md +56 -0
- package/template/.claude/skills/karpathy-guidelines/SKILL.md +1 -1
- package/template/.gitattributes +1 -0
- package/template/AGENTS.md +264 -130
- package/template/CLAUDE.md +5 -9
- package/template/README.md +116 -136
- package/template/commands.src/infra.md +7 -3
- package/template/commands.src/log-decision.md +1 -1
- package/template/commands.src/log-issue.md +1 -1
- package/template/commands.src/overview.md +55 -13
- package/template/commands.src/phase.md +153 -81
- package/template/commands.src/quick.md +1 -1
- package/template/commands.src/replan.md +1 -1
- package/template/commands.src/store-wisdom.md +1 -1
- package/template/commands.src/synthesize.md +1 -1
- package/template/commands.src/unstuck.md +1 -1
- package/template/docs/DESIGN_LOG.md +414 -9
- package/template/knowledge/azure.md +161 -0
- package/template/knowledge/webapp.md +265 -0
- package/template/scripts/spec-conformance.sh +93 -0
- package/template/scripts/spec-staleness.sh +115 -0
- package/template/setup.sh +30 -111
- package/template/tests/helpers/spec-assert.py +162 -0
- package/template/tests/helpers/spec-assert.ts +158 -0
- package/template/.claude/hooks/cursor-session-start.sh +0 -17
- package/template/.claude/skills/caveman/SKILL.md +0 -39
- package/template/.cursor/commands/infra.md +0 -82
- package/template/.cursor/commands/log-decision.md +0 -29
- package/template/.cursor/commands/log-issue.md +0 -23
- package/template/.cursor/commands/overview.md +0 -145
- package/template/.cursor/commands/phase.md +0 -249
- package/template/.cursor/commands/quick.md +0 -25
- package/template/.cursor/commands/replan.md +0 -73
- package/template/.cursor/commands/store-wisdom.md +0 -191
- package/template/.cursor/commands/synthesize.md +0 -22
- package/template/.cursor/commands/unstuck.md +0 -36
- package/template/.cursor/hooks.json +0 -14
- package/template/.cursor/rules/anpunkit.md +0 -11
- package/template/anpunkit.png +0 -0
- package/template/docker-compose.test.yml +0 -34
- package/template/e2e/global-setup.ts +0 -57
- package/template/index.html +0 -340
- package/template/playwright.config.ts +0 -28
- package/template/scripts/auth-setup.sh +0 -51
- package/template/scripts/e2e-stack.sh +0 -65
package/bin/cli.js
CHANGED
|
@@ -61,8 +61,8 @@ if (!bash) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// Pass through recognised flags only; setup.sh validates the rest.
|
|
64
|
-
const passthrough = ['--kb-path', '--kb-remote', '--no-kb', '--force', '--dry-run'
|
|
65
|
-
const valueFlags = ['--kb-path', '--kb-remote'
|
|
64
|
+
const passthrough = ['--kb-path', '--kb-remote', '--no-kb', '--force', '--dry-run'];
|
|
65
|
+
const valueFlags = ['--kb-path', '--kb-remote'];
|
|
66
66
|
const argv = process.argv.slice(2);
|
|
67
67
|
// Git Bash is happiest with forward slashes; Windows APIs accept them too.
|
|
68
68
|
const fwd = p => p.split(path.sep).join('/');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-anpunkit",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Scaffold the anpunkit AI-coding workflow (Claude Code
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "Scaffold the anpunkit AI-coding workflow (Claude Code) into a project. Upgrade-safe, non-destructive.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-anpunkit": "bin/cli.js"
|
|
7
7
|
},
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"author": "Methee S. (Pun) <methee84@gmail.com> (https://github.com/MetheeS)",
|
|
25
25
|
"keywords": [
|
|
26
26
|
"claude-code",
|
|
27
|
-
"cursor",
|
|
28
27
|
"agents",
|
|
29
28
|
"tdd",
|
|
30
29
|
"workflow",
|
|
@@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Edit, Bash, Write
|
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the DEBUGGER.
|
|
8
|
+
You are the DEBUGGER. compression: internal (.claude/ref/compression.md).
|
|
9
9
|
|
|
10
10
|
Why you exist: debugging generates huge noisy context. Running it isolated +
|
|
11
11
|
writing noise to a file keeps the orchestrator's context clean.
|
|
@@ -1,48 +1,63 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: e2e-runner
|
|
3
|
-
description:
|
|
3
|
+
description: Playwright emitter (v2.2) for `ui` boundary cases. Reads each ui case's fixtures/<case-id>-ui.json descriptor (selector/assert/value) and emits the assertion against the deployed/local-docker target. Captures screenshot evidence at each UI-existence assertion. Does not author blind and does not read implementation.
|
|
4
4
|
tools: Read, Grep, Glob, Write, Bash
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the E2E-RUNNER.
|
|
8
|
+
You are the E2E-RUNNER. compression: internal (.claude/ref/compression.md). In v2.3 you are a Playwright EMITTER:
|
|
9
|
+
you generate assertions from the locked `ui` case descriptors, you do not author
|
|
10
|
+
blind from a prose acceptance line. The human reviewed the SPEC upstream.
|
|
9
11
|
|
|
10
12
|
CRITICAL constraint: you are BLIND to the implementation. Read only:
|
|
11
|
-
- docs/
|
|
12
|
-
-
|
|
13
|
-
- docs/
|
|
14
|
-
-
|
|
13
|
+
- `docs/spec-phase-<n>.md` — the FILLED, human-approved `ui` case rows
|
|
14
|
+
- `fixtures/<case-id>-ui.json` — the descriptor for each `ui` case
|
|
15
|
+
- `docs/INFRA.md` — E2E target, base URL, auth config
|
|
16
|
+
- `docs/ENDPOINTS.md` — known API routes (navigation context only)
|
|
17
|
+
- `playwright.config.ts`, `e2e/global-setup.ts`, existing spec files — materialize
|
|
18
|
+
the config + global-setup from `knowledge/webapp.md` if absent (first browser phase)
|
|
15
19
|
|
|
16
20
|
---
|
|
17
21
|
|
|
18
22
|
## PROCESS
|
|
19
23
|
|
|
20
|
-
1. Read docs/INFRA.md
|
|
24
|
+
1. Read `docs/INFRA.md`:
|
|
21
25
|
- E2E target mode: `local-docker` or `azure-deployed`
|
|
22
|
-
- Base URL (use E2E_BASE_URL from
|
|
26
|
+
- Base URL (use `E2E_BASE_URL` from `.env.test`)
|
|
23
27
|
- Auth config (tenant, client ID, ROPC setup)
|
|
24
28
|
|
|
25
|
-
2. Read docs/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
2. Read the `ui` case rows of `docs/spec-phase-<n>.md` and each row's
|
|
30
|
+
`fixtures/<case-id>-ui.json`. The descriptor is a closed, kit-versioned
|
|
31
|
+
vocabulary — emit, do not interpret freely:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
[
|
|
35
|
+
{ "selector": "#submit-btn", "assert": "visible", "value": null },
|
|
36
|
+
{ "selector": ".order-status", "assert": "text-equals", "value": "submitted" },
|
|
37
|
+
{ "selector": "#qty", "assert": "enabled", "value": null },
|
|
38
|
+
{ "selector": ".line-item", "assert": "count", "value": 3 }
|
|
39
|
+
]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Assert vocabulary (closed): `visible`, `text-equals`, `enabled`, `count`.
|
|
43
|
+
If a `ui` case appears on a `has_frontend: false` project, that is invalid input —
|
|
44
|
+
STOP and report it to the orchestrator (it should have been caught at SPEC fill).
|
|
45
|
+
|
|
46
|
+
3. Emit Playwright specs under `e2e/` from the descriptors. Each emitted spec block
|
|
47
|
+
carries a `// spec: <case-id>` comment — the citation `spec-conformance.sh`
|
|
48
|
+
checks. Test only the descriptor's user-visible assertions. No internals.
|
|
49
|
+
|
|
50
|
+
4. Run the stack (ritual + `scripts/e2e-stack.sh` template in `knowledge/webapp.md`;
|
|
51
|
+
materialize the script if absent):
|
|
52
|
+
- `scripts/e2e-stack.sh up` (no-op if `E2E_STACK_EXTERNAL=1`)
|
|
38
53
|
- `npx playwright test`
|
|
39
54
|
- `scripts/e2e-stack.sh down` when done
|
|
40
55
|
|
|
41
|
-
EVIDENCE (
|
|
42
|
-
screenshot REGARDLESS of pass/fail (override Playwright's failure-only
|
|
43
|
-
|
|
44
|
-
asserted element — evidence maps 1:1 to
|
|
45
|
-
|
|
56
|
+
EVIDENCE (mandatory, hard rule 13): at EACH UI-existence assertion, capture a
|
|
57
|
+
screenshot REGARDLESS of pass/fail (override Playwright's failure-only default)
|
|
58
|
+
to `docs/evidence/e2e-phase-<n>/<case-id>-<element-slug>.png`. One shot per
|
|
59
|
+
asserted element — evidence maps 1:1 to a `ui` case. This is the visual backstop
|
|
60
|
+
the descriptor assertions cannot fully replace, captured on green as well as red.
|
|
46
61
|
|
|
47
62
|
5. FAILURE CLASSIFICATION — for every failure:
|
|
48
63
|
- **LOGIC FAIL** — app behavior is wrong. Reaches the debugger.
|
|
@@ -51,6 +66,9 @@ CRITICAL constraint: you are BLIND to the implementation. Read only:
|
|
|
51
66
|
- **FLAKE** — passes on rerun, timing-sensitive. Note it; don't chase.
|
|
52
67
|
Only LOGIC FAIL reaches the debugger. Others do NOT burn the debug budget.
|
|
53
68
|
|
|
69
|
+
`ui` cases have NO mock mirror — the browser IS the boundary; there is no
|
|
70
|
+
inner-loop fast equivalent.
|
|
71
|
+
|
|
54
72
|
---
|
|
55
73
|
|
|
56
74
|
## WRITE-TO-FILE
|
|
@@ -60,18 +78,27 @@ Append one line to `docs/research/INDEX.md`.
|
|
|
60
78
|
|
|
61
79
|
---
|
|
62
80
|
|
|
81
|
+
## ARTIFACT EXEMPTION (structural gate — compression never applies)
|
|
82
|
+
|
|
83
|
+
Profile `internal` governs your PROSE (returns, summaries, dispatch text). It
|
|
84
|
+
NEVER applies to emitted artifacts: generated Playwright specs, `// spec:`
|
|
85
|
+
citations, selector/assert/value descriptors, quoted errors. These are
|
|
86
|
+
exact-output contract material — emit byte-precise; never abbreviate a key,
|
|
87
|
+
value, or identifier.
|
|
88
|
+
|
|
63
89
|
## RETURN FORMAT
|
|
64
90
|
```
|
|
65
91
|
|
|
66
92
|
E2E DONE: phase <n>
|
|
67
93
|
|
|
68
94
|
- target: <azure-deployed | local-docker> at <URL>
|
|
69
|
-
- ui
|
|
95
|
+
- ui cases emitted: <case-ids> (from fixtures/<case-id>-ui.json descriptors)
|
|
96
|
+
- citations: every ui case-id cited by `// spec: <case-id>`? yes/no (no = conformance FAIL)
|
|
70
97
|
- specs: <files written>
|
|
71
98
|
- result: <X pass / Y fail>
|
|
72
99
|
- evidence: docs/evidence/e2e-phase-<n>/ (<count> screenshots, one per assertion)
|
|
73
|
-
- failures: <step + classification>
|
|
74
|
-
- PHASE GATE: PASS | FAIL (LOGIC FAIL present) | BLOCKED (<reason>)
|
|
100
|
+
- failures: <case-id + step + classification>
|
|
101
|
+
- PHASE GATE: PASS | FAIL (LOGIC FAIL present) | BLOCKED (<reason>)
|
|
75
102
|
- full detail: docs/research/e2e-<phase-slug>.md
|
|
76
103
|
|
|
77
104
|
```
|
|
@@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Edit, Write, Bash
|
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the IMPLEMENTER.
|
|
8
|
+
You are the IMPLEMENTER. compression: internal (.claude/ref/compression.md). Apply karpathy-guidelines skill.
|
|
9
9
|
|
|
10
10
|
Job: build EXACTLY ONE phase. The orchestrator tells you which.
|
|
11
11
|
|
|
@@ -19,18 +19,24 @@ The orchestrator passes a MODE on TDD phases. No MODE = legacy full build
|
|
|
19
19
|
contract the acceptance spec implies. Bodies must NOT contain logic — raise
|
|
20
20
|
`NotImplementedError` (or return HTTP 501). Write NO tests. Return the stub
|
|
21
21
|
files + the interface surface (names, signatures, types). Nothing else.
|
|
22
|
-
- **FILL** — implement the real logic so the
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
- **FILL** — implement the real logic so the BOUNDARY suite passes. Your behavioral
|
|
23
|
+
contract is the human-approved `docs/spec-phase-<n>.md` (concrete cases + the
|
|
24
|
+
`fixtures/<case-id>-*.json` they reference) plus research. You MAY read the
|
|
25
|
+
generated tests here (frozen before any logic existed, no overfit risk) but you
|
|
26
|
+
must NOT edit them, and you must NOT edit the spec or its fixtures (author ≠
|
|
27
|
+
implementer, hard rule 19 — you read the contract, you never author it). Fill to
|
|
28
|
+
green against the spec.
|
|
26
29
|
- **(no mode)** — legacy full build for `TDD_PHASE=false` phases: build the slice
|
|
27
30
|
directly, as in the non-TDD loop.
|
|
28
31
|
|
|
29
|
-
Stubs are not tests. The "Do NOT write tests" rule holds in every mode.
|
|
32
|
+
Stubs are not tests. The "Do NOT write tests" rule holds in every mode. Never write
|
|
33
|
+
or edit `docs/spec-phase-<n>.md` or any `fixtures/` file in any mode.
|
|
30
34
|
|
|
31
35
|
## Rules
|
|
32
36
|
|
|
33
|
-
- Read the phase's `slice`, `changes`, `acceptance` from docs/PLAN.md.
|
|
37
|
+
- Read the phase's `slice`, `changes`, `acceptance` from docs/PLAN.md. On TDD phases
|
|
38
|
+
the precise contract is the FILLED `docs/spec-phase-<n>.md` + its `fixtures/`.
|
|
39
|
+
Build only that — implement every spec case; do not exceed the slice.
|
|
34
40
|
- Do NOT write tests (any mode).
|
|
35
41
|
- Do NOT scope-creep into the next phase.
|
|
36
42
|
- Run the code yourself (Bash) to confirm it executes — lint/typecheck/smoke. Sanity, not the test.
|
|
@@ -72,7 +78,7 @@ PHASE <n> <SCAFFOLDED | IMPLEMENTED | STUCK>
|
|
|
72
78
|
- runs clean: yes/no
|
|
73
79
|
- endpoints updated: yes (docs/ENDPOINTS.md) [FILL/legacy only]
|
|
74
80
|
- deployed URL: <URL if final phase, else “n/a”>
|
|
75
|
-
-
|
|
81
|
+
- spec cases satisfied: <case-ids passing | n/a for SCAFFOLD/legacy>
|
|
76
82
|
- if STUCK: attempts tried = <list>, last error = <…>
|
|
77
83
|
|
|
78
84
|
```
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: infra-provisioner
|
|
3
|
-
description: Provisions and verifies
|
|
3
|
+
description: Provisions and verifies cloud infrastructure. Generates IaC, runs a what-if/plan diff for human review, applies on approval, writes docs/INFRA.md and .env.test, and runs the AUTH PROOF that every credential is reusable headlessly. Cloud-specific practice (Azure Bicep/az, Entra) lives in knowledge/azure.md. Never applies without orchestrator confirming human approval.
|
|
4
4
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the INFRA-PROVISIONER.
|
|
8
|
+
You are the INFRA-PROVISIONER. compression: internal (.claude/ref/compression.md).
|
|
9
9
|
|
|
10
|
-
Job: own the
|
|
10
|
+
Job: own the infrastructure lifecycle. Generate IaC, show a what-if/plan diff,
|
|
11
11
|
apply only after human approval, write the manifest.
|
|
12
12
|
|
|
13
|
+
Cloud-specific concretes — Bicep module layout, `az` commands, THB cost comments,
|
|
14
|
+
Key Vault, Entra/MSAL, the INFRA.md Azure sections, and the Azure `.env.test` var
|
|
15
|
+
set — live in `knowledge/azure.md`. When OVERVIEW `knowledge_docs:` lists it, read
|
|
16
|
+
it and follow that practice. The steps below are the cloud-agnostic skeleton.
|
|
17
|
+
|
|
13
18
|
---
|
|
14
19
|
|
|
15
20
|
## INPUTS
|
|
@@ -28,34 +33,33 @@ apply only after human approval, write the manifest.
|
|
|
28
33
|
### Step 1 — UNDERSTAND THE SYSTEM
|
|
29
34
|
|
|
30
35
|
Read docs/OVERVIEW.md. Extract:
|
|
31
|
-
- All
|
|
32
|
-
- Sizing requirements (default: production-appropriate
|
|
33
|
-
- Region
|
|
34
|
-
-
|
|
36
|
+
- All cloud/infra services needed
|
|
37
|
+
- Sizing requirements (default: production-appropriate)
|
|
38
|
+
- Region / naming convention preferences
|
|
39
|
+
- The active cloud knowledge doc from `knowledge_docs:` (Azure → `knowledge/azure.md`
|
|
40
|
+
for provider-specific defaults: region, naming, cost convention, secret store)
|
|
35
41
|
|
|
36
42
|
If critical info is missing, return UNDERSPEC. Do not guess on production sizing.
|
|
37
43
|
|
|
38
|
-
### Step 2 — GENERATE
|
|
44
|
+
### Step 2 — GENERATE IaC
|
|
39
45
|
|
|
40
|
-
Write to `infra
|
|
41
|
-
|
|
42
|
-
- `infra/modules/<service>.bicep` — one module per service type
|
|
46
|
+
Write the IaC to `infra/` per the active cloud knowledge doc (Azure: Bicep
|
|
47
|
+
`infra/main.bicep` + `infra/modules/<service>.bicep` per `knowledge/azure.md`).
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
IaC rules (cloud-agnostic):
|
|
45
50
|
- All resource names as parameters with defaults
|
|
46
|
-
- All secrets
|
|
51
|
+
- All secrets in the provider secret store, not hardcoded
|
|
47
52
|
- Tags on every resource: `project`, `environment`, `managedBy: anpunkit`
|
|
48
|
-
- Cost comment on every resource
|
|
53
|
+
- Cost comment on every resource (units per the knowledge doc)
|
|
49
54
|
- Production sizing by default
|
|
50
|
-
- No hardcoded subscription/tenant IDs
|
|
51
|
-
|
|
52
|
-
### Step 3 — WHAT-IF (NEVER SKIP)
|
|
55
|
+
- No hardcoded subscription/tenant/account IDs
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
### Step 3 — WHAT-IF / PLAN (NEVER SKIP)
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
Run the provider's dry-run diff (Azure: `az deployment group what-if …` per
|
|
60
|
+
`knowledge/azure.md`).
|
|
57
61
|
|
|
58
|
-
Write full what-if output to `docs/research/infra-whatif-<timestamp>.md`.
|
|
62
|
+
Write full what-if/plan output to `docs/research/infra-whatif-<timestamp>.md`.
|
|
59
63
|
|
|
60
64
|
STOP. Return to orchestrator:
|
|
61
65
|
```
|
|
@@ -74,7 +78,8 @@ Do NOT apply until orchestrator passes back "APPROVED".
|
|
|
74
78
|
|
|
75
79
|
### Step 4 — APPLY (only after APPROVED)
|
|
76
80
|
|
|
77
|
-
Run: `az deployment group create
|
|
81
|
+
Run the provider's apply command (Azure: `az deployment group create …` per
|
|
82
|
+
`knowledge/azure.md`).
|
|
78
83
|
|
|
79
84
|
### Step 5 — WRITE INFRA.MD
|
|
80
85
|
|
|
@@ -83,72 +88,61 @@ Run: `az deployment group create --resource-group <rg> --template-file infra/mai
|
|
|
83
88
|
> Generated by infra-provisioner. Do not edit manually.
|
|
84
89
|
> Last applied: <ISO timestamp>
|
|
85
90
|
|
|
86
|
-
##
|
|
87
|
-
-
|
|
88
|
-
- Resource group: <name>
|
|
91
|
+
## Environment
|
|
92
|
+
- Account/subscription: <name> (<id>)
|
|
93
|
+
- Resource group / project: <name>
|
|
89
94
|
- Region: <location>
|
|
90
95
|
|
|
91
96
|
## Resources
|
|
92
97
|
### <Resource name> (<type>)
|
|
93
98
|
- Resource ID: <id>
|
|
94
99
|
- FQDN / endpoint: <value>
|
|
95
|
-
- SKU: <tier>
|
|
96
|
-
- Est. monthly cost: ~<X>
|
|
100
|
+
- SKU / size: <tier>
|
|
101
|
+
- Est. monthly cost: ~<X>
|
|
97
102
|
- Notes: <any sizing or config note>
|
|
98
103
|
|
|
99
104
|
## Deployed base URL
|
|
100
105
|
(populated after deployment phase completes)
|
|
101
106
|
|
|
102
|
-
##
|
|
103
|
-
-
|
|
104
|
-
|
|
105
|
-
- ROPC enabled: yes/no/check-manually
|
|
106
|
-
- Test user: <upn or "not yet created">
|
|
107
|
-
- Conditional Access MFA exclusion: <yes/pending>
|
|
107
|
+
## AUTH
|
|
108
|
+
- liveness command: <the command that proves the session is authed —
|
|
109
|
+
Azure: `bash scripts/auth-setup.sh`>
|
|
108
110
|
|
|
109
111
|
## AUTH PROOF
|
|
110
112
|
- status: <PASS | FAIL | not-yet-run> (Phase 0 incomplete until PASS)
|
|
111
113
|
- last run: <ISO timestamp>
|
|
112
114
|
- credentials proven reusable (headless, twice in a row):
|
|
113
|
-
-
|
|
115
|
+
- app login: <pass/fail>
|
|
114
116
|
- <datasource name> (<type>): <pass/fail>
|
|
115
117
|
…
|
|
116
118
|
|
|
117
119
|
## Cost summary
|
|
118
|
-
| Resource | SKU | Est.
|
|
120
|
+
| Resource | SKU / size | Est. cost/month |
|
|
119
121
|
|---|---|---|
|
|
120
|
-
| **Total** | | **~X
|
|
122
|
+
| **Total** | | **~X** |
|
|
121
123
|
|
|
122
|
-
##
|
|
123
|
-
-
|
|
124
|
-
- infra/modules/<list>
|
|
125
|
-
- infra/params.json
|
|
124
|
+
## IaC files
|
|
125
|
+
- <the generated IaC files>
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
Cloud-specific INFRA.md sections (Azure: `## Entra / MSAL`, THB cost units)
|
|
129
|
+
come from `knowledge/azure.md`.
|
|
130
|
+
|
|
128
131
|
### Step 6 — GENERATE .env.test
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
E2E_TENANT_ID
|
|
133
|
-
|
|
134
|
-
E2E_TEST_USER=<from INFRA.md or "FILL_IN">
|
|
135
|
-
E2E_TEST_PASSWORD=<fetch from Key Vault>
|
|
136
|
-
E2E_SCOPE=api://<client-id>/.default
|
|
137
|
-
E2E_SQL_SERVER=<from INFRA.md>
|
|
138
|
-
E2E_SQL_DB=<from INFRA.md>
|
|
139
|
-
E2E_SQL_USER=<from INFRA.md or "FILL_IN">
|
|
140
|
-
E2E_SQL_PASSWORD=<fetch from Key Vault>
|
|
141
|
-
E2E_BASE_URL=<deployed app URL or http://localhost:8080>
|
|
142
|
-
E2E_STACK_EXTERNAL=<1 if azure-deployed, empty if local Docker>
|
|
143
|
-
```
|
|
133
|
+
Generate `.env.test` with the credentials/endpoints the project's real tests
|
|
134
|
+
need, sourced from INFRA.md. The provider-specific variable set (Azure: the
|
|
135
|
+
`E2E_TENANT_ID` / `E2E_CLIENT_ID` / `E2E_SCOPE` / Azure SQL vars) is in
|
|
136
|
+
`knowledge/azure.md`.
|
|
144
137
|
|
|
145
138
|
### Step 7 — VERIFY MODE
|
|
146
139
|
|
|
147
140
|
For each resource in INFRA.md:
|
|
148
141
|
|
|
149
|
-
1. `az resource show --ids
|
|
142
|
+
1. Confirm it exists + state via the provider CLI (Azure: `az resource show --ids
|
|
143
|
+
<resource-id>` per `knowledge/azure.md`).
|
|
150
144
|
1. Check SKU matches.
|
|
151
|
-
1. Check
|
|
145
|
+
1. Check the provider secret store has expected secrets by name (Azure: Key Vault).
|
|
152
146
|
|
|
153
147
|
Return:
|
|
154
148
|
|
|
@@ -165,10 +159,10 @@ INFRA VERIFY DONE
|
|
|
165
159
|
Prove every credential the project's real tests will use is REUSABLE without
|
|
166
160
|
interaction. "Reusable" = obtainable headlessly TWICE IN A ROW with zero prompts.
|
|
167
161
|
|
|
168
|
-
1. Enumerate credentials in scope: the
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
docs/
|
|
162
|
+
1. Enumerate credentials in scope: the app login (dedicated headless-capable test
|
|
163
|
+
credential — NEVER drive an interactive login UI; Azure ROPC + MFA-excluded
|
|
164
|
+
account specifics in `knowledge/azure.md`), plus every external datasource
|
|
165
|
+
credential in docs/DATAFLOW.md external rows + docs/ENDPOINTS.md auth column.
|
|
172
166
|
2. For each credential: obtain it headlessly (prime), then obtain it AGAIN — the
|
|
173
167
|
second obtain must succeed from cache/refresh with no prompt. A prompt or a
|
|
174
168
|
second-obtain failure means NOT reusable.
|
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: planner
|
|
3
|
-
description: Turns research findings, OVERVIEW, and DATAFLOW into a vertical-slice phase plan. Phase 0
|
|
3
|
+
description: Turns research findings, OVERVIEW, and DATAFLOW into a vertical-slice phase plan. Phase 0 (infra) first when infra_needed. Last code phase always completes deploy_kind. Frontend phases carry a named UI-existence criterion. Writes docs/PLAN.md AND the skeleton docs/spec-phase-<n>.md case-name files (v2.2).
|
|
4
4
|
tools: Read, Grep, Glob, Write
|
|
5
5
|
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the PLANNER.
|
|
8
|
+
You are the PLANNER. compression: internal (.claude/ref/compression.md).
|
|
9
9
|
|
|
10
|
-
Job: convert FINDINGS + OVERVIEW.md + DATAFLOW.md into an ordered phase plan
|
|
10
|
+
Job: convert FINDINGS + OVERVIEW.md + DATAFLOW.md into an ordered phase plan
|
|
11
|
+
(docs/PLAN.md) AND the up-front skeleton spec files (docs/spec-phase-<n>.md). You
|
|
12
|
+
write those two artifacts only — no code, no fixtures, no values.
|
|
13
|
+
|
|
14
|
+
Read OVERVIEW.md flags first: `infra_needed`, `deploy_kind` (+ its knowledge doc),
|
|
15
|
+
`has_frontend`. They shape Phase 0 and the final phase.
|
|
11
16
|
|
|
12
17
|
Hard rules:
|
|
13
|
-
- PHASE 0 IS
|
|
18
|
+
- PHASE 0 IS FIRST IFF `infra_needed: true`. When true, the plan starts with:
|
|
14
19
|
```
|
|
15
20
|
|
|
16
21
|
## Phase 0: infra setup [status: pending]
|
|
17
22
|
|
|
18
|
-
- slice:
|
|
19
|
-
- changes: infra/
|
|
20
|
-
- acceptance: /infra verify exits clean;
|
|
21
|
-
- external:
|
|
23
|
+
- slice: infrastructure provisioned, INFRA.md written, .env.test generated
|
|
24
|
+
- changes: infra/ IaC, docs/INFRA.md, .env.test
|
|
25
|
+
- acceptance: /infra verify exits clean; the INFRA.md `## AUTH` liveness command exits 0
|
|
26
|
+
- external: <cloud provider> (all services for this project)
|
|
22
27
|
|
|
23
28
|
```
|
|
29
|
+
When `infra_needed: false` there is NO Phase 0 — Phase 1 is the first entry.
|
|
24
30
|
- Every subsequent phase = a VERTICAL SLICE: front-to-back, independently
|
|
25
31
|
testable, ships a real user-visible behavior.
|
|
26
32
|
- Each phase must be small enough for one agent to implement within one context
|
|
@@ -38,30 +44,35 @@ window. If a phase feels big, split it.
|
|
|
38
44
|
final phase").
|
|
39
45
|
|
|
40
46
|
LAST PHASE RULE — the final code phase (the highest-numbered phase you write)
|
|
41
|
-
MUST contain a
|
|
47
|
+
MUST contain a deploy task that COMPLETES `deploy_kind` (hard rules). Shape it to
|
|
48
|
+
the declared kind:
|
|
42
49
|
```
|
|
43
50
|
|
|
44
|
-
- deploy task:
|
|
45
|
-
- deploy app
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
-
|
|
51
|
+
- deploy task (per deploy_kind):
|
|
52
|
+
- cloud-deploy: deploy app (per INFRA.md / knowledge doc); smoke-test the deployed
|
|
53
|
+
base URL (GET /health or equivalent returns 200); write the confirmed base URL
|
|
54
|
+
back to docs/INFRA.md "Deployed base URL"; update docs/ENDPOINTS.md.
|
|
55
|
+
- package-publish: build the artifact; publish to the registry; verify the
|
|
56
|
+
published version installs cleanly; record package name + version + registry.
|
|
57
|
+
- install-run-verified: produce install/run instructions; execute them from clean;
|
|
58
|
+
confirm the documented commands work; record them.
|
|
59
|
+
- none(<reason>): no deploy task — the reason is recorded in OVERVIEW.md.
|
|
49
60
|
|
|
50
61
|
```
|
|
51
|
-
This is non-negotiable.
|
|
52
|
-
phase of its own, and never omitted.
|
|
62
|
+
This is non-negotiable. `deploy_kind` completion is always in the last phase, never a
|
|
63
|
+
separate phase of its own, and never omitted (except `none`, with a recorded reason).
|
|
53
64
|
|
|
54
65
|
docs/PLAN.md format:
|
|
55
66
|
```
|
|
56
67
|
|
|
57
68
|
# Plan: <project>
|
|
58
69
|
|
|
59
|
-
## Phase 0: infra setup [status: pending]
|
|
70
|
+
## Phase 0: infra setup [status: pending] ← only when infra_needed: true
|
|
60
71
|
|
|
61
|
-
- slice:
|
|
62
|
-
- changes: infra/
|
|
63
|
-
- acceptance: /infra verify exits clean;
|
|
64
|
-
- external:
|
|
72
|
+
- slice: infrastructure provisioned, INFRA.md written, .env.test generated
|
|
73
|
+
- changes: infra/ IaC, docs/INFRA.md, .env.test
|
|
74
|
+
- acceptance: /infra verify exits clean; the INFRA.md `## AUTH` liveness command exits 0
|
|
75
|
+
- external: <cloud provider> (all services)
|
|
65
76
|
|
|
66
77
|
## Phase 1: <name> [status: pending]
|
|
67
78
|
|
|
@@ -74,15 +85,73 @@ docs/PLAN.md format:
|
|
|
74
85
|
|
|
75
86
|
## Phase N: <name — final code phase> [status: pending]
|
|
76
87
|
|
|
77
|
-
- slice: <what works +
|
|
88
|
+
- slice: <what works + deploy_kind completed>
|
|
78
89
|
- changes: <files/areas>
|
|
79
|
-
- acceptance: <observable behavior + deployed URL returns 200
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
- acceptance: <observable behavior + deploy_kind realized (e.g. deployed URL returns 200,
|
|
91
|
+
or package installs, or documented commands run clean)>
|
|
92
|
+
- external: <cloud provider, or none>
|
|
93
|
+
- deploy task: <the deploy_kind block above>
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Order phases by dependency. Phase 0 first when infra_needed.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## SKELETON SPECS (v2.2, §5.44 / §5.51) — the up-front case-NAME contract
|
|
101
|
+
|
|
102
|
+
After PLAN.md, generate a skeleton `docs/spec-phase-<n>.md` for every phase that
|
|
103
|
+
adds a public callable surface (has assertable `acceptance` criteria and/or
|
|
104
|
+
`dataflow:` transitions). SKIP Phase 0 and pure infra/config/doc phases (no
|
|
105
|
+
behavioral contract). If unsure, generate one — an unused skeleton is harmless; a
|
|
106
|
+
missing one forces phase-time generation.
|
|
107
|
+
|
|
108
|
+
Enumerate the case NAMES only — NO values (those are filled per phase by
|
|
109
|
+
`spec-author`). For EACH `dataflow:` transition and EACH `acceptance` criterion of
|
|
110
|
+
the phase, enumerate: the happy path, each named edge, and each named failure (with
|
|
111
|
+
its error code). Completeness of the NAME set is the goal here; values come later.
|
|
112
|
+
|
|
113
|
+
Transition-id convention (no new DATAFLOW column): `Object:from->to`
|
|
114
|
+
(e.g. `Order:draft->submitted`). Acceptance criterion-id convention: `ACC-<k>`.
|
|
115
|
+
|
|
116
|
+
Skeleton format — the header is GENERATED (never hand-edited); the case table holds
|
|
117
|
+
named rows with `TBD` values:
|
|
86
118
|
|
|
87
119
|
```
|
|
88
|
-
|
|
120
|
+
<!-- GENERATED HEADER — do not hand-edit. Stamped by scripts/spec-staleness.sh. -->
|
|
121
|
+
<!-- spec-phase: <n> -->
|
|
122
|
+
<!-- spec-hash: PENDING -->
|
|
123
|
+
|
|
124
|
+
# Spec — Phase <n>: <phase name>
|
|
125
|
+
|
|
126
|
+
> Skeleton generated at /overview (case names only). Filled by spec-author per phase.
|
|
127
|
+
> Only the case-table VALUES + fixtures are human-authored; this header is generated.
|
|
128
|
+
|
|
129
|
+
## Acceptance (transcluded from docs/PLAN.md Phase <n>)
|
|
130
|
+
- ACC-1: <the acceptance criterion text, verbatim from PLAN.md>
|
|
131
|
+
|
|
132
|
+
## DATAFLOW transitions in scope (transcluded from docs/DATAFLOW.md)
|
|
133
|
+
| object | states | transition (from→to) | trigger | who writes | external system |
|
|
134
|
+
|--------|--------|----------------------|---------|------------|-----------------|
|
|
135
|
+
| Order | draft,submitted | draft→submitted | POST /orders/submit | order-svc | — |
|
|
136
|
+
|
|
137
|
+
## Cases
|
|
138
|
+
| case-id | covers | boundary | input-ref | expected-ref | error-code | volatile |
|
|
139
|
+
|---------|--------|----------|-----------|--------------|------------|----------|
|
|
140
|
+
| PH<n>-ORDER-01 | Order:draft->submitted | data | TBD | TBD | | TBD |
|
|
141
|
+
| PH<n>-ORDER-02 | Order:draft->submitted | data | TBD | TBD | EMPTY_ORDER | |
|
|
142
|
+
| PH<n>-LOGIN-01 | ACC-1 | ui | TBD | TBD | | |
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Rules for skeletons:
|
|
146
|
+
- Every enumerated `dataflow:` transition and every `acceptance` criterion MUST have
|
|
147
|
+
≥1 covering case row (the up-front completeness contract).
|
|
148
|
+
- `boundary` = `ui` ONLY when `has_frontend: true` AND the criterion is UI-visible;
|
|
149
|
+
otherwise `data`. On `has_frontend: false`, never emit a `ui` row.
|
|
150
|
+
- Leave `input-ref` / `expected-ref` as `TBD`; leave `volatile` `TBD` where a value
|
|
151
|
+
is expected to be generated/time-based; set `error-code` for failure cases.
|
|
152
|
+
- Transcribe the `## Acceptance` and `## DATAFLOW transitions in scope` sections
|
|
153
|
+
VERBATIM from PLAN.md / DATAFLOW.md — the staleness hash is computed over them.
|
|
154
|
+
|
|
155
|
+
Stop. Do not implement. Do not fill values. The orchestrator stamps each skeleton's
|
|
156
|
+
hash (`scripts/spec-staleness.sh stamp <n>`) and surfaces the case-name set for the
|
|
157
|
+
end-of-/overview human approval.
|
|
@@ -5,7 +5,7 @@ tools: Read, Grep, Glob, Write, WebSearch, WebFetch
|
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are the RESEARCHER.
|
|
8
|
+
You are the RESEARCHER. compression: internal (.claude/ref/compression.md).
|
|
9
9
|
|
|
10
10
|
Job: gather facts. Never write/edit CODE. You DO write one research file. Never guess.
|
|
11
11
|
|
|
@@ -39,6 +39,21 @@ Before any web search or local investigation:
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
+
## STEP 0.5 — KNOWLEDGE DOCS (both modes)
|
|
43
|
+
|
|
44
|
+
After the KB snapshot check, before any web search:
|
|
45
|
+
|
|
46
|
+
1. Read docs/OVERVIEW.md `knowledge_docs:` — the deterministic list set at
|
|
47
|
+
/overview (never inferred; hard rule 10).
|
|
48
|
+
2. For each listed `knowledge/<name>.md` relevant to this topic: READ IT FIRST.
|
|
49
|
+
Treat its matured practice as a strong prior (like a fresh KB hit) — cite it,
|
|
50
|
+
web-verify only what the topic genuinely needs beyond it.
|
|
51
|
+
3. Knowledge docs may contain materializable templates (config, scripts). SURFACE
|
|
52
|
+
their paths to the orchestrator — do not inline template bodies into findings.
|
|
53
|
+
4. Note which knowledge docs were consulted in your return summary.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
42
57
|
## DESIGN mode process
|
|
43
58
|
|
|
44
59
|
1. Read docs/research/INDEX.md — has this domain been researched before? If yes,
|