archgen-skill 0.0.3 → 0.0.5
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/README.md +31 -33
- package/bin/archgen.mjs +31 -1
- package/lib/block.js +147 -16
- package/lib/config.js +96 -0
- package/lib/doctor.js +144 -28
- package/lib/init.js +14 -3
- package/lib/install.js +124 -16
- package/lib/migrate.js +88 -0
- package/lib/migrations/001-stamp-provenance.mjs +77 -0
- package/lib/migrations/index.mjs +170 -0
- package/lib/restore.js +239 -0
- package/lib/store.js +125 -15
- package/lib/uninstall-project.js +6 -3
- package/lib/version-stamp.js +49 -0
- package/package.json +39 -10
- package/vendor/skills/archgen/SKILL.md +218 -145
- package/vendor/skills/archgen/archgen.config.json +16 -0
- package/vendor/skills/archgen/assets/skill-registry.json +4 -3
- package/vendor/skills/archgen/references/artifact-templates.md +308 -7
- package/vendor/skills/archgen/references/interview.md +226 -17
- package/vendor/skills/archgen/references/mcp-and-skills.md +88 -17
- package/vendor/skills/archgen/references/orchestration.md +230 -44
- package/vendor/skills/archgen/references/platforms.md +56 -14
- package/vendor/skills/archgen/scripts/doc-index.mjs +457 -0
- package/vendor/skills/archgen/scripts/impact.mjs +14 -1
- package/vendor/skills/archgen/scripts/lib/graph.mjs +99 -5
- package/vendor/skills/archgen/scripts/lib/scope.mjs +65 -0
- package/vendor/skills/archgen/scripts/lib/yaml.mjs +19 -3
- package/vendor/skills/archgen/scripts/plan-graph.mjs +329 -0
- package/vendor/skills/archgen/scripts/set-status.mjs +51 -9
- package/vendor/skills/archgen/scripts/update-agents.mjs +16 -5
- package/vendor/skills/archgen/scripts/validate.mjs +18 -1
- package/vendor/skills/archgen/scripts/verify-plan.mjs +8 -3
|
@@ -1,7 +1,166 @@
|
|
|
1
1
|
# Artifact templates — copy, fill, never invent structure
|
|
2
2
|
|
|
3
|
+
## Provenance header (SHOULD on every NEW tasks.yaml / architecture.yaml)
|
|
4
|
+
|
|
5
|
+
Begin both files with three YAML comment lines. Comments are ignored by every
|
|
6
|
+
consumer (skill scripts, VS Code extension, any YAML toolchain), so this is
|
|
7
|
+
purely additive metadata — it can never break a parser:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
# schema_version: 1
|
|
11
|
+
# generator: archgen v0.0.4
|
|
12
|
+
# generated_at: 2026-08-26T09:00:00.000Z
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Version token rules — code-defensive, NEVER guess:
|
|
16
|
+
|
|
17
|
+
1. If a `.archgen-version` stamp sits next to `SKILL.md` (the installed skill
|
|
18
|
+
root) and reads as exact `MAJOR.MINOR.PATCH`, write `generator: archgen vX.Y.Z`.
|
|
19
|
+
2. Else if an adjacent `archgen.config.json` carries a semver-shaped
|
|
20
|
+
`"version"` field, use that value the same way.
|
|
21
|
+
3. Else omit the version token entirely: plain `# generator: archgen`.
|
|
22
|
+
|
|
23
|
+
`generated_at` is one ISO-8601 timestamp per generation run (all files written
|
|
24
|
+
by the same run share it). Keep the header at the very top of the file; never
|
|
25
|
+
place content above it and never encode meaning anywhere except these three
|
|
26
|
+
lines.
|
|
27
|
+
|
|
28
|
+
Older artifacts without the header are backfilled by
|
|
29
|
+
`npx archgen-skill migrate --apply` (dry-run `--check` is the default), which
|
|
30
|
+
snapshots each file into `.archgen/.backup/<ts>/migrate/` before touching it
|
|
31
|
+
and skips already-stamped files, so re-running is always safe.
|
|
32
|
+
|
|
33
|
+
## Self-containment rules (anti-hallucination)
|
|
34
|
+
|
|
35
|
+
Artifacts are executed by sessions and sub-agents that were NEVER part of the
|
|
36
|
+
conversation that produced them. Hard rules, no exceptions:
|
|
37
|
+
|
|
38
|
+
1. **Full paths, always.** Every task step, `file_ownership` glob, artifact,
|
|
39
|
+
and verification command uses complete repo-root-relative paths
|
|
40
|
+
(`src/features/catalog/api/routes.ts`), never bare filenames (`routes.ts`)
|
|
41
|
+
and never invented directories. Paths come from `structure:` /
|
|
42
|
+
`owns[]` in architecture.yaml or from surveyed code — nowhere else.
|
|
43
|
+
2. **Names derive from naming_conventions.** Every file, symbol, table, and
|
|
44
|
+
env-var name you introduce cites WHICH convention key produced it, e.g.
|
|
45
|
+
`camelCase symbols per naming_conventions.symbol_casing`. If no key covers
|
|
46
|
+
it, add the key first, then use it.
|
|
47
|
+
3. **Plans survive context summarization alone.** Any session reading ONLY
|
|
48
|
+
`.archgen/<slug>/` must execute correctly with zero chat history. If a fact
|
|
49
|
+
matters, it is written in an artifact; if it is not written, it does not
|
|
50
|
+
exist.
|
|
51
|
+
4. **Forbidden phrases** (in any artifact): "as discussed", "the usual
|
|
52
|
+
pattern", "same as before", "see chat". Replace each with the concrete
|
|
53
|
+
artifact reference it was standing in for.
|
|
54
|
+
5. **Cross-references are artifact-relative**, e.g.
|
|
55
|
+
`see ../architecture.yaml data_contracts.orders` or
|
|
56
|
+
`payload per ../architecture.yaml api_contracts.payments.request_payload`.
|
|
57
|
+
Never restate a contract from memory — point at it.
|
|
58
|
+
6. **Verifier-compatible ids in plans.** `verify-plan.mjs` rejects any
|
|
59
|
+
UPPERCASE-numbered token in `plans/*.md` that is not a real tasks.yaml id
|
|
60
|
+
(`TASK-999` fails; your actual ids pass). So: requirement ids
|
|
61
|
+
(`FR-<MODULE>-nn`) are cited from `tasks.yaml` acceptance lines and
|
|
62
|
+
`docs/prd.md` itself; inside plan prose link the anchor instead —
|
|
63
|
+
`../docs/prd.md#fr-catalog-01`. Every tasks.yaml id MUST appear in some
|
|
64
|
+
plan file (coverage check runs both directions).
|
|
65
|
+
|
|
66
|
+
## Plan depth by scope class
|
|
67
|
+
|
|
68
|
+
Pick ONE class before writing any artifact; depth scales with risk, not
|
|
69
|
+
enthusiasm. Misclassifying is a defect: inflating SMALL wastes tokens,
|
|
70
|
+
shrinking LARGE hallucinates.
|
|
71
|
+
|
|
72
|
+
- **SMALL** (add/touch few things): lean plan-note shape stays —
|
|
73
|
+
|
|
74
|
+
```markdown
|
|
75
|
+
# <feature> — plan note (SMALL)
|
|
76
|
+
Intent: <one paragraph>
|
|
77
|
+
Tasks: see tasks.yaml entries <ids>
|
|
78
|
+
Risks: <bullets or none>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Every task entry STILL carries absolute-from-repo-root paths verbatim —
|
|
82
|
+
in `file_ownership`, in each step, in verification commands. No Context
|
|
83
|
+
section, no diagrams, no PRD.
|
|
84
|
+
|
|
85
|
+
- **MEDIUM**: `plans/<feature>.md` gains, in order:
|
|
86
|
+
- **Context** — 2–4 paragraphs max: why now, what exists, what changes.
|
|
87
|
+
- **Per-task sections** (one `<id> — <title>` heading per task):
|
|
88
|
+
Approach (short bullets) + **Edge cases** (min 3 bullets each, feeding
|
|
89
|
+
the edge-case matrix below) + **Out-of-scope** (explicit non-goals).
|
|
90
|
+
- **Verification steps** — ordered, runnable, repo-root-relative.
|
|
91
|
+
No PRD, no diagrams unless structure changed.
|
|
92
|
+
|
|
93
|
+
- **LARGE / greenfield-from-scratch**: FULL professional stack — PRD
|
|
94
|
+
(`docs/prd.md`, ~1 page per major module) + expanded `architecture.yaml`
|
|
95
|
+
(naming_conventions, data_contracts, api_contracts, environment_matrix) +
|
|
96
|
+
per-task edge-case matrices + per-module diagrams + MEDIUM-grade plan
|
|
97
|
+
sections. Every diagram ≤15 nodes.
|
|
98
|
+
|
|
99
|
+
## Structural correctness — verifier-enforced authoring rules
|
|
100
|
+
|
|
101
|
+
- **Waves derive from `depends_on`.** Declared wave / `parallel_group` labels
|
|
102
|
+
MUST match the dependency-derived topological order — never hand-label a
|
|
103
|
+
task into a wave that contradicts its `depends_on`. A dependent task may not
|
|
104
|
+
sit in an earlier (or parallel) wave than its prerequisite.
|
|
105
|
+
`plan-graph.mjs --mermaid` is the ground truth for wave order.
|
|
106
|
+
- **artifacts ⊆ file_ownership.** Every path a task lists in `artifacts` must
|
|
107
|
+
fall inside that task's `file_ownership` globs — workers can write ONLY
|
|
108
|
+
owned paths. Listing a doc the task doesn't own is a verifier-blocking
|
|
109
|
+
defect.
|
|
110
|
+
- **Verification commands**: repo-root-relative (no `../`, no `--plan .`),
|
|
111
|
+
fully specific — exact commands, versions, sample sizes, thresholds — the
|
|
112
|
+
same form a worker would actually run. Generic "run the tests" or
|
|
113
|
+
wrong-root-resolved paths fail.
|
|
114
|
+
- **YAML subset**: emit only the parser's supported subset — block mappings
|
|
115
|
+
and block sequences only. Avoid flow mappings (`{...}`), block scalars
|
|
116
|
+
(`|` / `>`), duplicate keys, and comma-heavy inline values, which the
|
|
117
|
+
strict parser rejects (these caused format-repair loops).
|
|
118
|
+
- **tasks.yaml edits**: make small targeted edits or one clean full
|
|
119
|
+
regeneration — never large multi-region patches (they corrupted tasks.yaml
|
|
120
|
+
in the field).
|
|
121
|
+
|
|
122
|
+
## Agent workspace & artifact location — the two-tier rule
|
|
123
|
+
|
|
124
|
+
Location follows LIFETIME + AUDIENCE: the plan (and its rationale) travels as
|
|
125
|
+
ONE self-contained, reviewable, git-versioned unit; the product's deliverables
|
|
126
|
+
travel with the product.
|
|
127
|
+
|
|
128
|
+
INSIDE `.archgen/<slug>/` — the plan + everything needed to execute/review it:
|
|
129
|
+
- tasks.yaml, plans/, architecture.yaml, answers.yaml, codebase-map.md.
|
|
130
|
+
- `docs/prd.md` — a PLANNING artifact (defines the FR-ids tasks cite), not a
|
|
131
|
+
shipped doc — stays inside so doc-index can validate FR references.
|
|
132
|
+
- `decisions/NNNN-title.md` — the plan's formal ADRs (its rationale). Inside
|
|
133
|
+
keeps the feature folder self-contained and ADR↔task↔plan references valid.
|
|
134
|
+
- `.agent/` — ALL agent/sub-agent working state. The leading dot keeps it out
|
|
135
|
+
of doc-index scans (process state, not a validated artifact):
|
|
136
|
+
- `.agent/decisions/NNNN-<slug>.md` — EXECUTION-time decisions a sub-agent
|
|
137
|
+
takes while working (distinct from the plan's formal ADRs in `decisions/`).
|
|
138
|
+
- `.agent/learnings.md` — conventions/patterns discovered (append-only).
|
|
139
|
+
- `.agent/notes/<task-id-or-topic>.md` — worker/survey/investigator notes.
|
|
140
|
+
- `.agent/reports/<verifier|reviewer|investigate>-<round>.md` — persisted
|
|
141
|
+
verifier/reviewer/investigation findings.
|
|
142
|
+
|
|
143
|
+
OUTSIDE `.archgen/` — project DELIVERABLES an approved task produces, written
|
|
144
|
+
to the task's `file_ownership` paths at the repo root (never into `.archgen/`):
|
|
145
|
+
- source code (`src/...`), and
|
|
146
|
+
- shipped documentation: README, API reference, deployment/runbooks, user
|
|
147
|
+
guides — the docs the running software ships to users/operators.
|
|
148
|
+
|
|
149
|
+
Enterprise refinement — durable ADRs: a decision that outlives this feature
|
|
150
|
+
(project-wide, e.g. "Postgres over MongoDB") SHOULD also be promoted to the
|
|
151
|
+
project's canonical ADR register (`docs/adr/` or the team's equivalent) so
|
|
152
|
+
future features discover it. `.archgen/<slug>/decisions/` is the working
|
|
153
|
+
record; the register is the durable project-wide copy. Never delete or
|
|
154
|
+
re-number an accepted ADR — supersede it.
|
|
155
|
+
|
|
3
156
|
## architecture.yaml (LARGE scope)
|
|
4
157
|
|
|
158
|
+
The four contract blocks below (`naming_conventions`, `data_contracts`,
|
|
159
|
+
`api_contracts`, `environment_matrix`) are THE anti-hallucination source of
|
|
160
|
+
truth: tasks cite them by key instead of re-describing shapes from memory.
|
|
161
|
+
Module entries extend `schemas/architecture-conventions.md` (its
|
|
162
|
+
`name`/`responsibility`/`owns[]` trio is unchanged and still normative).
|
|
163
|
+
|
|
5
164
|
```yaml
|
|
6
165
|
name: Acme Shop
|
|
7
166
|
slug: acme-shop # becomes .archgen/acme-shop/
|
|
@@ -17,13 +176,44 @@ structure: # planned folder tree — planned BEFORE code exists
|
|
|
17
176
|
purpose: cross-feature utilities, no feature imports
|
|
18
177
|
- path: src/config/
|
|
19
178
|
purpose: env parsing + constants
|
|
179
|
+
naming_conventions: # filled during generation; referenced by EVERY task
|
|
180
|
+
file_naming: kebab-case files, feature folder mirrors module name
|
|
181
|
+
dir_layout: "<module>/{api,internal,tests}; shared code only in src/shared/"
|
|
182
|
+
symbol_casing: PascalCase types, camelCase functions, SCREAMING_SNAKE env
|
|
183
|
+
test_placement: colocated <name>.test.ts next to unit under test
|
|
20
184
|
modules:
|
|
21
185
|
- name: catalog
|
|
22
186
|
responsibility: product browsing + search
|
|
23
187
|
owns: ["src/features/catalog/**"]
|
|
188
|
+
depends_on_modules: [] # acyclic; drives task depends_on edges
|
|
189
|
+
key_interfaces: # what OTHER modules may import — nothing else
|
|
190
|
+
- CatalogApi (src/features/catalog/api/index.ts)
|
|
24
191
|
- name: checkout
|
|
25
192
|
responsibility: cart → payment orchestration
|
|
26
193
|
owns: ["src/features/checkout/**"]
|
|
194
|
+
depends_on_modules: [catalog]
|
|
195
|
+
key_interfaces:
|
|
196
|
+
- CheckoutApi (src/features/checkout/api/index.ts)
|
|
197
|
+
data_contracts: # schemas/entities; field tables, not prose
|
|
198
|
+
orders:
|
|
199
|
+
storage: postgres table orders (migration migrations/NNNN_orders.sql)
|
|
200
|
+
fields:
|
|
201
|
+
- {field: id, type: uuid, required: true, notes: pk}
|
|
202
|
+
- {field: session_id, type: uuid, required: true, notes: fk sessions}
|
|
203
|
+
- {field: total_cents, type: integer, required: true, notes: >= 0}
|
|
204
|
+
- {field: status, type: enum(pending,paid,failed), required: true}
|
|
205
|
+
- {field: created_at, type: timestamptz, required: true, notes: db default now()}
|
|
206
|
+
api_contracts: # endpoint/method/auth/payload/error-shape tables
|
|
207
|
+
payments:
|
|
208
|
+
- endpoint: /api/checkout/pay
|
|
209
|
+
method: POST
|
|
210
|
+
auth: session cookie; 401 when absent
|
|
211
|
+
request_payload: {order_id: uuid}
|
|
212
|
+
success: 200 {payment_id: uuid, status: paid}
|
|
213
|
+
error_shape: {code: string, message: string, retryable: boolean}
|
|
214
|
+
environment_matrix: # vars per env; unparsed vars fail fast in src/config/
|
|
215
|
+
- {var: DATABASE_URL, dev: local docker postgres, ci: ephemeral service, prod: secret ref, required: true}
|
|
216
|
+
- {var: PAYMENT_API_KEY, dev: stub key, ci: stub key, prod: secret ref, required: true}
|
|
27
217
|
decisions: # ADR-lite; full ADRs live in decisions/
|
|
28
218
|
- id: D1
|
|
29
219
|
title: Postgres over MongoDB
|
|
@@ -32,6 +222,49 @@ decisions: # ADR-lite; full ADRs live in decisions/
|
|
|
32
222
|
consequences: schema migrations required per release
|
|
33
223
|
```
|
|
34
224
|
|
|
225
|
+
Token balance: one contract block per module/domain (~10–20 lines each);
|
|
226
|
+
split further rather than letting any single block exceed ~40 lines.
|
|
227
|
+
|
|
228
|
+
## Product requirements document (PRD) — LARGE/greenfield
|
|
229
|
+
|
|
230
|
+
Written to `docs/prd.md` BEFORE tasks.yaml. Bullet-dense prose, zero filler
|
|
231
|
+
paragraphs; target ~1 page per major module. Requirement ids here are the
|
|
232
|
+
stable handles every task acceptance cites.
|
|
233
|
+
|
|
234
|
+
```markdown
|
|
235
|
+
# PRD — <project name>
|
|
236
|
+
|
|
237
|
+
## Problem statement & goals
|
|
238
|
+
- <pain, quantified where possible>
|
|
239
|
+
- Goals: <3–5 outcome bullets, each measurable>
|
|
240
|
+
|
|
241
|
+
## Non-goals
|
|
242
|
+
- <explicitly out; prevents scope creep mid-execution>
|
|
243
|
+
|
|
244
|
+
## Personas / stakeholders
|
|
245
|
+
- <persona>: <need>, <success looks like>
|
|
246
|
+
|
|
247
|
+
## Functional requirements — <module-name> (repeat per module)
|
|
248
|
+
- FR-<MODULE>-01: <single verifiable behavior statement>
|
|
249
|
+
- FR-<MODULE>-02: ...
|
|
250
|
+
<!-- ids are immutable once tasks reference them -->
|
|
251
|
+
|
|
252
|
+
## Non-functional requirements (measurable targets, no adjectives)
|
|
253
|
+
- Perf: p95 API latency < 300 ms at 50 rps; LCP < 2.5 s
|
|
254
|
+
- Security: authz check on every endpoint; no secrets in repo; OWASP top-10 reviewed
|
|
255
|
+
- i18n: all user-facing strings externalized; ICU plurals; RTL-safe layouts
|
|
256
|
+
- A11y: WCAG 2.1 AA; full keyboard nav; contrast ≥ 4.5:1
|
|
257
|
+
|
|
258
|
+
## Success metrics
|
|
259
|
+
- <metric>: <baseline> → <target> within <window>
|
|
260
|
+
|
|
261
|
+
## Risks & mitigations
|
|
262
|
+
- <risk> → <mitigation>, <owner task id or ADR ref>
|
|
263
|
+
|
|
264
|
+
## Open questions
|
|
265
|
+
- <question> — owner <name/role>, blocks <task id | none>
|
|
266
|
+
```
|
|
267
|
+
|
|
35
268
|
## tasks.yaml (canonical shape)
|
|
36
269
|
|
|
37
270
|
```yaml
|
|
@@ -41,7 +274,7 @@ tasks:
|
|
|
41
274
|
- id: C
|
|
42
275
|
title: Scaffold project skeleton + config loading
|
|
43
276
|
depends_on: []
|
|
44
|
-
file_ownership: ["src/config/**", "package.json"]
|
|
277
|
+
file_ownership: ["src/config/**", "package.json"] # FULL repo-root-relative paths, never bare filenames
|
|
45
278
|
acceptance:
|
|
46
279
|
- "npm run build exits 0"
|
|
47
280
|
- "config loads from env with typed schema"
|
|
@@ -62,17 +295,55 @@ tasks:
|
|
|
62
295
|
```
|
|
63
296
|
|
|
64
297
|
Rules encoded above: depends_on = prerequisites; ownership globs disjoint
|
|
65
|
-
within a wave; acceptance = objectively checkable statements.
|
|
298
|
+
within a wave; acceptance = objectively checkable statements. Acceptance
|
|
299
|
+
bullets SHOULD reference edge-matrix rows (`E1`–`En` of that task's matrix)
|
|
300
|
+
and, on LARGE, the FR ids they implement. Schema stays stable
|
|
301
|
+
(`schemas/tasks.schema.json`, schema_version 1) — no new required fields;
|
|
302
|
+
guidance lives in comments and plan files.
|
|
303
|
+
|
|
304
|
+
LARGE-grade example task (same schema, richer acceptance — sits beside the
|
|
305
|
+
minimal ones above, never replaces them):
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
- id: PAY-2
|
|
309
|
+
title: Order payment capture with retry
|
|
310
|
+
depends_on: [A]
|
|
311
|
+
parallel_group: wave-payments
|
|
312
|
+
file_ownership:
|
|
313
|
+
- src/features/checkout/internal/capture.ts # full path per naming_conventions.dir_layout
|
|
314
|
+
- src/features/checkout/internal/capture.test.ts # colocated per naming_conventions.test_placement
|
|
315
|
+
artifacts: ["docs/payment-retry.md"]
|
|
316
|
+
acceptance:
|
|
317
|
+
- "capture() sends idempotency key; double submit charges once (E3)"
|
|
318
|
+
- "gateway 5xx retries 3x exponential backoff, then raises PaymentFailed (E5)"
|
|
319
|
+
- "denied card → 402 with error_shape from ../architecture.yaml api_contracts.payments (FR-PAYMENTS-02)"
|
|
320
|
+
- "amounts render via session locale, cents-safe integer math (E6)"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Edge-case matrix (per task, MEDIUM+)
|
|
66
324
|
|
|
67
|
-
|
|
325
|
+
Each MEDIUM/LARGE task carries a matrix in its plan section. Every row MUST
|
|
326
|
+
map to an acceptance bullet — no orphan rows; every acceptance bullet SHOULD
|
|
327
|
+
trace to ≥1 row. Minimum coverage classes per task: empty/null, boundary
|
|
328
|
+
values, authz denied, concurrent/conflicting write, failure/retry path,
|
|
329
|
+
i18n/formatting edge. Tasks touching infra (migrations, deploys, queues)
|
|
330
|
+
ADD: partial-failure recovery, rollback story.
|
|
68
331
|
|
|
69
332
|
```markdown
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
333
|
+
| Case | Input/state | Expected behavior | Covered by |
|
|
334
|
+
| ---- | ------------------------------- | ------------------------------------ | ---------- |
|
|
335
|
+
| E1 | empty/null: cart with 0 items | 200, total 0, no gateway call | PAY-2#1 |
|
|
336
|
+
| E2 | boundary: qty = max allowed 999 | accepted; 1000 rejected with 422 | PAY-2#1 |
|
|
337
|
+
| E3 | concurrent: same order paid 2x | idempotency key → single charge | PAY-2#1 |
|
|
338
|
+
| E4 | authz denied: expired session | 401 error_shape, no state change | PAY-2#2 |
|
|
339
|
+
| E5 | failure/retry: gateway 5xx x3 | backoff retry then PaymentFailed | PAY-2#2 |
|
|
340
|
+
| E6 | i18n: locale de-DE, ¥-less cur | EUR formatting, correct decimal comma| PAY-2#3 |
|
|
74
341
|
```
|
|
75
342
|
|
|
343
|
+
`Covered by` = `<task-id>#<acceptance index>` (1-based, matching the
|
|
344
|
+
tasks.yaml `acceptance` array). Rows are additive across waves; keep each
|
|
345
|
+
matrix ≤10 rows — split into per-concern tables beyond that.
|
|
346
|
+
|
|
76
347
|
## ADR template (decisions/NNNN-title.md)
|
|
77
348
|
|
|
78
349
|
```markdown
|
|
@@ -103,3 +374,33 @@ graph LR
|
|
|
103
374
|
api --> db[(Postgres)]
|
|
104
375
|
api --> cache[(Redis)]
|
|
105
376
|
```
|
|
377
|
+
|
|
378
|
+
## Per-module diagram (LARGE)
|
|
379
|
+
|
|
380
|
+
For EACH `modules:` entry in architecture.yaml, one small flowchart of its
|
|
381
|
+
internal components plus its `depends_on_modules` edges (arrow points from
|
|
382
|
+
consumer to provider). Plus ONE integration diagram wiring all modules —
|
|
383
|
+
edges between modules only, no internals. HARD LIMIT: ≤15 nodes per diagram;
|
|
384
|
+
split into two diagrams rather than cramming. Internals stay ≤6 nodes per
|
|
385
|
+
module.
|
|
386
|
+
|
|
387
|
+
Catalog module (internal + inbound depends_on edge):
|
|
388
|
+
|
|
389
|
+
```mermaid
|
|
390
|
+
graph LR
|
|
391
|
+
subgraph catalog
|
|
392
|
+
routes[api routes] --> svc[search service]
|
|
393
|
+
svc --> repo[(product repository)]
|
|
394
|
+
end
|
|
395
|
+
checkout -.->|depends_on CatalogApi| routes
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Integration (modules as atoms, mirrors depends_on_modules):
|
|
399
|
+
|
|
400
|
+
```mermaid
|
|
401
|
+
graph LR
|
|
402
|
+
accounts --> catalog
|
|
403
|
+
cart --> catalog
|
|
404
|
+
checkout --> cart
|
|
405
|
+
checkout --> accounts
|
|
406
|
+
```
|
|
@@ -1,26 +1,193 @@
|
|
|
1
1
|
# Interview playbook — requirement elicitation
|
|
2
2
|
|
|
3
3
|
Goal: complete, conflict-free requirements in the FEWEST round-trips.
|
|
4
|
-
Batch 3–5 questions per message. Never ask what you can infer
|
|
4
|
+
Batch 3–5 questions per message. Never ask what you can infer — ask only
|
|
5
|
+
decision-forks, state everything else as a veto-able decision (§ How to ask).
|
|
5
6
|
|
|
6
|
-
##
|
|
7
|
+
## How to ask
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
- **Tool-first, options-fallback.** Use your harness's ask-question /
|
|
10
|
+
interactive multiple-choice tool when one exists; no such tool → ask inline
|
|
11
|
+
with labeled options. Same content either way.
|
|
12
|
+
- **Recommendation-first.** Every option set leads with YOUR best judgment
|
|
13
|
+
tagged `(recommended)`, then alternatives. The user accepts the
|
|
14
|
+
recommendation by default and may override — never present bare options
|
|
15
|
+
without a recommendation.
|
|
16
|
+
- **Ask forks, state decisions.** Ask ONLY the few decision-forks that
|
|
17
|
+
materially branch the plan. Everything derivative: DECIDE autonomously and
|
|
18
|
+
announce — "I'll use X because Y — say so if you'd rather Z" — so the user
|
|
19
|
+
can veto without being interrogated.
|
|
20
|
+
- **Volume scales with scope.** Round caps (§ Step 1) are MAXIMA, not targets:
|
|
21
|
+
SMALL/simple prompt → at most 1–2 core questions, decide the rest; MEDIUM →
|
|
22
|
+
the targeted set; LARGE — or an experienced engineer signaling they want
|
|
23
|
+
control → the fuller discovery set.
|
|
11
24
|
|
|
12
|
-
|
|
25
|
+
Worked example (recommendation-first, inline fallback form):
|
|
26
|
+
|
|
27
|
+
> Rollout strategy?
|
|
28
|
+
> 1. Feature flag + staged rollout **(recommended)** — existing users unaffected
|
|
29
|
+
> 2. Immediate cutover — simpler, riskier
|
|
30
|
+
> 3. Versioned API alongside — only if existing clients break
|
|
31
|
+
> Reply 1–3, or just "ok" to accept the recommendation.
|
|
32
|
+
|
|
33
|
+
## Round 0 — calibration exchange (skippable)
|
|
34
|
+
|
|
35
|
+
Two or three rapid items, asked once at the very start — each INFERRED first
|
|
36
|
+
(§ How to ask), asked only when genuinely ambiguous:
|
|
37
|
+
|
|
38
|
+
1. Rough scale: prototype, MVP, or production-bound? INFER from the opening
|
|
39
|
+
message + repo context; state the inference + one line of reasoning and
|
|
40
|
+
let the user confirm or correct. Ask open-ended ONLY when genuinely
|
|
41
|
+
ambiguous.
|
|
42
|
+
2. Team size + convention constraints? (solo? existing lint/CI/style guides?)
|
|
43
|
+
3. Deadline pressure: none, moderate, crunch?
|
|
44
|
+
|
|
45
|
+
Purpose is ONLY to pick question-set depth and right-size later verification
|
|
46
|
+
rigor — never to collect requirements. SKIP the whole exchange when the user's
|
|
47
|
+
opening message already answers these items (e.g. "quick prototype by
|
|
48
|
+
Friday"); SMALL/simple prompts skip calibration entirely and go straight to
|
|
49
|
+
their 1–2 core forks (§ How to ask). Record whatever was captured under
|
|
50
|
+
`calibration:` in answers.yaml.
|
|
51
|
+
|
|
52
|
+
## Step 1 — classify intent (decide during round 1)
|
|
53
|
+
|
|
54
|
+
From the opening message + calibration, decide ONE intent class, state it to
|
|
55
|
+
the user in one sentence, and record it as `intent_class` in answers.yaml:
|
|
56
|
+
|
|
57
|
+
| intent_class | Signal | Question depth | Round cap |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| GREENFIELD-SYSTEM | net-new product/system from scratch; no host repo | full PRD-grade discovery | ≤6 |
|
|
60
|
+
| GREENFIELD-MODULE | net-new capability inside an existing system/repo | targeted; infer from host repo first | ≤3 |
|
|
61
|
+
| BROWNFIELD-FEATURE | existing repo, additive behavior | survey-first; ask only survey gaps (max ~5 questions) | ≤3 |
|
|
62
|
+
| BROWNFIELD-CHANGE | modify existing behavior in place | survey-first; diff current vs desired | ≤3 |
|
|
63
|
+
|
|
64
|
+
Never interrogate a BROWNFIELD-FEATURE with PRD-grade questions — token waste,
|
|
65
|
+
user annoyance. Round caps INCLUDE round 0 when it runs.
|
|
66
|
+
|
|
67
|
+
Default `scope_class` from the intent class (user's choice wins — scope_class
|
|
68
|
+
is agreed in GENERATE step 1 and recorded in answers.yaml):
|
|
69
|
+
GREENFIELD-SYSTEM→LARGE, GREENFIELD-MODULE→MEDIUM,
|
|
70
|
+
BROWNFIELD-FEATURE→MEDIUM/SMALL, BROWNFIELD-CHANGE→SMALL.
|
|
71
|
+
|
|
72
|
+
Scale is INFERRED, not asked: derive scope_class from the opening message +
|
|
73
|
+
repo context + the class above, state it with one line of reasoning, and let
|
|
74
|
+
the user confirm or correct. Ask about scale ONLY when genuinely
|
|
75
|
+
ambiguous/confused. Small/simple prompts: skip heavy calibration, ask only
|
|
76
|
+
the 1–2 core forks (§ How to ask), decide the rest.
|
|
77
|
+
|
|
78
|
+
## GREENFIELD-SYSTEM — professional discovery (≤6 rounds)
|
|
79
|
+
|
|
80
|
+
Creating a system from scratch demands PRD-grade inputs. Each round below
|
|
81
|
+
lists its questions and where the answers land (`feeds:` tags — see
|
|
82
|
+
Traceability).
|
|
83
|
+
|
|
84
|
+
### R1 — problem, users, success → PRD
|
|
85
|
+
|
|
86
|
+
1. What problem does this solve, for whom — and what is explicitly NOT a goal?
|
|
87
|
+
2. Who uses it? Sketch 1–3 personas: role, key job-to-be-done, environment.
|
|
88
|
+
3. What does success look like — measurable (activation, conversion,
|
|
89
|
+
time-saved, error rate)? Adjectives are not metrics.
|
|
90
|
+
|
|
91
|
+
### R2 — shape & module decomposition → architecture.yaml `modules`
|
|
92
|
+
|
|
93
|
+
Infer stack/hosting from stated preferences, then confirm:
|
|
13
94
|
|
|
14
|
-
Draft answers from context (existing repo, stated stack), then confirm:
|
|
15
95
|
4. Stack + hosting target correct? (state your inference)
|
|
16
|
-
5.
|
|
17
|
-
|
|
96
|
+
5. Integration surfaces: auth, payments, email, existing APIs?
|
|
97
|
+
|
|
98
|
+
Then PROPOSE a strawman module map from the domain talk — one line per
|
|
99
|
+
candidate module as `name — responsibility` (mirroring `modules[]`:
|
|
100
|
+
name/responsibility/owns) — and ask the user to react:
|
|
101
|
+
|
|
102
|
+
6. React to this strawman module map: [list]. What is missing, misnamed, or
|
|
103
|
+
should be merged/split? Iterate until agreement — this seeds
|
|
104
|
+
architecture.yaml `modules`.
|
|
105
|
+
|
|
106
|
+
### R3 — data & API sketches → `data_contracts`, `api_contracts`
|
|
107
|
+
|
|
108
|
+
7. Core data entities and relationships — one line each: Entity — key fields —
|
|
109
|
+
belongs-to / has-many? (seeds `data_contracts`)
|
|
110
|
+
8. Primary API surface: the 5–10 operations users/systems perform, verb +
|
|
111
|
+
resource? (seeds `api_contracts`)
|
|
112
|
+
|
|
113
|
+
### R4 — NFRs with numbers → PRD
|
|
114
|
+
|
|
115
|
+
Numbers or it didn't happen — reject "fast"/"scalable" without figures.
|
|
18
116
|
|
|
19
|
-
|
|
117
|
+
9. Performance budgets: p95 latency, throughput at peak?
|
|
118
|
+
10. Scale targets: users, reqs/day, data growth per year?
|
|
119
|
+
11. Security/compliance checklist level (GDPR/HIPAA/PCI)? i18n locales?
|
|
120
|
+
Accessibility level (e.g. WCAG 2.2 AA)?
|
|
20
121
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
122
|
+
### R5 — environment & naming → `environment_matrix`, `naming_conventions`
|
|
123
|
+
|
|
124
|
+
12. Environment/deploy reality: which environments exist (dev/staging/prod),
|
|
125
|
+
hosting, config/secrets handling, deploy cadence? (seeds
|
|
126
|
+
`environment_matrix`)
|
|
127
|
+
13. Naming/brand conventions that already exist: product-name casing, domain
|
|
128
|
+
terms to preserve, UI copy language(s)? (seeds `naming_conventions`;
|
|
129
|
+
"none" is a valid answer)
|
|
130
|
+
|
|
131
|
+
### R6 — close-out → PRD
|
|
132
|
+
|
|
133
|
+
14. Explicit out-of-scope list — adjacent things on record as NOT in this build?
|
|
134
|
+
15. Top 2 risks you already know about?
|
|
135
|
+
|
|
136
|
+
Close by presenting the agreed module map + captured NFR numbers for final
|
|
137
|
+
confirmation ([wait for user]).
|
|
138
|
+
|
|
139
|
+
### Traceability — `feeds:` tags
|
|
140
|
+
|
|
141
|
+
Every recorded answer MAY carry a `feeds:` tag naming the artifact section it
|
|
142
|
+
lands in. Keep the vocabulary literal — downstream templates consume these
|
|
143
|
+
exact names:
|
|
144
|
+
|
|
145
|
+
- PRD sections: `prd.problem`, `prd.goals`, `prd.non_goals`, `prd.personas`,
|
|
146
|
+
`prd.metrics`, `prd.nfrs`, `prd.constraints`, `prd.integrations`,
|
|
147
|
+
`prd.risks`, `prd.out_of_scope`
|
|
148
|
+
- architecture.yaml keys: `arch.modules`, `arch.data_contracts`,
|
|
149
|
+
`arch.api_contracts`, `arch.environment_matrix`, `arch.naming_conventions`
|
|
150
|
+
|
|
151
|
+
Multiple targets join with `|`, e.g. `feeds: prd.goals|arch.modules`.
|
|
152
|
+
|
|
153
|
+
## GREENFIELD-MODULE — net-new inside an existing system (≤3 rounds)
|
|
154
|
+
|
|
155
|
+
Infer first from the host repo (structure, conventions, neighboring modules),
|
|
156
|
+
confirm second:
|
|
157
|
+
|
|
158
|
+
1. Where does it plug in — which host modules does it read from / expose to?
|
|
159
|
+
2. Contract with the host: data it consumes/produces, APIs or events it
|
|
160
|
+
exposes? (seeds `data_contracts` / `api_contracts` deltas)
|
|
161
|
+
3. Inherited vs new NFRs: follow host perf/a11y/i18n baselines or set new ones?
|
|
162
|
+
4. Naming follows host conventions — confirm? (seeds `naming_conventions`)
|
|
163
|
+
|
|
164
|
+
## BROWNFIELD classes — survey BEFORE questioning (mandatory)
|
|
165
|
+
|
|
166
|
+
Run the survey first (SKILL.md BROWNFIELD steps 1–2): prefer the codegraph MCP
|
|
167
|
+
(`codegraph_explore`) when configured, else structured glob/grep; produce or
|
|
168
|
+
update `.archgen/<slug>/codebase-map.md`. Then ask ONLY what the survey could
|
|
169
|
+
not answer. NEVER ask what a file already answers — quote the file and ask for
|
|
170
|
+
confirmation instead.
|
|
171
|
+
|
|
172
|
+
### BROWNFIELD-FEATURE (additive; max ~5 questions, one batched message)
|
|
173
|
+
|
|
174
|
+
Ask only unresolved gaps, typically:
|
|
175
|
+
|
|
176
|
+
1. Acceptance criteria the code cannot reveal — exact expected behavior, edge
|
|
177
|
+
cases that matter.
|
|
178
|
+
2. Back-compat expectations for existing records or clients.
|
|
179
|
+
3. Rollout preference: feature flag, staged, immediate?
|
|
180
|
+
4. Must-NOT-touch paths beyond what the map shows?
|
|
181
|
+
5. Anything the codebase-map got wrong?
|
|
182
|
+
|
|
183
|
+
### BROWNFIELD-CHANGE (behavior modification; ≤3 rounds)
|
|
184
|
+
|
|
185
|
+
Survey focus: current behavior + blast radius (callers, tests, consumers).
|
|
186
|
+
|
|
187
|
+
1. Current vs desired behavior — precise diff, including what must stay.
|
|
188
|
+
2. Compatibility: migrate in place, version alongside, or breaking change?
|
|
189
|
+
3. Acceptance for "changed": how do we prove old behavior is gone and the new
|
|
190
|
+
behavior holds?
|
|
24
191
|
|
|
25
192
|
## Conflict detection
|
|
26
193
|
|
|
@@ -32,18 +199,47 @@ While collecting, watch for and surface immediately:
|
|
|
32
199
|
Format: "I see a tension between X and Y. Which wins?" — one per message,
|
|
33
200
|
resolve before proceeding. [wait for user]
|
|
34
201
|
|
|
202
|
+
## Token discipline
|
|
203
|
+
|
|
204
|
+
- Batch 3–5 questions per message; never ping-pong one-per-message.
|
|
205
|
+
- Hard round caps — MAXIMA, not targets (small prompts ask far fewer;
|
|
206
|
+
§ How to ask): GREENFIELD-SYSTEM ≤6 rounds, every other class ≤3
|
|
207
|
+
(round 0 counts when it runs).
|
|
208
|
+
- Skip any question already answered by the opening message, calibration, or
|
|
209
|
+
survey artifacts.
|
|
210
|
+
|
|
35
211
|
## Answers-file format (machine-readable, enables non-interactive runs)
|
|
36
212
|
|
|
37
213
|
For scripted E2E or re-runs, requirements may come from a file instead of
|
|
38
214
|
conversation — `.archgen/<slug>/answers.yaml`:
|
|
39
215
|
|
|
40
216
|
```yaml
|
|
41
|
-
scope_class: MEDIUM # SMALL | MEDIUM | LARGE
|
|
217
|
+
scope_class: MEDIUM # SMALL | MEDIUM | LARGE — UNCHANGED; SKILL.md reads
|
|
218
|
+
# this for right-sizing. Never remove or rename.
|
|
219
|
+
intent_class: GREENFIELD-SYSTEM # optional: GREENFIELD-SYSTEM |
|
|
220
|
+
# GREENFIELD-MODULE | BROWNFIELD-FEATURE |
|
|
221
|
+
# BROWNFIELD-CHANGE
|
|
222
|
+
calibration: # optional — from round 0
|
|
223
|
+
scale: production # prototype | mvp | production
|
|
224
|
+
teamConstraints: solo dev, repo lint rules apply
|
|
225
|
+
pressure: medium # low | medium | high
|
|
42
226
|
problem: one-line problem statement
|
|
43
227
|
success_criteria:
|
|
44
|
-
- measurable outcome
|
|
228
|
+
- text: measurable outcome # structured entries MAY carry feeds:
|
|
229
|
+
feeds: prd.metrics
|
|
45
230
|
constraints:
|
|
46
|
-
- must-not-change
|
|
231
|
+
- must-not-change item # plain scalars stay valid; tag via
|
|
232
|
+
# trailing comment: # feeds: prd.constraints
|
|
233
|
+
non_goals: # optional (GREENFIELD-SYSTEM)
|
|
234
|
+
- multi-tenant accounts
|
|
235
|
+
personas: # optional (GREENFIELD-SYSTEM)
|
|
236
|
+
- role: shopper
|
|
237
|
+
goal: find and buy in under two minutes
|
|
238
|
+
nfrs: # optional; NUMBERS required for GREENFIELD-SYSTEM
|
|
239
|
+
- "p95 API latency < 300ms at 50 rps"
|
|
240
|
+
- "locales: en, de"
|
|
241
|
+
- "accessibility: WCAG 2.2 AA"
|
|
242
|
+
out_of_scope: [] # optional
|
|
47
243
|
stack:
|
|
48
244
|
language: typescript
|
|
49
245
|
runtime: node
|
|
@@ -54,13 +250,26 @@ risks:
|
|
|
54
250
|
- known risk text
|
|
55
251
|
```
|
|
56
252
|
|
|
253
|
+
Backward compatibility: ALL additions (`intent_class`, `calibration`,
|
|
254
|
+
`non_goals`, `personas`, `nfrs`, `out_of_scope`, per-answer `feeds:` tags) are
|
|
255
|
+
OPTIONAL. Existing fields keep their names and semantics; `scope_class` is
|
|
256
|
+
retained verbatim because SKILL.md consumes it. Consumers that do not trace
|
|
257
|
+
provenance ignore `feeds:` tags in both forms (sibling key on structured
|
|
258
|
+
entries, trailing comment on plain scalars).
|
|
259
|
+
|
|
57
260
|
The orchestrator treats answers.yaml as authoritative user input and skips
|
|
58
261
|
the conversational rounds when it exists and parses cleanly.
|
|
59
262
|
|
|
60
263
|
## Completion test
|
|
61
264
|
|
|
62
265
|
Requirements are done when ALL hold:
|
|
63
|
-
- Every
|
|
266
|
+
- Every applicable question in the chosen intent class's question set answered
|
|
267
|
+
(or explicitly waived by the user)
|
|
64
268
|
- All drafted inferences confirmed or corrected
|
|
65
269
|
- Zero unresolved conflicts
|
|
66
270
|
- Scope class agreed (SMALL/MEDIUM/LARGE) — this gates artifact generation
|
|
271
|
+
(unchanged; SKILL.md consumes it)
|
|
272
|
+
- Chosen `intent_class` recorded in answers.yaml
|
|
273
|
+
- GREENFIELD-SYSTEM only: module-map agreement reached (user reacted to the
|
|
274
|
+
strawman and the revision is confirmed) AND NFR numbers captured — an NFR
|
|
275
|
+
without a number fails this gate
|