feat(ecad): fab-prep as one command, with the DRC delta as its receipt#678
Open
ecto wants to merge 1 commit into
Open
feat(ecad): fab-prep as one command, with the DRC delta as its receipt#678ecto wants to merge 1 commit into
ecto wants to merge 1 commit into
Conversation
Taking a routed board to a manufacturable Gerber package was a hand-run sequence of example binaries: certify the remaining connections, calibrate the rules, census the offending nets, strip them, re-route, repeat, prune the dead copper, export. New crate `vcad-ecad-fabprep` is that sequence, exposed as `vcad fab-prep` and the `fab_prep` MCP tool. The receipt is the point. On an imported fixture "zero DRC violations" is not achievable and anyone reporting it is reporting something else: the CM5 board stripped of all routing already scores 1,546 violations against its own land patterns. So the report never gives one number. It gives the pair — stripped baseline and finished board — and charges only the difference to the router, stating per rule how the difference was taken (set difference for geometric rules whose identity survives a strip; count difference for connectivity rules that adding copper legitimately rewrites). Two attribution subtleties the naive delta gets wrong, both fixed here: - Shorts propagate. If the fixture's own overlapping pads short X–A and Y–A, routing net A between its own pads merges the blobs and X–Y is newly reported — a pair the router did not cause. A final short is charged only when it bridges two *baseline* short groups. - The loop can "fix" DRC by deleting copper. Every geometric violation goes away if you remove the trace, and a board with no traces scores perfectly. Connectivity is now measured on arrival and on completion, and a run that bought cleanliness with unconnected nets does not converge. Rule calibration is opt-in and logged: it only relaxes a rule to the point where the board's own *given* geometry stops being illegal (declared via classes; pre-existing pad drills — never router-placed vias, which would let the routing justify its own rules), is floored at laser-microvia limits, and records its derivation. Hole-to-hole is deliberately not inferred from a via class — it is a process capability, not something a class declares. Waivers (`--accept MinTraceWidth`) make the exceptions a real fab package ships with explicit instead of prose: waived violations stay counted, stay listed, and are tagged WAIVED in the dump. An unrecognised rule name refuses the run rather than silently accepting nothing. Fails closed throughout: a non-converging run writes the receipt and the board, withholds every fabrication file, and exits 1. `export_gerber`'s clean-DRC gate is untouched — fab-prep is the supported way to get clean, not around it. Verified against the manual result: `vcad fab-prep board.pcb.json --calibrate-rules --accept MinTraceWidth --accept SameNetBypass` reproduces ~/Downloads/cm5-vcad-fab byte-for-byte across all 27 fabrication artifacts (21 gerbers, drill.drl, board.kicad_pcb, bom.csv, pick_place.csv, board.svg), replacing the hand-written FAB_NOTES.md/drc_report.txt with the generated receipt and adding machine-readable fab_report.json. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Choji has used up today's reviewsYour team has reached the free plan's limit of 5 reviews per day, so Choji stepped aside on this pull request. That's a plan limit, not a reflection of the change itself. Your free reviews reset tomorrow. To have Choji review every push without waiting, upgrade to Pro for unlimited reviews. You're on the free plan · 5 reviews/day. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Turns the manual CM5 "fab prep" sequence — certify the remaining connections, calibrate the rules, census the offending nets, strip them, re-route, repeat, prune the dead copper, export — into one reproducible command. New crate
crates/vcad-ecad-fabprep, exposed asvcad fab-prepand thefab_prepMCP tool.The receipt is the point
On an imported fixture "zero DRC violations" is not achievable, and anyone reporting it is reporting something else — the CM5 board stripped of all routing already scores 1,546 violations against its own land patterns. So the report never gives one number. It gives the pair, and charges only the difference to the router:
How the difference is taken is stated per rule rather than assumed: a set difference for geometric rules whose identity survives a strip, a count difference for connectivity rules that adding copper legitimately rewrites (there the claim is the weaker, non-fictional one — the router left fewer than it found).
drc_report.txttags every lineROUTE/WAIVED/FIXTURE.Two attribution subtleties the naive delta gets wrong
Rule calibration: opt-in, floored, logged
Only relaxes a rule to the point where the board's own given geometry stops being illegal — declared via classes, and pre-existing pad drills. Never router-placed vias, which would let the routing justify its own rules. Every change carries its derivation:
Hole-to-hole is deliberately not inferred from a via class: it is a process capability, not something a class declares. If a board's declared value is wrong for its fab, the fix is to state the correct rule on the board — a decision with a named owner.
Waivers
Real fab packages ship with real exceptions; the CM5 campaign accepted 69 fab-legal 0.08 mm neckdowns in prose.
--accept MinTraceWidthmakes that explicit — waived violations stay counted, stay listed, and the waiver is named inFAB_NOTES.md. An unrecognised rule name refuses the run rather than silently accepting nothing.Fail closed
A non-converging run writes the receipt and the board, withholds every fabrication file, and exits 1.
export_gerber's clean-DRC gate is untouched — fab-prep is the supported way to get clean, not a way around it.Acceptance
vcad fab-prep ~/Downloads/cm5-vcad-fab/board.pcb.json --calibrate-rules --accept MinTraceWidth --accept SameNetBypassreproduces the reference package byte-for-byte across all 27 fabrication artifacts (21 gerbers,drill.drl,board.kicad_pcb,bom.csv,pick_place.csv,board.svg), replacing the hand-writtenFAB_NOTES.md/drc_report.txtwith the generated receipt and adding machine-readablefab_report.json.Tests cover the convergence loop, the fail-closed path (
write_fab_packagerefuses and leaves the evidence), the clean-by-deletion refusal, the best-board guard, short propagation, calibration derivation/floor/refusal, and waiver handling — 31 Rust unit tests plus 3 MCP tool tests.Verification
cargo test --workspace— green except a pre-existingvcad-kernel-physicsbuild failure (Joint: Defaultinm11_adjoint_rollout) caused by uncommitted drift in the siblingphyzcheckout, unrelated to this change.--exclude vcad-kernel-physics: 2,619+ tests, 0 failures.cargo clippy --workspace --exclude vcad-desktop -- -D warnings— clean.cargo fmt --all --check— clean.npm test -w @vcad/mcp— 937 passed.Note:
packages/kernel-wasm/vcad_kernel_wasm*was rebuilt locally to exercise the newecadFabPrepbinding, then restored fromorigin/mainper the single-writer policy. CI builds WASM from source, so the TypeScript job exercises the binding.🤖 Generated with Claude Code