Skip to content

Commit acfc292

Browse files
maxgfrclaude
andcommitted
feat: build phase — machine-readable BUILD-PLAN.json and construct verify
The engine now plans and referees the build; the agent writes all app code. - BUILD-PLAN.json emitted on every render: deterministic task DAG (T-000 skeleton + one task per FR, milestone-ordered must→should→could, entity- aware dependency edges), acceptance entries POINT into SRD.json (refs, never copies) - merge-by-feature-title preserves agent progress (status, artifacts, tests, verify commands, testCommand/appDir) across re-renders — FR ids are positional, titles are the stable identity - new `construct verify`: static referee (plan well-formed + acyclic, refs resolve into the SRD, done tasks' files exist, FR→test coverage via the FR-tag grep, stale-tag detection); `--run-tests` opt-in executes the declared test commands; `--strict` fails a built must-have with no referencing test; `--json` for orchestration; status shows task progress - SKILL.md step 8 (Build): task-by-task TDD with FR-tagged tests, verify after every task, `--run-tests --strict` + adversarial review per milestone; frontmatter triggers extended to 'build the app from the SRD' - references/build-playbook.md (the task loop, milestone gates, what to do when reality pushes back) and references/verify.md (what each check proves and what still needs eyes) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 8e730ee commit acfc292

12 files changed

Lines changed: 1372 additions & 43 deletions

File tree

SKILL.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: construct
3-
description: "Use when the user wants to turn a product idea into a serious, buildable requirements document (an SRD/PRD) — e.g. 'write an SRD for my app idea', 'spec out this product', 'turn my idea into requirements', 'design the requirements for X'. construct interviews the user about the product, then GROUNDS every major decision in real research — competitors and market signal (keyless web: SearXNG → DuckDuckGo → your WebSearch), comparable open-source projects and their issues/PRs (GitHub/GitLab), candidate-technology official docs and StackOverflow pitfalls, and an optional local semantic pass (Qdrant + Ollama) — writing an evidence dossier the SRD cites. It then renders a complete SRD suite (vision, scope, numbered functional requirements with Given/When/Then acceptance criteria, non-functional requirements, system context, data model, interfaces, ADRs, competitive landscape, build plan, traceability) and validates it: a HARD structural completeness gate plus an ADVISORY grounding-coverage report. Triggers: SRD, PRD, software requirements document, spec a product, requirements from an idea, greenfield product spec, idea to requirements."
3+
description: "Use when the user wants to turn a product idea into a serious, buildable requirements document (an SRD/PRD) — and optionally build the app from it. E.g. 'write an SRD for my app idea', 'spec out this product', 'turn my idea into requirements', 'design the requirements for X', 'build the app from the SRD', 'implement the spec'. construct interviews the user about the product, then GROUNDS every major decision in real research — competitors and market signal (keyless web: SearXNG → DuckDuckGo → your WebSearch), comparable open-source projects and their issues/PRs (GitHub/GitLab), candidate-technology official docs and StackOverflow pitfalls, and an optional local semantic pass (Qdrant + Ollama) — writing an evidence dossier the SRD cites. It then renders a complete SRD suite (vision, scope, numbered functional requirements with Given/When/Then acceptance criteria, non-functional requirements, system context, inferred data model and interfaces, ADRs, competitive landscape, build plan, traceability) and validates it: a HARD structural completeness gate plus an ADVISORY grounding-coverage report (opt-in --min-grounding threshold). For building, it emits a machine-readable BUILD-PLAN.json task DAG; the agent implements task-by-task with TDD while `construct verify` referees the app against the SRD (artifacts exist, every requirement is test-covered, suites pass). Triggers: SRD, PRD, software requirements document, spec a product, requirements from an idea, greenfield product spec, idea to requirements, build from spec, implement the SRD."
44
license: MIT
55
metadata:
66
version: 1.0.2
@@ -41,6 +41,11 @@ No `npm install`, no API keys. Run `--help` for the full surface. Key commands:
4141
gate (exit ≠ 0 on an incomplete SRD) plus the ADVISORY grounding-coverage
4242
report. `--min-grounding N` opts into a second gate that fails below N%
4343
grounded claims.
44+
- `verify --out <run> [--app <dir>] [--run-tests] [--strict] [--json]` — the
45+
build referee: BUILD-PLAN.json well-formed and acyclic, every task ref
46+
resolves into SRD.json, done tasks' files exist, every requirement is
47+
referenced by a test. `--run-tests` also executes the declared test
48+
commands; `--strict` fails a built must-have with no referencing test.
4449
- `status --out <run>` — what exists in the run so far.
4550
- `semantic up|down|status` — optional local Docker stack (Qdrant + Ollama +
4651
SearXNG).
@@ -124,6 +129,26 @@ loop to completion; only pause to ask the user a real decision.
124129
landscape, the grounded requirements and the key decisions (with their `[E#]`
125130
evidence and links). Pin any unknowns explicitly rather than guessing.
126131

132+
8. **Build (when the user wants the app, not just the SRD).** The render also
133+
emitted `BUILD-PLAN.json` — a machine-readable task DAG (T-000 skeleton +
134+
one task per FR, must → should → could, entity-aware dependencies) whose
135+
`acceptance` entries POINT into `SRD.json`. **You write all app code; the
136+
engine referees.** Follow `references/build-playbook.md`:
137+
- Do `T-000` (scaffold, test harness, CI); set `conventions.appDir` and
138+
`conventions.testCommand` in `BUILD-PLAN.json`.
139+
- Per task, in topological order: read the acceptance criteria from
140+
`SRD.json`; TDD them — **every test names its FR id** (e.g.
141+
`describe("FR-001 …")`; that's what `verify` greps); record `artifacts` +
142+
`tests`; set `status: "done"`; run
143+
`node scripts/construct.mjs verify --out <run>` and fix any error before
144+
the next task.
145+
- Per milestone: `verify --out <run> --run-tests --strict`, then a
146+
milestone adversarial review — fresh eyes hunting for an acceptance
147+
criterion no test actually exercises (see the playbook;
148+
`references/verify.md` explains what verify can and cannot prove).
149+
- If an FR proves wrong while building, amend the brief, re-render
150+
(progress merges by feature title), retag shifted FR ids, re-`check`.
151+
127152
## What it produces (the SRD tree, under `--out`)
128153

129154
```
@@ -133,7 +158,8 @@ requirements/ FUNCTIONAL.md (FR-NNN · priority · Given/When/Then · [E#])
133158
architecture/ SYSTEM-CONTEXT.md · DATA-MODEL.md · INTERFACES.md
134159
decisions/NNNN-*.md (ADRs)
135160
competitive/ LANDSCAPE.md (competitors + OSS prior art)
136-
BUILD-PLAN.md · TRACEABILITY.md (FR ↔ NFR ↔ ADR ↔ entity ↔ interface)
161+
BUILD-PLAN.md · BUILD-PLAN.json (task DAG for the build phase)
162+
TRACEABILITY.md (FR ↔ NFR ↔ ADR ↔ entity ↔ interface)
137163
evidence/ EVIDENCE.md · evidence.json · meta.json · brief.json · SRD.json
138164
```
139165

@@ -165,6 +191,8 @@ See `references/semantic-setup.md`.
165191
- `references/acceptance-criteria.md` — bad→good Given/When/Then rewrites and measurable NFR metric patterns.
166192
- `references/citation-format.md` — the `[E#]` grounding convention.
167193
- `references/grounding-coverage.md` — what the advisory coverage report means and how to raise it.
194+
- `references/build-playbook.md` — the build loop: task TDD, FR-tag convention, milestone gates, the milestone review.
195+
- `references/verify.md` — what each `verify` check proves and what still needs eyes.
168196
- `references/provider-apis.md` — how OSS issues/PRs are fetched per host, keyless.
169197
- `references/web-discovery.md` — the layered keyless web search.
170198
- `references/semantic-setup.md` — the optional local Docker stack.

references/build-playbook.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Build playbook — from a validated SRD to a verified app
2+
3+
The engine plans and verifies; **you write every line of app code**. The
4+
contract is `BUILD-PLAN.json` (next to `BUILD-PLAN.md`): the engine derives
5+
its structure from the SRD on every render, and you own the progress fields.
6+
`construct verify` is the referee between the two.
7+
8+
## The contract
9+
10+
Engine-derived (a re-render refreshes these — never hand-edit):
11+
`id`, `title`, `milestone`, `frIds`, `acceptance` (pointers into `SRD.json`
12+
read the criteria there, they are never copied), `dependsOn`,
13+
`conventions.frTagPattern`.
14+
15+
Agent-owned (a re-render preserves these, keyed by the feature title):
16+
`conventions.testCommand`, `conventions.appDir`, and per task `artifacts`,
17+
`tests`, `verify.commands`, `status` (`todo``in-progress``done`).
18+
19+
**The FR-tag convention is load-bearing.** Every test you write must name the
20+
FR id it exercises (in the describe/it string or a comment) — e.g.
21+
`describe("FR-001 save an article", …)`. This is exactly what
22+
`construct verify` greps (`conventions.frTagPattern`, default `FR-\d{3}`).
23+
No tag → the FR reads as untested, and `--strict` fails the build for
24+
must-haves.
25+
26+
## Setup (once)
27+
28+
1. Read `BUILD-PLAN.json`; topologically order the tasks by `dependsOn`
29+
(milestones already order must → should → could).
30+
2. Do `T-000`: scaffold the app repo, choose and wire the test harness, CI.
31+
Set `conventions.appDir` (app directory, relative to the run folder or
32+
absolute) and `conventions.testCommand` (e.g. `pnpm test`). Mark `T-000`
33+
done with its artifacts.
34+
35+
## The task loop (every FR task)
36+
37+
1. **Pick** the next task whose `dependsOn` are all done. Set
38+
`status: "in-progress"`.
39+
2. **Read the spec, not your memory:** the FR's description and each
40+
acceptance criterion via the task's `acceptance` pointers into `SRD.json`.
41+
3. **TDD against the criteria.** For each acceptance criterion, write a
42+
failing test whose name carries the FR id and mirrors the Given/When/Then.
43+
Implement until green. Failure-path criteria get failure-path tests.
44+
4. **Record:** fill `artifacts` (the source files that implement it) and
45+
`tests` (the test files), both app-relative. Add any extra
46+
`verify.commands` worth running for this task (lint, a smoke script).
47+
5. **Set `status: "done"`**, then referee:
48+
```
49+
node scripts/construct.mjs verify --out <run>
50+
```
51+
Static, fast — run it after EVERY task. Fix any error before moving on.
52+
6. **Per milestone**, run the full gate:
53+
```
54+
node scripts/construct.mjs verify --out <run> --run-tests --strict
55+
```
56+
It executes `testCommand` + every done task's `verify.commands`, and fails
57+
if a built must-have FR has no referencing test.
58+
59+
## The milestone review (adversarial)
60+
61+
After each milestone passes `verify --run-tests --strict`, spawn one reviewer
62+
subagent (or do a hostile self-pass). Give it ONLY: the milestone's FR ids,
63+
their acceptance criteria from `SRD.json`, and the diff (or file list) of
64+
what you built. Its question: **which acceptance criterion is not actually
65+
exercised by any test?** A test that names an FR but asserts something weaker
66+
than the criterion is the main target — `verify` greps names, the reviewer
67+
checks honesty. Fix what it finds before starting the next milestone.
68+
69+
## When reality pushes back
70+
71+
- **An FR proves unimplementable / wrong as specified:** do not silently
72+
build something else. Amend the brief (or `SRD.json` + the rendered docs
73+
together), re-render, and re-run `check`. The plan merge keys progress by
74+
feature title, so other tasks keep their status. Then retag any tests whose
75+
FR ids shifted — `verify` warns about stale tags.
76+
- **A re-render renumbered FR ids:** `verify` reports "tests reference FR
77+
id(s) absent from the SRD". Retag those tests before trusting coverage.
78+
- **A dependency is blocked:** mark the task back to `todo`, note why to the
79+
user, and pick another ready task.
80+
81+
## What "done" means
82+
83+
A milestone is done when: every task is `done`, `verify --run-tests --strict`
84+
exits 0, and the milestone review found nothing unaddressed. The build is
85+
done when every milestone is — then `construct status` shows
86+
`build: N/N tasks done`, and you present the app against the SRD's success
87+
metrics, not just its file tree.

references/verify.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# What `construct verify` proves — and what it cannot
2+
3+
`verify` is the deterministic referee between `BUILD-PLAN.json`, `SRD.json`
4+
and the app directory. Knowing exactly what each check proves keeps you (and
5+
the user) honest about the build.
6+
7+
## Static checks (always run, pure reads)
8+
9+
| Check | Proves | Does NOT prove |
10+
|---|---|---|
11+
| plan parses, schema version, unique ids | the plan is machine-readable | the plan is sensible |
12+
| DAG acyclic, `dependsOn` resolve | the task order is executable | the order is optimal |
13+
| `frIds` / `acceptance` refs resolve into SRD.json | the plan builds *this* SRD, no orphan claims | the SRD itself is right (that is `check`'s job) |
14+
| done tasks' `artifacts`/`tests` exist under the app dir | the declared files are real | the files do what the task says |
15+
| FR-tag grep over test files (`conventions.frTagPattern`) | each FR is *referenced* by at least one test | the test actually exercises the criterion — a test can name FR-001 and assert nothing |
16+
| stale-tag warning | tags match the current SRD's FR ids ||
17+
18+
Exit ≠ 0 on any hard error. `--strict` upgrades "a built must-have FR has no
19+
referencing test" from warning to error — use it at every milestone gate.
20+
21+
## `--run-tests` (opt-in execution)
22+
23+
Runs `conventions.testCommand` and every done task's `verify.commands` inside
24+
the app directory (your own toolchain — the engine installs nothing). Proves
25+
**the suite passes**. Does not prove the suite is honest: a weakened
26+
assertion, a skipped test, or a tautological expect all pass. It is opt-in
27+
because executing user-declared commands is side-effectful — never run it on
28+
a plan you have not read.
29+
30+
## The gap that needs eyes
31+
32+
Greps prove *reference*; execution proves *green*; neither proves a test
33+
faithfully encodes its acceptance criterion. That is the milestone
34+
adversarial review in `references/build-playbook.md`: a fresh reader compares
35+
each criterion in `SRD.json` against what the tests actually assert. Engine
36+
for structure, agent for honesty — same split as `check` vs. grounding.

0 commit comments

Comments
 (0)