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.
3.5 KiB
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
- 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. - 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."
- 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-comprehensionon 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
narrativelane 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.