# idea-to-reality

One sentence to a manufacturable product — enclosure, PCB and firmware, cross-checked and packaged. Use for any invent/build-me-a-device ask, or to drive it from a terminal or MCP client.


# Idea to reality

One sentence in, three artifacts out, cross-checked. The pipeline derives requirements from the ask,
re-derives its own plan from them, designs the board, sizes the enclosure **around that board**,
writes firmware **against that board's netlist**, checks the three against each other, and assembles
a work order for a machine that can actually make the part.

**Everything is one adapter call.** `inventor.invent` is the door; the six-stage gate loop lives
behind it. Reach for the stage-by-stage API only when a person is approving each gate.

```bash
pnpm invent "A desk environment monitor: an ESP32 reading a BME280 over I2C, with a status LED
             and a button, in a small printed enclosure." --provider cursor-agent
```

| flag | what it does |
|---|---|
| `--provider <id>` | `cursor-agent` · `codex` · `claude` · `openai` · `ollama` · `gemini`. **Name one for a reproducible run** — `auto` can answer differently on two machines. |
| `--boot` | boot an API in-process instead of talking to one. Needs no server; what makes this work on a clean checkout. |
| `--api <url>` | an API already running (default `http://127.0.0.1:3000`, or `LEUMAS_API_URL`). |
| `--hold` | stop at the first gate and print the plan instead of building. |
| `--export <dir>` | write the finished geometry there as STL + 3MF, one file per part. |
| `--json` | the result as JSON and nothing else, for a script. |

Exit code is 0 only when the run finished **and** every interface check passed.

## From another agent — Claude Code, Codex, any MCP client

The adapter registry exposes every function as an MCP tool automatically, so nothing needs building:

```bash
# 1. mint a key (session-authenticated, once)
curl -s -X POST http://127.0.0.1:3000/keys -H 'content-type: application/json' \
  --cookie "$LEUMAS_COOKIE" -d '{"name":"invent","scopes":["mcp"]}'

# 2. point the client at the gateway
claude mcp add --transport http leumas http://127.0.0.1:3000/mcp/rpc \
  --header "Authorization: Bearer lk_…"
```

Then call **`inventor__invent`** with `{brief, provider}`. The gateway flattens all 190 adapter
systems into one server and namespaces tools `<system>__<fn>`, so ~1,800 tools arrive at once — which
is exactly why `invent` exists as a single call. For a curated server, create an Imperium config with
`mode: 'mcp'` selecting `adapter:inventor.*` and connect to `/mcp/s/<configId>` instead.

Codex and any other client work identically: the pipeline hands every provider the same typed
grammar and makes every adapter call itself, so **none of this needs tool-calling support** from the
model. `toolloop.js` gates tools on `provider.capabilities.tools`, and `cursor-agent` is `tools:
false` — that constraint is why the design is a grammar rather than an agent loop, and why it is
portable.

## What comes back

```
product   <product-ir>     the requirements, and what covers each one
board     <circuit-ir>     spec · netlist · BOM · verdict · readiness
enclosure <design-ir>      features · parts · walls · cavities · mounts · ports · measured stats
firmware  <software-ir>    source · pin map, resolved against the netlist
package   <build-package>  plates · BOM · assembly steps · the machine command
```

Plus `interfaces: {checked, passed, failing, skipped}`. **Read `skipped`** — a check nobody could
assemble is not a check that passed, and it names what was missing.

## The five interface checks

Derived by `product-compiler.deriveInterfaces` from the three stored documents. Every number is
measured; **every threshold is a declaration and none is ever invented**, because a check with a
made-up threshold passes and means nothing.

| check | what it proves |
|---|---|
| `board-fits-enclosure` | the board's clearance envelope is a volume-intersection fit inside the measured cavity |
| `mount-alignment` | every hole has a boss **and every boss has a hole** — the direction nobody else checks |
| `connector-cutouts` | every external connector has an opening in the wall it faces, sized for the plug |
| `pin-map-matches` | every firmware pin exists on the board, on the net the firmware thinks, in a direction the part can do |
| `bom-complete` | one bill of materials covers every made part, every component and every fastener |

## The rules that make it work first try

Everything below is **algorithmic** — computed and handed to the model, never left to its judgement.
Each one was added because its absence produced a specific, repeatable failure.

- **The board is designed first.** `defaultPlan` orders electronic → mechanical → software; the later
  two read the board. An enclosure sized before the board exists is sized for a guess.
- **The cavity arithmetic is computed** ("at least W+2c × D+2c × stack+2c") and put in the prompt.
- **The connector rectangle is computed** (body + 2× plug clearance), and the wall frame — `[u,v]`
  from the CENTRE of the face — is stated in *both* grammars. Two frames for one number put a cutout
  50mm from its socket.
- **The pin table is resolved.** A netlist says `U1.GPIO4`; `pinMode()` takes `4`. `mcuPads()` in
  `@leumas/reality-compiler/pinMap.js` is the one bridge, and an ambiguous number is dropped rather
  than guessed.
- **The parts library is in the prompt.** A chip whose `value` is not a library id is refused as an
  unknown pinout, so guessing costs a round trip. `circuit-studio.parts` is the door.
- **A refusal is fed back verbatim, `details` and all.** Told only that something failed, a model
  guesses and burns the retry on the wrong fix.

## What it refuses, and why that is the feature

- **A stage that refuses fails the run.** A refusal recorded as `done` is the most expensive lie a
  pipeline can tell — indistinguishable from success in every count.
- **Firmware naming a pin the board does not route is not stored** (`pins-not-routed`), and the
  correction carries the right number.
- **A board whose electrical rules fail is not stored.** A stored artifact is one later passes trust.
- **A part with a guessed pinout cannot be exported.** `provisional` → `derived` → `verified`; only a
  human promotes to `verified`.
- **A brief needing a part nobody has entered is refused**, not approximated. Add it with
  `circuit-studio.importParts` (which requires a `source`) or put an inline `pins` map with a
  `pinSource` on the component.

## Proving it

```bash
pnpm smoke:one-prompt                             # the simple brief, once
pnpm smoke:one-prompt --brief hub --runs 3         # a harder board, three times, with a rate
pnpm smoke:one-prompt --brief all                  # every preset
pnpm smoke:one-prompt --provider codex             # any brain
```

Three presets that climb: `monitor` (one MCU, two peripherals) · `hub` (a regulated rail, four
peripherals, two buses) · `array` (dozens of emitters behind buffers). Every part in all three is
already in the library, so what is measured is the **pipeline**, not the parts catalogue. The tail of
the run is a consistency table and a first-try rate.

Without a provider the smoke skips loudly — except the anti-green-tick assertion, which always runs.

## Where the code is

| | |
|---|---|
| the engine | `shared/engines/inventor/` — `decompose` · `loop` · `stages` · `contracts` |
| the IR contract | `shared/packages/reality-compiler/` — 12 kinds, hashing, lineage, the interface tables |
| the geometry | `shared/engines/generation/.../cad/kit/` — evaluator, joinery, exporters, `interfaceCheck` |
| the adapters | `inventor` · `product-compiler` · `cad-compiler` · `circuit-studio` · `fabrication-plan` |
| the CLI | `ops/tools/invent/index.mjs` |

Deeper: `leumas-circuits` for boards, `leumas-capabilities` for what exists and how to wire more in.

## Gerbers

The adapter lane produces source, netlist, BOM and a verdict. **Real fab files are produced in the
browser** by `buildFabPackage`, reachable headlessly:

```bash
node ops/tools/circuit-check/index.mjs --export
```

That is the only lane that yields Gerbers, Excellon, BOM CSV and pick-and-place, because they are
made from the *evaluated* circuit graph and nothing on the server side has one.


---
Source: .claude/skills/idea-to-reality/SKILL.md
Canonical: https://docs.leumas.tech/p/skills/idea-to-reality
