fix(design-review): resolve audit nets through the net graph - #336
Conversation
audit_decoupling, audit_connections, audit_power_rails and run_design_review's coverage found a pin's net by scanning the file for a label within 0.5 mm of it. That follows no wires, reads no junctions and knows no power symbols, so a capacitor one grid step from the label naming its rail was netless and a rail named by a GND or +3V3 symbol did not exist at all. The audits under-reported connectivity and so over-reported faults: run_design_review returned NOT READY on a correct sheet. Resolve through net_graph_for instead — the graph the connectivity tools already share — and delete find_net_at_point, the last 0.5 mm text scan on the schematic side. collect_power_nets reads extract_all_net_labels, so a power-symbol rail is a rail; PWR_FLAG still is not one, its pin being power_out. One pin_nets is the only definition of "the nets this component's pins reach", with capacitor_nets, test_point_nets and pull_up_nets as filters over it. pull_up_nets is built once per sheet: has_pull_up_on_net re-walked every resistor for each I2C or reset pin. Test-point nets were a stub that always returned an empty set, so every rail was reported as having no test point. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
This PR's own Known limitations section points to #182: the new Could this PR make that walker unit-aware before merge? The smallest correction is to iterate The checked-in I am taking the independent |
The audit walks applied a placement's transform to extract_lib_pins, which returns every unit of a multi-unit symbol. A dual amplifier whose power pin lives on unit 3 therefore reported that pin at unit 1's and unit 2's coordinates too — three power pins where the sheet draws one, two of them on no net, so audit_decoupling raised two false errors and run_design_review counted them. Walk placed_pins_by_reference instead: the shared representation that selects the placed unit's pins and resolves a sheet-local derived symbol's (lib_name …). pin_nets, audit_decoupling and audit_connections now take those pins, so unit selection has one definition rather than three. With the audits unit-aware, the multi_unit_review_incomplete diagnostic is false — it made every review of a multi-unit sheet INCOMPLETE. Dropped; the coverage count stays, as a count. The rest of mixelpixx#182 (sch_analysis, sch_export, sch_batch) is unaffected and still open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Done in Regression coverage is three tests. Two are a synthetic dual amplifier whose One consequence worth flagging: with the audits unit-aware, the The |
Summary
audit_decoupling,audit_connections,audit_power_railsandrun_design_review's coverage found a pin's net by scanning the file text for(label "or(global_label "within 0.5 mm of the point. That follows nowires, reads no junctions and knows no power symbols, so on any sheet drawn the
normal way almost every pin was netless.
run_design_reviewis the "is my boardready?" tool, and it returned
NOT READY — critical issues must be fixed before manufacturingon a correct schematic, with all of its errors false.Found dogfooding on a real board (25 footprints, 99 nets, KiCad 10.0). On that
sheet:
audit_decoupling0/2 power pins have decouplingaudit_power_railspower_nets: ["VBUS"]+3V3andGNDare rails too — they are power symbolsaudit_power_railsPower rail 'VBUS' has no decoupling capacitorsrun_design_reviewcoverage.named_nets: 24The VBUS row is the sharpest: that rail is label-named and the audit still
missed its caps, because C1's pin is 3.81 mm from the label — eight times the
tolerance. So the failure was never only "power symbols are invisible"; any pin
more than 0.5 mm from the label naming its net was netless to these audits. A
sheet drawn entirely with labels at pins would pass, which is exactly the
sheet the tools were written against.
Not linked to an issue; the tracker has nothing on it. #184 and #247 made
run_design_reviewfail closed when coverage is incomplete, and neither toucheswhat the audits themselves resolve. #323 gave the connectivity tools one shared
index and left
find_net_at_pointout because it never used the net graph —this is what that exclusion cost.
Introduced by
dd49a86(the initial public release).83ec1cdfixed the tag itsearched for (
label, notnet_label) without changing the approach.Approach
Resolve through
net_graph_for— the graphsch_analysisandsch_exportalready share — so a pin reaches its net along the wires and junctions it is
drawn with, and a rail named by a power symbol is a net like any other.
find_net_at_pointis deleted, and with it the last 0.5 mm text scan on theschematic side.
collect_power_netsreadsextract_all_net_labelsinstead of scanning for(label ", so a power-symbol rail is a rail.PWR_FLAGstill is not one: itspin is
power_out, which the extractor skips. The list is now sorted; it wasHashSetiteration order.pin_nets(graph, pins)is the only definition of "the nets this placedunit's pins reach", with
capacitor_nets,test_point_netsandpull_up_netsas filters over it. Its pins come fromtools::placed_pins_by_reference, so the walk is unit-aware: a dualamplifier whose power pin lives on unit 3 no longer reports that pin at
units 1 and 2 as well.
audit_decouplingandaudit_connectionswalk thesame representation, so unit selection and
lib_nameresolution have onedefinition rather than three. That is the design-review half of sch_batch, sch_export, sch_analysis and design_review still resolve pins against unit 1 #182; the
sch_analysis,sch_exportandsch_batchhalf is untouched and still open.run_design_review'smulti_unit_review_incompletediagnostic is false — it made every review ofa multi-unit sheet INCOMPLETE. Dropped;
coverage.multi_unit_symbolsstays,as a count.
pull_up_netsis built once per sheet.has_pull_up_on_netwas called perI2C or reset pin and re-walked every resistor on the sheet each time.
comment saying a proper implementation would trace the wire — so every rail
was reported as having no test point. It traces the wire now.
run_design_review'scoverage.named_netscountsextract_all_net_labels,which makes it agree with what
list_schematic_netsreports for the samesheet.
net_graph_forrather than theConnectivityIndex#323 landed: the audits wantnet names at points, which is that function's exact contract, and it is the
primitive the other ten read-only tools already use.
ConnectivityIndexparsespin geometry these audits do not need.
Compatibility and safety
No tool names, arguments or response keys change. Read paths only — nothing is
written, no IPC. The findings these audits produce do change, which is the point
of the fix: fewer, and true.
Validation
Eight tests in a new
net_resolution_testsmodule, over sheets shaped like theone above: a capacitor reaching a power pin down a wire under a junction dot, a
rail named only by a power symbol, a test point at the far end of the wire, and
an I2C pull-up whose two ends are a wire and a power symbol.
Four of the five net-resolution sheets fail against the old resolver, and its
output on those sheets reproduces every row of the table above. The fifth is the fitted pull-up,
which the old code also passed — by never resolving either pin and reporting
nothing — so its pair, the missing pull-up that used to go unreported, is tested
alongside it. That direction matters as much: a pin whose net could not be
resolved was skipped silently, so the fault the audit exists to find was dropped.
Three of the eight cover the unit-aware walk: a dual amplifier whose
V+sitson a third unit is one power pin and not three, that same sheet reviews as
completerather than INCOMPLETE, and each placement of the checked-inecc83_multiunit.kicad_sch(two triodes and a heater, placed apart) walks onlyits own three pins. All three fail against the unit-agnostic walk.
Not re-run against the board itself; it is not in this repository.
cargo fmt --all -- --checkcargo test --workspace --locked --lib --tests(what CI runs)cargo test --workspace --locked --doccargo clippy --workspace --locked -- -D warningskonnect-sexp'severy_installed_demo_board_scans_losslesslyfails on mymachine, on
mainwith this branch's commit reverted as well: it skips 2 zonesfrom
royalblue54L_featherin the locally installed KiCad demo corpus. Pre-existingand unrelated to this change, which touches one file in
konnect-core.Known limitations
NetGraph::net_atreturns the firstpoint_netsentry whose union-find rootmatches —
HashMaporder. A net carrying two names therefore resolves to anarbitrary one of them while both are listed as rails, so the other reports as
undecoupled, and which one changes between runs. Pre-existing in
sch_connectivity, but this change makesdesign_reviewits heaviest caller.Fixing it means comparing nets by identity rather than by name, which is its
own change.
pull_up_netsstill decides "the other end is a rail" with theis_power_net_nameheuristic, so a pull-up to a rail named by a power symbolbut not by that regex —
VBAT,VDDA_EXT— is still invisible.Review checklist
docs/NAMING_CONVENTIONS.md; public renames include compatibility handling.