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).
This commit is contained in:
Shay 2026-07-17 06:19:33 -07:00
parent 904380e96a
commit c3b4d045f1
6 changed files with 1717 additions and 0 deletions

View file

@ -118,6 +118,32 @@ _LAZY_EXPORTS: dict[str, str] = {
"multi_scale_energy_for_schedule": "core.physics.multi_scale_energy",
"multi_scale_energy_vector": "core.physics.multi_scale_energy",
"schedule_mid_span_fraction": "core.physics.multi_scale_energy",
# cognitive_lifecycle — ADR-0243 ingress→relaxation→egress (never serve)
"CognitiveLifecycleEngine": "core.physics.cognitive_lifecycle",
"CognitiveLifecycleError": "core.physics.cognitive_lifecycle",
"CrystallizationProposal": "core.physics.cognitive_lifecycle",
"EgressValidationError": "core.physics.cognitive_lifecycle",
"EgressVerdict": "core.physics.cognitive_lifecycle",
"HamiltonianCompileError": "core.physics.cognitive_lifecycle",
"IngressDegenerate": "core.physics.cognitive_lifecycle",
"IngressWavePacket": "core.physics.cognitive_lifecycle",
"LifecycleOutcome": "core.physics.cognitive_lifecycle",
"ProblemHamiltonian": "core.physics.cognitive_lifecycle",
"PropositionalEntailmentVerdict": "core.physics.cognitive_lifecycle",
"PropositionalProblem": "core.physics.cognitive_lifecycle",
"RelaxationCertificate": "core.physics.cognitive_lifecycle",
"RelaxationInputError": "core.physics.cognitive_lifecycle",
"RelaxationNotConverged": "core.physics.cognitive_lifecycle",
"RelaxationNumericalFailure": "core.physics.cognitive_lifecycle",
"RelaxationResult": "core.physics.cognitive_lifecycle",
"assignment_component_index": "core.physics.cognitive_lifecycle",
"compile_propositional": "core.physics.cognitive_lifecycle",
"compile_quadratic_well": "core.physics.cognitive_lifecycle",
"egress_gate": "core.physics.cognitive_lifecycle",
"ingest_context": "core.physics.cognitive_lifecycle",
"propositional_entails": "core.physics.cognitive_lifecycle",
"relax_to_ground": "core.physics.cognitive_lifecycle",
"uniform_assignment_state": "core.physics.cognitive_lifecycle",
}
from typing import TYPE_CHECKING
@ -153,6 +179,33 @@ if TYPE_CHECKING: # static-analysis only — never imported at runtime (serve q
multi_scale_energy_vector,
schedule_mid_span_fraction,
)
from core.physics.cognitive_lifecycle import (
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,
)
__all__ = [
"SalienceOperator", "SalienceMap", "FieldRegion",
@ -207,6 +260,31 @@ __all__ = [
"multi_scale_energy_for_schedule",
"multi_scale_energy_vector",
"schedule_mid_span_fraction",
"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",
]

View file

@ -0,0 +1,960 @@
"""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-1D-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 certificatestate 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 `` 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-1D-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",
]

View file

@ -104,6 +104,20 @@ prototype must **never** be ported verbatim (precedent: PR #52 sketch-defect pin
D-5; E3/E4 → readback-eligible). Ingress delegates to `sensorium_wave_feed` /
`WaveManifold` — no duplication. TDD; ground-state property test vs. direct
eigensolve; determinism digests.
- *Phase 2 verification record:* adversarial finder/verifier workflow over
the module (most verify agents were lost to a session limit; every
surviving finding was reproduced in-tree before acting). Two hardenings
landed beyond the plan text: (1) `RelaxationCertificate.psi_digest` binds
convergence evidence to the exact certified state and `egress_gate`
refuses borrowed certificates (`certificate_state_mismatch`) — closes a
false-provenance `CrystallizationProposal`; (2) certification additionally
requires the spectral gap be resolvable at the requested tolerance
(excited weight ≤ (Eλ0)/gap ≤ tol, refusal
`spectral_gap_below_tolerance`), and the degeneracy cluster is capped at
the acceptance window so the certificate reports the honest rate-limiting
gap — closes a zero-ground-overlap mis-certification reachable at loose
`tol`. Dense-branch refusals, the E2 hold route, iterate-collapse, and
hardcoded canonical entailment verdicts are pinned in tests.
- **Phase 3 — wiring lanes** (three independent PRs after Phase 2 API lands):
- **Lane A (§2.4; closes caveat 2):** wire `is_discovery_eligible` +
`cross_band_discovery_gate` into the contemplation runner's existing sink;

View file

@ -0,0 +1,662 @@
"""ADR-0243 §2 cognitive lifecycle — ingress → relaxation → egress (Tier-2).
Authority: docs/plans/adr-0243-implementation-plan.md §5 Phase 2.
Companion pins: tests/test_adr_0243_sketch_defect_pins.py (SD-A/SD-B/SD-C).
Gold is INDEPENDENT of the module under test: propositional truth is a
truth-table evaluator written here; ground states are cross-checked against
direct spectral projection. Deterministic fixtures only no random spinors.
"""
from __future__ import annotations
import ast
import hashlib
import json
import subprocess
import sys
from pathlib import Path
import numpy as np
import pytest
from algebra.cl41 import N_COMPONENTS
from algebra.rotor import make_rotor_from_angle
from core.physics.cognitive_lifecycle import (
CognitiveLifecycleEngine,
CognitiveLifecycleError,
CrystallizationProposal,
EgressValidationError,
HamiltonianCompileError,
IngressDegenerate,
ProblemHamiltonian,
PropositionalProblem,
RelaxationInputError,
RelaxationNotConverged,
RelaxationNumericalFailure,
assignment_component_index,
compile_propositional,
compile_quadratic_well,
egress_gate,
ingest_context,
propositional_entails,
relax_to_ground,
uniform_assignment_state,
)
from core.physics.sensorium_wave_feed import fake_deterministic_packet
from core.physics.wave_energy_boundary import crystallization_for_holographic_seal
from core.physics.wave_manifold import WaveManifold
_ROOT = Path(__file__).resolve().parents[1]
def _onehot(i: int) -> np.ndarray:
v = np.zeros(N_COMPONENTS, dtype=np.float64)
v[i] = 1.0
return v
def _unit(v: np.ndarray) -> np.ndarray:
return v / np.linalg.norm(v)
# --- Independent gold ---------------------------------------------------------
def _truth_table_counts(atoms, clauses) -> list[int]:
"""Clauses falsified per assignment mask — independent of the module."""
index = {a: i for i, a in enumerate(atoms)}
counts = []
for mask in range(1 << len(atoms)):
c = 0
for clause in clauses:
if not any(bool(mask >> index[a] & 1) == pol for a, pol in clause):
c += 1
counts.append(c)
return counts
def _entails_gold(atoms, premises, conclusion) -> bool:
"""Semantic entailment by truth table — independent of the module."""
index = {a: i for i, a in enumerate(atoms)}
for mask in range(1 << len(atoms)):
model = all(
any(bool(mask >> index[a] & 1) == pol for a, pol in clause)
for clause in premises
)
if model and not any(
bool(mask >> index[a] & 1) == pol for a, pol in conclusion
):
return False
return True
_ATOMS3 = ("a", "b", "c")
_PREMISES3 = (
(("a", True), ("b", True)),
(("a", False), ("c", True)),
(("b", False), ("c", True)),
)
# --- Blade lattice ↔ assignment lattice ----------------------------------------
def test_assignment_component_map_is_bijective_and_grade_consistent():
indices = [assignment_component_index(m) for m in range(32)]
assert sorted(indices) == list(range(32))
assert assignment_component_index(0) == 0 # ∅ ↔ scalar
for i in range(5):
assert assignment_component_index(1 << i) == 1 + i # {e_i} ↔ vector slot
assert assignment_component_index(0b11111) == 31 # full set ↔ pseudoscalar
def test_assignment_component_index_out_of_range_refused():
with pytest.raises(HamiltonianCompileError):
assignment_component_index(32)
# --- Ingress --------------------------------------------------------------------
def test_ingest_context_superposes_normalizes_and_digests():
packets = [
fake_deterministic_packet("audio", angle=0.3, plane=6),
fake_deterministic_packet("vision", angle=0.4, plane=7),
]
ingress = ingest_context(packets, "demo")
assert abs(float(np.linalg.norm(ingress.psi)) - 1.0) < 1e-12
assert ingress.modality_ids == ("audio", "vision")
again = ingest_context(packets, "demo")
assert ingress.packet_digest == again.packet_digest
assert np.array_equal(ingress.psi, again.psi)
with pytest.raises(ValueError):
ingress.psi[0] = 5.0 # frozen read-only field
def test_ingest_context_refuses_empty_and_degenerate():
with pytest.raises(ValueError):
ingest_context([], "demo") # delegation: superpose_packets refuses empty
p = fake_deterministic_packet("audio")
anti = {"modality_id": "anti", "coefficients": -p.coefficients}
with pytest.raises(IngressDegenerate):
ingest_context([p, anti], "demo") # destructive cancellation
with pytest.raises(IngressDegenerate):
ingest_context([p], " ") # empty domain id
# --- Hamiltonian compilers -------------------------------------------------------
def test_quadratic_well_spectrum_and_refusals():
target = _onehot(0)
ham = compile_quadratic_well(target, curvature=2.0)
evals, evecs = np.linalg.eigh(ham.matrix)
assert abs(evals[0]) < 1e-12
assert np.allclose(evals[1:], 2.0, atol=1e-12)
assert abs(abs(float(evecs[:, 0] @ target)) - 1.0) < 1e-9
with pytest.raises(HamiltonianCompileError):
compile_quadratic_well(2.0 * target) # non-unit target — no repair
with pytest.raises(HamiltonianCompileError):
compile_quadratic_well(target, curvature=0.0)
bad = target.copy()
bad[3] = np.nan
with pytest.raises(HamiltonianCompileError):
compile_quadratic_well(bad)
def test_problem_hamiltonian_validation_and_immutability():
asym = np.zeros((N_COMPONENTS, N_COMPONENTS))
asym[0, 1] = 1.0
with pytest.raises(HamiltonianCompileError):
ProblemHamiltonian(matrix=asym, domain="test")
with pytest.raises(HamiltonianCompileError):
ProblemHamiltonian(matrix=np.eye(16), domain="test") # wrong shape
nan_mat = np.eye(N_COMPONENTS)
nan_mat[4, 4] = np.nan
with pytest.raises(HamiltonianCompileError):
ProblemHamiltonian(matrix=nan_mat, domain="test")
ham = ProblemHamiltonian(matrix=np.eye(N_COMPONENTS), domain="test")
assert ham.is_diagonal
assert ham.hamiltonian_id
with pytest.raises(ValueError):
ham.matrix[0, 0] = 9.0 # read-only
dense = compile_quadratic_well(_unit(_onehot(0) + _onehot(6)))
assert not dense.is_diagonal
def test_propositional_diag_matches_independent_truth_table_gold():
problem = PropositionalProblem(atoms=_ATOMS3, clauses=_PREMISES3)
ham = compile_propositional(problem, penalty=1.0)
assert ham.is_diagonal
diag = np.diagonal(ham.matrix)
gold = _truth_table_counts(_ATOMS3, _PREMISES3)
mapped = set()
for mask, count in enumerate(gold):
idx = assignment_component_index(mask)
mapped.add(idx)
assert diag[idx] == float(count)
out_of_domain = 1.0 * (len(_PREMISES3) + 1)
for idx in set(range(N_COMPONENTS)) - mapped:
assert diag[idx] == out_of_domain
def test_propositional_problem_validation():
with pytest.raises(HamiltonianCompileError):
PropositionalProblem(atoms=("a",) * 6, clauses=()) # >5 and duplicate
with pytest.raises(HamiltonianCompileError):
PropositionalProblem(atoms=("a", "a"), clauses=())
with pytest.raises(HamiltonianCompileError):
PropositionalProblem(atoms=("a",), clauses=((),)) # empty clause
with pytest.raises(HamiltonianCompileError):
PropositionalProblem(atoms=("a",), clauses=((("z", True),),))
with pytest.raises(HamiltonianCompileError):
PropositionalProblem(atoms=("a",), clauses=((("a", True), ("a", True)),))
p1 = PropositionalProblem(atoms=("a", "b"), clauses=((("a", True),),))
p2 = PropositionalProblem(atoms=("a", "b"), clauses=((("b", True),),))
assert p1.problem_id and p1.problem_id != p2.problem_id
with pytest.raises(HamiltonianCompileError):
compile_propositional(p1, penalty=-1.0)
# --- Relaxation --------------------------------------------------------------------
def test_relaxation_decodes_quadratic_well_target_dense_path():
target = np.asarray(make_rotor_from_angle(0.3, bivector_idx=6), dtype=np.float64)
ham = compile_quadratic_well(target, curvature=1.0)
psi0 = _unit(target + 0.5 * _onehot(2) + 0.3 * _onehot(9))
result = relax_to_ground(psi0, ham)
cert = result.certificate
assert cert.converged and cert.reason == "ground_state_certified"
assert abs(cert.ground_energy) < 1e-9
assert abs(cert.spectral_gap - 1.0) < 1e-9
assert cert.steps_taken >= 1
# Independent gold: normalized spectral projection onto the ground space.
proj = target * float(target @ psi0)
gold = proj / np.linalg.norm(proj)
assert np.allclose(result.psi_steady, gold, atol=1e-6)
assert abs(abs(float(result.psi_steady @ target)) - 1.0) < 1e-8
def test_relaxation_decodes_propositional_model_set_uniform_start():
problem = PropositionalProblem(
atoms=("a", "b"),
clauses=((("a", True), ("b", True)), (("a", False), ("b", True))),
)
gold_counts = _truth_table_counts(problem.atoms, problem.clauses)
models = [m for m, c in enumerate(gold_counts) if c == 0]
assert models == [2, 3] # b=True with a free — independent check
ham = compile_propositional(problem)
result = relax_to_ground(uniform_assignment_state(problem), ham)
cert = result.certificate
assert cert.converged
assert cert.ground_energy == 0.0 # exact on the diagonal path
assert cert.spectral_gap == 1.0 # min nonzero falsification count × penalty
psi = result.psi_steady
model_components = {assignment_component_index(m) for m in models}
for idx in range(N_COMPONENTS):
if idx in model_components:
assert abs(abs(psi[idx]) - 1.0 / np.sqrt(2.0)) < 1e-9
else:
assert abs(psi[idx]) < 1e-9
def test_relaxation_degenerate_ground_preserves_input_weighting():
problem = PropositionalProblem(
atoms=("a", "b"),
clauses=((("a", True), ("b", True)), (("a", False), ("b", True))),
)
ham = compile_propositional(problem)
c2, c3 = assignment_component_index(2), assignment_component_index(3)
psi0 = np.zeros(N_COMPONENTS)
psi0[c2], psi0[c3] = 0.8, 0.6 # unit by construction
result = relax_to_ground(psi0, ham)
assert abs(abs(result.psi_steady[c2]) - 0.8) < 1e-9
assert abs(abs(result.psi_steady[c3]) - 0.6) < 1e-9
def test_relaxation_energy_is_monotone_nonincreasing():
target = np.asarray(make_rotor_from_angle(0.3, bivector_idx=6), dtype=np.float64)
psi0 = _unit(target + 0.5 * _onehot(2) + 0.3 * _onehot(9))
result = relax_to_ground(psi0, compile_quadratic_well(target))
assert result.certificate.energy_monotone
def test_relaxation_refuses_orthogonal_start_as_excited_eigenspace():
ham = compile_quadratic_well(_onehot(0), curvature=1.0)
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(_onehot(6), ham) # exactly orthogonal to the ground space
cert = exc_info.value.certificate
assert cert.reason == "excited_eigenspace"
assert not cert.converged
assert abs(cert.achieved_energy - 1.0) < 1e-9 # settled at the excited level
def test_relaxation_max_steps_exhaustion_and_nonconverged_return_path():
diag = np.ones(N_COMPONENTS)
diag[0], diag[1] = 0.0, 1e-6 # tiny gap — cannot converge in 3 steps
ham = ProblemHamiltonian(matrix=np.diag(diag), domain="tiny_gap")
psi0 = _unit(_onehot(0) + _onehot(1))
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(psi0, ham, max_steps=3)
assert exc_info.value.certificate.reason == "max_steps_exhausted"
result = relax_to_ground(psi0, ham, max_steps=3, require_converged=False)
assert not result.certificate.converged
def test_relaxation_input_refusals_fail_closed():
ham = compile_quadratic_well(_onehot(0))
with pytest.raises(RelaxationInputError):
relax_to_ground(0.5 * _onehot(0), ham) # non-unit ψ0 — no hidden repair
nan_psi = _onehot(0).copy()
nan_psi[7] = np.nan
with pytest.raises(RelaxationInputError):
relax_to_ground(nan_psi, ham)
with pytest.raises(RelaxationInputError):
relax_to_ground(_onehot(0), ham, dt=0.0)
with pytest.raises(RelaxationInputError):
relax_to_ground(_onehot(0), ham, max_steps=0)
with pytest.raises(RelaxationInputError):
relax_to_ground(_onehot(0), ham, tol=0.0)
def test_relaxation_refuses_unresolvable_spectral_gap_but_certifies_true_ground():
"""A gap below the requested tolerance must never mis-certify (audit F4a).
With gap 1e-7 and tol 1e-6 the energy window alone cannot separate ground
from first-excited: the pure excited e-state passed both legacy checks with
ZERO ground overlap. The excited-weight check refuses it while the TRUE
ground state (energy exactly λ0) still certifies under the same H and tol.
"""
diag = np.ones(N_COMPONENTS)
diag[0], diag[1] = 0.0, 1e-7
ham = ProblemHamiltonian(matrix=np.diag(diag), domain="sub_tol_gap")
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(_onehot(1), ham, tol=1e-6)
cert = exc_info.value.certificate
assert cert.reason == "spectral_gap_below_tolerance"
assert not cert.converged
assert cert.spectral_gap == 1e-7 # exact on the diagonal path
ground = relax_to_ground(_onehot(0), ham, tol=1e-6)
assert ground.certificate.converged
assert ground.certificate.reason == "ground_state_certified"
def test_relaxation_certificate_reports_rate_limiting_gap():
"""Cluster ⊆ acceptance window: the reported gap is the honest rate (audit F4b).
A 5e-10 split sat inside the old 1e-9 degeneracy cluster, so the refusal
certificate claimed gap=1.0 while the energy check refused that very level.
The cluster is now capped at the acceptance window, so the certificate
reports the true rate-limiting split.
"""
diag = np.ones(N_COMPONENTS)
diag[0], diag[1] = 0.0, 5e-10
ham = ProblemHamiltonian(matrix=np.diag(diag), domain="hairline_split")
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(_onehot(1), ham)
cert = exc_info.value.certificate
assert cert.reason == "excited_eigenspace"
assert cert.spectral_gap == 5e-10 # not the 1.0 the old cluster absorbed it into
def test_relaxation_dense_path_refusals_fail_closed():
"""The eigh/propagator branch must refuse honestly, not just decode happy paths.
A projection-returning mutant with a fabricated converged certificate
passed the suite when refusals were exercised only on the diagonal branch
(audit F2a) these two pin the dense branch's refusal mechanics.
"""
target = np.asarray(make_rotor_from_angle(0.3, bivector_idx=6), dtype=np.float64)
slow = compile_quadratic_well(target, curvature=1e-6)
assert not slow.is_diagonal
psi0 = _unit(target + 0.5 * _onehot(2))
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(psi0, slow, max_steps=3)
assert exc_info.value.certificate.reason == "max_steps_exhausted"
well = compile_quadratic_well(target, curvature=1.0)
assert not well.is_diagonal
with pytest.raises(RelaxationNotConverged) as exc_info:
relax_to_ground(_onehot(2), well, max_steps=8) # e2 ⊥ span(scalar, biv6)
cert = exc_info.value.certificate
assert cert.reason == "excited_eigenspace"
assert not cert.converged
def test_relaxation_iterate_collapse_raises_numerical_failure():
"""Underflow of every surviving component is a typed failure, not a repair."""
diag = np.ones(N_COMPONENTS)
diag[0] = 0.0
ham = ProblemHamiltonian(matrix=np.diag(diag), domain="collapse")
psi0 = np.zeros(N_COMPONENTS)
psi0[0], psi0[1] = 1e-13, 1.0 # ground weight below _NEAR_ZERO after one decay
with pytest.raises(RelaxationNumericalFailure) as exc_info:
relax_to_ground(_unit(psi0), ham, dt=100.0)
assert exc_info.value.reason == "iterate_collapsed"
def test_relaxation_is_bit_deterministic():
target = np.asarray(make_rotor_from_angle(0.3, bivector_idx=6), dtype=np.float64)
ham = compile_quadratic_well(target)
psi0 = _unit(target + 0.5 * _onehot(2))
r1 = relax_to_ground(psi0, ham)
r2 = relax_to_ground(psi0, ham)
assert np.array_equal(r1.psi_steady, r2.psi_steady)
assert r1.certificate.certificate_id == r2.certificate.certificate_id
# --- Propositional verdicts (exact spectrum path) -----------------------------------
@pytest.mark.parametrize(
"conclusion",
[
(("c", True),),
(("a", True),),
(("a", True), ("b", True)),
(("b", False),),
],
)
def test_entailment_matches_independent_truth_table_gold(conclusion):
premises = PropositionalProblem(atoms=_ATOMS3, clauses=_PREMISES3)
verdict = propositional_entails(premises, conclusion)
assert verdict.entailed == _entails_gold(_ATOMS3, _PREMISES3, conclusion)
assert verdict.satisfiable_premises # these premises have models
assert verdict.verdict_id
def test_entailment_hardcoded_canonical_verdicts():
"""Hand-verified verdicts, hardcoded — no shared code shape with the module.
The truth-table gold above uses the same literal-evaluation idiom as the
compiler (audit F2e), so these canonical cases pin absolute truth values.
"""
mp = PropositionalProblem(
atoms=("p", "q"),
clauses=((("p", False), ("q", True)), (("p", True),)), # p→q, p
)
assert propositional_entails(mp, (("q", True),)).entailed is True # modus ponens
assert propositional_entails(mp, (("q", False),)).entailed is False
disj = PropositionalProblem(atoms=("p", "q"), clauses=((("p", True), ("q", True)),))
assert propositional_entails(disj, (("p", True),)).entailed is False # pq ⊭ p
chain = PropositionalProblem(
atoms=("p", "q", "r"),
clauses=(
(("p", False), ("q", True)), # p→q
(("q", False), ("r", True)), # q→r
(("p", True),),
),
)
verdict = propositional_entails(chain, (("r", True),))
assert verdict.entailed is True # hypothetical syllogism
assert verdict.satisfiable_premises is True
def test_entailment_vacuous_from_unsat_premises_is_disclosed():
premises = PropositionalProblem(
atoms=("a",), clauses=((("a", True),), (("a", False),))
)
verdict = propositional_entails(premises, (("a", True),))
assert verdict.entailed
assert not verdict.satisfiable_premises # ex falso — disclosed, not hidden
assert verdict.ground_energy_premises > 0.0
def test_entailment_refuses_unknown_atom_and_empty_conclusion():
premises = PropositionalProblem(atoms=("a",), clauses=((("a", True),),))
with pytest.raises(HamiltonianCompileError):
propositional_entails(premises, (("z", True),))
with pytest.raises(HamiltonianCompileError):
propositional_entails(premises, ())
# --- Egress ---------------------------------------------------------------------------
def _crystalline_outcome():
engine = CognitiveLifecycleEngine()
target = np.asarray(make_rotor_from_angle(0.3, bivector_idx=6), dtype=np.float64)
ham = compile_quadratic_well(target)
packets = [fake_deterministic_packet("audio", angle=0.25, plane=6)]
return engine, engine.solve(packets, "crystal-demo", ham)
def test_egress_routes_cold_closed_versor_to_crystallization_proposal():
_engine, outcome = _crystalline_outcome()
verdict = outcome.verdict
assert verdict.admitted and verdict.reason == "admitted"
assert verdict.versor_closed
assert verdict.energy_class.vault_candidate
assert verdict.route == "crystallization_proposal"
proposal = verdict.proposal
assert proposal is not None
assert proposal.epistemic_status == "SPECULATIVE"
assert proposal.certificate_id == outcome.relaxation.certificate.certificate_id
assert proposal.decision.may_speculative_seal
json.dumps(proposal.as_dict()) # JSON-serializable artifact
def test_egress_routes_hot_state_to_readback_eligible():
_engine, outcome = _crystalline_outcome()
verdict = egress_gate(
outcome.relaxation.psi_steady,
outcome.relaxation.certificate,
convergence_density=8,
activation_count=8,
current_cycle=1,
last_activation_cycle=1,
morphology_features={"mood": "imperative"},
)
assert verdict.admitted
assert verdict.energy_class.value in ("E3", "E4")
assert verdict.route == "readback_eligible"
assert verdict.proposal is None
def test_egress_holds_cold_open_superposition_without_proposal():
problem = PropositionalProblem(
atoms=("a", "b"),
clauses=((("a", True), ("b", True)), (("a", False), ("b", True))),
)
result = relax_to_ground(uniform_assignment_state(problem), compile_propositional(problem))
verdict = egress_gate(result.psi_steady, result.certificate)
assert verdict.admitted
assert not verdict.versor_closed # interference state, not a versor
assert verdict.energy_class.vault_candidate
assert verdict.route == "hold" # cold but not crystalline: no proposal
assert verdict.proposal is None
def test_egress_refuses_unnormalized_and_uncertified_states():
_engine, outcome = _crystalline_outcome()
cert = outcome.relaxation.certificate
scaled = 0.5 * outcome.relaxation.psi_steady
verdict = egress_gate(scaled, cert)
assert not verdict.admitted and verdict.route == "refused"
assert verdict.reason == "amplitude_density_not_unit"
diag = np.ones(N_COMPONENTS)
diag[0], diag[1] = 0.0, 1e-6
slow = ProblemHamiltonian(matrix=np.diag(diag), domain="tiny_gap")
nonconv = relax_to_ground(
_unit(_onehot(0) + _onehot(1)), slow, max_steps=3, require_converged=False
)
verdict2 = egress_gate(nonconv.psi_steady, nonconv.certificate)
assert not verdict2.admitted and verdict2.route == "refused"
assert verdict2.reason.startswith("relaxation_not_certified")
bad = outcome.relaxation.psi_steady.copy()
bad[3] = np.inf
with pytest.raises(EgressValidationError):
egress_gate(bad, cert)
with pytest.raises(EgressValidationError):
egress_gate(np.zeros(16), cert) # wrong shape — malformed, not refused
def test_egress_refuses_certificate_not_bound_to_state():
"""A borrowed converged certificate must not admit a foreign ψ (audit A).
Before the binding, any unit state paired with any converged certificate
was admitted and could emit a CrystallizationProposal whose psi_digest and
certificate_id asserted a provenance that never existed.
"""
_engine, outcome = _crystalline_outcome()
psi = outcome.relaxation.psi_steady
cert = outcome.relaxation.certificate
# Independent gold for the binding: byte digest of the certified state.
gold_digest = hashlib.sha256(
np.ascontiguousarray(psi, dtype=np.float64).tobytes()
).hexdigest()[:24]
assert cert.psi_digest == gold_digest
assert cert.as_dict()["psi_digest"] == gold_digest
foreign = np.asarray(make_rotor_from_angle(1.1, bivector_idx=8), dtype=np.float64)
verdict = egress_gate(foreign, cert) # unit closed versor, never relaxed
assert not verdict.admitted
assert verdict.reason == "certificate_state_mismatch"
assert verdict.route == "refused"
assert verdict.proposal is None
def test_egress_holds_e2_midband_without_proposal():
"""The E2 else-branch routes to hold — neither vault-cold nor readback-hot."""
_engine, outcome = _crystalline_outcome()
verdict = egress_gate(
outcome.relaxation.psi_steady,
outcome.relaxation.certificate,
convergence_density=8,
morphology_features={"aspect": "qatal"},
)
assert verdict.admitted
assert verdict.energy_class.value == "E2"
assert not verdict.energy_class.vault_candidate
assert verdict.route == "hold"
assert verdict.proposal is None
def test_crystallization_proposal_type_pins_speculative_status():
rotor = np.asarray(make_rotor_from_angle(0.2, bivector_idx=6), dtype=np.float64)
decision = crystallization_for_holographic_seal(rotor)
with pytest.raises(CognitiveLifecycleError):
CrystallizationProposal(
proposal_id="crystal-x",
epistemic_status="COHERENT", # forbidden by the type itself (I-03)
psi_digest="d",
certificate_id="c",
decision=decision,
)
def test_composed_lifecycle_outcome_is_deterministic():
_e1, o1 = _crystalline_outcome()
_e2, o2 = _crystalline_outcome()
assert o1.outcome_id == o2.outcome_id
assert np.array_equal(o1.relaxation.psi_steady, o2.relaxation.psi_steady)
# --- Quarantine / structural pins -----------------------------------------------------
def test_module_imports_no_vault_surface():
"""I-03 structural pin: the lifecycle can propose, never touch a vault."""
src = (_ROOT / "core/physics/cognitive_lifecycle.py").read_text()
tree = ast.parse(src)
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
assert "vault" not in alias.name, alias.name
if isinstance(node, ast.ImportFrom) and node.module:
assert "vault" not in node.module, node.module
def test_barrel_export_is_lazy_and_resolves():
probe = (
"import sys;"
"import core.physics;"
"assert 'core.physics.cognitive_lifecycle' not in sys.modules, 'eager load';"
"core.physics.CognitiveLifecycleEngine;"
"assert 'core.physics.cognitive_lifecycle' in sys.modules;"
"print('ok')"
)
result = subprocess.run(
[sys.executable, "-c", probe],
cwd=str(_ROOT),
capture_output=True,
text=True,
env={"PYTHONPATH": str(_ROOT), "PATH": ""},
)
assert result.returncode == 0, result.stderr[-2000:]
assert result.stdout.strip().endswith("ok")
def test_versor_closure_of_steady_state_reported_via_wave_manifold():
"""Egress residual is the canonical WaveManifold measurement, not a fork."""
_engine, outcome = _crystalline_outcome()
manifold = WaveManifold()
assert outcome.verdict.versor_residual == pytest.approx(
manifold.measure_unitary_residual(outcome.relaxation.psi_steady), abs=0.0
)

View file

@ -28,6 +28,7 @@ _BANNED = (
"core.physics.wave_energy_boundary",
"core.physics.multi_scale_energy",
"core.physics.sensorium_wave_feed",
"core.physics.cognitive_lifecycle", # ADR-0243 lifecycle — never serve
# NOTE: core.physics.wave_manifold is intentionally excluded pending the
# Joshua design ruling (goldtether delegates to it). Add it here if the
# ruling is "quarantine wave_manifold for real".

View file

@ -70,6 +70,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
"wave_energy_boundary", # P10 Trace B — energy/τ gate, never serve
"multi_scale_energy", # ADR-0242 V2 research multi-band E_n(t), never serve
"sensorium_wave_feed", # D7 I-04 sensorium→ψ feed, never serve
"cognitive_lifecycle", # ADR-0243 ingress→relaxation→egress, never serve
}
banned_substrings = (
"holographic_vault",
@ -80,6 +81,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
"wave_energy_boundary",
"multi_scale_energy",
"sensorium_wave_feed",
"cognitive_lifecycle",
)
for node in ast.walk(tree):
if isinstance(node, ast.Import):