{
  "schema": "leumas.docs.page/1",
  "id": "skill:idea-to-reality",
  "slug": "skills/idea-to-reality",
  "kind": "tools",
  "bucket": "skill",
  "title": "idea-to-reality",
  "name": "Idea to Reality",
  "eyebrow": null,
  "chip": null,
  "summary": "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.",
  "keywords": [
    "idea-to-reality",
    "enclosure",
    "cross-checked",
    "firmware",
    "invent",
    "leumas idea to reality",
    "sentence",
    "refuses feature"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "\n# Idea to reality\n\nOne sentence in, three artifacts out, cross-checked. The pipeline derives requirements from the ask,\nre-derives its own plan from them, designs the board, sizes the enclosure **around that board**,\nwrites firmware **against that board's netlist**, checks the three against each other, and assembles\na work order for a machine that can actually make the part.\n\n**Everything is one adapter call.** `inventor.invent` is the door; the six-stage gate loop lives\nbehind it. Reach for the stage-by-stage API only when a person is approving each gate.\n\n```bash\npnpm invent \"A desk environment monitor: an ESP32 reading a BME280 over I2C, with a status LED\n             and a button, in a small printed enclosure.\" --provider cursor-agent\n```\n\n| flag | what it does |\n|---|---|\n| `--provider <id>` | `cursor-agent` · `codex` · `claude` · `openai` · `ollama` · `gemini`. **Name one for a reproducible run** — `auto` can answer differently on two machines. |\n| `--boot` | boot an API in-process instead of talking to one. Needs no server; what makes this work on a clean checkout. |\n| `--api <url>` | an API already running (default `http://127.0.0.1:3000`, or `LEUMAS_API_URL`). |\n| `--hold` | stop at the first gate and print the plan instead of building. |\n| `--export <dir>` | write the finished geometry there as STL + 3MF, one file per part. |\n| `--json` | the result as JSON and nothing else, for a script. |\n\nExit code is 0 only when the run finished **and** every interface check passed.\n\n## From another agent — Claude Code, Codex, any MCP client\n\nThe adapter registry exposes every function as an MCP tool automatically, so nothing needs building:\n\n```bash\n# 1. mint a key (session-authenticated, once)\ncurl -s -X POST http://127.0.0.1:3000/keys -H 'content-type: application/json' \\\n  --cookie \"$LEUMAS_COOKIE\" -d '{\"name\":\"invent\",\"scopes\":[\"mcp\"]}'\n\n# 2. point the client at the gateway\nclaude mcp add --transport http leumas http://127.0.0.1:3000/mcp/rpc \\\n  --header \"Authorization: Bearer lk_…\"\n```\n\nThen call **`inventor__invent`** with `{brief, provider}`. The gateway flattens all 190 adapter\nsystems into one server and namespaces tools `<system>__<fn>`, so ~1,800 tools arrive at once — which\nis exactly why `invent` exists as a single call. For a curated server, create an Imperium config with\n`mode: 'mcp'` selecting `adapter:inventor.*` and connect to `/mcp/s/<configId>` instead.\n\nCodex and any other client work identically: the pipeline hands every provider the same typed\ngrammar and makes every adapter call itself, so **none of this needs tool-calling support** from the\nmodel. `toolloop.js` gates tools on `provider.capabilities.tools`, and `cursor-agent` is `tools:\nfalse` — that constraint is why the design is a grammar rather than an agent loop, and why it is\nportable.\n\n## What comes back\n\n```\nproduct   <product-ir>     the requirements, and what covers each one\nboard     <circuit-ir>     spec · netlist · BOM · verdict · readiness\nenclosure <design-ir>      features · parts · walls · cavities · mounts · ports · measured stats\nfirmware  <software-ir>    source · pin map, resolved against the netlist\npackage   <build-package>  plates · BOM · assembly steps · the machine command\n```\n\nPlus `interfaces: {checked, passed, failing, skipped}`. **Read `skipped`** — a check nobody could\nassemble is not a check that passed, and it names what was missing.\n\n## The five interface checks\n\nDerived by `product-compiler.deriveInterfaces` from the three stored documents. Every number is\nmeasured; **every threshold is a declaration and none is ever invented**, because a check with a\nmade-up threshold passes and means nothing.\n\n| check | what it proves |\n|---|---|\n| `board-fits-enclosure` | the board's clearance envelope is a volume-intersection fit inside the measured cavity |\n| `mount-alignment` | every hole has a boss **and every boss has a hole** — the direction nobody else checks |\n| `connector-cutouts` | every external connector has an opening in the wall it faces, sized for the plug |\n| `pin-map-matches` | every firmware pin exists on the board, on the net the firmware thinks, in a direction the part can do |\n| `bom-complete` | one bill of materials covers every made part, every component and every fastener |\n\n## The rules that make it work first try\n\nEverything below is **algorithmic** — computed and handed to the model, never left to its judgement.\nEach one was added because its absence produced a specific, repeatable failure.\n\n- **The board is designed first.** `defaultPlan` orders electronic → mechanical → software; the later\n  two read the board. An enclosure sized before the board exists is sized for a guess.\n- **The cavity arithmetic is computed** (\"at least W+2c × D+2c × stack+2c\") and put in the prompt.\n- **The connector rectangle is computed** (body + 2× plug clearance), and the wall frame — `[u,v]`\n  from the CENTRE of the face — is stated in *both* grammars. Two frames for one number put a cutout\n  50mm from its socket.\n- **The pin table is resolved.** A netlist says `U1.GPIO4`; `pinMode()` takes `4`. `mcuPads()` in\n  `@leumas/reality-compiler/pinMap.js` is the one bridge, and an ambiguous number is dropped rather\n  than guessed.\n- **The parts library is in the prompt.** A chip whose `value` is not a library id is refused as an\n  unknown pinout, so guessing costs a round trip. `circuit-studio.parts` is the door.\n- **A refusal is fed back verbatim, `details` and all.** Told only that something failed, a model\n  guesses and burns the retry on the wrong fix.\n\n## What it refuses, and why that is the feature\n\n- **A stage that refuses fails the run.** A refusal recorded as `done` is the most expensive lie a\n  pipeline can tell — indistinguishable from success in every count.\n- **Firmware naming a pin the board does not route is not stored** (`pins-not-routed`), and the\n  correction carries the right number.\n- **A board whose electrical rules fail is not stored.** A stored artifact is one later passes trust.\n- **A part with a guessed pinout cannot be exported.** `provisional` → `derived` → `verified`; only a\n  human promotes to `verified`.\n- **A brief needing a part nobody has entered is refused**, not approximated. Add it with\n  `circuit-studio.importParts` (which requires a `source`) or put an inline `pins` map with a\n  `pinSource` on the component.\n\n## Proving it\n\n```bash\npnpm smoke:one-prompt                             # the simple brief, once\npnpm smoke:one-prompt --brief hub --runs 3         # a harder board, three times, with a rate\npnpm smoke:one-prompt --brief all                  # every preset\npnpm smoke:one-prompt --provider codex             # any brain\n```\n\nThree presets that climb: `monitor` (one MCU, two peripherals) · `hub` (a regulated rail, four\nperipherals, two buses) · `array` (dozens of emitters behind buffers). Every part in all three is\nalready in the library, so what is measured is the **pipeline**, not the parts catalogue. The tail of\nthe run is a consistency table and a first-try rate.\n\nWithout a provider the smoke skips loudly — except the anti-green-tick assertion, which always runs.\n\n## Where the code is\n\n| | |\n|---|---|\n| the engine | `shared/engines/inventor/` — `decompose` · `loop` · `stages` · `contracts` |\n| the IR contract | `shared/packages/reality-compiler/` — 12 kinds, hashing, lineage, the interface tables |\n| the geometry | `shared/engines/generation/.../cad/kit/` — evaluator, joinery, exporters, `interfaceCheck` |\n| the adapters | `inventor` · `product-compiler` · `cad-compiler` · `circuit-studio` · `fabrication-plan` |\n| the CLI | `ops/tools/invent/index.mjs` |\n\nDeeper: `leumas-circuits` for boards, `leumas-capabilities` for what exists and how to wire more in.\n\n## Gerbers\n\nThe adapter lane produces source, netlist, BOM and a verdict. **Real fab files are produced in the\nbrowser** by `buildFabPackage`, reachable headlessly:\n\n```bash\nnode ops/tools/circuit-check/index.mjs --export\n```\n\nThat is the only lane that yields Gerbers, Excellon, BOM CSV and pick-and-place, because they are\nmade from the *evaluated* circuit graph and nothing on the server side has one.\n",
  "source": {
    "path": ".claude/skills/idea-to-reality/SKILL.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 8446,
    "hash": "659d50817dec375ca8bfb2adf07b88192956e588"
  },
  "urls": {
    "html": "/p/skills/idea-to-reality",
    "json": "/docs/skills/idea-to-reality.json",
    "md": "/docs/skills/idea-to-reality.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
