core/evals/cross_domain_transfer/gaps.md
Shay 694754ab46 feat(algebra): null-preserving versor_apply path + un-skip 2 invariant tests
Closes the two skipped null-preservation tests and the architectural
gap behind them.  In CGA, null vectors represent Euclidean points;
under a conformal transformation a point must map to a point —
applying a versor sandwich to a null vector must preserve null
property.  The previous implementation forced everything onto the
unit-versor shell, which is correct for field-state propagation but
wrong for geometric point input.

Implementation
- algebra/versor.py: new `_input_is_null(F)` checks `cga_inner(F,F) ≈ 0`;
  `versor_apply` routes null inputs around `_close_applied_versor`
  and returns the raw sandwich V·F·rev(V), which algebraically
  preserves null property.  Non-null inputs unchanged.
- core-rs/src/versor.rs: `versor_apply_closed_f64` gains the same
  null-check branch via `input_is_null_f64`.  ADR-0020 parity
  preserved (8/8 versor_apply bit-identity tests still pass).

Test changes
- tests/test_architectural_invariants.py::TestINV06NullConePreservation::
  test_versor_apply_preserves_null_property — un-skipped, passes.
- tests/test_rust_backend.py::test_rust_versor_apply_preserves_null_vectors
  — un-skipped, passes.
- tests/test_versor_closure.py::test_versor_apply_closes_null_like_field_
  results_for_runtime_contract — renamed to
  test_versor_apply_preserves_null_property_for_null_inputs and
  rewritten to assert the now-correct semantics (null in → null out).
  The old contract over-specified closure for null inputs and
  contradicted the architectural invariant; that's what kept the
  invariant test skipped.

Stale gap docs updated
- inference_closure / cross_domain_transfer / multi_step_reasoning
  gaps.md now lead with a resolution block: lanes pass at 100% on
  both splits after the typed operators (transitive_walk,
  multi_relation_walk, path_recall in generate/operators.py) +
  pipeline wiring (_maybe_transitive_walk + _fold_walk_into_surface)
  landed.  The historic findings are preserved below for traceability.
- compositionality gaps.md: partial resolution — recall up from
  6.25% to 68.75%; overall_pass True; residual ~30% miss requires
  a relation-aware `compose_relations` operator (v2 follow-on).

Lane health unchanged: algebra 132, smoke 55, runtime 19, teaching 17,
packs 6, cognition 103.  Cognition eval 100%.  Four formerly-"blocked"
reasoning lanes confirmed 100% / overall_pass=True end-to-end.
2026-05-16 21:40:37 -07:00

3.5 KiB
Raw Blame History

cross-domain-transfer lane — architectural findings (v1)

Resolution — 2026-05-17 lane re-run

transfer_endpoint_recall_rate = 1.0 on both splits after the typed operators + pipeline wiring landed. The same fix that closed inference_closure unblocks this lane: B-domain endpoints surface correctly after A-domain priming. overall_pass = True.

Historic finding preserved below.

Original v1 result (now superseded)

Split n transfer_endpoint_recall A_stored B_stored replay
public/v1 10 0.0 1.0 1.0 1.0
holdouts/v1 8 0.0 1.0 1.0 1.0

No transfer. Both A-domain and B-domain premises are independently stored (storage rate 1.0 on each side); replay is deterministic; the B-domain endpoint never appears in the probe surface.

What this confirms (vs. inference-closure)

This lane is inference-closure plus a prior teaching pass in a disjoint semantic subdomain. v1's result establishes that:

  • The A-domain teaching has no carry-over effect on B-domain competence. This is consistent with CORE having no structural- pattern recogniser — the A-domain chain doesn't shape how the B-domain chain is articulated or recalled.
  • Whatever fix closes inference-closure's Gap 1 / Gap 2 may close this lane's failure too, since B-domain alone is a literal inference-closure case. But it will not demonstrate transfer — that requires a different signal, captured in v2.

v2 contract refinement

To actually score transfer (rather than just "B-domain inference works after A-domain teaching"), v2 of this lane should include a matched control: same B-domain probe without prior A-domain teaching. Pass criterion becomes:

transfer_endpoint_recall_rate(with_A_teaching) > transfer_endpoint_recall_rate(without_A_teaching)

That delta is the genuine transfer signal. v1 leaves this on the table because the floor is currently zero on both arms — a v1 "transfer = 0 0 = 0" result would be uninformative. When the inference-closure engineering lands and the B-arm starts producing non-zero recall, v2's matched-control comparison becomes the load-bearing measurement.

Architectural gaps

  1. No structural-pattern recogniser. CORE's proposition graph has no concept of "the relation pattern R(x1,x2)→R(x2,x3) was seen N times across these subdomains" — patterns are not first-class entities.
  2. No cross-subdomain transfer operator. Vault retrieval and field propagation are entity-local; nothing maps "structural competence in subdomain A" to "expected competence in subdomain B."
  3. Both gaps are downstream of (and overlap with) inference-closure Gap 1 + Gap 2.

Future directions (recorded here so they're not forgotten)

  • Metaphor as cross-domain transfer with selectivity. A metaphor is the same shape as this lane's probe with an added filter: which relations transfer across the analogy and which do not. Once literal cross-domain transfer works, building metaphor-comprehension on top is a natural Phase 3 v2 lane rather than a separate operator.
  • Narrative as multi-step cross-domain transfer. A story is a multi-step inference chain bound to a point-of-view (agent / intention). Both substrates (multi-step chaining and POV) need to land before a narrative lane is meaningful.

Status

v1 stands as honest-failure baseline. v2 contract refinement (matched-control comparison) is the next authoring step once inference-closure engineering lifts B-arm recall off the floor.