lower-to-canonical.ts: clauseEquivalent now compares compoundOperator
and compoundGroupId. Previously, compound assertions with different
operators (.and vs .or) were considered equivalent.
fol-compiler.ts: adaptGrammarFormulaToLogicAst validates node.kind
against known formula kinds (forall/exists/and/or/not/implies/predicate)
before passing through as FormulaNode. Previously any object with a
'kind' property was blindly cast.
predicates.ts / registry.ts: @deprecated tags on globalPredicateRegistry
and globalClauseRegistry. Both are still functional but consumers should
transition to explicit injection via LogicEngineOptions / EvaluationOptions.
454 solver+DSL tests pass, zero regressions.
geometry-cache.ts: replace 5 empty catch blocks with console.warn
- statSync failure, rmSync failure (x2), readCachedWorld failure,
readCachedExtractionResult failure were all silently swallowed.
Now emit context-bearing warnings so stale/corrupt caches are visible.
predicates.ts: replace __boxIndex as any mutation with WeakMap
- getBorderRect used (world as any).__boxIndex to cache a subject-to-
box-index map on the world object. Replaced with module-level WeakMap
that auto-collects when the world is GC'd. Eliminates 2 as any casts.
extraction.ts: serialize materializeSemanticSelector + debug cleanup
- 3 Promise.all sites over page.evaluate changed to sequential for..of
to eliminate DOM modification race conditions.
- 2 .catch(()=>{}) cleanup blocks now use console.debug so failed
cleanup is traceable when debugging.
- resolveViewport catch now emits console.warn on zero-viewport fallback.
648 SDK + 57 E2E tests pass.
All 27 BUILTIN_PREDICATES now have real evaluators. The
makeNotImplementedPredicate factory and its IMH_FEATURE_NOT_YET_IMPLEMENTED
path were the last remaining NYI scaffolding — no caller existed for it.
IMH_FEATURE_NOT_YET_IMPLEMENTED diagnostic code kept in the taxonomy
as a future fallback, but no evaluator produces it.
- CRITICAL: escapeClippingChainOf now has an evaluator (returns indeterminate
with clear diagnostic — full implementation requires fragment-level bounds
analysis). Previously parsed but silently produced IMH_EVALUATOR_MISSING.
- attachedToScrollContainer added to BUILTIN_PREDICATES with evaluator
(checks world.topology.scrollContainerOf). Was only in legacy engine.
- aspectRatio added to BUILTIN_PREDICATES with evaluator (compares
width/height ratio against min/max bounds). Was only in legacy engine.
- Fix all BUILTIN_PREDICATES index references shifted by new entries
(beside 17→20, nextTo 18→21, adjacent 19→22, touching 20→23,
near 21→24, under 22→25, within 23→26, separatedFrom 16→18,
inStackingContext 15→17).
- Register attachedToScrollContainer, escapeClippingChainOf, aspectRatio
in registerDefaultPredicates.
- Zero NYI/not-implemented predicates remain in the registry.
- 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
- 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)