Kicad
Make KiCad 9 a node in the swamp automation graph —
headless ERC/DRC/BOM/netlist/gerber/pos/render over KiCad's kicad-cli, run in
a podman/toolbox container and surfaced as typed, CEL-referenceable swamp
evidence for factory gates.
One model INSTANCE is scoped to a SINGLE board/source-set: kicad is the TYPE,
the instance handle is the board name (e.g. swamp model create @kneel/kicad badge_min). A second board needs a second instance, so the fixed data-names
never collide across boards. Every evidence payload self-identifies its board
via source + sha256, and consuming gates MUST assert
data.latest("<board>","drc").attributes.source == <expected> before trusting
clean.
Trust model
GlobalArgs are trusted-operator config set at model-create time, but every
security-critical value with a single correct answer is a HARDCODED in-code
constant, not a configurable field: the binary name (kicad-cli) and the
version pin (9.0.9) are constants. GlobalArgs expose only runtime
(toolbox|podman|local), container, and sharedMountRoot (validated at
config-time to resolve to a real directory under a minimum depth). Every
caller-influenced argv element is path-checked, enum-bounded, or an integer —
no free-form string reaches argv unchecked, and no -- terminator is emitted
(KiCad 9.0.9 rejects it).
Methods
- erc — schematic electrical-rules check →
ercevidence (clean,errorCount,warningCount,exclusionCount,violations[]). - drc — board design-rules check →
drcevidence (addsunconnectedCount,parityCount). - netlist — export the KiCad-sexpr netlist →
netlist(componentCount). - bom — export the CSV BOM →
bom(rows[],lineCount). - export_gerbers — export Gerbers AND the Excellon drill file →
gerbers(deterministic normalizedsha256bundle digest,layers[],fileCount). - pos — export the placement CSV →
pos(placementCount). - render — render a PCB PNG →
render(width,height,side). - check — Rule-6 fan-out: run erc + drc (+ optional bom) in ONE execution /
one model-lock, writing each evidence instance (no separate
checkinstance).
ERC/DRC are invoked WITHOUT --exit-code-violations and parse the -o JSON
file UNCONDITIONALLY regardless of child exit status; clean is authoritative
and model-computed from parsed error-severity violations (fail-closed) — an
unknown/missing severity counts as an error and keeps the board dirty.
Quickstart
swamp model create @kneel/kicad badge_min \
--global-arg runtime=toolbox \
--global-arg container=fedora \
--global-arg sharedMountRoot=/home/neil/dev
swamp model method run badge_min check --input source=.../badge.kicad_sch \
--input pcb=.../badge.kicad_pcb --input outDir=.../outReference the evidence with CEL (2nd arg is the board instance):
data.latest("badge_min", "drc").attributes.clean
data.latest("badge_min", "drc").attributes.sourceInitial @kneel/kicad — KiCad 9 kicad-cli wrapper. 7 methods (erc/drc/netlist/bom/export_gerbers/pos/render) + Rule-6 fan-out check. Fail-closed ERC/DRC; security seam with in-code constants + assertSafeSource/OutDir. 26 unit tests, E2E-green on kicad-cli 9.0.9.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| runtime | enum | Transport for running kicad-cli. 'local' runs on PATH; toolbox/podman hop into a container. |
| container | string | Container name (toolbox/podman). Spliced as the value token after '-c', so getopt consumes it regardless of a leading dash. Documented low-risk default (SEC4-6). |
| sharedMountRoot | string | Host directory shared into the container. Source/outDir must resolve (realPath) under this root. Validated at config-time to resolve to a real directory below a minimum depth (SEC4-2). '~' expands to $HOME. |
| metadata | record |
| Argument | Type | Description |
|---|---|---|
| side | enum | |
| width | number | |
| height | number |
| Argument | Type | Description |
|---|---|---|
| bom | boolean | Also export + write the `bom` evidence. |
Resources
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License1/2partial
no SPDX license declared
- Verified public repository0/2missing