fix(drc): name what owns each DRC report item (#413) - #439
Conversation
A copper_edge_clearance item read identically whether the offending Edge.Cuts geometry was the board's real outline or a cutout a footprint carries in its own artwork, and the two need opposite repairs. Callers had to cross-reference list_board_footprint_graphics by hand to tell them apart; in the reported case that produced several turns of wrong fix guidance. Ownership is now resolved by exact UUID against the saved .kicad_pcb that DRC ran on, structurally and never from KiCad's prose. Every DRC item gains additive ownership_status / owner / item_kind / layer fields; an unresolvable item comes back owner: null with the status that says why, never defaulted to board. The enrichment sits in cli::run_drc, the one path run_drc and get_drc_violations share, so the two cannot disagree. Footprint ownership does not make a finding false: a footprint-owned Edge.Cuts circle is real fabrication geometry. It selects the remedy. Closes mixelpixx#413 Assisted-by: Claude Code / claude-opus-5[1m] Machine: A-Mac16-2019-PaloAlto Account: tonydzi Operator: robot:connector-butcher-daily Signed-off-by: tonydzi <194927794+tonydzi@users.noreply.github.com>
|
I reviewed exact head I also ran the previously unexecuted live test on this exact head: The review worktree was clean and detached at
Please also add the exact locked doctest command/result required by the contributor gate. The full-board UUID-index performance concern is not a blocker for this PR; optimizing only report UUIDs can be follow-up work if measurement shows it matters. No redesign or restack is requested. These are localized truthfulness and evidence fixes around an otherwise useful implementation. |
|
Thank you for running the Windows live test — that is the item I could not close from here, and it is now in the PR body with your environment and output. All three corrections accepted. Before I push anything, here is what I measured today on the exact head you reviewed, 1. duplicate UUIDs — the answer depends on file orderTwo nodes carrying the same UUID, one a board-owned Same board content, opposite owner, and both come out as
2. enrichment failure — you are right, and the code says so plainly
Every item will get 3. fixtures — accepted, and this is the one I cannot finish on this machineYou are right that the augmented file is presented as a KiCad-authored acceptance pair and is not one. Splitting it as you describe: the reporter's genuine J1 board/report pair stays the acceptance fixture; the missing/unknown UUID records — which no KiCad run can produce — become clearly named parser-only fixtures; the board-owned outline and the unrelated graphic get regenerated and resaved by KiCad with provenance recorded. That last step needs KiCad, and this node has none: So I will do it on the machine that has KiCad rather than hand-author another file and describe it as generated — which is the exact defect you are asking me to remove. The what happens nextOne push carrying 1, 2, the Agreed on the full-board UUID-index performance point being follow-up work, and I would rather it stay unmeasured than get an optimisation nobody has shown a need for. Disclosure where it can be checked: I am a synthetic co-founder (Claude) running unattended on Anton Dzyatkovsky's machine, github user |
|
Reconstructed on current main as #481. The replacement preserves Anton Dziatkovskii's authorship, resolves the current-main conflicts, addresses the duplicate-UUID and unavailable-enrichment review findings, adds real KiCad 10 evidence, and passes the complete local gate. Closing this stale branch in favor of the focused replacement. |
Closes #413.
run_drcandget_drc_violationsreduced every KiCad report item todescription,pos, and an optionaluuid. Acopper_edge_clearanceitem therefore reads identically whether the offendingEdge.Cutsgeometry is the board's real outline or a cutout a footprint carries in its own artwork — and the remedies are opposite. In the reported case that produced several turns of wrong fix guidance before manual cross-referencing againstlist_board_footprint_graphicsfound the real cause.Footprint ownership does not make the finding false. J1's circles are real cutouts in real copper. Ownership selects the remedy: a pad and a cutout carried by the same footprint move together, so repositioning the component cannot change their mutual clearance, and the footprint definition or the rule is what needs review.
What this does
Follows the focused PR direction on the issue:
konnect_sexp::board::uuid_indexbuilds a UUID index from the exact saved.kicad_pcbthat DRC ran on, using the existing s-expression parser — no new parser, no regex.(kicad_pcb …)index asowner.kind: "board"; nodes nested under a(footprint …)index asowner.kind: "footprint"with the footprint's reference and UUID. A(footprint …)node is itself a top-level board item, so it indexes as board-owned withitem_kind: "footprint".ReportItemis enriched by exact UUID only withitem_kind,layer,owner, andownership_status."owner": nullwith"ownership_status": "uuid_missing"or"not_found". Ownership is never inferred from prose like"Circle of J1"— a test renames every reference in the board and proves the reported reference changes with it while the description does not.cli::run_drc, the one path both tools take, sorun_drcandget_drc_violationscannot disagree. All three categories —violations,unconnected_items,schematic_parity— go through it.description,pos,uuid,severity, andruleare unchanged. The four new fields serialise away when unset, so ERC — which sharesReportItemand has no board to index — and any caller that ignores them see exactly the previous response. A board that will not parse still returns full DRC results, unannotated, with a warning logged: withholding findings over a failed lookup would be the worse answer.A report with no items at all skips the board re-read and parse entirely, so a clean board costs nothing new.
run_drcis called once per candidate inside the routing loop, which is where that would otherwise have been felt.Response shape
{"description":"Circle of J1 on Edge.Cuts","pos":{"x":136.19,"y":93.375}, "uuid":"7b970478-1e4a-48b6-b01a-35348027ca5e", "ownership_status":"resolved","item_kind":"fp_circle","layer":"Edge.Cuts", "owner":{"kind":"footprint","reference":"J1", "uuid":"b432574a-bdcd-4387-8d5e-65f34938c3a0"}}Board-owned items carry
"owner":{"kind":"board"}. Unresolved items carry"owner": nullbeside the status that says why.layercomes only from a single(layer …); pads spell(layers …)and are left unset rather than having one of three guessed for them.Fixture provenance
crates/konnect-core/tests/fixtures/drc_ownership_j1.{kicad_pcb,drc.json}is the board and raw report @ncolomer pasted inline in the comment on #413 — no file was attached; the bytes come from that comment'sj1-repro.kicad_pcbandraw_kicad_cli_drc.jsoncode blocks (KiCad 10.0.5, macOS). Both files are byte-identical to that source apart from the hand-written additions listed below, verified bydiff: additions only, plus one trailing blank line.The J1 footprint, its four
Edge.Cutscircles, its four pads and all fourcopper_edge_clearanceviolations are KiCad's own bytes — confirming KiCad does emit the nested graphic UUID, so nouuid_missingfallback is needed for this case.kicad-cliwas not available on the machine that assembled the fixture, so the board outline, the unrelated board graphic, and the two unresolved-path report items were written by hand, not generated by KiCad. The siblingdrc_ownership_j1.README.mdstates exactly which bytes are which, and the hand-written UUIDs use obviously synthetic prefixes (e0000000,50000000,ffffffff) so they cannot be mistaken for KiCad's.Acceptance coverage
Edge.Cutsoutlinegr_line e0000000-…-4owner.kind = boardEdge.Cutscircle nested in J1fp_circle 7b970478-…owner.kind = footprint, refJ1pad 5bc25fc3-…owner.kind = footprint, refJ1gr_line 50000000-…-1onF.SilkSowner.kind = boarduuid_missing,owner: nullffffffff-ffff-4fff-8fff-ffffffffffffnot_found,owner: null12 parser/unit tests in
konnect-core, 5 index tests inkonnect-sexp.Every one was shown failing before it went green, on source with the enrichment defeated. Two mutants, restored from a byte-copy and md5-verified afterwards, cover the two axes this issue is about:
board— the exact failure mode copper_edge_clearance DRC violations don't distinguish footprint-owned Edge.Cuts (e.g. mounting-peg cutouts) from the board's real outline #413 describes — killsan_item_without_a_uuid_stays_explicitly_unresolved,an_unknown_uuid_stays_explicitly_unresolved,the_response_shape_is_additive:a_footprint_owned_edge_cuts_circle_names_its_footprint,a_pad_names_the_footprint_that_carries_it,the_boards_own_outline_is_board_owned,an_unrelated_board_graphic_is_board_owned,ownership_never_comes_from_the_description,the_response_shape_is_additive.One honest gap:
an_unknown_uuid_has_no_entryinkonnect-sexpis a negative assertion about aHashMapmiss and no honest mutant reddens it. Its behavioural counterpart inkonnect-coredoes go red, under both mutants above.run_drc_enriches_items_from_the_board_it_ran_onrepeats the assertions against a livekicad-cli pcb drcrun. It follows the repo's live-KiCad convention (#[ignore = "needs a real kicad-cli on PATH"]) and, to be straightforward about it, was not executed — no KiCad on the machine that wrote this. Run it with:Verification
Windows live execution — run by the maintainer, not by me
The
--ignoredlive test needs a realkicad-cli, which the hosted checks do nothave. @neusse ran it on the exact head
bb18215ed029e588a8b87d836c91c10ea0f2fe1a,from a clean worktree detached at that commit:
All ten hosted checks were green on the same head. Recorded here because it is the
one piece of evidence for this PR that did not come from my own machine.
Docs
This adds a public response surface, so:
tool-directory.md(both tool rows and the shared-path note), a new## Unreleased: DRC item ownership (minor release)section indocs/API_MIGRATIONS.md, and the three bundled skills that mentionrun_drc(konnect,kicad-pcb,kicad-review) — the last two now tell an agent to readownerbefore advising a fix, and never to assume board ownership whenownership_statusis notresolved.asset_references'sbackticked_tool_names_in_prose_exist_in_the_registrycaught the three new field names in the skill prose; they are added toNOT_TOOLSas structured response vocabulary.doc_tool_countsis untouched — no tool was added or removed.Authored by Mycroft, the synthetic co-founder at Anton Dzyatkovsky's lab (autonomous mode; named responsible person: Anton Dziatkovskii). The test runs above were independently re-executed before submission.