"""ADR-0243 §2 — Wave-Field Cognitive Lifecycle (Tier-2, OFF-SERVING). Ingress → Hamiltonian-well relaxation → egress, on the Cl(4,1) coefficient space. Implements the ADR-0243 lifecycle honestly, with the §3 reference prototype's defects corrected (they are pinned in ``tests/test_adr_0243_sketch_defect_pins.py``; deviations D-1…D-5 are recorded in ``docs/plans/adr-0243-implementation-plan.md`` §4): * **Ingress** delegates to :mod:`core.physics.sensorium_wave_feed` (superposition) and normalizes ONCE at this module's owned construction boundary (deviation D-3; master-plan doctrine note — no hot-path repair). * **Relaxation** is the dissipative imaginary-time semigroup ``ψ ← normalize(exp(−(H−λ0)·dt)·ψ)`` — deterministic power iteration that provably converges to the ground eigenspace at a rate set by the spectral gap (deviation D-1). The sketch's ``exp(H·I·t)`` loop oscillates and cannot relax (pin SD-B). Convergence is certified, never assumed (deviation D-2): the certificate carries the exact ground energy from the spectrum, the achieved Rayleigh energy, the eigen-residual, the gap (certification requires the gap be resolvable at the requested tolerance), and a byte digest of the certified state binding the evidence to that exact ψ. * **Egress** composes the existing organs — unit amplitude density, the certificate↔state binding check (a borrowed certificate refuses), :meth:`WaveManifold.measure_unitary_residual` (the ADR's R_GoldTether; reported, and REQUIRED only on the crystallization route where states must be closed versors), ADR-0006 energy classes via :func:`core.physics.wave_energy_boundary.energy_profile_from_wave`, and the E0/E1 crystallization policy via :func:`~core.physics.wave_energy_boundary.crystallization_for_holographic_seal`. Gating a multi-mode superposition on versor closure would reject every legitimate interference state (the dual of pin SD-A), so versor closure routes rather than admits. * **No mutation**: cold states emit a :class:`CrystallizationProposal` (``epistemic_status="SPECULATIVE"`` enforced by the type) — never a vault write (deviation D-5 / cohesion I-03). This module imports no vault store. Problem domains (v1, plan §5 Phase 2 — two checkable domains only): * ``quadratic_well`` — H = curvature·(Id − ψ₀ψ₀ᵀ): ground space is span(ψ₀); relaxation decodes the target from any non-orthogonal start. * ``propositional`` — the Cl(4,1) blade lattice IS the assignment lattice of ≤ 5 atoms: blade {e_{i₁}…e_{i_k}} ↔ assignment with exactly those atoms True. Clauses compile to a DIAGONAL penalty Hamiltonian counting falsified clauses per assignment; the ground space is the span of satisfying assignments and relaxation decodes the model set. Verdicts (SAT / entailment) read the exact ground energy of the same H — integer counts scaled by ``penalty``, no floating eigensolve on the diagonal path. Honesty note (D-2): the propositional compiler enumerates the ≤ 32 assignment components — this is exact small-domain decoding, not a scalability claim. Its value is falsifiability: verdicts are scored against independent gold (truth tables here; ``generate.proof_chain`` ROBDD in the Phase 4 eval). Serve quarantine (A-04): never imported by ``chat/runtime.py``; exported lazily via the ``core.physics`` barrel; enforced by ``tests/test_serve_quarantine_transitive.py`` and the cohesion suite. """ from __future__ import annotations import functools import hashlib import json from dataclasses import dataclass, field from typing import TYPE_CHECKING, Any, Mapping, Sequence if TYPE_CHECKING: # annotation-only: the monitor instance is caller-supplied from core.physics.goldtether import GoldTetherMonitor import numpy as np from algebra.cl41 import N_COMPONENTS, geometric_product, reverse from algebra.rotor import word_transition_rotor from algebra.versor import versor_condition from core.physics.energy import EnergyClass, EnergyProfile, FieldEnergyOperator from core.physics.goldtether import GoldTetherViolationError, require_unitary from core.physics.sensorium_wave_feed import ( PacketLike, _coerce_packet, compile_packet_to_psi, superpose_packets, ) from core.physics.wave_energy_boundary import ( CrystallizationDecision, crystallization_for_holographic_seal, energy_profile_from_wave, ) from core.physics.wave_manifold import WaveManifold, multivector_content_digest _NEAR_ZERO = 1e-12 _UNIT_TOL = 1e-9 _EPSILON_DRIFT = 1e-6 _MAX_ATOMS = 5 _SPECULATIVE = "SPECULATIVE" # --- Typed fail-closed errors -------------------------------------------------- class CognitiveLifecycleError(ValueError): """Fail-closed lifecycle refusal with structured disclosure.""" def __init__(self, reason: str, **disclosure: Any) -> None: self.reason = reason self.disclosure = dict(disclosure) super().__init__(f"cognitive_lifecycle refused [{reason}]: {self.disclosure}") class IngressDegenerate(CognitiveLifecycleError): """Superposed context has no resolvable amplitude (no confabulated field).""" class HamiltonianCompileError(CognitiveLifecycleError): """Problem → Hamiltonian compilation refused (malformed constraints).""" class RelaxationInputError(CognitiveLifecycleError): """Relaxer input refused (shape / non-finite / non-unit ψ0). No repair.""" class RelaxationNumericalFailure(CognitiveLifecycleError): """Non-finite value produced during relaxation (mirrors OptimizationFailure).""" class RelaxationNotConverged(CognitiveLifecycleError): """Relaxation did not certify the ground state; carries the certificate.""" def __init__(self, reason: str, certificate: "RelaxationCertificate", **disclosure: Any) -> None: self.certificate = certificate super().__init__(reason, **disclosure) class EgressValidationError(CognitiveLifecycleError): """Egress gate refused to evaluate a malformed state (shape / non-finite).""" # --- Content addressing ---------------------------------------------------------- def _le_f64_bytes(arr: np.ndarray) -> bytes: """Canonical little-endian float64 bytes for cross-platform-stable digests. ADR-0244 §2.7 byte-order guard: coerce to little-endian float64 before hashing so the digest is identical on every little-endian platform and deterministic on big-endian ones. Byte-wise a no-op on the M1/x86 targets, but an explicit contract rather than an implicit platform assumption — and a coercion, not an ``assert`` (the assert form is stripped under ``-O``). """ contiguous = np.ascontiguousarray(arr, dtype=np.float64) return contiguous.astype(np.dtype(" str: # Full 256-bit digest (64 hex). No ``default=str``: a non-serializable # payload element fails closed with a typed ``TypeError`` at the # serialization boundary rather than silently collapsing distinct objects # onto identical string forms (ADR-0244 §2.7). raw = json.dumps(payload, sort_keys=True, separators=(",", ":")) return hashlib.sha256(raw.encode("utf-8")).hexdigest() def _psi_digest(psi: np.ndarray) -> str: # Full 256-bit digest over canonical little-endian float64 bytes — no # 96-bit truncation (birthday-collision floor at 2^48), no platform # byte-order ambiguity (ADR-0244 §2.7). return hashlib.sha256(_le_f64_bytes(psi)).hexdigest() def _as_psi(x: np.ndarray, name: str, *, error: type[CognitiveLifecycleError]) -> np.ndarray: arr = np.asarray(x, dtype=np.float64) if arr.shape != (N_COMPONENTS,): raise error("bad_shape", name=name, shape=list(np.shape(x))) if not np.all(np.isfinite(arr)): raise error("non_finite", name=name) return arr # --- Blade lattice ↔ assignment lattice (propositional substrate) ----------------- # # Subset S ⊆ {0..4} of basis-vector indices ↔ the canonical blade e_{i1}…e_{ik} # (ascending product) ↔ the truth assignment with exactly the atoms in S True. # The component index and sign are DERIVED from the algebra's own geometric # product — no hand-maintained table to drift from algebra/cl41. def _vector_onehot(i: int) -> np.ndarray: v = np.zeros(N_COMPONENTS, dtype=np.float64) v[1 + i] = 1.0 # basis vector e_i lives at component 1+i (0-indexed atoms) return v def _build_subset_component_map() -> tuple[tuple[int, ...], tuple[float, ...]]: indices: list[int] = [] signs: list[float] = [] for mask in range(1 << _MAX_ATOMS): blade = np.zeros(N_COMPONENTS, dtype=np.float64) blade[0] = 1.0 for i in range(_MAX_ATOMS): if mask & (1 << i): blade = geometric_product(blade, _vector_onehot(i)) support = np.nonzero(np.abs(blade) > 0.5)[0] if support.size != 1: raise RuntimeError(f"blade map degenerate for mask {mask}: support={support}") idx = int(support[0]) indices.append(idx) signs.append(float(np.sign(blade[idx]))) if len(set(indices)) != (1 << _MAX_ATOMS): raise RuntimeError("blade map is not a bijection onto components") return tuple(indices), tuple(signs) _SUBSET_COMPONENT, _SUBSET_SIGN = _build_subset_component_map() def assignment_component_index(assignment_mask: int) -> int: """Component index of the blade encoding *assignment_mask* (bit i = atom i True).""" if not (0 <= int(assignment_mask) < (1 << _MAX_ATOMS)): raise HamiltonianCompileError("assignment_mask_out_of_range", mask=int(assignment_mask)) return _SUBSET_COMPONENT[int(assignment_mask)] # --- Ingress ---------------------------------------------------------------------- @dataclass(frozen=True, slots=True) class ModalityTransition: """Provenance for a versor-sandwich modality transition (Spin(4,1)).""" psi_in_digest: str psi_out_digest: str rotor_digest: str goldtether_residual: float source_modality: str target_modality: str def as_dict(self) -> dict[str, Any]: return { "psi_in_digest": self.psi_in_digest, "psi_out_digest": self.psi_out_digest, "rotor_digest": self.rotor_digest, "goldtether_residual": float(self.goldtether_residual), "source_modality": self.source_modality, "target_modality": self.target_modality, } def modality_transition_sandwich( psi_in: np.ndarray, rotor: np.ndarray, *, source_modality: str = "", target_modality: str = "", epsilon_drift: float = _EPSILON_DRIFT, ) -> tuple[np.ndarray, ModalityTransition]: """Inter-modality transition: ψ_out = R · ψ_in · rev(R), R ∈ Spin(4,1). Fail-closed GoldTether validation on the output (and on the rotor unit residual). Digests are full SHA-256 over little-endian float64 bytes. Maps the dossier's multimodal_lifecycle sandwich contract onto this module (the real lifecycle owner; ``multimodal_lifecycle.py`` does not exist). """ psi = _as_psi(psi_in, "ψ_in", error=IngressDegenerate) R = np.asarray(rotor, dtype=np.float64) if R.shape != (N_COMPONENTS,): raise IngressDegenerate("bad_rotor_shape", shape=list(R.shape)) if float(versor_condition(R)) >= float(epsilon_drift): raise GoldTetherViolationError( float(versor_condition(R)), float(epsilon_drift), detail="modality rotor not unit versor", ) # ψ_out = R ψ rev(R) psi_out = geometric_product(geometric_product(R, psi), reverse(R)).astype(np.float64) residual = float(require_unitary(psi_out, epsilon=float(epsilon_drift))) transition = ModalityTransition( psi_in_digest=multivector_content_digest(psi), psi_out_digest=multivector_content_digest(psi_out), rotor_digest=multivector_content_digest(R), goldtether_residual=residual, source_modality=str(source_modality), target_modality=str(target_modality), ) return psi_out, transition @dataclass(frozen=True, slots=True) class IngressWavePacket: """Normalized ingress field ψ_context with provenance (ADR-0243 §2.1). Multi-modality composition is sandwich-governed: each inter-modality step is recorded in ``modality_transitions`` with full SHA-256 digests. """ psi: np.ndarray domain_id: str modality_ids: tuple[str, ...] packet_digest: str modality_transitions: tuple[ModalityTransition, ...] = () def __post_init__(self) -> None: arr = _as_psi(self.psi, "ψ_context", error=IngressDegenerate) arr = arr.copy() arr.setflags(write=False) object.__setattr__(self, "psi", arr) object.__setattr__( self, "modality_transitions", tuple(self.modality_transitions), ) def _construction_unitize(psi: np.ndarray, *, name: str) -> np.ndarray: """Owned construction-boundary Euclidean unitize (not hot-path repair).""" arr = np.asarray(psi, dtype=np.float64).reshape(-1) if arr.shape != (N_COMPONENTS,): raise IngressDegenerate("bad_shape", name=name, shape=list(arr.shape)) if not np.all(np.isfinite(arr)): raise IngressDegenerate("non_finite", name=name) norm = float(np.linalg.norm(arr)) if not np.isfinite(norm) or norm < _NEAR_ZERO: raise IngressDegenerate("degenerate_packet", name=name, norm=norm) return (arr / norm).astype(np.float64) def ingest_context(packets: Sequence[PacketLike], domain_id: str) -> IngressWavePacket: """Compose modality packets into ψ_context with sandwich-governed multi-modality. * Empty input refuses (via superpose preflight / empty list). * Degenerate linear cancellation (Σψ ≈ 0) refuses as construction failure. * Single packet: construction-boundary unitize only. * Multi-packet: successive Spin(4,1) sandwiches ``ψ ← R_i · ψ · rev(R_i)`` with ``R_i = word_transition_rotor(ψ, ψ_{i+1})``, each step fail-closed via :func:`modality_transition_sandwich` (GoldTether + SHA-256 digests). Normalization / unitize lives only at this owned construction boundary. """ domain = str(domain_id).strip() if not domain: raise IngressDegenerate("empty_domain_id") if not packets: raise ValueError("superpose_packets: empty packet list") # Preflight: refuse empty and destructive cancellation (Σψ ≈ 0). total = superpose_packets(packets) mass = float(np.linalg.norm(total)) if not np.isfinite(mass) or mass < _NEAR_ZERO: raise IngressDegenerate( "degenerate_superposition", norm=mass, n_packets=len(packets) ) coerced = [_coerce_packet(p) for p in packets] modality_ids = tuple(p.modality_id for p in coerced) transitions: list[ModalityTransition] = [] # Seed from first packet at construction boundary. psi = _construction_unitize( compile_packet_to_psi(coerced[0]), name="packet[0]" ) # Multi-modality: sandwich each subsequent packet into the field. for i in range(1, len(coerced)): target = _construction_unitize( compile_packet_to_psi(coerced[i]), name=f"packet[{i}]" ) try: rotor = word_transition_rotor(psi, target) except ValueError as exc: raise IngressDegenerate( "modality_rotor_refused", source=modality_ids[i - 1], target=modality_ids[i], detail=str(exc), ) from exc psi, tr = modality_transition_sandwich( psi, rotor, source_modality=modality_ids[i - 1], target_modality=modality_ids[i], epsilon_drift=_EPSILON_DRIFT, ) transitions.append(tr) # Final construction close: unit Euclidean density for energy path. psi = _construction_unitize(psi, name="ψ_context") digests = [tr.psi_out_digest for tr in transitions] return IngressWavePacket( psi=psi, domain_id=domain, modality_ids=modality_ids, packet_digest=_content_id( { "psi": _psi_digest(psi), "domain": domain, "modalities": list(modality_ids), "transitions": digests, } ), modality_transitions=tuple(transitions), ) # --- Problem Hamiltonians ----------------------------------------------------------- @dataclass(frozen=True, slots=True) class ProblemHamiltonian: """Typed, content-addressed constraint operator H (symmetric, 32×32, f64). ``matrix`` is validated (shape, finiteness, symmetry ≤ 1e-12) and frozen read-only; asymmetric input is refused, never symmetrized (no repair). """ matrix: np.ndarray domain: str metadata: Mapping[str, Any] = field(default_factory=dict) hamiltonian_id: str = "" is_diagonal: bool = False def __post_init__(self) -> None: arr = np.asarray(self.matrix, dtype=np.float64) if arr.shape != (N_COMPONENTS, N_COMPONENTS): raise HamiltonianCompileError("bad_shape", shape=list(arr.shape)) if not np.all(np.isfinite(arr)): raise HamiltonianCompileError("non_finite_matrix") asym = float(np.max(np.abs(arr - arr.T))) if asym > 1e-12: raise HamiltonianCompileError("not_symmetric", max_asymmetry=asym) arr = arr.copy() arr.setflags(write=False) diagonal = bool(np.count_nonzero(arr - np.diag(np.diagonal(arr))) == 0) meta = dict(self.metadata) object.__setattr__(self, "matrix", arr) object.__setattr__(self, "metadata", meta) object.__setattr__(self, "is_diagonal", diagonal) object.__setattr__( self, "hamiltonian_id", _content_id( { "domain": str(self.domain), "matrix_sha": hashlib.sha256(_le_f64_bytes(arr)).hexdigest(), "metadata": {k: str(v) for k, v in sorted(meta.items())}, } ), ) def compile_quadratic_well(target_psi: np.ndarray, *, curvature: float = 1.0) -> ProblemHamiltonian: """H = curvature·(Id − ψ₀ψ₀ᵀ): ground space span(ψ₀) at energy 0, gap = curvature.""" target = _as_psi(target_psi, "target_psi", error=HamiltonianCompileError) c = float(curvature) if not np.isfinite(c) or c <= 0.0: raise HamiltonianCompileError("curvature_not_positive", curvature=c) norm_err = abs(float(np.linalg.norm(target)) - 1.0) if norm_err > _UNIT_TOL: raise HamiltonianCompileError("target_not_unit", norm_residual=norm_err) matrix = c * (np.eye(N_COMPONENTS, dtype=np.float64) - np.outer(target, target)) return ProblemHamiltonian( matrix=matrix, domain="quadratic_well", metadata={"curvature": c, "target_digest": _psi_digest(target)}, ) PropositionalLiteral = tuple[str, bool] Clause = tuple[PropositionalLiteral, ...] @dataclass(frozen=True, slots=True) class PropositionalProblem: """CNF over ≤ 5 atoms; atom i ↔ basis vector e_i (order as given).""" atoms: tuple[str, ...] clauses: tuple[Clause, ...] problem_id: str = "" def __post_init__(self) -> None: atoms = tuple(str(a) for a in self.atoms) if not (1 <= len(atoms) <= _MAX_ATOMS): raise HamiltonianCompileError("atom_count_out_of_range", n_atoms=len(atoms)) if len(set(atoms)) != len(atoms) or any(not a.strip() for a in atoms): raise HamiltonianCompileError("atoms_not_unique_nonempty", atoms=list(atoms)) clauses: list[Clause] = [] for ci, clause in enumerate(self.clauses): lits = tuple((str(a), bool(p)) for a, p in clause) if not lits: raise HamiltonianCompileError("empty_clause", clause_index=ci) if len(set(lits)) != len(lits): raise HamiltonianCompileError("duplicate_literal", clause_index=ci) for atom, _ in lits: if atom not in atoms: raise HamiltonianCompileError("unknown_atom", clause_index=ci, atom=atom) clauses.append(lits) object.__setattr__(self, "atoms", atoms) object.__setattr__(self, "clauses", tuple(clauses)) object.__setattr__( self, "problem_id", _content_id({"atoms": list(atoms), "clauses": [list(c) for c in clauses]}), ) @property def n_atoms(self) -> int: return len(self.atoms) def _falsification_counts(problem: PropositionalProblem) -> tuple[int, ...]: """Clauses falsified per assignment mask (exact integer counts).""" k = problem.n_atoms index = {a: i for i, a in enumerate(problem.atoms)} counts = [0] * (1 << k) for mask in range(1 << k): for clause in problem.clauses: satisfied = False for atom, polarity in clause: bit = bool(mask & (1 << index[atom])) if bit == polarity: satisfied = True break if not satisfied: counts[mask] += 1 return tuple(counts) def compile_propositional(problem: PropositionalProblem, *, penalty: float = 1.0) -> ProblemHamiltonian: """Diagonal penalty Hamiltonian: diag[component(a)] = penalty · #clauses falsified by a. Out-of-domain components (blades using vectors beyond the atom set) get ``penalty·(len(clauses)+1)`` — strictly above every in-domain value, so the ground space is always inside the assignment lattice. Satisfiable iff the exact ground energy is 0. """ p = float(penalty) if not np.isfinite(p) or p <= 0.0: raise HamiltonianCompileError("penalty_not_positive", penalty=p) counts = _falsification_counts(problem) diag = np.full(N_COMPONENTS, p * float(len(problem.clauses) + 1), dtype=np.float64) for mask, count in enumerate(counts): diag[_SUBSET_COMPONENT[mask]] = p * float(count) return ProblemHamiltonian( matrix=np.diag(diag), domain="propositional", metadata={"problem_id": problem.problem_id, "penalty": p, "n_atoms": problem.n_atoms}, ) def uniform_assignment_state(problem: PropositionalProblem) -> np.ndarray: """Unit uniform superposition over the problem's assignment components. Uses the algebra-derived blade signs so every assignment basis state enters with amplitude +1/√(2^k) on the CANONICAL blade orientation. """ k = problem.n_atoms psi = np.zeros(N_COMPONENTS, dtype=np.float64) amp = 1.0 / float(np.sqrt(1 << k)) for mask in range(1 << k): psi[_SUBSET_COMPONENT[mask]] = amp * _SUBSET_SIGN[mask] return psi # --- Relaxation (imaginary-time semigroup; deviation D-1) --------------------------- @dataclass(frozen=True, slots=True) class RelaxationCertificate: """Convergence evidence for one relaxation run (D-2: certified, not assumed). ``psi_digest`` binds the certificate to the exact final state it describes (byte digest of ψ_steady) — the egress gate refuses a certificate presented with any other state, so convergence evidence cannot be borrowed. """ hamiltonian_id: str domain: str dt: float tol: float max_steps: int steps_taken: int ground_energy: float achieved_energy: float spectral_gap: float eigen_residual: float energy_monotone: bool converged: bool reason: str psi_digest: str certificate_id: str = "" def __post_init__(self) -> None: payload = { "hamiltonian_id": self.hamiltonian_id, "domain": self.domain, "dt": repr(float(self.dt)), "tol": repr(float(self.tol)), "max_steps": int(self.max_steps), "steps_taken": int(self.steps_taken), "ground_energy": repr(float(self.ground_energy)), "achieved_energy": repr(float(self.achieved_energy)), "spectral_gap": repr(float(self.spectral_gap)), "eigen_residual": repr(float(self.eigen_residual)), "energy_monotone": bool(self.energy_monotone), "converged": bool(self.converged), "reason": self.reason, "psi_digest": self.psi_digest, } object.__setattr__(self, "certificate_id", _content_id(payload)) def as_dict(self) -> dict[str, Any]: return { "hamiltonian_id": self.hamiltonian_id, "domain": self.domain, "dt": float(self.dt), "tol": float(self.tol), "max_steps": int(self.max_steps), "steps_taken": int(self.steps_taken), "ground_energy": float(self.ground_energy), "achieved_energy": float(self.achieved_energy), "spectral_gap": float(self.spectral_gap), "eigen_residual": float(self.eigen_residual), "energy_monotone": bool(self.energy_monotone), "converged": bool(self.converged), "reason": self.reason, "psi_digest": self.psi_digest, "certificate_id": self.certificate_id, } @dataclass(frozen=True, slots=True) class RelaxationResult: psi_steady: np.ndarray certificate: RelaxationCertificate def __post_init__(self) -> None: arr = np.asarray(self.psi_steady, dtype=np.float64).copy() arr.setflags(write=False) object.__setattr__(self, "psi_steady", arr) def _spectral_gap(evals: np.ndarray, tol: float) -> tuple[float, float, float]: """(λ0, gap, energy_tol) with the degeneracy cluster ⊆ the acceptance window. Capping ``deg_tol`` at ``energy_tol`` keeps the certificate internally consistent: an eigenvalue counted into the ground cluster is never refused by the energy check, and ``gap`` is the honest rate-limiting gap (a split just above ``energy_tol`` is reported, not absorbed). """ lam0 = float(evals[0]) energy_tol = float(tol) * max(1.0, abs(lam0)) deg_tol = min(1e-9 * max(1.0, abs(lam0)) + 1e-12, energy_tol) above = evals[evals > lam0 + deg_tol] gap = float(above[0] - lam0) if above.size else 0.0 return lam0, gap, energy_tol @functools.lru_cache(maxsize=128) def _cached_eigh(hamiltonian_id: str, matrix_bytes: bytes) -> tuple[np.ndarray, np.ndarray]: """Memoized symmetric eigendecomposition (ADR-0244 §2.8 / directive M2). ``ProblemHamiltonian`` is frozen and content-addressed, so a fresh LAPACK ``eigh`` on an identical matrix (repeated active-turn / biography checks) is wasted AMX compute. Keyed on the immutable ``hamiltonian_id`` *and* the raw matrix bytes (collision-resistant: the id already content-addresses the matrix; the bytes make a same-id/different-bytes hit impossible). The returned arrays are frozen read-only so a cache hit cannot be mutated by a caller — every hit yields bit-identical ``(evals, evecs)``. """ matrix = np.frombuffer(matrix_bytes, dtype=np.float64).reshape(N_COMPONENTS, N_COMPONENTS) evals, evecs = np.linalg.eigh(matrix) evals = np.ascontiguousarray(evals) evecs = np.ascontiguousarray(evecs) evals.setflags(write=False) evecs.setflags(write=False) return evals, evecs def relax_to_ground( psi0: np.ndarray, hamiltonian: ProblemHamiltonian, *, dt: float = 1.0, max_steps: int = 512, tol: float = 1e-10, require_converged: bool = True, ) -> RelaxationResult: """Deterministic imaginary-time relaxation to the ground eigenspace of H. ``ψ ← normalize(exp(−(H−λ0)·dt)·ψ)`` — normalized power iteration on the dissipative semigroup (D-1; the λ0 shift only rescales, dynamics identical). Along the iteration the Rayleigh energy is non-increasing (a falsifiable physics invariant, recorded as ``energy_monotone``). Converged means ``‖Hψ − Eψ‖ ≤ tol`` AND ``E − λ0 ≤ tol·max(1,|λ0|)`` AND, when the spectral gap is positive, ``E − λ0 ≤ tol·gap`` — the excited-space weight of ψ is bounded by ``(E−λ0)/gap``, so the third check certifies ground weight ≥ 1−tol instead of trusting an energy window the spectrum may not resolve. A start orthogonal to the ground space settles in an excited eigenspace with a small residual and is refused as ``excited_eigenspace``; a state whose energy sits inside the window while the gap is below the requested resolution is refused as ``spectral_gap_below_tolerance``, never mis-certified. Degenerate ground spaces (gap 0 after clustering) converge to the normalized projection of ψ0 (input-dependent decoding within the solution space). Fail-closed: non-finite input/iterates and non-unit ψ0 raise typed errors; nothing is repaired. """ psi = _as_psi(psi0, "ψ0", error=RelaxationInputError).copy() unit_err = abs(float(np.linalg.norm(psi)) - 1.0) if unit_err > _UNIT_TOL: raise RelaxationInputError("psi0_not_normalized", norm_residual=unit_err) dt_f = float(dt) if not np.isfinite(dt_f) or dt_f <= 0.0: raise RelaxationInputError("dt_not_positive", dt=dt_f) steps = int(max_steps) if steps < 1: raise RelaxationInputError("max_steps_not_positive", max_steps=steps) tol_f = float(tol) if not np.isfinite(tol_f) or tol_f <= 0.0: raise RelaxationInputError("tol_not_positive", tol=tol_f) H_mat = hamiltonian.matrix if hamiltonian.is_diagonal: # Exact spectrum from the diagonal — no LAPACK on the propositional path. diag = np.diagonal(H_mat).copy() lam0, gap, energy_tol = _spectral_gap(np.sort(diag), tol_f) decay = np.exp(-(diag - lam0) * dt_f) def step(v: np.ndarray) -> np.ndarray: return decay * v def apply_h(v: np.ndarray) -> np.ndarray: return diag * v else: evals_full, evecs_full = _cached_eigh(hamiltonian.hamiltonian_id, H_mat.tobytes()) lam0, gap, energy_tol = _spectral_gap(evals_full, tol_f) propagator = evecs_full @ np.diag(np.exp(-(evals_full - lam0) * dt_f)) @ evecs_full.T def step(v: np.ndarray) -> np.ndarray: return propagator @ v def apply_h(v: np.ndarray) -> np.ndarray: return H_mat @ v def _measure(v: np.ndarray) -> tuple[float, float]: hv = apply_h(v) energy = float(v @ hv) residual = float(np.linalg.norm(hv - energy * v)) return energy, residual def _certified(energy: float, residual: float) -> bool: near_ground = (energy - lam0) <= energy_tol gap_resolved = gap == 0.0 or (energy - lam0) <= tol_f * gap return residual <= tol_f and near_ground and gap_resolved energies: list[float] = [] energy, residual = _measure(psi) energies.append(energy) steps_taken = 0 for _ in range(steps): if _certified(energy, residual): break psi = step(psi) if not np.all(np.isfinite(psi)): # Defensive only: decay/propagator entries are exp(−x) with x ≥ 0. raise RelaxationNumericalFailure("non_finite_iterate", steps_taken=steps_taken) norm = float(np.linalg.norm(psi)) if norm < _NEAR_ZERO: raise RelaxationNumericalFailure("iterate_collapsed", steps_taken=steps_taken) psi = psi / norm steps_taken += 1 energy, residual = _measure(psi) energies.append(energy) monotone = all( energies[i + 1] <= energies[i] + 1e-9 * max(1.0, abs(energies[i])) for i in range(len(energies) - 1) ) residual_ok = residual <= tol_f at_ground = (energy - lam0) <= energy_tol converged = _certified(energy, residual) if converged: reason = "ground_state_certified" elif residual_ok and not at_ground: reason = "excited_eigenspace" elif residual_ok: reason = "spectral_gap_below_tolerance" else: reason = "max_steps_exhausted" certificate = RelaxationCertificate( hamiltonian_id=hamiltonian.hamiltonian_id, domain=hamiltonian.domain, dt=dt_f, tol=tol_f, max_steps=steps, steps_taken=steps_taken, ground_energy=lam0, achieved_energy=energy, spectral_gap=gap, eigen_residual=residual, energy_monotone=monotone, converged=converged, reason=reason, psi_digest=_psi_digest(psi), ) if not converged and require_converged: raise RelaxationNotConverged( reason, certificate, achieved_energy=energy, ground_energy=lam0, eigen_residual=residual, ) return RelaxationResult(psi_steady=psi, certificate=certificate) # --- Propositional verdicts (exact spectrum path) ----------------------------------- @dataclass(frozen=True, slots=True) class PropositionalEntailmentVerdict: """Entailment via UNSAT(premises ∧ ¬conclusion) on the SAME compiled H family. ``satisfiable_premises=False`` discloses vacuous (ex falso) entailment. Distinct name from ``generate.proof_chain.EntailmentVerdict`` (the ROBDD flagship) — that is the independent gold this domain is scored against. """ entailed: bool satisfiable_premises: bool ground_energy_premises: float ground_energy_augmented: float penalty: float verdict_id: str = "" def __post_init__(self) -> None: object.__setattr__( self, "verdict_id", _content_id( { "entailed": bool(self.entailed), "satisfiable_premises": bool(self.satisfiable_premises), "ge_premises": repr(float(self.ground_energy_premises)), "ge_augmented": repr(float(self.ground_energy_augmented)), "penalty": repr(float(self.penalty)), } ), ) def _in_domain_ground_energy(problem: PropositionalProblem, *, penalty: float) -> float: counts = _falsification_counts(problem) return float(penalty) * float(min(counts)) def propositional_entails( premises: PropositionalProblem, conclusion: Clause, *, penalty: float = 1.0, ) -> PropositionalEntailmentVerdict: """premises ⊨ (⋁ conclusion) iff premises ∧ ¬conclusion is UNSAT. ¬conclusion compiles to unit clauses over the SAME atom set (unknown atoms are refused — the v1 domain is closed-vocabulary). The verdict reads exact integer ground energies of the compiled Hamiltonians; relaxation is the constructive decoder of the same operators, so what is asserted and what relaxes are one object. """ p = float(penalty) if not np.isfinite(p) or p <= 0.0: raise HamiltonianCompileError("penalty_not_positive", penalty=p) lits = tuple((str(a), bool(pol)) for a, pol in conclusion) if not lits: raise HamiltonianCompileError("empty_conclusion") for atom, _ in lits: if atom not in premises.atoms: raise HamiltonianCompileError("unknown_atom_in_conclusion", atom=atom) negation_units: tuple[Clause, ...] = tuple(((atom, not pol),) for atom, pol in lits) augmented = PropositionalProblem( atoms=premises.atoms, clauses=premises.clauses + negation_units, ) ge_premises = _in_domain_ground_energy(premises, penalty=p) ge_augmented = _in_domain_ground_energy(augmented, penalty=p) return PropositionalEntailmentVerdict( entailed=bool(ge_augmented > 0.0), satisfiable_premises=bool(ge_premises == 0.0), ground_energy_premises=ge_premises, ground_energy_augmented=ge_augmented, penalty=p, ) # --- Egress (ADR-0243 §2.3) ---------------------------------------------------------- @dataclass(frozen=True, slots=True) class CrystallizationProposal: """Proposal-only cold-state artifact (D-5 / I-03). NEVER a vault write. ``epistemic_status`` is pinned to ``"SPECULATIVE"`` by the type itself; ratification and any COHERENT promotion live outside this module, behind the one-mutation-path. """ proposal_id: str epistemic_status: str psi_digest: str certificate_id: str decision: CrystallizationDecision adr_refs: tuple[str, ...] = ("ADR-0243", "ADR-0241") def __post_init__(self) -> None: if self.epistemic_status != _SPECULATIVE: raise CognitiveLifecycleError( "proposal_must_be_speculative", epistemic_status=self.epistemic_status ) def as_dict(self) -> dict[str, Any]: return { "proposal_id": self.proposal_id, "epistemic_status": self.epistemic_status, "psi_digest": self.psi_digest, "certificate_id": self.certificate_id, "decision": self.decision.as_dict(), "adr_refs": list(self.adr_refs), } @dataclass(frozen=True, slots=True) class EgressVerdict: """Composed egress verdict (ADR-0243 §2.3, corrected per pin SD-A). ``admitted`` = unit amplitude density + a converged certificate BOUND to this exact ψ (``certificate.psi_digest`` must match the presented state byte-for-byte; a borrowed certificate refuses as ``certificate_state_mismatch``, so no proposal can pair a state with foreign convergence evidence). ``versor_closed`` (the ADR's R_GoldTether ≤ ε) ROUTES — it is required on the crystallization path (only closed versors may SPECULATIVE-seal) and reported on all paths; demanding it of multi-mode superpositions would reject every legitimate interference state. """ admitted: bool reason: str route: str # refused | readback_eligible | crystallization_proposal | hold unit_norm_residual: float versor_residual: float versor_closed: bool energy_class: EnergyClass energy_profile: EnergyProfile proposal: CrystallizationProposal | None def egress_gate( psi_steady: np.ndarray, certificate: RelaxationCertificate, *, epsilon_drift: float = _EPSILON_DRIFT, manifold: WaveManifold | None = None, operator: FieldEnergyOperator | None = None, **energy_kwargs: object, ) -> EgressVerdict: """Thermodynamic egress: admit → classify → route (E0/E1 cold, E3/E4 hot). Structural energy axes (convergence, activation, aspect) are caller-supplied via ``energy_kwargs`` — never invented here; the coherence residual is measured on ψ by the energy boundary itself. Malformed states raise; legitimate bad states get ``admitted=False``. """ arr = _as_psi(psi_steady, "ψ_steady", error=EgressValidationError) m = manifold if manifold is not None else WaveManifold(epsilon_drift=float(epsilon_drift)) unit_norm_residual = abs(float(np.linalg.norm(arr)) - 1.0) versor_residual = float(m.measure_unitary_residual(arr)) versor_closed = versor_residual <= float(epsilon_drift) psi_dig = _psi_digest(arr) profile = energy_profile_from_wave( arr, operator=operator, manifold=m, epsilon_drift=float(epsilon_drift), **energy_kwargs ) energy_class = profile.energy_class if unit_norm_residual > float(epsilon_drift): admitted, reason = False, "amplitude_density_not_unit" elif psi_dig != certificate.psi_digest: admitted, reason = False, "certificate_state_mismatch" elif not certificate.converged: admitted, reason = False, f"relaxation_not_certified:{certificate.reason}" else: admitted, reason = True, "admitted" proposal: CrystallizationProposal | None = None if not admitted: route = "refused" elif energy_class in (EnergyClass.E3, EnergyClass.E4): route = "readback_eligible" elif energy_class.vault_candidate: decision = crystallization_for_holographic_seal( arr, epsilon_drift=float(epsilon_drift), manifold=m, operator=operator, **energy_kwargs, ) if decision.may_speculative_seal: route = "crystallization_proposal" proposal = CrystallizationProposal( proposal_id="crystal-" + _content_id( { "psi": psi_dig, "certificate": certificate.certificate_id, "decision": decision.as_dict(), } ), epistemic_status=_SPECULATIVE, psi_digest=psi_dig, certificate_id=certificate.certificate_id, decision=decision, ) else: route = "hold" # cold but not crystalline (e.g. open superposition) else: route = "hold" # E2 mid-band: neither vault-cold nor readback-hot return EgressVerdict( admitted=admitted, reason=reason, route=route, unit_norm_residual=unit_norm_residual, versor_residual=versor_residual, versor_closed=versor_closed, energy_class=energy_class, energy_profile=profile, proposal=proposal, ) # --- Serving-boundary f64 -> f32 cast (ADR-0244 §2.5 / ADR-0245 §2.2) ----------------- # # The lifecycle relaxes and certifies entirely in float64 (relaxation, # eigendecomposition, the psi_digest content-address chain — all f64). f32 is a # *serving* representation only: the down-cast happens once, at the certified # egress hand-off, for consumers on the f32 fast path (the Rust f32 # geometric_product, SIMD, GPU). This is the single governed cast — explicit, # gated on certification, precision-checked, and auditable — not an implicit # dtype coercion sprinkled through the hot path. _F32_CAST_TOL = 1e-6 # float32 has ~1.19e-7 machine eps; a unit versor's # components are O(1), so a faithful down-cast keeps # max|f64 - f32| ~6e-8 and unit-norm within a few ulp. The # tolerance fails closed on a state whose dynamic range # exceeds what f32 can represent (a genuine precision # cliff) rather than serving a silently-degraded state. class ServingCastError(CognitiveLifecycleError): """Refused to serve a state as f32: uncertified, digest-mismatched, or f32 precision-insufficient. f64 stays the source of truth; the cast never silently degrades a state.""" @dataclass(frozen=True, slots=True) class ServingState: """f32 serving projection of a certified ψ_steady (ADR-0244 §2.5 / ADR-0245 §2.2). The f64 state and its ``psi_digest`` remain authoritative; this is the down-cast handed to f32 serving consumers, carrying provenance back to the f64 certificate and the measured round-trip error so the cast is auditable. """ psi_f32: np.ndarray source_psi_digest: str certificate_id: str cast_error: float unit_norm_f32: float def as_dict(self) -> dict[str, Any]: return { "source_psi_digest": self.source_psi_digest, "certificate_id": self.certificate_id, "cast_error": float(self.cast_error), "unit_norm_f32": float(self.unit_norm_f32), "dtype": str(self.psi_f32.dtype), } def serving_cast( psi_steady: np.ndarray, certificate: RelaxationCertificate, verdict: EgressVerdict, *, tol: float = _F32_CAST_TOL, ) -> ServingState: """Governed f64→f32 down-cast at the certified serving boundary. Fail-closed. The state is cast **only** if it (a) validates as a finite 32-vector, (b) matches its certificate's ``psi_digest`` (the state served is provably the certified one), and (c) was admitted by the egress gate — an uncertified or refused state is never handed to a serving consumer. The f32 representation is then precision-checked: if the down-cast perturbs any component or the unit norm beyond ``tol``, the state sits on an f32 precision cliff and the cast fails closed rather than serving a degraded state. f64 remains the source of truth: neither ``psi_steady`` nor the certificate / digest chain is mutated. This is the single explicit cast the ADR-0245 §2.2 mechanical-sympathy contract permits — f64 everywhere inside, f32 only here. """ arr = _as_psi(psi_steady, "ψ_steady", error=ServingCastError) # f64 validate if _psi_digest(arr) != certificate.psi_digest: raise ServingCastError( "certificate_state_mismatch", certificate_id=certificate.certificate_id ) if not verdict.admitted: raise ServingCastError("uncertified_state_not_served", verdict_reason=verdict.reason) f32 = np.ascontiguousarray(arr, dtype=np.dtype(" float(tol) or abs(unit_norm_f32 - 1.0) > float(tol) + _EPSILON_DRIFT: raise ServingCastError( "f32_precision_insufficient", cast_error=cast_error, unit_norm_f32=unit_norm_f32, tol=float(tol), ) f32.setflags(write=False) return ServingState( psi_f32=f32, source_psi_digest=certificate.psi_digest, certificate_id=certificate.certificate_id, cast_error=cast_error, unit_norm_f32=unit_norm_f32, ) # --- Unified autonomy floor (seam S3, ADR-0238 / spark-audit adjudication §4) ---------- @dataclass(frozen=True, slots=True) class TetherReading: """Per-turn GoldTether autonomy-floor reading for one corridor turn. ``updated`` discloses whether the monitor's floor/autonomy state advanced (see :func:`tether_reading` for the control law) or the residual was measured without a state update (admitted open superpositions). """ residual: float autonomy: float chiral_verdict: str updated: bool def as_dict(self) -> dict[str, Any]: return { "residual": float(self.residual), "autonomy": float(self.autonomy), "chiral_verdict": self.chiral_verdict, "updated": bool(self.updated), } def tether_reading( monitor: "GoldTetherMonitor", psi_steady: np.ndarray, *, admitted: bool, versor_closed: bool, ) -> TetherReading: """Feed one corridor turn to the unified autonomy floor (seam S3). Control law, composed with pin SD-A (the residual KERNEL was already unified — ``goldtether.coherence_residual`` delegates to :meth:`WaveManifold.measure_unitary_residual`; what was missing is the MONITOR state seeing corridor turns): * **not admitted** → ``monitor.update`` — the non-unit/uncertified state drives residual > ε and autonomy hard to 0 (fail-closed). * **admitted + versor_closed** → ``monitor.update`` — a certified closed state may elevate autonomy toward the floor. * **admitted + open** → measure only, no state update: a legitimate interference state neither elevates nor decays the floor. Punishing open superpositions here would encode the exact SD-A defect the egress gate refuses to (versor closure routes, it does not gate). Chiral orientation is observed on EVERY reading — Q_top is material only on non-versor states, which is precisely the open route — and a material sign flip raises :class:`~core.physics.chiral_gate.ChiralOrientationError` (fail-closed, never averaged). """ arr = np.asarray(psi_steady, dtype=np.float64) if admitted and not versor_closed: residual = float(monitor.residual(arr)) autonomy = float(monitor.autonomy) updated = False else: # ``GoldTetherMonitor.update`` raises on R > ε after forcing autonomy # to zero. Corridor tether readings must surface that fail-closed # residual without aborting the lifecycle observation path. try: residual, autonomy = monitor.update(arr) except GoldTetherViolationError as exc: residual = float(exc.residual) autonomy = float(monitor.autonomy) updated = True chiral_verdict = monitor.chiral_gate.observe(arr).verdict return TetherReading( residual=float(residual), autonomy=float(autonomy), chiral_verdict=chiral_verdict, updated=updated, ) # --- Composed lifecycle --------------------------------------------------------------- @dataclass(frozen=True, slots=True) class LifecycleOutcome: ingress: IngressWavePacket relaxation: RelaxationResult verdict: EgressVerdict # Monitoring metadata, deliberately OUTSIDE outcome_id: the outcome's # identity is its cognitive content (ingress/certificate/route/ψ), not the # observer's floor state at the time it was watched. tether: TetherReading | None = None outcome_id: str = "" def __post_init__(self) -> None: object.__setattr__( self, "outcome_id", _content_id( { "ingress": self.ingress.packet_digest, "certificate": self.relaxation.certificate.certificate_id, "route": self.verdict.route, "psi": _psi_digest(self.relaxation.psi_steady), } ), ) class CognitiveLifecycleEngine: """Thin deterministic composer over the pure lifecycle functions. Name matches the ADR §3 sketch for traceability; the implementation is the corrected one (pins SD-A/SD-B/SD-C; deviations D-1…D-5). """ def __init__( self, *, epsilon_drift: float = _EPSILON_DRIFT, monitor: "GoldTetherMonitor | None" = None, ) -> None: self.epsilon_drift = float(epsilon_drift) self.manifold = WaveManifold(epsilon_drift=self.epsilon_drift) # Seam S3: optional unified autonomy floor. solve() feeds it one # reading per turn; stage-level drivers (e.g. the sensorium corridor # eval) own their monitor calls explicitly and should not also pass # one here (double-counting a turn). self.monitor = monitor def ingest_context(self, packets: Sequence[PacketLike], domain_id: str) -> IngressWavePacket: return ingest_context(packets, domain_id) def relax( self, ingress: IngressWavePacket, hamiltonian: ProblemHamiltonian, **kwargs: Any, ) -> RelaxationResult: return relax_to_ground(ingress.psi, hamiltonian, **kwargs) def egress( self, psi_steady: np.ndarray, certificate: RelaxationCertificate, **energy_kwargs: Any, ) -> EgressVerdict: return egress_gate( psi_steady, certificate, epsilon_drift=self.epsilon_drift, manifold=self.manifold, **energy_kwargs, ) def solve( self, packets: Sequence[PacketLike], domain_id: str, hamiltonian: ProblemHamiltonian, *, dt: float = 1.0, max_steps: int = 512, tol: float = 1e-10, energy_inputs: Mapping[str, object] | None = None, ) -> LifecycleOutcome: """Ingress → relax → egress (→ tether). Fail-closed at every stage (typed errors).""" ingress = self.ingest_context(packets, domain_id) result = relax_to_ground(ingress.psi, hamiltonian, dt=dt, max_steps=max_steps, tol=tol) verdict = self.egress( result.psi_steady, result.certificate, **dict(energy_inputs or {}) ) tether = ( tether_reading( self.monitor, result.psi_steady, admitted=verdict.admitted, versor_closed=verdict.versor_closed, ) if self.monitor is not None else None ) return LifecycleOutcome( ingress=ingress, relaxation=result, verdict=verdict, tether=tether ) __all__ = [ "CognitiveLifecycleEngine", "CognitiveLifecycleError", "CrystallizationProposal", "EgressValidationError", "EgressVerdict", "HamiltonianCompileError", "IngressDegenerate", "IngressWavePacket", "LifecycleOutcome", "ProblemHamiltonian", "PropositionalEntailmentVerdict", "PropositionalProblem", "RelaxationCertificate", "RelaxationInputError", "RelaxationNotConverged", "RelaxationNumericalFailure", "RelaxationResult", "ServingCastError", "ServingState", "TetherReading", "tether_reading", "assignment_component_index", "compile_propositional", "compile_quadratic_well", "egress_gate", "ingest_context", "modality_transition_sandwich", "ModalityTransition", "propositional_entails", "relax_to_ground", "serving_cast", "uniform_assignment_state", ]