Adds the correct grade-raising "wire" the field substrate was missing — so cga_inner
can operate on RELATIONS among entities (lines/planes/incidence), not just pairwise
point distance. Built only from existing Cl(4,1) primitives (geometric_product,
grade_project) + the pseudoscalar; no normalization, no approximation, versor_condition
path untouched (flats are null-cone wedges, not unit versors).
- outer_product: DOCSTRING-ONLY honesty fix (behavior byte-identical, every caller
unchanged). It is the commutator 0.5*(XY-YX) = the wedge ONLY for grade-1 vectors;
for higher grades it is the Lie bracket, NOT the wedge, and does NOT build a k-blade
by repetition. Existing callers consume it as an opaque cga_inner-reduced feature
(none read it by grade), so the relabel is safe. Points to graded_wedge for the real
exterior product.
- graded_wedge(X,Y) = <XY>_{grade(X)+grade(Y)} — the true wedge; agrees with
outer_product on grade-1, differs above (pinned by test). Builds lines/planes.
- is_incident(point, flat): EXACT zero-test (point^flat == 0, no float tolerance to
admit — near-incident is refused, per wrong=0). Exact at scale in f64.
- dual(X) = X*I5^{-1} (I5^2=-1 confirmed); involutive up to sign.
- meet(A,B) = dual(dual(A)^dual(B)): correct for spanning operands (two planes -> their
line, incidence verified). HONEST ENVELOPE: degenerates for non-spanning operands
(coplanar lines) — returns the ZERO multivector (detectable, documented, tested),
never a silent wrong value. The general coplanar intersection needs the join-relative
meet, deliberately NOT faked here.
Green: smoke 87, algebra 82, incidence 8, outer_product consumers + invariants 109;
zero regressions (outer_product behavior unchanged).
Phase 0 of the field-reasoner wedge — net hardening regardless of the
experiment's outcome.
- algebra/cga.py: embed_point gains a dtype kwarg (f32 default byte-unchanged;
cl41.geometric_product already preserves f64) + read_scalar_e1 projective
dehomogenization read-back (weight-invariant; correct for dilations, where a
raw distance-from-origin is wrong) + EMBED_EXACT_MAX pinned magnitude ceiling.
f32 silently collapsed integer coordinates past ~1e4.
- core/reasoning/evidence.py: verify_tier2_agreement now keys independence on a
reader_lineage pathway token (refuses SAME_READER_LINEAGE), replacing the
label-only len(set(signatures))<2 check a single reader could satisfy by
relabeling. reader_lineage is excluded from canonical serialization, so the
entailment trace_hash is unchanged.
- tests INV-27: transitive reader-disjointness over TIER2_READER_PATHWAYS makes
the lineage check load-bearing (distinct lineage => proven import-disjoint
pathway). The two seeded readers share zero transitive first-party modules.
Green: smoke 87, algebra 82, cognition 121, 53 architectural invariants,
reasoning/deductive/r1 50; 16 new f64-exactness tests; zero regressions.