OptionalcandidatesBroad-phase candidate pairs the geometry kernel actually narrow-phase
tested for THIS rule (RuleDetection.candidatesProcessed in
engine-ts/kernel.ts), surfaced here so a caller can tell "matched
elements on both sides AND compared some of them" apart from "matched
elements on both sides but the broad phase found nothing worth testing".
matchedA/matchedB alone cannot make that distinction — they are
selector-match counts taken before any geometry runs, so they read as
full coverage even when the broad phase (BVH margin query) ends up
empty (#4244).
0 here is NOT on its own evidence of a problem: two selected groups
that are genuinely far apart (further than the rule's tolerance/
clearance margin) legitimately produce zero candidate pairs and a real
'clean' result — that is the ordinary, correct outcome for a rule
whose matched elements never come close to touching. classifyRuleCoverage
does not treat this field as a coverage signal for exactly that reason;
it exists as a diagnostic a caller can inspect when a 'clean' result
looks suspicious for other reasons (e.g. a much larger selector match
count than expected), not as an automatic verdict. Absent on a result
recorded before this field existed, or from a hand-built fixture.
OptionalfromWhether each side was resolved from explicit membership (membersA /
membersB) rather than from its type selector. A caller explaining an
empty side needs it and cannot recover it from rulesRun, which
deliberately drops the resolved member lists. Absent on a result recorded
before this existed — which is the same thing as "by selector".
OptionalfromOptionalmatchedThe durable key (IfcGUID / USD prim path) of every element THIS rule
matched on each side, deduplicated and sorted for determinism — not just
a count. compareClashRevisions (revision.ts) needs this to ask "was
this SPECIFIC element re-examined?", which matchedA/matchedB (counts
only) cannot answer: a narrowed selector that drops one previously-
matched element while keeping the total count non-zero is invisible to a
count-only check. matchedKeysB mirrors matchedB's null for a
self-clash rule (no b side). Absent (not just empty) on a result
recorded before this existed, or from a hand-built fixture — callers
MUST treat an absent matchedKeysA as "cannot verify", never as "matched
nothing".
Optionalmatched
How many elements a rule's selectors actually matched in THIS model, before any geometry test ran.
matchedBisnullfor a self-clash rule (nobselector). A rule withmatchedA === 0ormatchedB === 0never compared a single pair — its selector simply doesn't describe anything in this model (e.g. an MEP selector run against an infrastructure model).