11 — PCB evidence, enclosure readback and release packaging
Distilled from the incident notes of a second project: a two- and four-port CAN breakout PCB with a printed housing,
designed with KiCad 10 and cad-agent on 2026-10-26 (repository mvalancy/pcb-agx-thor-can-breakout). The board-specific
detail (coordinates, net names, project tools) stays in that repository's .agents/ notes; each Source line names
the note. Nothing here was electrically or physically tested; the lessons are about CAD evidence.
Treat ERC, DRC, connectivity and schematic parity as separate evidence
- Rule: a routed board with zero unconnected items is not a verified board. Keep ERC, DRC violations, unconnected
items and schematic parity as separate results, and never reduce a DRC report to its
violationsarray. - Incident: the first routed KiCad 10 reports showed 0 unconnected items but 100/131 schematic parity warnings.
The PCB net names lacked the schematic's root
/namespace, no-connect pads had no isolated net, and footprint fields were missing. Netlist-based synchronisation and board-only mount attributes closed the parity gap. - Check:
cad-agent pcb-check(docs/pcb.md) fails on any error, warning, unconnected item or parity finding. - Source:
.agents/inbox/2026-10-26-pcb-evidence.md(cad-agent PR #1).
Run every severity, and account for every ignored check
- Rule: generate ERC/DRC with
--severity-all. A default kicad-cli run leaves excluded violations out of the report and--severity-errordrops warnings, yet both reports look clean. Checks a project switched off (ignored_checks) are findings too: accept each one only by name, with a written reason. - Incident: the committed DRC report recorded
included_severities: ["error","warning"]and five ignored checks (for examplemissing_courtyard). The first evidence adapter passed it with no trace of either. A review of the adapter caught it by re-running DRC with--severity-error, which still passed. - Check: the adapter fails a report whose
included_severitieslacks error, warning or exclusion, and fails every ignored or excluded check key the evidence manifest does not waive with a reason. - Source: cad-agent PR #1 review (finding on
pcb.py);exports/2port/drc.jsonin the PCB project.
Re-run DRC on the bytes you saved
- Rule: bind reports to source hashes taken after the last write to the sources.
kicad-cli pcb drc --refill-zones --save-boardwrites the board after its JSON, so the report describes the board before the save; run DRC again on the saved board without saving. Touching a report's timestamp is not evidence. - Incident: a refill-and-save run produced a report older than the board it described; the export sequence now runs a second, read-only DRC.
- Check: the bundle records
source_sha256andreport_sha256; binding rejects reports older than any source. - Source:
.agents/inbox/2026-10-26-report-freshness-formats.md.
Check each report's declared hashes with one shared helper
- Rule: different reports declare different evidence (source hashes, report hashes, mechanical sources, exported solids). Verify whichever maps a report declares, all through one containment-aware function, and use it everywhere a pass is displayed. An empty or invalid declared map fails.
- Incident: the review workbench applied the PCB-bundle checker to every report with
source_sha256, so current routing and fabrication reports showed STALE. The standalone report had the opposite gap: it trustedpass: truewithout checking hashes, so a changed solid still passed. Later, the design card and the workbench disagreed about a bundle whose source path left the project root. - Check:
cadagent.evidence.hashes_are_current; regression tests change one source byte and expect STALE in the workbench, the report row and the design card. - Source:
.agents/inbox/2026-10-26-report-freshness-formats.md; cad-agent PR #1 review.
Measure routing geometry and the return plane; DRC does not
- Rule: connectivity and clearance checks say nothing about differential pairing or return-path continuity. Measure the shortest layer-aware copper path per signal (excluding stubs such as termination branches), require the protection pads on that path, compare pair imbalance and layer changes, and sample the reference copper under each trace. Route constrained pairs first and reserve the plane beneath them before routing anything else.
- Incident: boards that passed ERC, DRC and parity had separated pair conductors, and an auxiliary track left a 19.3 mm gap in the reference plane under one pair. A total-copper-length sum hid it by adding the termination branch.
- Check:
cadagent.pcb_routinggraph/path and paired-spacing measurements, with project-defined limits. They do not establish impedance, data rate, EMC or transient immunity. - Source:
.agents/inbox/2026-10-26-can-routing-is-not-connectivity.md.
Prove a stitching via joins the main plane, not another island
- Rule: a via touching copper on both layers may join two isolated islands. When a zone-to-zone ratsnest remains, inspect the filled, connected regions and re-run native connectivity after each stitch. Never disable the unconnected check or treat a zone-to-zone finding as cosmetic.
- Incident: one DRC
unconnected_itemsfinding persisted after stitching; the via had joined a small bottom island to a separate front region. A second via where the island overlapped the main-plane region closed it. - Check: DRC with
--refill-zonesreports zero unconnected items. - Source:
.agents/inbox/2026-10-26-ground-islands-need-a-real-bridge.md.
A part substitution is a new design: re-source and re-check it
- Rule: identify a bought part by manufacturer plus exact MPN plus full supplier code. A short name, pitch or category is not substitution approval. After changing a footprint, rerun electrical and mechanical checks, even within the same connector family.
- Incident: exact connector pad geometry replaced a generic footprint of the same family and changed clearances, which needed a fresh DRC. A TVS part was referred to by a short family name that matches several products.
- Check: BOM rows carry exact C-codes (
cadagent.pcb.check_jlc_files), and a C-code is still not proof of stock or orientation. - Source:
.agents/inbox/2026-10-26-pcb-evidence.md,.agents/domains/pcb.md(cad-agent PR #1).
Align a PCB STEP with a rotation, never a mirror
- Rule: reorient native or manufacturer STEP assemblies with proper rotations and translations (determinant +1). A mirror can make a symmetric outline fit while reversing every asymmetric connector. Record the transform and apply the same map to labels, port centres, mating envelopes and clamps.
- Incident: the enclosure import used
mirror('XZ')to make the board's Y positive. Outline collision checks passed while the ribbon header sat on the mirrored side. A 180° rotation about Z plus a translation fixed it. - Check: check one asymmetric feature (a header, a polarised connector) in housing coordinates after import.
- Source:
.agents/inbox/2026-10-26-preserve-pcb-handedness.md.
Give joined features positive overlap; a valid BREP can still mesh badly
- Rule: a boss or rib that only touches a wall tangentially can give a valid single solid and a non-manifold STL. Joined features need positive volume overlap. Check the solid, the STL and the 3MF separately after every change.
- Incident: a Ø9.2 mm corner boss touched the inner wall with no overlap; the CAD was valid but the STL had six edges not shared by exactly two faces. Ø9.6 mm (0.2 mm overlap) fixed it.
- Check: the watertight-mesh check in
cad-agent check. - Source:
.agents/inbox/2026-10-26-tangent-boss-mesh.md.
Render final review images from the exported STEP
- Rule: final assembly pictures should show the deliverable: re-import the exported STEP for each scene and compare visible placement to model coordinates, especially for text, repeated instances and exploded views.
- Incident: an in-memory render showed two lid labels run together although their centres were 42 mm apart; the STEP readback rendered them correctly. The exported solids were right; the preview was not.
- Check: render from readback; record export hashes next to the images.
- Source:
.agents/inbox/2026-10-26-review-export-readbacks.md.
Engrave panel artwork in bounded operations
- Rule: do not subtract one compound of many overlapping text and stroke tools. Cut item by item, fusing only each polyline's own stroke and cap solids, and validate the final solid count and the exported mesh.
- Incident: one aggregate subtraction ran for more than twelve minutes without finishing; the staged cuts finished a probe in about 109 s with one valid solid.
- Check:
cadagent.markings.PanelMarkings.engrave; timing depends on the artwork and is not guaranteed. - Source:
.agents/inbox/2026-10-26-panel-engraving-overlap-cost.md(cad-agent PR #1).
Package releases from the validated manifest, not a folder glob
- Rule: release membership comes from the validated public file list. Compare the member hashes of a local package with one built from a clean checkout.
- Incident: local PCB packages contained KiCad's Git-ignored
.kicad_prlUI-state files; CI packages built from clean checkouts did not. Both passed source validation because the glob, not the manifest, chose the files. - Check: package candidates are filtered through the allowlist; local and clean-checkout ZIP membership match.
- Source:
.agents/inbox/2026-10-26-release-manifest-allowlist.md.
Don't let .github/README.md replace the repository overview
- Rule: GitHub picks the landing README from
.github/, then the root, thendocs/. When the root README is the overview, do not create.github/README.md; document CI in.github/workflows/README.md. After publishing, check the hosted/readmeAPI and the visible page, not only local links. - Incident: a README-in-every-folder generator created
.github/README.md, and the public page showed only "CI validation and prerelease publication". - Check:
gh api repos/<owner>/<repo>/readme --jq .pathreturnsREADME.md. - Source:
.agents/inbox/2026-10-26-github-readme-precedence.md; https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
Keep CAD checks, fit and qualification as separate gates
- Rule: a clean CAD check never turns fabrication, physical fit, transient protection, bus timing, stock or supplier orientation green. Check the enclosure against the native PCB STEP with its components, mating plugs, cables, fasteners and tool access, not a bare-board proxy; record physical qualification as pending until measured.
- Incident: the review playbook for the breakout listed eight steps from carrier revision to physical
qualification; the evidence bundle keeps
physical_fit_verifiedandelectrical_testedfalse and release gates open. - Check: design cards show CAD status and open release gates separately (docs/pcb.md).
- Source:
.agents/playbooks/pcb-review.md,.agents/issues/pcb-evidence.md(cad-agent PR #1).