core/core/physics/cognitive_lifecycle.py
Shay c3b4d045f1 feat(adr-0243): flagship cognitive_lifecycle.py — ingress/relax/egress, Tier-2 off-serving
Implements ADR-0243 §2 honestly per the plan's deviations ledger, correcting
the §3 sketch's three pinned defects (SD-A/B/C):

- Ingress delegates superposition to sensorium_wave_feed, normalizes once at
  the owned construction boundary (D-3).
- Relaxation is the imaginary-time semigroup psi <- normalize(exp(-(H-lam0)*dt)*psi)
  (D-1) with a certified, never-assumed convergence certificate (D-2): exact
  ground energy, achieved Rayleigh energy, eigen-residual, spectral gap, and a
  psi_digest binding the certificate to the exact state it certifies.
- Two checkable problem domains: quadratic_well (convex target-decoding) and
  propositional (Cl(4,1) blade lattice = assignment lattice of <=5 atoms;
  diagonal penalty Hamiltonian; entailment via UNSAT(premises & !conclusion)
  scored against independent truth-table gold).
- Egress composes unit-amplitude-density + certificate-binding + versor
  closure (routes, does not admit, per the dual of SD-A) + ADR-0006 energy
  classes + E0/E1 crystallization policy. Cold states emit a
  CrystallizationProposal (epistemic_status pinned SPECULATIVE by the type;
  D-5/I-03) — never a vault write.
- Quarantined off-serving (A-04): lazy barrel export, banned in the
  transitive subprocess probe and the cohesion AST suite.

Adversarial verification (finder/verifier workflow; most verify agents lost
to a session limit, every surviving finding reproduced in-tree before acting)
surfaced and this closes two real defects beyond the plan text:

- egress_gate admitted any unit state paired with any converged certificate
  from an unrelated run, so CrystallizationProposal could package a foreign
  psi_digest next to an unrelated certificate_id as false provenance. Fixed
  by binding the certificate to its state (psi_digest) and refusing mismatches
  (certificate_state_mismatch).
- A state with a spectral gap below the requested tolerance could certify
  with ZERO ground-space overlap (energy window alone can't resolve it).
  Certification now also requires the excited weight (E-lam0)/gap <= tol
  (refusal spectral_gap_below_tolerance), and the degeneracy cluster is
  capped at the acceptance window so certificates report the honest
  rate-limiting gap instead of absorbing a hairline split.

38 tests (31 original + 7 hardening: certificate-binding must-reject,
gap-refusal + true-ground pair, dense-branch (eigh) refusals, iterate-collapse,
Hamiltonian/egress shape must-rejects, E2 hold route, hardcoded canonical
entailment verdicts independent of the gold function's code shape).

[Verification]: lifecycle+pins+cohesion+transitive 58 passed; in-worktree
smoke 176 passed (131s); fast lane 11750 passed, 108 skipped (574s, exit 0).
2026-07-17 06:19:33 -07:00

960 lines
36 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""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 hashlib
import json
from dataclasses import dataclass, field
from typing import Any, Mapping, Sequence
import numpy as np
from algebra.cl41 import N_COMPONENTS, geometric_product
from core.physics.energy import EnergyClass, EnergyProfile, FieldEnergyOperator
from core.physics.sensorium_wave_feed import PacketLike, _coerce_packet, 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
_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 _content_id(payload: Mapping[str, Any]) -> str:
raw = json.dumps(payload, sort_keys=True, separators=(",", ":"), default=str)
return hashlib.sha256(raw.encode("utf-8")).hexdigest()[:24]
def _psi_digest(psi: np.ndarray) -> str:
return hashlib.sha256(np.ascontiguousarray(psi, dtype=np.float64).tobytes()).hexdigest()[:24]
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 IngressWavePacket:
"""Normalized ingress field ψ_context with provenance (ADR-0243 §2.1)."""
psi: np.ndarray
domain_id: str
modality_ids: tuple[str, ...]
packet_digest: str
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)
def ingest_context(packets: Sequence[PacketLike], domain_id: str) -> IngressWavePacket:
"""Superpose modality packets and normalize at the owned construction boundary.
Delegates superposition to :func:`sensorium_wave_feed.superpose_packets`
(which refuses empty input). Normalization here is the ONE owned
construction boundary of the lifecycle (D-3) — a degenerate superposition
(destructive cancellation below ``1e-12``) is refused, never zero-filled.
"""
domain = str(domain_id).strip()
if not domain:
raise IngressDegenerate("empty_domain_id")
total = superpose_packets(packets)
norm = float(np.linalg.norm(total))
if not np.isfinite(norm) or norm < _NEAR_ZERO:
raise IngressDegenerate("degenerate_superposition", norm=norm, n_packets=len(packets))
psi = (total / norm).astype(np.float64)
modality_ids = tuple(_coerce_packet(p).modality_id for p in packets)
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)}
),
)
# --- 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(arr.tobytes()).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
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 ≥ 1tol 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 = np.linalg.eigh(H_mat)
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,
)
# --- Composed lifecycle ---------------------------------------------------------------
@dataclass(frozen=True, slots=True)
class LifecycleOutcome:
ingress: IngressWavePacket
relaxation: RelaxationResult
verdict: EgressVerdict
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) -> None:
self.epsilon_drift = float(epsilon_drift)
self.manifold = WaveManifold(epsilon_drift=self.epsilon_drift)
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. 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 {})
)
return LifecycleOutcome(ingress=ingress, relaxation=result, verdict=verdict)
__all__ = [
"CognitiveLifecycleEngine",
"CognitiveLifecycleError",
"CrystallizationProposal",
"EgressValidationError",
"EgressVerdict",
"HamiltonianCompileError",
"IngressDegenerate",
"IngressWavePacket",
"LifecycleOutcome",
"ProblemHamiltonian",
"PropositionalEntailmentVerdict",
"PropositionalProblem",
"RelaxationCertificate",
"RelaxationInputError",
"RelaxationNotConverged",
"RelaxationNumericalFailure",
"RelaxationResult",
"assignment_component_index",
"compile_propositional",
"compile_quadratic_well",
"egress_gate",
"ingest_context",
"propositional_entails",
"relax_to_ground",
"uniform_assignment_state",
]