Both guards that gate a via append — would_overlap_existing_via and
via_in_pad_conflict's drill loop — iterate pcb_data.vias only, and
vias_to_add is appended to but never read back, so two vias placed in ONE
call are never clearance-checked against each other
(py_router/bga_fanout/__init__.py, manage_vias, ~line 607). Same shape as
the QFN underpad escape bug; the QFN fix (run_output_conflict, testing
candidates against the run's own output) is reusable and would be this code's
second caller. Structurally verified by reading; impact deliberately stated as
UNMEASURED — clamp_via_to_pad shrinks first and may legalize the pair on
real pitches. The honest fix wants a measured fine-pitch-BGA reproduction
first, and the reuse refactor spans both fanout engines.
Both guards that gate a via append —
would_overlap_existing_viaandvia_in_pad_conflict's drill loop — iteratepcb_data.viasonly, andvias_to_addis appended to but never read back, so two vias placed in ONEcall are never clearance-checked against each other
(
py_router/bga_fanout/__init__.py,manage_vias, ~line 607). Same shape asthe QFN underpad escape bug; the QFN fix (
run_output_conflict, testingcandidates against the run's own output) is reusable and would be this code's
second caller. Structurally verified by reading; impact deliberately stated as
UNMEASURED —
clamp_via_to_padshrinks first and may legalize the pair onreal pitches. The honest fix wants a measured fine-pitch-BGA reproduction
first, and the reuse refactor spans both fanout engines.