Status: implemented and ready for focused review. This slice promotes the native in-process version-E-oriented netlist projection and KiCad version-E S-expression writer. It does not promote a JSON, TypeSpec, WASM, or stable Cargo interchange API.
build_kicad_netlist consumes the existing
SchematicBundleIndex and an optional typed
ProjectView. It materializes resolved design nets, terminals,
components, component units, embedded library parts and pins, and per-sheet
title metadata. emit_kicad_netlist writes that model directly to
KiCad's version-E S-expression format through a bounded pretty emitter.
This slice intentionally governs the semantic subset consumed by the version-E writer. It does not yet promote net-class aliases, graphical IDs, bus flags, terminal endpoint records, libraries, or design source/date/tool metadata as complete native model fields. The Rust structs are native compiler state. The example gate serializes them only as test evidence. Any future browser, downstream JSON, or public interchange operation must first receive a TypeSpec-owned contract and generated projections; this implementation must not become an accidental hand-maintained transport contract.
~ blank sentinel normalizes to the empty model value and returns to ~ where the version-E writer requires it.Default.*, ?, bracket classes, negated classes, and ranges without exponential star backtracking.The scalar compiler's net and terminal ceilings are tightened to the caller's netlist ceilings before compilation. Net, terminal, component-row, component-candidate, field, unit, unit-pin, library-part, library-pin, sheet, retained-string, and output-byte allowances are independent. Component rows are rejected when a new group would cross the ceiling; candidates and pins are rejected before insertion. Title-block children and comments are counted from the structural index before model allocation. Recursive variable expansion has separate per-result and aggregate-work ceilings. Wildcard matching likewise has a caller-owned aggregate work ceiling across all nets and patterns.
Source parsing and model construction are linear apart from ordered map/set operations and natural pin sorting. Wildcard matching uses an iterative active-state simulation with O(pattern length) work memory and predictable O(pattern length times net-name length) time per attempted pattern. It never uses recursive or exponential wildcard backtracking. Version-E output is appended directly and checked before every write; an output-limit failure returns an error and publishes no partial string.
kicad_netlist.rs owns synthetic model, writer, wildcard,
reachability, title-block, and one-over/one-under resource evidence. Rack
L3_020 builds the native example once and compares the governed
version-E projection with Python on four governed real projects: Yoshi
Mainboard, Taillight, Speedy Processing Module, and Jumperless V5r7. The same
gate parses both emitted version-E documents and compares their governed
semantic trees. The four-project gate is mandatory corpus evidence and does
not silently skip unavailable inputs.
This slice does not replace the native kicad_cruncher command,
expose a public package API, reproduce every CLI option, or approve browser
packaging. Those remain later native-first slices. Exact KiCad CLI-oracle
expansion may add cases, but should reuse this model and direct writer rather
than introduce a parallel JSON-shaped compiler.