Skip to main content

Kicad

@kneel/kicadv2026.07.18.1beta· 3mo agoBEHAVIORS
01README

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 → erc evidence (clean, errorCount, warningCount, exclusionCount, violations[]).
  • drc — board design-rules check → drc evidence (adds unconnectedCount, 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 normalized sha256 bundle 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 check instance).

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=.../out

Reference the evidence with CEL (2nd arg is the board instance):

data.latest("badge_min", "drc").attributes.clean
data.latest("badge_min", "drc").attributes.source
02Release Notes

Initial @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.

03Behaviors1
@kneel/kicadv2026.07.18.1kicad.ts

Global Arguments

ArgumentTypeDescription
runtimeenumTransport for running kicad-cli. 'local' runs on PATH; toolbox/podman hop into a container.
containerstringContainer 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).
sharedMountRootstringHost 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.
metadatarecord
fn erc()
Run the schematic ERC (WITHOUT --exit-code-violations); parse the -o JSON unconditionally and write fail-closed `erc` evidence.
fn drc()
Run the board DRC (WITHOUT --exit-code-violations); parse the -o JSON unconditionally and write fail-closed `drc` evidence.
fn netlist()
Export the KiCad-sexpr netlist and write `netlist` provenance + componentCount.
fn bom()
Export the CSV BOM and write parsed `bom` rows.
fn export_gerbers()
Export Gerbers AND the Excellon drill file (SEC5-1) into outDir; write `gerbers` with a normalized bundle digest, layer list and file count.
fn pos()
Export the placement CSV and write `pos` provenance + placementCount.
fn render(side: enum, width: number, height: number)
Render a PCB PNG (side ∈ {top,bottom}) and write `render` with the ACTUAL decoded dimensions.
ArgumentTypeDescription
sideenum
widthnumber
heightnumber
fn check(bom: boolean)
Rule-6 fan-out: run ERC + DRC (+ optional BOM) in ONE execution / one model-lock, writing the `erc`, `drc` (and `bom`) evidence instances so a gate never issues N contending method runs. Declares NO separate 'check' instance.
ArgumentTypeDescription
bombooleanAlso export + write the `bom` evidence.

Resources

erc(infinite)— Schematic electrical-rules-check evidence (fail-closed clean).
drc(infinite)— Board design-rules-check evidence (fail-closed clean).
netlist(infinite)— Exported netlist provenance + component count.
bom(infinite)— Parsed BOM rows from the CSV export.
gerbers(infinite)— Gerber + Excellon bundle digest (normalized) + layer list.
pos(infinite)— Placement (pick-and-place) file provenance + count.
render(infinite)— PCB render PNG provenance + actual dimensions.
04Stats
B
80 / 100
Downloads
26
Archive size
25.3 KB
  • 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
05Platforms
06Labels