From the requirements tool to Figma without the copy-paste.
Requirements live in one system. Design lives in another. The trip between them was four to six weeks of reading, re-reading, and pasting. This is the pipeline that made it two days, and the four things it had to get right to be allowed near a production requirements database.
Thesis
00Extract once, into a stable schema, in the repo.
One read-only extraction lands a content-hashed artifact in the repo, and every later task reads that instead of re-querying the source. The agent never writes to the system of record. Not by convention. By construction.
Five moves
0101 · source of recordRequirements DB
SRS and SSRS sections in the requirements tool: 170+ documents, around 5,500 requirements. The script reads them through a single GET-only helper; no code path can write back.
02 · the repo is the promptmachine_readable/
full_text.md, sections.json, workitems.json, and manifest.json, committed with a content hash on canonicalised text. Downstream tasks (cross-reference, audit, decomposition, traceability) read this instead of the source; "did the spec move?" is one comparison.
03 · designFigma wireframes
21 screens across 3 flows, generated through MCP against a design-system library the agent can read but never write, so the output matches the system by construction. Every screen carries its requirement IDs; 27 of 38 requirements got status-coded cards.
04 · demoOperable demo
Built in 13 agent turns from the 21 PNGs alone. Real state, real typing. The requirement IDs, the deviation labels, and the read-only guarantees do not cross that last arrow. It is the least auditable and the most persuasive thing in the chain.
The demo exists because the fourth move produced screens good enough to be the only input to the next stage. Note what does not cross that last arrow: the requirement IDs.
Four guardrails
02We didn't ask an agent to be careful. We made carelessness impossible to express.
A naive pull returns most of a section, and nobody notices what is missing until review. The failure is silent, so the extraction is a script with tripwires, not a prompt.
Capture · 03Read-only is structuralthe HTTP method is hardcoded once
The HTTP method is hardcoded in a single helper, never passed by callers. No code path can mutate the source. That is why this was allowed to run against a production instance.
Transform · 04Capture / transform splitpure function over captured bytes
Transform is a pure function over captured bytes: re-runnable offline, reproducible, no re-hitting the API while iterating on format. A content hash on canonicalised text makes "did the spec move?" one comparison.
Verify · 01Boundary tripwirestop instead of guess
If a section runs to the end of the document, or its items aren't contiguous, the script stops instead of guessing. This caught a numbering convention that would have produced a tidy export containing only headings.
Verify · 02Direct-child requirementsthe ones subtree matching drops
Requirements hanging directly off a root heading are dropped silently by naive subtree matching. The skill checks for them explicitly. Our own section had two.
Artifact, verbatim
03Leverage the requirements MCP to extract requirement <ROOT-ID> and its children
into the repository directory requirements/machine_readable/<SECTION_NAME>.
Store it as markdown and json where applicable. Ensure read-only operations.
Before you begin, please let me know if you have any clarifying questions.directive 1 "Here are the rewuirments for the [subsystem] user interface. Please go
ahead and analyze these requirements from a UX perspective."
-> a UX critique before any Figma work. It caught the read/unread
defect. Had the build started first, it would have been drawn
faithfully into every screen.
directive 9 "Make sure [flow B] has all of the requiremnents in the [flow B] section"
-> flow B went from 4 screens to 10. Set a completeness bar that
flow C then met without being asked.
directive 11 the rule that came out of four floating boxes nobody could classify:
"If a user sees it, it goes in the window. If it's something the
specification fails to say, it goes in the requirement card below
or the Gaps section. Nothing floats over the modal."Why it's here
The corrections are kept because the screens only show the outcome. Capturing direction as it is given is what stops the reasoning evaporating with the session. Same argument as extracting requirements to the repo, applied to design intent.
What it found
04Drawing every state proved the requirements incomplete.
Six defect classes, each anchored to an ID in the source system and documented on the canvas as a deviation, never silently absorbed. IDs and content stripped; the taxonomy is the insight.
01Two approved reqs contradict
Two approved requirements that contradict each other when combined.
02A state nobody specified
A state no requirement describes, so no screen can be drawn for it.
03Happy path only
No failure, retry, or disconnect behaviour specified, on a system where "did my message get through" is safety-adjacent.
04Satisfiable, useless
A requirement that can be met to the letter and still leaves the operator with nothing to act on.
05Actor unspecified
Unspecified actor and unspecified interaction.
06Two reqs, one display
Two requirements that collapse to the same display, losing provenance.
+1 · found by the demoEverything the demo had to invent is an unwritten requirement
A static screen can omit what the specification never says. A working application cannot. Delivery states, notification timing, error handling: the invented parts were also the most convincing parts, and nothing in the demo marked them as invented.
Honest scorecard
05Say it before the room does.
| 01 Requirements DB | 02 Repo artifact | 03 Figma wireframes | 04 Demo | |
|---|---|---|---|---|
| Read-only against the source | holds | holds | holds | lost |
| Content-hashed | — not applicable | holds | — not applicable | lost |
| Requirement IDs carried | holds | holds | holds27 of 38 status-coded in Figma | lost |
| Deviations labelled | — not applicable | — not applicable | holds | lost |
| holds holdslost lost at this stage— not applicable not applicable | ||||
Flag"4–6 weeks to 2 days" is an estimate, not a measurement
The requirements-to-wireframes duration is a practitioner estimate from a working session, not a measured baseline. Every other number on this page traces to a file. The defect list and the per-section coverage stand without it.
Open questionDoes discovery compress on someone else's spec?
Untested here. The wireframes arguably are the user flows, at higher fidelity and traced, but nobody has proven that when the designer did not write the requirements.
Replicate
06For another team, starting Monday.
1Clone the reposkills and MCP config included
Config is versioned with the work, so onboarding is a clone and one environment variable.
2Set one tokenthe only secret
Nothing else is secret; the repo says so in its own .gitignore.
3Capture your sectionnetwork, read-only GET
Read the printed resolution line. Item count and stop item deserve two seconds of human attention.
4Transform offlinepure function
Pure function over the captured bytes; re-run it as often as the output format needs.
5Verifyfive checks
Count reconciliation, boundary, direct-child requirements, images, description fidelity.
6Design, export, demoagent + you
Design the screens against the artifact and the design system, export them as PNGs, hand them to the demo tool. The screens are the specification for the demo, which is the strongest argument for making them complete and self-describing.
Same shape for Jira, Confluence, SharePoint, or any other system of record. What changes is the role: the pipeline does most of the work, and the remaining share is judgment, verification, and presentation. That share has to be staffed deliberately.