← Commit history

docs: close the three matrix gaps in the plan, ecosystem section, column key with links, Astra evidence

John Lauer ·a7bbc4b945 ·29d ago ·parent 00a1b92
2 files changed +93−16
docs/comparison.md+60−13
@@ -22,7 +22,22 @@ Adjacent code-first tools that generate KiCad files rather than drive KiCad ([ts  ## Feature matrix -Y = yes, P = partial, N = no. Columns: **Adom** this bridge, **MX** KiCAD-MCP-Server, **KN** Konnect, **HP** kicad-happy, **LA** kicad-mcp, **SD** Seeed, **PRO** kicad-mcp-pro, **AIA** KiCad-AI-Assistant, **KP** KiPilot, **POA** mcp-server-kicad.+Y = yes, P = partial, N = no. Column key:++| Column | Tool | Repository | Docs or site |+|---|---|---|---|+| Adom | Adom KiCad Bridge | [wiki.adom.inc/adom/kicad-bridge](https://wiki.adom.inc/adom/kicad-bridge) | [Adom Hydrogen](https://wiki.adom.inc/adom/hydrogen), [Adom Bridge](https://wiki.adom.inc/adom/adom-bridge) |+| MX | KiCAD-MCP-Server | [github.com/mixelpixx/KiCAD-MCP-Server](https://github.com/mixelpixx/KiCAD-MCP-Server) | [Platform guide](https://github.com/mixelpixx/KiCAD-MCP-Server/blob/main/docs/PLATFORM_GUIDE.md), [KiCad forum thread](https://forum.kicad.info/t/kicad-mcp-server/60704) |+| KN | Konnect | [github.com/mixelpixx/Konnect](https://github.com/mixelpixx/Konnect) | [Releases](https://github.com/mixelpixx/Konnect/releases) |+| HP | kicad-happy | [github.com/aklofas/kicad-happy](https://github.com/aklofas/kicad-happy) | README validation numbers on the repo |+| LA | kicad-mcp | [github.com/lamaalrajih/kicad-mcp](https://github.com/lamaalrajih/kicad-mcp) | [Glama listing](https://glama.ai/mcp/servers/@lamaalrajih/kicad-mcp) |+| SD | Seeed kicad-mcp-server | [github.com/Seeed-Studio/kicad-mcp-server](https://github.com/Seeed-Studio/kicad-mcp-server) | [PulseMCP listing](https://www.pulsemcp.com/servers/seeed-studio-kicad) |+| PRO | kicad-mcp-pro | [github.com/oaslananka/kicad-mcp-pro](https://github.com/oaslananka/kicad-mcp-pro) | [PyPI](https://pypi.org/project/kicad-mcp-pro/), [KiCad forum thread](https://forum.kicad.info/t/i-built-an-open-source-mcp-server-for-ai-assisted-kicad-workflows/68678) |+| AIA | KiCad-AI-Assistant | [github.com/paul356/KiCad-AI-Assistant](https://github.com/paul356/KiCad-AI-Assistant) | [KiCad forum thread](https://forum.kicad.info/t/kicad-ai-assistant-a-llm-powered-kicad-plugin/69770) |+| KP | KiPilot | [github.com/belaszalontai/kipilot-mcp](https://github.com/belaszalontai/kipilot-mcp) | [kipilot.org docs](https://www.kipilot.org/docs.html) |+| POA | mcp-server-kicad | [github.com/ProductOfAmerica/mcp-server-kicad](https://github.com/ProductOfAmerica/mcp-server-kicad) | [PyPI](https://pypi.org/project/mcp-server-kicad/) |++Also audited, not in the matrix because they are too small or too different: [kicad-agentic-mcp](https://github.com/nevenfo/kicad-agentic-mcp), [eda-agent](https://github.com/salitronic/eda-agent), [Huaqiu kicad-mcp](https://github.com/Huaqiu-Electronics/kicad-mcp), [kicad-harness](https://github.com/zxkmm/kicad-harness), [codex-kicad-mcp](https://pypi.org/project/codex-kicad-mcp/), [pcb-mcp](https://github.com/bunnyf/pcb-mcp).  | Feature | Adom | MX | KN | HP | LA | SD | PRO | AIA | KP | POA | |---|---|---|---|---|---|---|---|---|---|---|@@ -32,12 +47,12 @@ Y = yes, P = partial, N = no. Columns: **Adom** this bridge, **MX** KiCAD-MCP-Se | Screenshot of the real KiCad windows, dialogs included, without stealing focus | Y | N | N | N | N | N | N | N | N | N | | Video recording of a narrated tour | Y | N | N | N | N | N | N | N | N | N | | Schematic read (netlist, connections, lint) | Y | Y | Y | Y | Y | Y | Y | Y | P | Y |-| Schematic edit in place (symbols, wires, labels) | N | Y | Y | N | N | P | Y | Y | P | Y |+| Schematic edit in place (symbols, wires, labels) | Y (1) | Y | Y | N | N | P | Y | Y | P | Y | | BOM and netlist export | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | ERC and DRC with parsed results | Y | Y | Y | N | P | Y | Y | Y | N | Y | | Board read (pads, nets, tracks, routing state) | Y | Y | Y | Y | P | Y | Y | Y | Y | Y | | Board edit through KiCad's IPC API as native undo steps | Y | P | Y | N | N | N | P | Y | Y | N |-| Autorouting (Freerouting) | N | Y | Y | N | N | N | Y | N | N | Y |+| Autorouting: Freerouting engine plus AI routing through the IPC verbs | Y (1) | Y | Y | N | N | N | Y | N | N | Y | | Gerber, drill, STEP, SVG, PDF export | Y | Y | Y | P | N | P | Y | P | P | Y | | 3D image of a board or chip | Y (live viewer capture and kicad-cli render) | P | N | N | Y | N | Y | Y | N | N | | 3D model diagnostics (missing, unresolved, wrong scale) | Y | N | N | N | N | N | N | N | N | N |@@ -52,33 +67,65 @@ Y = yes, P = partial, N = no. Columns: **Adom** this bridge, **MX** KiCAD-MCP-Se | Auto-update with an insiders tier | Y | N | N | N | N | N | P | N | N | N | | Health and readiness verbs | Y | P | Y | N | N | N | Y | N | Y | N | | Supported uninstall | Y | N | Y | P | N | N | N | N | N | N |-| Runs with no KiCad installed | N | N | N | Y | N | P | Y | N | N | Y |+| Runs with no KiCad installed (service-kicad container, kicad-cli in the container, or KiCad on another box) | Y | N | N | Y | N | P | Y | N | N | Y |+| Tool discovery: bridges are the tools, ab describes and routes them, the wiki hosts community add-ons | Y | N | Y | N | N | N | P | N | N | N |+| Parts search companion (Mouser, DigiKey, JLCPCB, best-source pick) | Y | P | Y | Y | N | P | N | N | N | N |+| Parts wiki: community-contributed components, each one ready for the AI to use | Y | N | N | N | N | P | N | N | N | N |+| Cross-app library conversion into KiCad format (adom-lbr) | Y | N | N | N | N | N | N | N | N | N |+| Datasheet straight to symbol and footprint (ds2sf) | Y | N | N | N | N | N | P | N | N | N |+| AI-first web dashboards for every KiCad surface, no KiCad window needed (adom-symbol, adom-footprint, adom-schematic, adom-2dboard) | Y | N | P | N | N | N | P | N | N | N |+| Drive KiCad from any AI (Claude, Codex, Antigravity, Grok, Kimi) with no per-AI MCP or plugin install | Y | N | N | N | N | N | N | N | N | N |+| One bridge ecosystem: KiCad, Fusion, Altium, pup, native browser, Blender, SolidWorks share ab's verbs | Y | N | N | N | N | N | N | N | N | N |+| Your wiki project is also your PCM repository | Y | N | N | N | N | N | N | N | N | N |+| Backed by a funded company rather than one maintainer | Y (NSF-funded) | N | N | N | N | Y (Seeed) | N | N | N | N |++(1) Scoped in [the Rust port plan](rust-port-plan.md) with a concrete design: schematic edit in phase 1, Freerouting in phase 2. Not in 0.9.350. The release notes will name the build that ships each one.  ## Where we lead, with the evidence  - **Window control that stays in the background.** No other tool opens KiCad's editors on a named part or captures the real window. The mechanism is a native menu walk with WM_COMMAND, UI Automation invoke, and PostMessage to one hwnd, all documented in the code with the measurements that led to them. The release gate on 2026-09-08 ran every window verb on two machines with the foreground-steal check on: 72 passed, 1 failed, 15 skipped on ConfRoomROG and 70, 3, 15 on winvm, and the six-beat narrated tour recorded on both.+- **A frontier model has already used it on a real board, on camera.** The [adom/codex page](https://wiki.adom.inc/adom/codex) carries four real KiCad window recordings of GPT-6 Astra routing through this bridge from a Hydrogen container: six nets, a 24-net crossbar, a first pass on the public Teazzers Solenoid Driver RP2040, and the [narrated full rerun](https://wiki.adom.inc/api/pages/adom/codex/files/videos/04-public-adom-solenoid-full-routing-narrated.mp4) that strips 484 segments and 58 vias from a copy and rebuilds it to 1,463 segments and 33 vias with zero unconnected items under native DRC. The [method log](https://wiki.adom.inc/adom/codex/files/docs/ASTRA-KICAD.md) names every bridge and ab verb used. No other tool on this page has a comparable public record. - **Dialogs.** The bridge seeds KiCad's settings so the first-run wizard never appears, sweeps transient dialogs after every verb, refuses to click Cancel on progress dialogs, and attaches a screenshot of anything it dismissed. The nearest competitor has one environment variable that auto-confirms a reload prompt. - **Install to uninstall.** `kicad_upgrade` performs the silent official KiCad install and verifies with kicad-cli; `kicad_uninstall` removes only our artifacts. ab polls the manifest every four hours and insiders get builds before the public tier. The audit found one competitor with a supported uninstall and none with an update path. - **Library and PCM.** Symbol, footprint and 3D install with lib-table registration, an Adom library that heals itself, in-place rescan verified in the editor, and PCM installs that reproduce KiCad's own on-disk layout. Three competitors author parts; none touch PCM. - **Cloud to desktop.** Every verb is addressable by machine name from a container, with the caller's thread and reason stamped on the request by Adom Bridge. Every competitor assumes the agent runs on the same desktop as KiCad or fully headless. - **Volume of releases.** 290 insiders builds since 0.9.60, each staged on a test box and verified before the manifest moved, with the bug history public on the [issue tracker](https://wiki.adom.inc/adom/kicad-bridge/issues). -## Where others lead, honestly+## Where others lead today, and what closes each gap -- **Schematic editing.** Konnect, KiCAD-MCP-Server, kicad-mcp-pro and mcp-server-kicad rewrite `.kicad_sch` on disk to place symbols and wires. We generate part projects but do not edit an existing schematic's wires. Every one of those tools carries the same caveat (close and reopen the schematic editor to see the change) because KiCad 10 has no schematic API. We chose to wait for the KiCad 11 API rather than ship file rewrites that KiCad cannot validate; that is a judgment call, and it is a gap today.-- **Autorouting.** Four tools wrap Freerouting. Our routing verbs route the waypoints the AI chooses and DRC-check each step; there is no autorouter, on purpose, and no plan to add one.-- **Headless without KiCad.** kicad-happy runs anywhere with no KiCad and publishes corpus-scale validation (6,845 schematics parsed at 100 percent). We require an installed KiCad and are Windows-first.-- **Zero-install distribution.** kicad-mcp-pro runs from `uvx`; Konnect is one static binary with 7,648 downloads and PCM install. We need Adom Bridge on the desktop, and until the Rust port lands we still ship a Python program that ab hosts. See [the Rust port plan](rust-port-plan.md).-- **Permission profiles inside the tool.** kicad-mcp-pro ships a read-only default profile and a human-gated release profile. Ours is enforced one layer down by Adom Bridge (risk classes, human-only grants, a reason on every gated call), which is stronger but is not visible in the bridge's own README.-- **Tool discovery economy.** Konnect loads a 2K-token starter kit and pulls toolsets on demand. Our describe verb returns all 85 entries at once.+- **Schematic editing.** Konnect, KiCAD-MCP-Server, kicad-mcp-pro and mcp-server-kicad rewrite `.kicad_sch` on disk to place symbols and wires, with the same caveat in every README (close and reopen the schematic editor to see the change) because KiCad 10 has no schematic API. We ship the same file-level verbs in phase 1 of the port plan, validated by kicad-cli ERC after every edit and reloaded in the editor by the bridge, and switch to the KiCad 11 schematic API the day it lands.+- **Autorouting.** Four tools wrap Freerouting. The port plan adds `kicad_autoroute` with Freerouting as one engine and the AI as the other, and the verb's hints tell the AI to ask the user which they want. Our recommendation is the AI: the routing verbs land each trace as a native undo step with a DRC check, and GPT-6 Astra in Codex has shown that a frontier model routes a board well this way, with Claude Fable 5.1 close behind and newer models arriving in the coming weeks. Freerouting stays for the user who wants a deterministic pass.+- **Headless without KiCad.** kicad-happy runs anywhere with no KiCad and publishes corpus-scale validation (6,845 schematics parsed at 100 percent). We match this three ways, all available today: the shared `service-kicad` container runs DRC, ERC, exports and library lookups for any container with no local install; the `service-kicad` skill installs kicad-cli into your own container; and Adom Bridge lets the GUI live on a second laptop, a conference room box, or a Grok Computer session driven through the Grok bot, with the AI talking to it by name.+- **Zero-install distribution.** kicad-mcp-pro runs from `uvx`; Konnect is one static binary with 7,648 downloads and PCM install. We need Adom Bridge on the desktop, and until the Rust port lands we ship a Python program that ab hosts. The port plan closes the binary half; the ab requirement is the price of everything in the ecosystem section below.+- **Permission profiles inside the tool.** kicad-mcp-pro ships a read-only default profile and a human-gated release profile. Ours is enforced one layer down by Adom Bridge (risk classes, human-only grants, a reason on every gated call). It is stronger and it is not visible in this bridge's own README, which this page now fixes.  ## What nobody else does at all -From the audit, no tool in the field does any of these: real window screenshots, video, driving a desktop from a cloud agent, per-call caller identity plus approval, PCM installs, dialog handling beyond one env var, auto-update, silent KiCad install, foreground etiquette, or 3D model diagnostics. That list is the argument for this bridge, and each item is a verb you can call today.+From the audit, no tool in the field does any of these: real window screenshots, video, driving a desktop from a cloud agent, per-call caller identity plus approval, PCM installs, dialog handling beyond one env var, auto-update, silent KiCad install, foreground etiquette, or 3D model diagnostics. Each item is a verb you can call today.++Nor does any of them come with what surrounds this bridge, which is the larger difference.++## The ecosystem around the bridge++Every other tool on this page is a KiCad tool. This bridge is one part of an environment built for hardware work, and the AI uses the parts together. When GPT-6 Astra in Codex built the TMF8829 depth lab project, it lived in the web dashboards in Hydrogen and reached for the KiCad window only when it needed KiCad's own verdict.++| Companion | What it adds |+|---|---|+| [Hydrogen](https://wiki.adom.inc/adom/hydrogen) | One workspace where Claude, Codex, Antigravity, Grok and Kimi all drive KiCad through the same bridge. No MCP server or plugin to install per AI. |+| [Adom Bridge](https://wiki.adom.inc/adom/adom-bridge) | The desktop host that has grown into a small operating system for bridges: KiCad, Fusion, Altium, pup, the native browser, Blender, SolidWorks. Screenshots, window control, recording, files, permissions and identity are ab verbs, so a new bridge never re-implements them and hardware work that spans CAD tools runs through one door. |+| [service-kicad](https://wiki.adom.inc/adom/service-kicad) | A shared headless KiCad service and a kicad-cli install for your own container. DRC, ERC, gerbers, STEP, GLB, renders and library lookups with no KiCad on any desktop. |+| [adom-parts-search](https://wiki.adom.inc/adom/adom-parts-search) | Mouser, DigiKey and JLCPCB in one search with a best-source recommendation, as a CLI and a Hydrogen app. |+| The parts wiki | Community-contributed components on wiki.adom.inc, each with symbol, footprint, 3D model and provenance ready for the AI. A part that is missing gets added by the user who needs it, and every user's AI gets it from then on. |+| [adom-lbr](https://wiki.adom.inc/adom/adom-lbr) | Library conversion across the popular CAD formats so existing work lands in KiCad format. |+| [adom-ds2sf](https://wiki.adom.inc/adom/adom-ds2sf) | Datasheet PDF straight to a KiCad symbol and footprint with provenance. |+| [adom-symbol](https://wiki.adom.inc/adom/adom-symbol), [adom-footprint](https://wiki.adom.inc/adom/adom-footprint), [adom-schematic](https://wiki.adom.inc/adom/adom-schematic), [adom-2dboard](https://wiki.adom.inc/adom/adom-2dboard) | AI-first web dashboards for every KiCad surface. The AI (and the user) sees symbols, footprints, schematics and boards instantly without opening KiCad, drives them over a live channel, and opens the real KiCad window only for the steps that need it. |+| Wiki PCM repositories | A project stored on the wiki can carry one or more PCM repositories, so the project is also its own plugin and library source for KiCad's Plugin and Content Manager. |+| Tool discovery | ab's `describe` and `discover` surface every bridge verb with hints, examples and pitfalls, and the wiki hosts add-on skills and bridges the community writes. Konnect's on-demand toolsets solve the same problem inside one tool. |+| Funding | Adom is a funded company (National Science Foundation) with this ecosystem as its focus, which is a claim a single maintainer cannot make and which matters for anyone deciding what to build on. |  ## The parts of this that are not ours to claim -- The GPT-6 Astra demo drove KiCad's GUI directly, per OpenAI's announcement and the KiCad forum thread. That is a lab demo, not a tool anyone can install, but it is the only other public example of GUI-level KiCad automation.+- OpenAI's GPT-6 Astra announcement showed Astra driving KiCad's GUI in a lab demo that nobody can install. The public, reproducible version of that exists on our side: Astra running in Codex inside Hydrogen, routing real boards through this bridge while the KiCad window is recorded. See the evidence bullet above. - Diode and atopile have the only public benchmark numbers for AI board design (EEBench). Those measure design quality of generated boards, not automation of KiCad, so they are not comparable to anything here. - KiCad developers have said on the forum that the MCP scene is "experiments you run, not products you install once." The evidence that we are the exception is the release gate, the tour recordings and the issue tracker, not this page. 
docs/rust-port-plan.md+33−3
@@ -141,6 +141,36 @@ The port adds, at first-run seeding time only (never on a settings file the user  Two prompts have no setting: "Save changes?" and "3D model not found". The port avoids the first with `SaveDocument` over IPC before any close (or the existing `discardChanges` contract) and the second with the existing `kicad_model_check` pre-flight before opening a footprint in 3D. +## Closing the three gaps in the comparison++The [comparison](comparison.md) marks three rows Y on the strength of this plan rather than of 0.9.350. Here is what each one is.++### Schematic edit in place (phase 1)++KiCad 10 has no schematic API, so every tool that edits a schematic today rewrites `.kicad_sch` on disk. We do the same, with the two things the others skip: validation and reload.++- Verbs: `kicad_sch_place_symbol {libId, ref, at, rotation, unit}`, `kicad_sch_wire {points}`, `kicad_sch_label {text, at, kind: local|global|hierarchical|power}`, `kicad_sch_move {ref, to}`, `kicad_sch_delete {uuid}`, `kicad_sch_set_property {ref, name, value}`.+- Mechanics: lossless s-expression round trip (the same parser the file group uses), UUIDs and symbol instances written the way eeschema writes them, `.bak` before every write, `kicad-cli sch erc` after every write with the delta reported, then a background reload of the open schematic editor (close and reopen through the existing window verbs, which is what KiCad itself requires; the response says so).+- KiCad 11: the moment `schematic_commands.proto` gains write commands, the same verbs switch to the API and the reload step disappears. The read-only hierarchy and netlist commands already in 10.99 get wired first.++### Autorouting (phase 2)++`kicad_autoroute {engine: "ai" | "freerouting", nets?, dryRun?}`.++- **`ai` is the default and the recommendation.** The routing verbs already give the AI what it needs: pads, nets, zones, live revision, one native undo step per trace, DRC per step. GPT-6 Astra in Codex has routed a 94-footprint public board this way to zero unconnected items ([recorded](https://wiki.adom.inc/adom/codex)), Claude Fable 5.1 handles the same verbs well, and newer models arriving in the coming weeks are expected to be better still. The AI sees the board, honours the schematic's intent (current, return paths, thermal), and can explain every trace; an autorouter cannot.+- **`freerouting` stays for the user who wants a deterministic pass.** The bridge writes a Specctra DSN from the parsed board (own writer; kicad-cli has no DSN export and RunAction names are unstable), fetches the Freerouting release and a portable Java runtime the way it fetches Mesa today (once, verified, into the bridge cache, never a UAC prompt), runs it headless, and applies the SES result through `kicad_add_track` and `kicad_add_via`, so even the autorouter's copper lands as native undo steps with a DRC check.+- **The hints decide nothing for the user.** The verb's `_hint` and `describe` entry tell the AI to ask the user which engine they want before routing, to say why `ai` is recommended, and to report which engine produced the copper. That is the same pattern as `foregroundReason`: the bridge makes the AI ask.++### Runs with no KiCad installed (already true, made visible in phase 1)++Three paths exist today and readiness should say so instead of reporting `not_installed` and stopping:++1. **The shared `service-kicad` container**: DRC, ERC, gerbers, STEP, GLB, renders and library lookups for any container, no desktop involved.+2. **kicad-cli in your own container**: the `service-kicad` skill installs it, so the headless verb group runs locally.+3. **KiCad on another box**: a second laptop, a conference room machine, or a Grok Computer session driven through the Grok bot, addressed by name through Adom Bridge.++Phase 1 adds a `backend` field to every headless verb (`local | service | target:<name>`) with `local` as default, and a `kicad_readiness.alternatives` block that lists the three paths with a one-line hint each when no local KiCad is found.+ ## Target architecture  ```@@ -184,14 +214,14 @@ Each phase ships to insiders through the existing release script and is gated by | Phase | Scope | Verbs | Effort | Exit test | |---|---|---|---|---| | 0. Prune in Python (now) | Delete `launch_editor.ps1`, `tour/` (older standalone tour), unused `foreground_guard.py`; delegate capture, enumeration and taskkill to ab; add the do_not_show_again seeding; record `mechanism` on every window verb | 0 new | 1 week | Runner unchanged, zip smaller, no PowerShell left except uia.py |-| 1. Rust skeleton and headless verbs | HTTP, catalog, describe, status, readiness, detect, diagnostics, kicad-cli group, file group, PCM, model_check, upgrade, uninstall, settings, design rules, part projects | ~45 | 3 to 4 weeks | Runner parity on those verbs, both boxes, zero Python |-| 2. IPC verbs | The nine routing verbs on kicad-ipc-rs; routing demo passes; `routing_deps/` deleted | 9 | 2 weeks | `demo/routing/run_demo.py --expect-version` green on 10.0.6 |+| 1. Rust skeleton and headless verbs | HTTP, catalog, describe, status, readiness (with alternatives), detect, diagnostics, kicad-cli group with `backend`, file group, PCM, model_check, upgrade, uninstall, settings, design rules, part projects, the six schematic edit verbs | ~51 | 4 to 5 weeks | Runner parity on those verbs, both boxes, zero Python |+| 2. IPC verbs | The nine routing verbs on kicad-ipc-rs; `kicad_autoroute` with the ai and freerouting engines; routing demo passes; `routing_deps/` deleted | 10 | 3 weeks | `demo/routing/run_demo.py --expect-version` green on 10.0.6 | | 3. Window verbs | launch, open_*, close_*, show_*, state, screenshot_all, send_key, click, dismiss_dialogs, window_info, place_footprint, software OpenGL | ~28 | 4 to 5 weeks | Runner parity plus the six-beat tour | | 4. Etiquette | Sentinel, WinEvent hook, ledger, idle rule, placement heal, ported or moved into ab | 0 | 2 weeks | Foreground-steal test from the runner (`fg_before`, `foreground_notes`) at zero steals | | 5. Demo tour | Beats, narration, motion, evidence | 1 | 2 weeks | Recorded tour on ConfRoomROG and winvm | | 6. Plugin retirement and KiCad 11 | Drop `plugin_payload`, register the exe as an IPC plugin through PCM, test on 10.99 nightly | 0 | 2 weeks | Runner on 10.0.6 and on the nightly | -Total: roughly 16 to 19 weeks of one AI thread's time with human test time on the boxes, or half that with two threads splitting phases 1+2 and 3+4 after the skeleton lands. The Python line count suggests 25,000 to 30,000 lines of Rust; the window group shrinks the most because ab absorbs the plumbing.+Total: roughly 18 to 21 weeks of one AI thread's time with human test time on the boxes, or half that with two threads splitting phases 1+2 and 3+4 after the skeleton lands. The Python line count suggests 25,000 to 30,000 lines of Rust; the window group shrinks the most because ab absorbs the plumbing.  ## Risks, stated plainly