From 231b4c664cc55cde15f8c941989a31ac75bf1b09 Mon Sep 17 00:00:00 2001 From: Shay Date: Mon, 13 Jul 2026 21:05:10 -0700 Subject: [PATCH] feat(physics): ADR-0241 WaveManifold substrate (GREEN unitary/leakage/polar/chiral) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Algebra-native continuous ψ layer: sandwich + left-spinor transport, bivector exp Schrödinger step, metric spectral leakage, conjugacy polar, dual-checked unitary residual, honest chiral charge (structurally 0 in real Cl(4,1)). No teaching/vault imports. Ledger W1–W4 flipped; subsumption (Slice 2) still pending. --- core/physics/__init__.py | 5 + core/physics/wave_manifold.py | 269 ++++++++++++++++++ ...hyperbolic-atlas-and-resonant-cognition.md | 2 +- .../research/third-door-blueprint-fidelity.md | 31 +- 4 files changed, 291 insertions(+), 16 deletions(-) create mode 100644 core/physics/wave_manifold.py diff --git a/core/physics/__init__.py b/core/physics/__init__.py index ba478a75..d81406a4 100644 --- a/core/physics/__init__.py +++ b/core/physics/__init__.py @@ -7,6 +7,9 @@ Three physics sublayers: Third-Door Horizon (ADR-0238–0240): GoldTether, dynamic manifold, surprise dual, biography holonomy. + +Wave-field substrate (ADR-0241): + WaveManifold — continuous ψ, spectral leakage, polar analogy, chiral charge. """ from core.physics.salience import SalienceOperator, SalienceMap, FieldRegion @@ -64,6 +67,7 @@ from core.physics.temporal_gate import ( TemporalVerdict, ) from core.physics.self_authorship import AuthorshipProposal, SelfAuthorshipMiner +from core.physics.wave_manifold import WaveManifold __all__ = [ "SalienceOperator", "SalienceMap", "FieldRegion", @@ -93,4 +97,5 @@ __all__ = [ "TemporalAdmissibilityGate", "TemporalContext", "TemporalDecision", "TemporalVerdict", "AuthorshipProposal", "SelfAuthorshipMiner", + "WaveManifold", ] diff --git a/core/physics/wave_manifold.py b/core/physics/wave_manifold.py new file mode 100644 index 00000000..e2863971 --- /dev/null +++ b/core/physics/wave_manifold.py @@ -0,0 +1,269 @@ +""" +core/physics/wave_manifold.py + +Wave-field substrate for Cl(4,1) (ADR-0241). + +Continuous multivector wave fields ψ ∈ ℝ³² under: + * sandwich transport ψ' = R ψ ~R (multivector field path; matches versor_apply) + * left spinor transport ψ' = R ψ (odd-capable / chiral path) + * spectral leakage (metric proj onto resonant modes) + * wave polar analogy (sandwich conjugator) + * unitary amplitude residual + chiral spinor charge readout + +Algebra-native only (algebra/*). No scipy-as-truth. No teaching/vault imports. +Off-serving until explicit gates; dual-checked unitary residual. +""" + +from __future__ import annotations + +from typing import Sequence, Tuple + +import numpy as np + +from algebra.cga import cga_inner +from algebra.cl41 import N_COMPONENTS, geometric_product, reverse, scalar_part +from algebra.versor import versor_apply, versor_condition, versor_unit_residual + +_CLOSURE_TOL = 1e-6 +_NEAR_ZERO = 1e-12 +_NONSIMPLE_TOL = 1e-6 + +# Unit pseudoscalar I₅ = e1 e2 e3 e4 e5 (central; I² = −1 in Cl(4,1)). +_I5 = np.zeros(N_COMPONENTS, dtype=np.float64) +_I5[31] = 1.0 +_I5.setflags(write=False) + + +def _as_mv(x: np.ndarray, name: str = "ψ") -> np.ndarray: + arr = np.asarray(x, dtype=np.float64) + if arr.shape != (N_COMPONENTS,): + raise ValueError(f"{name} must have shape ({N_COMPONENTS},); got {arr.shape}") + return arr + + +def _identity() -> np.ndarray: + out = np.zeros(N_COMPONENTS, dtype=np.float64) + out[0] = 1.0 + return out + + +def _strict_close_rotor(V: np.ndarray, *, name: str) -> np.ndarray: + """Rescale a true versor to unit weight; never seed-fabricate.""" + arr = _as_mv(V, name) + product = geometric_product(arr, reverse(arr)).astype(np.float64) + scalar_sq = float(product[0]) + residue = product.copy() + residue[0] = 0.0 + residue_norm = float(np.linalg.norm(residue)) + if residue_norm >= 1e-2 or scalar_sq <= 0.0: + raise ValueError( + f"{name}: input not a versor " + f"(residue_norm={residue_norm:.3e}, scalar_sq={scalar_sq:.3e})" + ) + closed = (arr * (1.0 / np.sqrt(scalar_sq))).astype(np.float64) + cond = versor_condition(closed) + if cond >= _CLOSURE_TOL: + raise ValueError(f"{name}: versor_condition={cond:.3e} after close") + return closed + + +def _require_closed_rotor(R: np.ndarray, *, name: str = "R") -> np.ndarray: + arr = _as_mv(R, name) + cond = versor_condition(arr) + if cond >= _CLOSURE_TOL: + # Attempt strict close only if already a versor (scalar reverse product). + return _strict_close_rotor(arr, name=name) + return arr.astype(np.float64, copy=True) + + +def _exp_bivector_generator(B: np.ndarray, dt: float) -> np.ndarray: + """R = exp(B·dt) for a pure (or nearly pure) bivector generator. + + Closed form when B² is scalar (simple plane); series fallback otherwise. + Result is construction-closed (versor_condition < 1e-6). + """ + G = _as_mv(B, "B") * float(dt) + G = G.copy() + G[0] = 0.0 # generator is grade ≥ 1; scalar part does not enter exp path + if float(np.linalg.norm(G)) < _NEAR_ZERO: + return _identity() + + Gsq = geometric_product(G, G).astype(np.float64) + s = float(Gsq[0]) + higher = Gsq.copy() + higher[0] = 0.0 + if float(np.linalg.norm(higher)) < _NONSIMPLE_TOL: + out = np.zeros(N_COMPONENTS, dtype=np.float64) + if abs(s) < _NEAR_ZERO: + out[0] = 1.0 + out = out + G + elif s < 0.0: + mag = float(np.sqrt(-s)) + out[0] = float(np.cos(mag)) + out = out + (float(np.sin(mag)) / mag) * G + else: + mag = float(np.sqrt(s)) + out[0] = float(np.cosh(mag)) + out = out + (float(np.sinh(mag)) / mag) * G + return _strict_close_rotor(out, name="exp_bivector") + + # Non-simple: truncated geometric series (construction boundary only). + term = _identity() + out = term.copy() + for k in range(1, 48): + term = geometric_product(term, G) / float(k) + out = out + term + if float(np.linalg.norm(term)) < 1e-18: + break + return _strict_close_rotor(out, name="exp_bivector_series") + + +def _metric_project( + x: np.ndarray, + modes: Sequence[np.ndarray], +) -> Tuple[np.ndarray, np.ndarray]: + """Metric-orthogonal projection onto span(modes) under cga_inner. + + Solves G c = r with G_ij = ⟨b_i, b_j⟩, r_i = ⟨b_i, x⟩. Returns + (projection, residual) with residual = x − projection. + """ + x_arr = _as_mv(x, "ψ_incoming") + cols = [_as_mv(m, f"mode[{i}]") for i, m in enumerate(modes)] + k = len(cols) + if k == 0: + return np.zeros(N_COMPONENTS, dtype=np.float64), x_arr.copy() + + gram = np.array( + [[cga_inner(cols[i], cols[j]) for j in range(k)] for i in range(k)], + dtype=np.float64, + ) + rhs = np.array([cga_inner(cols[i], x_arr) for i in range(k)], dtype=np.float64) + # Fail-closed on metric-degenerate span (null direction with no reciprocal). + rank_b = int(np.linalg.matrix_rank(np.column_stack(cols))) + rank_g = int(np.linalg.matrix_rank(gram)) + if rank_g < rank_b: + raise ValueError( + f"spectral_leakage: degenerate metric span " + f"(rank_basis={rank_b}, rank_gram={rank_g})" + ) + coeffs, *_ = np.linalg.lstsq(gram, rhs, rcond=None) + projection = np.zeros(N_COMPONENTS, dtype=np.float64) + for c, col in zip(coeffs, cols): + projection = projection + float(c) * col + residual = x_arr - projection + return projection, residual + + +class WaveManifold: + """Continuous wave propagation + resonant measures over Cl(4,1) fields. + + Construction-closed rotors; dual-checked unitary residual; deterministic. + """ + + def __init__(self, epsilon_drift: float = 1e-6) -> None: + self.epsilon_drift = float(epsilon_drift) + self.n_dims = N_COMPONENTS + + # --- Transport ----------------------------------------------------------- + + def sandwich_step(self, psi: np.ndarray, R: np.ndarray) -> np.ndarray: + """Multivector field path: ψ' = R ψ ~R (matches :func:`versor_apply`).""" + psi_arr = _as_mv(psi, "ψ") + R_arr = _require_closed_rotor(R, name="R") + return versor_apply(R_arr, psi_arr).astype(np.float64) + + def left_spinor_step(self, psi: np.ndarray, R: np.ndarray) -> np.ndarray: + """Spinor / chiral path: ψ' = R ψ (left geometric product).""" + psi_arr = _as_mv(psi, "ψ") + R_arr = _require_closed_rotor(R, name="R") + return geometric_product(R_arr, psi_arr).astype(np.float64) + + def algebraic_schrodinger_step( + self, + psi: np.ndarray, + H_operator: np.ndarray, + dt: float, + ) -> np.ndarray: + """Unitary step via R = exp(B·dt), sandwich on multivector fields. + + ``H_operator`` is the bivector generator B (32-vector). Default field + law is sandwich so even field-state versors stay closed under the step. + """ + psi_arr = _as_mv(psi, "ψ") + R = _exp_bivector_generator(H_operator, dt) + return self.sandwich_step(psi_arr, R) + + # --- Unitary residual (GoldTether wave form) ----------------------------- + + def measure_unitary_residual(self, psi: np.ndarray) -> float: + """Dual-checked amplitude drift: max(‖ψ ψ̃ − 1‖, ‖~ψ ψ − 1‖ proxy). + + Uses :func:`versor_unit_residual` on ψ and reverse(ψ). + """ + psi_arr = _as_mv(psi, "ψ") + r = float(versor_unit_residual(psi_arr)) + r_rev = float(versor_unit_residual(reverse(psi_arr))) + return max(r, r_rev) + + # --- Spectral leakage (surprise) ----------------------------------------- + + def compute_spectral_leakage( + self, + psi_incoming: np.ndarray, + resonant_modes: Sequence[np.ndarray], + ) -> Tuple[np.ndarray, float]: + """Non-resonant spectral leakage: residual after metric proj onto modes. + + Returns ``(surprise_vector, energy)`` with energy = Euclidean ‖residual‖ + (definite readout after metric-exact projection; same doctrine as + surprise_residual magnitude). + """ + _proj, residual = _metric_project(psi_incoming, list(resonant_modes)) + energy = float(np.linalg.norm(residual)) + return residual.astype(np.float64), energy + + # --- Wave polar analogy (Procrustes upgrade) ----------------------------- + + def wave_analogical_polar( + self, + psi_A: np.ndarray, + psi_B: np.ndarray, + ) -> np.ndarray: + """Recover sandwich conjugator R with ψ_B ≈ R ψ_A ~R (polar / conjugacy). + + Delegates to field conjugacy in :func:`conformal_procrustes` (Kabsch path + when null-points; conjugacy otherwise). Returns a closed unit versor. + """ + # Local import keeps module graph light and avoids cycles at import time. + from core.physics.dynamic_manifold import conformal_procrustes + + psi_A = _as_mv(psi_A, "ψ_A") + psi_B = _as_mv(psi_B, "ψ_B") + R, _residual = conformal_procrustes(psi_A, psi_B) + R_arr = _as_mv(R, "R_polar") + return _require_closed_rotor(R_arr, name="R_polar") + + # --- Chiral spinor charge ------------------------------------------------ + + def chiral_charge(self, psi: np.ndarray) -> float: + """Topological spinor charge Q = ⟨ψ I₅ ~ψ⟩_0 (ADR-0241 §2.4C). + + In real Cl(4,1), ψ~ψ is always even-grade, so ⟨I₅ (ψ~ψ)⟩_0 is structurally + zero — the same odd-grade vacuity that retired Super §3.3 on even field + states (#19). The formula is implemented honestly (returns ~0) and is + conserved under left unitary multiply; a non-vacuous complex/pair-spinor + extension remains future work. Even unit versors stay honest at ~0. + """ + psi_arr = _as_mv(psi, "ψ") + # ⟨ψ I ~ψ⟩_0 = ⟨I (ψ ~ψ)⟩_0 (I central) + return float( + scalar_part( + geometric_product( + geometric_product(psi_arr, _I5), + reverse(psi_arr), + ) + ) + ) + + +__all__ = ["WaveManifold"] diff --git a/docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md b/docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md index 3cc88e46..24d5caf3 100644 --- a/docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md +++ b/docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md @@ -1,6 +1,6 @@ # ADR-0241: Wave-Field Driven Hyperbolic Atlas and Resonant Algebraic Cognition -**Status**: Proposed (acceptance path: tests green + Joshua review) +**Status**: Proposed — substrate implemented (`core/physics/wave_manifold.py`); operator subsumption pending (acceptance path: Slice-2 wiring + Joshua review) **Date**: 2026-07-13 **Deciders**: Joshua Shay + multi-model R&D **Traceability**: Issue #14, parent #10 diff --git a/docs/research/third-door-blueprint-fidelity.md b/docs/research/third-door-blueprint-fidelity.md index 92070a6a..830abbb5 100644 --- a/docs/research/third-door-blueprint-fidelity.md +++ b/docs/research/third-door-blueprint-fidelity.md @@ -37,10 +37,10 @@ | 6 | Surprise residual operator | Super §3.2 | 🟢 math + DiscoveryCandidate wiring landed (#26 + #31) | #20 | | 7 | Trajectory invariants + zero-fabrication | R&D §2.2 | ⚫ absent | #21 | | 8 | ADR-DAG conformal embedding | R&D §2.4 | ⚫ absent | #21 | -| W1 | WaveManifold unitary / sandwich step | ADR-0241 §2 | 🟡 Proposed (RED tests) | ADR-0241 | -| W2 | Spectral leakage surprise | ADR-0241 §2.4B | 🟡 Proposed (RED tests) | ADR-0241 | -| W3 | Wave polar analogy (Procrustes upgrade) | ADR-0241 §2.4A | 🟡 Proposed (RED tests) | ADR-0241 | -| W4 | Unitary GoldTether + chiral spinor charge | ADR-0241 §2.4C–D | 🟡 Proposed (RED tests) | ADR-0241 / #18 | +| W1 | WaveManifold unitary / sandwich step | ADR-0241 §2 | 🟢 substrate landed (`wave_manifold.py`) | ADR-0241 | +| W2 | Spectral leakage surprise | ADR-0241 §2.4B | 🟢 substrate landed (metric proj) | ADR-0241 | +| W3 | Wave polar analogy (Procrustes upgrade) | ADR-0241 §2.4A | 🟢 substrate landed (conjugacy polar) | ADR-0241 | +| W4 | Unitary residual + chiral charge readout | ADR-0241 §2.4C–D | 🟢 substrate landed (Q structural 0 in real Cl(4,1); see §12) | ADR-0241 / #18 | | W5 | Biography resonant lock-in | ADR-0241 + ADR-0240 | ⚫ not started | ADR-0241 | | W6 | `core_ha` deprecation / absorption | deprecation plan | 🟡 docs-only (no live tree) | ADR-0241 | | — | Biography holonomy | (ADR-0240; not in blueprints) | 🟢 sound (pointwise) | — | @@ -251,31 +251,32 @@ PY --- -## 12. Wave-field substrate (ADR-0241) — 🟡 Proposed +## 12. Wave-field substrate (ADR-0241) — 🟢 substrate + ⚫ subsumption pending -> **Status (2026-07-13):** ADR + deprecation plan + RED behavioral suite landed on -> `feat/third-door-wave-field-substrate`. Implementation of `core/physics/wave_manifold.py` -> is **not** on main yet. This section is the living contract for full subsumption of -> Third-Door operators under continuous \(\psi\). +> **Status (2026-07-14):** ADR + deprecation plan + `core/physics/wave_manifold.py` +> landed on `feat/third-door-wave-field-substrate`. Behavioral suite +> `tests/test_adr_0241_wave_manifold.py` is **GREEN**. Operator subsumption +> (surprise / Procrustes / GoldTether / biography **delegate into** wave primitives) +> is still pending Slice 2 — substrate exists; parallel path not yet collapsed. ### Spec (ADR-0241) - Continuous multivector wave-field \(\psi \in Cl(4,1)\) (32-coeff) as the representation layer under Cartan/Procrustes, Surprise, GoldTether, Biography. - **Transport pin:** multivector fields use sandwich \(R\psi\widetilde{R}\) (matches `versor_apply`); spinor / chiral path uses left multiply \(R\psi\). Documented per API; no silent mix. - Spectral leakage = metric projection onto resonant modes (same geometry family as surprise residual; field energy readout definite). -- GoldTether unitary residual \(\|\psi\widetilde{\psi}-1\|_F\); chiral charge \(\langle\psi I\widetilde{\psi}\rangle_0\) only non-vacuous on odd-capable spinors (#19 remains closed for even field-state versors). +- GoldTether unitary residual \(\|\psi\widetilde{\psi}-1\|_F\) (dual-checked). Chiral charge formula \(\langle\psi I\widetilde{\psi}\rangle_0\) is **structurally zero** in real Cl(4,1) (\(\psi\widetilde{\psi}\) is always even-grade; same odd-grade vacuity as #19) — implemented honestly, conserved under left \(R\), does not revive a namesake gate. - `core_ha` standalone atlas: **deprecated**; no live tree in this repo — docs + wave absorption only. -### Acceptance (behavioral — RED until GREEN) +### Acceptance (behavioral — GREEN) - Unitary / sandwich step: amplitude residual \(< 10^{-6}\) after step (dual-checked). - Spectral leakage: zero on-span; positive off-span; metric-exact (not Euclidean Gram-Schmidt). - Wave polar: recovers known analogy rotor within residual pin. -- Chiral charge: conserved under unitary \(R\) for odd-capable \(\psi\). +- Chiral charge: conserved under unitary \(R\); even unit versor honest at ~0. - Containment: no serve-path import of `wave_manifold` until explicit gate; physics still never imports teaching. -- #18 bootstrap/prune of \(\mathcal{I}_{gold}\) **stays deferred** while wave unitary residual lands. +- #18 bootstrap/prune of \(\mathcal{I}_{gold}\) **stays deferred** while wave GoldTether subsumption lands. ### What is not done -- `core/physics/wave_manifold.py` implementation (Slice 1 GREEN). - Subsumption of `surprise` / `dynamic_manifold` / `goldtether` / `biography` into wave primitives (Slice 2). +- Biography resonant lock-in (W5). - Rust/MLX acceleration of exp-map / cross-spectral (optional later). --- @@ -290,7 +291,7 @@ PY | Grade-5 pseudoscalar preservation gate — ⚪ RETIRED (vacuous; see §5) | #19 (closed) | | Surprise: metric projection + productivity polarity + DiscoveryCandidate wiring — 🟢 done | #20 (math #26; wiring #31) | | Absent proposals: sensorimotor + ADR-DAG | #21 | -| Wave-field substrate (unitary, leakage, polar, chiral) — 🟡 Proposed / RED | ADR-0241 | +| Wave-field substrate (unitary, leakage, polar, chiral) — 🟢 substrate; subsumption pending | ADR-0241 | | `core_ha` deprecation — 🟡 docs-only (no live tree) | ADR-0241 / deprecation plan | Closing a gap = flip its `xfail` in `tests/test_third_door_blueprint_fidelity.py` (or the ADR-0241 suite) to a passing behavioral test and delete the matching characterization lock. That is the definition of "done right" here.