Custom rule to disallow certain vias in area not working

(Originally seen in KiCad 8, just upgraded to 9.0.2 to verify that the problem is still present.)

I’m working on a board that will be mounted flush against an aluminum extrusion - so my bottom layer is entirely a ground plane (no traces allowed), and I want to disallow any signal vias in the area that’s touching the aluminum, so that nothing gets shorted out if the via tenting gets scraped off. But ground vias are fine, the extrusion is grounded anyway. I tried to implement this via a custom design rule:

(rule NoNonGndVias
(condition “A.Type == ‘Via’ && A.intersectsArea(‘Extrusion’) && A.NetName != ‘/NEG’”)
(constraint disallow via)
)

But this disallows ALL non-ground vias, whether or not they’re in the rule area - it acts as if though intersectsArea() unconditionally returns true. (I’ve tried enclosedByArea(), it behaves the same). Here’s a visual example:
Screenshot 2025-05-20 103747
The rule area is shown highlighted. The bottom of the three visible vias is on the /NEG net, and is correctly allowed. The middle via is correctly flagged, I should have placed it one grid unit higher. But the top via, along with every other non-ground via on the board, is being flagged for no reason; it’s clearly outside the rule area. The Constraints Resolution command seems to be the proper tool for debugging this - but it is claiming that there’s no violation:

Keepout resolution for:
Via [/C2P] on F.Cu - B.Cu [netclass Default]

Checking rule ‘NoNonGndVias’.
Checking rule condition “A.Type == ‘Via’ && A.intersectsArea(‘Extrusion’) && A.NetName != ‘/NEG’”.
Condition not satisfied; rule ignored.

Item allowed at current location.

The DRC message is “Items not allowed (rule ‘NoNonGndVias’)”, so where is this failure coming from?

Can you share a minimal reproducable example project?

I tried creating a minimal example - and of course it works just fine. Turns out that the problem was that my ground plane zone somehow also got named “Extrusion”, I blanked out its name and now I’m getting DRC flags exactly where they should be.

It still seems like something is wrong here - should intersectsArea() return true for a via and a zone on different nets? The documentation says that this function considers only the actual copper area of a zone, not merely its bounds, and the copper should be punched out around the via. Also, why was Constraint Resolution saying “condition not satisfied”, when it actually was satisfied?

I wondered if another zone had the same name…

On the intersects things - it sounds like it’s checking if the enclosing boundary of the copper fill before punch-ours is being tested (which is what you wanted?). We could clarify this in docs perhaps.

On the constraint resolution message question, without a test case I don’t think anybody could comment on the correctness. It may be that this is a message from the accepted via - but we can’t see the via net names so it would just be a guess without an example project.

Ok, here’s an extremely minimal project exhibiting both issues.
CDR bug report.zip (9.6 KB)