Measured on run 19 (urchin, piled, see the run record in discussion #118): SW17 at (128.399, 61.001) rot 330 had pad copper spanning x 127.095–129.645 against an interior milled slot at x 127.127–129.667 — the pad sits inside the ring — and every placement gate graded it clean: copper-free check_drc 0 at the 0.2 floor, check_assembly buildable / blocking 0, channels 0 deficit. The parser already KNOWS about the contour (staging prints "reclassified 1 Edge.Cuts contour(s)... Kept as a milled edge for clearance") but placement/legality.py never consumes the classification, and check_reachability answered PASSABLE for the stranded pad because it does not model contour/edge clearance either. The defect was found only by the router: a single-net route probe failed at 219k iterations with zero copper competition, which cost a full routing cycle to discover what a placement gate could have said in milliseconds.
Suggested fix: thread the parse-time reclassification into rect_blocked / pad legality as keepouts, and into reachability's geometry. A sibling defect measured in the same run: a contour FULLY swallowed by a candidate rect is invisible to the outline gate (rect_outside_amount only sees edges crossing the rect boundary).
Full evidence: LEARNINGS.md finding 1 on the run19-assets branch (https://github.com/edgehero/KiCadRoutingTools/blob/run19-assets/LEARNINGS.md).
Measured on run 19 (urchin, piled, see the run record in discussion #118): SW17 at (128.399, 61.001) rot 330 had pad copper spanning x 127.095–129.645 against an interior milled slot at x 127.127–129.667 — the pad sits inside the ring — and every placement gate graded it clean: copper-free
check_drc0 at the 0.2 floor,check_assemblybuildable / blocking 0, channels 0 deficit. The parser already KNOWS about the contour (staging prints "reclassified 1 Edge.Cuts contour(s)... Kept as a milled edge for clearance") butplacement/legality.pynever consumes the classification, andcheck_reachabilityanswered PASSABLE for the stranded pad because it does not model contour/edge clearance either. The defect was found only by the router: a single-net route probe failed at 219k iterations with zero copper competition, which cost a full routing cycle to discover what a placement gate could have said in milliseconds.Suggested fix: thread the parse-time reclassification into
rect_blocked/ pad legality as keepouts, and into reachability's geometry. A sibling defect measured in the same run: a contour FULLY swallowed by a candidate rect is invisible to the outline gate (rect_outside_amountonly sees edges crossing the rect boundary).Full evidence: LEARNINGS.md finding 1 on the run19-assets branch (https://github.com/edgehero/KiCadRoutingTools/blob/run19-assets/LEARNINGS.md).