John Dvorak
6a98d8ce9e
refactor: compiler pipeline hardening — parser diagnostics + exhaustive switches + golden equivalence
...
grammar.ts:
- Replace 2 parseAssertion console.warn + return-null patterns with
this.errorWithCode() throws, producing structured ParseError
diagnostics instead of silently skipping invalid clauses
- Maintain parseBlock's return-null contract for unmatched tokens
(caller loops over tokens expecting null for non-block starters)
compiler.ts:
- buildOptionsFromAssertion: convert 3 standalone ifs to if/else if/else
with never-exhausted throw on unknown assertion type
- compileToFormula: replace silent return-null with throw on unknown
assertion type
validator.ts:
- validateAssertion: replace silent return {valid:true} for unknown
assertion types with throw
fol-compiler.ts:
- compileSingleAssertion: replace silent return-null with throw
Golden equivalence tests (fol-equivalence-golden.test.ts):
7 new deterministic tests covering gaps identified in REFACTOR item 5:
- Size assertions: atLeast, atMost, between (fluent vs dense)
- Compound assertions: .and chain, .or chain
- Options: gap, tolerance in jnd
Documents known discrepancy: fluent size.* prefix vs dense canonical name
(fol-compiler normalizes at FormulaNode level, canonical path does not)
Existing property-based equivalence tests cover spatial, quantifier,
and frame equivalence. Topology predicates have no fluent API surface
(dense-DSL-only), so equivalence must be verified at evaluation level
(already covered by hard E2E topology tests).
662 tests pass (315 DSL + 141 core + 149 solver + 57 E2E).
2026-05-22 15:23:29 -07:00
John Dvorak
1bc0c8e6df
refactor: replace smuggled compound properties with typed FluentRelation API
...
fluent.ts: Add public getters isCompound, compoundOperator, compoundParts
to FluentRelation. Add optional CompoundState to constructor. Add
CompoundPart/CompoundState interfaces. Replace 4 (this as any)._xxx
property smuggles in FluentCompoundBuilder._addPart() with properly
typed constructor initialization via CompoundState.
fol-compiler.ts: Replace 3 (relation as any)._compoundParts /
._compoundOperator / ._isCompound duck-type reads with direct
relation.compoundParts / relation.compoundOperator / relation.isCompound.
extraction.ts: Replace (rel as any)._compoundParts read in
getSelectorsFromAssertion with typed compoundRel.isCompound /
compoundRel.compoundParts access.
Eliminates 7 (as any) casts across 3 production files. Zero remaining
_compoundParts/_compoundOperator/_isCompound/_originalFirstRelation
smuggled references in any production source file.
598 SDK + 3 conformance + 57 E2E = 658 tests pass.
2026-05-22 13:31:34 -07:00
John Dvorak
9b691b2c7c
fix: close out remaining audit findings — type safety, equivalence, deprecations
...
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.
2026-05-22 12:05:43 -07:00