- evaluateAnd: carry left metrics on left-fail short-circuit,
carry right metrics on right fail/indeterminate
- evaluateOr: carry left metrics on left-pass short-circuit,
carry right metrics on right pass, merge both on double-fail
- evaluateNot: carry operand metrics when operand passes
(so not fails with diagnostic context), carry on indeterminate
- evaluateImplies: carry consequent metrics on fail/indeterminate
This ensures compound formula failures preserve measured geometry
context (gap, dimensions, direction) rather than presenting empty
diagnostics to users investigating layout contract violations.
- Change BUILTIN_PREDICATES[15] arity from 1 to 2 to match binary usage
in the FOL compiler and topology engine
- Update evaluator to handle both unary (does element have stacking context)
and binary (do both elements share the same stacking context) cases
- Binary comparison: both elements must have a valid stacking context
AND their stackingContextOf values must match
- Aligns predicate semantics with the legacy engine in solver/topology.ts
and the topology query layer's inStackingContext(graph, subj, ref?) API
- Extend DomainResolver.resolve() signature to accept optional BindingEnv
so that parentVar domains can be resolved with runtime variable bindings
- Pass BindingEnv through evaluateForAll/evaluateExists to resolver calls
- Add buildAncestorIndex() to precompute DOM ancestor sets from CDP data
- SelectorDomainResolver now filters descendant domains by the bound parent
when domain.parentVar is present and ancestor index is available
- Return undefined for parentVar domains when no ancestor index or env
(prevents silent fallback to global domain resolution)
- Update all test DomainResolver mocks for new resolve interface
- Add 10 unit tests covering ancestor index construction, backward compat,
descendant filtering, exclusion of non-descendants, empty descendants,
missing parentVar/env, and no-ancestor-index safety
- Add 4 unit tests in predicates.test.ts for new contain metrics:
inside hasClippedOverflow (with/without clipping)
clippedBy clipKind (contain:paint=1, overflow=2)
- Unskip and implement clippedBy e2e test with overflow:hidden container
in e2e-edge.test.ts (was stale skipped with 'not yet implemented')
- Replace makeNotImplementedPredicate stubs for leftAlignedWith,
rightAlignedWith, topAlignedWith, bottomAlignedWith with real
evaluators delegating to alignedWithPredicate with axis option
- Update logic-engine.test.ts to expect real evaluation results
instead of IMH_FEATURE_NOT_YET_IMPLEMENTED
- insidePredicate: add hasClippedOverflow=1 when reference element
clips its content (contain:paint or overflow:hidden) and the
subject overflows beyond the reference bounds
- containsPredicate: same, checking the subject (container) clips
- Reads world.clipping table to determine if the container clips
- Safe when clipping data is absent (unit test fixtures)