build_spec
maps the demand report to a feature list — every feature backed by a real quote — and
scaffold writes a project on disk for your agent (Claude Code, Cursor, etc.) to build inside.
metalworks writes the spec and scaffolds the project. It does not write your product code.
No React components, no API routes, no migrations. It carries the validated demand forward — as
a spec and a frozen quote table — so the agent that does write the code can’t drift from what
real users asked for.
| Flag | Default | What it does |
|---|---|---|
--dest / -d | ./build | Directory to scaffold the project into. |
--surface | web | Target: web · mobile · cli · api · sdk · browser_extension · desktop. |
--base | empty | Stack hint recorded in the spec (e.g. next-shipfast). Not vendored boilerplate. |
What you give it / what you get back
You give it: a finishedResearch bundle (the report on .demand), your positioning, and a
target surface. The report argument to the CLI is a stored report id (metalworks research list) or a path to a report.json.
You get back: a BuildSpec — three parts, each line tied to a real quote:
- Features. The model proposes features from the demand clusters; metalworks attaches each cluster’s real quotes as the feature’s evidence. A feature with no real cluster behind it is dropped — the build stays tied to real demand. What survives is only what people actually asked for (capped at 8 core features).
- Personas. Derived from the report’s audience segments, each tied to a real voice.
- Pricing. Tiers are copied straight from the report’s price evidence (
Starterat the low end of observed willingness to pay,Proat the high end). No price signal → no tiers.
scaffold writes the project — pure deterministic templating, no model, idempotent:
EVIDENCE.md is the frozen verbatim quote + permalink table — every id SPEC.md cites appears
here with its exact Reddit text and a source link. The agent must not edit it; to add a feature,
go back to metalworks and re-run the research.
How your coding agent uses it
Once the project is written, metalworks is done. The hand-off:- Open the scaffolded directory in your coding agent (the project’s
CLAUDE.mdand skills are now in scope). - Run
/scaffold-startup. The agent readsdocs/SPEC.md(what to build) anddocs/EVIDENCE.md(the proof), picks the stack hint’s starter, stands up the surface, and builds the features top to bottom — each one a demand a real user voiced. - The lint holds it to the evidence. As the agent writes user-facing copy, a hook runs
cite_or_die.pyon the edited files. A headline that cites an id not inEVIDENCE.mdfails the build; the agent has to find the real supporting quote or drop the claim.
When the result is thin
When the report can’t back a buildable plan, the spec comes backpartial with a caveat. A
partial spec still writes (so you can read the evidence), but it opens with a “Partial spec”
banner instead of pretending to be buildable. The CLI prints the caveat before scaffolding.
One honesty guarantee: an infra error (a 404, an auth failure, a network blip during the model
call) surfaces as a real failure — it’s never silently relabelled a thin-demand partial.
scaffold() raises ValueError if the spec wasn’t built from the report you pass it — otherwise
the frozen EVIDENCE.md would resolve the spec’s refs against the wrong report. Always scaffold a
spec against the report it came from.
Next: draft your launch assets and a content & SEO plan from the same report. Or read why you can trust the output — the rule that keeps every feature tied to a real quote.