feat(wave): P10 Trace B energy boundary + multi-scale Fibonacci τ

Land ADR-0241 cohesion package P10:
- core/physics/wave_energy_boundary.py wires WaveManifold unitary residual
  into energy profiles and trajectory energy gates (no free-floating residual).
- fibonacci_tau_schedule: τ_n = F_n · τ_0 constants table + recency bands.
- crystallization_for_holographic_seal: E0–E1 + closed residual may
  SPECULATIVE-seal; dirty residual or hot classes refuse.
- Public fibonacci_number; serve quarantine includes wave_energy_boundary.
- Fidelity + ADR-0241 status updated.

Lane: pytest tests/test_adr_0241_wave_energy_boundary.py
      tests/test_adr_0242_fibonacci.py tests/test_energy.py
      tests/test_third_door_cohesion.py → green.
This commit is contained in:
Shay 2026-07-14 18:39:01 -07:00
parent aa86f1ae35
commit f123e0ea75
7 changed files with 401 additions and 2 deletions

View file

@ -82,6 +82,16 @@ from core.physics.holographic_vault import (
HolographicVaultStore,
SealedMode,
)
from core.physics.wave_energy_boundary import (
CrystallizationDecision,
assess_wave_trajectory,
crystallization_for_holographic_seal,
energy_profile_from_wave,
fibonacci_tau_schedule,
recency_band_index,
wave_unitary_residual,
)
from core.physics.fibonacci_search import fibonacci_number
__all__ = [
"SalienceOperator", "SalienceMap", "FieldRegion",
@ -116,4 +126,12 @@ __all__ = [
"assess_trajectory", "energy_boundary_ok",
"relative_holonomy", "trajectory_divergence",
"HolographicVaultError", "HolographicVaultStore", "SealedMode",
"CrystallizationDecision",
"assess_wave_trajectory",
"crystallization_for_holographic_seal",
"energy_profile_from_wave",
"fibonacci_tau_schedule",
"recency_band_index",
"wave_unitary_residual",
"fibonacci_number",
]

View file

@ -41,7 +41,7 @@ class SearchTrace:
certificate: dict = field(default_factory=dict)
def _fibonacci(n: int) -> int:
def fibonacci_number(n: int) -> int:
"""F_0=0, F_1=1, … standard Fibonacci. n may be 0."""
if n < 0:
raise ValueError("fibonacci index must be non-negative")
@ -51,6 +51,11 @@ def _fibonacci(n: int) -> int:
return a
def _fibonacci(n: int) -> int:
"""Internal alias — prefer :func:`fibonacci_number` at call sites."""
return fibonacci_number(n)
def _assert_sampled_unimodality(eval_values: dict[float, float]) -> None:
"""Fail-closed if sorted samples are not unimodal about the observed min."""
sorted_points = sorted(eval_values.keys())
@ -168,6 +173,8 @@ def fibonacci_section_search(
__all__ = [
"fibonacci_number",
"BoundedUnimodalObjective",
"SearchTrace",
"fibonacci_section_search",

View file

@ -0,0 +1,219 @@
"""P10 Trace B — wave unitary residual → energy boundary + multi-scale τ.
ADR-0241 cohesion package P10:
1. **Wire wave residual into energy / trajectory gates** coherence is not a
free-floating float; it is :meth:`WaveManifold.measure_unitary_residual`.
2. **Multi-scale recency** ``τ_n = F_n · τ_0`` as a constants table (not dogma).
3. **Crystallization E0E1 holographic seal policy** only low-energy
classes with closed residual may SPECULATIVE-seal; COHERENT still requires
authorized teaching review outside this module.
Serve path remains quarantined (no import from ``chat/runtime.py``).
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Sequence
import numpy as np
from core.physics.energy import EnergyClass, EnergyProfile, FieldEnergyOperator
from core.physics.fibonacci_search import fibonacci_number
from core.physics.trajectory_invariants import (
TrajectoryAssessment,
assess_trajectory,
)
from core.physics.wave_manifold import WaveManifold
_DEFAULT_EPSILON_DRIFT = 1e-6
_DEFAULT_TAU0 = 1.0
def wave_unitary_residual(
psi: np.ndarray,
*,
manifold: WaveManifold | None = None,
epsilon_drift: float = _DEFAULT_EPSILON_DRIFT,
) -> float:
"""Unitary residual ‖ψ~ψ 1‖_F dual-checked via WaveManifold."""
m = manifold if manifold is not None else WaveManifold(epsilon_drift=epsilon_drift)
return float(m.measure_unitary_residual(psi))
def energy_profile_from_wave(
psi: np.ndarray,
*,
operator: FieldEnergyOperator | None = None,
manifold: WaveManifold | None = None,
epsilon_drift: float = _DEFAULT_EPSILON_DRIFT,
**compute_kwargs: object,
) -> EnergyProfile:
"""Build an EnergyProfile with coherence_residual from the wave field.
Structural axes (convergence, activation, aspect) remain caller-supplied;
residual is never invented it is measured on ψ.
"""
residual = wave_unitary_residual(
psi, manifold=manifold, epsilon_drift=epsilon_drift
)
op = operator if operator is not None else FieldEnergyOperator()
# FieldEnergyOperator.compute takes coherence_residual as float kwarg.
kwargs = dict(compute_kwargs)
kwargs["coherence_residual"] = residual
return op.compute(**kwargs) # type: ignore[arg-type]
def assess_wave_trajectory(
versors: Sequence[np.ndarray],
*,
eps_trajectory: float = 1e-5,
kappa: float = 1.0,
dt: float = 1.0,
epsilon_drift: float = _DEFAULT_EPSILON_DRIFT,
manifold: WaveManifold | None = None,
) -> TrajectoryAssessment:
"""Trajectory gate with exertion energy from max wave unitary residual.
``E_exertion`` = max residual along the path.
``E_sensory`` = ``epsilon_drift`` (GoldTether-scale sensory budget).
Closed unit paths stay under the boundary when residual κ · ε.
"""
if not versors:
# Delegate fail-closed empty handling to trajectory_invariants.
return assess_trajectory(
versors,
E_exertion=0.0,
E_sensory=float(epsilon_drift),
eps_trajectory=eps_trajectory,
kappa=kappa,
dt=dt,
)
residuals = [
wave_unitary_residual(v, manifold=manifold, epsilon_drift=epsilon_drift)
for v in versors
]
e_exertion = float(max(residuals))
e_sensory = float(epsilon_drift)
return assess_trajectory(
versors,
E_exertion=e_exertion,
E_sensory=e_sensory,
eps_trajectory=eps_trajectory,
kappa=kappa,
dt=dt,
)
def fibonacci_tau_schedule(
tau0: float = _DEFAULT_TAU0,
*,
levels: int = 8,
) -> tuple[float, ...]:
"""Multi-scale recency hierarchy τ_n = F_n · τ_0 for n = 1..levels.
Constants table only not a runtime dogma. F_1=1, F_2=1, F_3=2,
"""
t0 = float(tau0)
if not (t0 > 0.0) or t0 != t0: # NaN check via !=
raise ValueError("tau0 must be a positive finite scalar")
n = int(levels)
if n < 1:
raise ValueError("levels must be >= 1")
return tuple(float(fibonacci_number(i) * t0) for i in range(1, n + 1))
def recency_band_index(age: float, taus: Sequence[float]) -> int:
"""Smallest band index with age ≤ τ_n, or ``len(taus)`` if beyond schedule."""
a = float(age)
if a < 0.0:
raise ValueError("age must be non-negative")
for i, tau in enumerate(taus):
if a <= float(tau) + 1e-15:
return i
return len(taus)
@dataclass(frozen=True, slots=True)
class CrystallizationDecision:
"""E0E1 crystallization gate aligned with holographic SPECULATIVE seal policy."""
energy: EnergyProfile
unitary_residual: float
vault_candidate: bool
residual_closed: bool
may_speculative_seal: bool
reason: str
epsilon_drift: float
def as_dict(self) -> dict[str, object]:
return {
"energy_class": self.energy.energy_class.value,
"unitary_residual": self.unitary_residual,
"vault_candidate": self.vault_candidate,
"residual_closed": self.residual_closed,
"may_speculative_seal": self.may_speculative_seal,
"reason": self.reason,
"epsilon_drift": self.epsilon_drift,
}
def crystallization_for_holographic_seal(
psi: np.ndarray,
*,
epsilon_drift: float = _DEFAULT_EPSILON_DRIFT,
manifold: WaveManifold | None = None,
operator: FieldEnergyOperator | None = None,
**energy_kwargs: object,
) -> CrystallizationDecision:
"""Decide whether ψ may enter the SPECULATIVE holographic seal path.
Policy (Trace B Trace A):
* residual must be closed ( epsilon_drift) fail-closed, no repair
* energy class must be vault_candidate (E0/E1)
* both required for ``may_speculative_seal``
COHERENT promotion is never authorized here.
"""
residual = wave_unitary_residual(
psi, manifold=manifold, epsilon_drift=epsilon_drift
)
energy = energy_profile_from_wave(
psi,
operator=operator,
manifold=manifold,
epsilon_drift=epsilon_drift,
**energy_kwargs,
)
vault = bool(energy.energy_class.vault_candidate)
closed = bool(residual <= float(epsilon_drift))
may_seal = vault and closed
if may_seal:
reason = "e0_e1_closed_residual_speculative_seal_ok"
elif not closed:
reason = "residual_not_closed"
elif not vault:
reason = "energy_class_not_vault_candidate"
else:
reason = "refused"
return CrystallizationDecision(
energy=energy,
unitary_residual=residual,
vault_candidate=vault,
residual_closed=closed,
may_speculative_seal=may_seal,
reason=reason,
epsilon_drift=float(epsilon_drift),
)
__all__ = [
"CrystallizationDecision",
"assess_wave_trajectory",
"crystallization_for_holographic_seal",
"energy_profile_from_wave",
"fibonacci_tau_schedule",
"recency_band_index",
"wave_unitary_residual",
]

View file

@ -1,6 +1,6 @@
# ADR-0241: Wave-Field Driven Hyperbolic Atlas and Resonant Algebraic Cognition
**Status**: Proposed — substrate + entity suite + ADR-0242 packing/Fibonacci + P9 Trace A wave_seam (SPECULATIVE holographic seal / hypothesis-vs-evidence reconstruct); remaining cohesion packages P10 energy + P12 governance; acceptance path: Joshua review
**Status**: Proposed — substrate + entity suite + ADR-0242 packing/Fibonacci + P9 Trace A wave_seam + P10 Trace B wave_energy_boundary (residual→energy/τ/crystallization); remaining cohesion package P12 governance (+ optional P11 Rust); acceptance path: Joshua review
**Date**: 2026-07-13
**Deciders**: Joshua Shay + multi-model R&D
**Traceability**: Issue #14, parent #10

View file

@ -302,6 +302,7 @@ PY
| Golden-Angle atlas packing \(d_{\min}=0.12\) | 🟢 ADR-0242 (`atlas_packing`; CGA null-point \(d\)) |
| Fibonacci κ search | 🟢 ADR-0242 (`fibonacci_search`) |
| Contemplation Trace A SPECULATIVE holographic seal (P9) | 🟢 `core/contemplation/wave_seam.py` (hypothesis vs COHERENT evidence) |
| Energy boundary + multi-scale τ (P10 Trace B) | 🟢 `wave_energy_boundary` (wave residual → energy/trajectory; τ_n=F_n·τ_0; E0E1 crystallization) |
### Subsumption map (Slice 23)
| Operator | Delegation |
@ -337,6 +338,7 @@ PY
| Durable holographic vault spectrum — 🟢 HolographicVaultStore | ADR-0241 |
| Entity cohesion I-01…I-05 + Trace A/B | cohesion master plan |
| Contemplation Trace A SPECULATIVE seal (P9) — 🟢 wave_seam | ADR-0241 P9 |
| Energy boundary + multi-scale τ (P10) — 🟢 wave_energy_boundary | ADR-0241 P10 |
| Atlas packing + Fibonacci κ (ADR-0242) — 🟢 packing + search | PR #37 / ADR-0242 |
Closing a gap = flip its `xfail` in `tests/test_third_door_blueprint_fidelity.py` (or the ADR-0241 / cohesion suite) to a passing behavioral test and delete the matching characterization lock. That is the definition of "done right" here.

View file

@ -0,0 +1,151 @@
"""P10 Trace B — wave residual → energy boundary + Fibonacci τ + crystallization.
ADR-0241 cohesion package P10:
* Unitary residual from WaveManifold feeds energy / trajectory gates.
* Multi-scale recency τ_n = F_n · τ_0 is a constants table (not dogma).
* E0E1 crystallization + closed residual may SPECULATIVE-seal; else refuse.
* Serve remains quarantined from this module.
"""
from __future__ import annotations
import ast
from pathlib import Path
import numpy as np
import pytest
from algebra.rotor import make_rotor_from_angle
from core.physics.energy import EnergyClass
from core.physics.wave_energy_boundary import (
CrystallizationDecision,
assess_wave_trajectory,
crystallization_for_holographic_seal,
energy_profile_from_wave,
fibonacci_tau_schedule,
recency_band_index,
wave_unitary_residual,
)
from core.physics.trajectory_invariants import TrajectoryInvariantError
_ROOT = Path(__file__).resolve().parents[1]
def _closed(angle: float = 0.3, plane: int = 6) -> np.ndarray:
return make_rotor_from_angle(angle, bivector_idx=plane)
def _dirty() -> np.ndarray:
v = np.zeros(32, dtype=np.float64)
v[0] = 0.5
v[1] = 0.5
return v
# --- Wave residual wiring ---------------------------------------------------
def test_wave_unitary_residual_closed_under_eps():
r = wave_unitary_residual(_closed(0.25))
assert r < 1e-6
def test_wave_unitary_residual_dirty_above_eps():
r = wave_unitary_residual(_dirty())
assert r > 1e-6
def test_energy_profile_from_wave_uses_residual():
profile = energy_profile_from_wave(_closed(0.1))
assert profile.coherence_residual < 1e-6
# Low residual + defaults → crystallizable class (E0/E1).
assert profile.energy_class in {EnergyClass.E0, EnergyClass.E1}
def test_energy_profile_from_wave_high_residual_feeds_raw():
profile = energy_profile_from_wave(_dirty())
# Operator clamps residual into [0,1] for the scalar mix.
assert profile.coherence_residual > 0.0
def test_assess_wave_trajectory_closed_path_energy_ok():
steps = [_closed(0.1 * i, plane=6) for i in range(1, 5)]
assessment = assess_wave_trajectory(steps)
assert assessment.energy_ok is True
assert assessment.n_steps == 4
assert assessment.within_replay_bound is True
def test_assess_wave_trajectory_refuses_empty():
with pytest.raises(TrajectoryInvariantError):
assess_wave_trajectory([])
# --- Fibonacci multi-scale τ ------------------------------------------------
def test_fibonacci_tau_schedule_matches_F_n_tau0():
# F_1=1, F_2=1, F_3=2, F_4=3, F_5=5
taus = fibonacci_tau_schedule(tau0=0.5, levels=5)
assert taus == (0.5, 0.5, 1.0, 1.5, 2.5)
def test_fibonacci_tau_schedule_rejects_bad_inputs():
with pytest.raises(ValueError):
fibonacci_tau_schedule(tau0=0.0, levels=3)
with pytest.raises(ValueError):
fibonacci_tau_schedule(tau0=1.0, levels=0)
def test_recency_band_index_progressive():
taus = fibonacci_tau_schedule(tau0=1.0, levels=5) # 1,1,2,3,5
assert recency_band_index(0.5, taus) == 0
assert recency_band_index(1.0, taus) == 0
assert recency_band_index(1.5, taus) == 2
assert recency_band_index(10.0, taus) == len(taus) # beyond schedule
# --- Crystallization ↔ holographic seal policy ------------------------------
def test_crystallization_closed_e0_may_speculative_seal():
decision = crystallization_for_holographic_seal(_closed(0.12))
assert isinstance(decision, CrystallizationDecision)
assert decision.residual_closed is True
assert decision.vault_candidate is True
assert decision.may_speculative_seal is True
assert decision.energy.energy_class.vault_candidate is True
def test_crystallization_dirty_refuses_seal():
decision = crystallization_for_holographic_seal(_dirty())
assert decision.residual_closed is False
assert decision.may_speculative_seal is False
def test_crystallization_high_activity_not_vault_candidate():
# Force E3/E4 via structural inputs while residual stays closed.
decision = crystallization_for_holographic_seal(
_closed(0.05),
convergence_density=20,
activation_count=20,
current_cycle=1,
last_activation_cycle=1,
anchor_adjacent=True,
)
assert decision.residual_closed is True
assert decision.vault_candidate is False
assert decision.may_speculative_seal is False
# --- Serve quarantine -------------------------------------------------------
def test_serve_runtime_does_not_import_wave_energy_boundary():
tree = ast.parse((_ROOT / "chat/runtime.py").read_text(encoding="utf-8"))
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom) and node.module:
assert "wave_energy_boundary" not in node.module
if isinstance(node, ast.Import):
for alias in node.names:
assert "wave_energy_boundary" not in alias.name

View file

@ -62,6 +62,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
"fibonacci_search",
"atlas_packing",
"wave_seam", # P9 Trace A — contemplation only, never serve
"wave_energy_boundary", # P10 Trace B — energy/τ gate, never serve
}
banned_substrings = (
"wave_manifold",
@ -69,6 +70,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
"fibonacci_search",
"atlas_packing",
"wave_seam",
"wave_energy_boundary",
)
for node in ast.walk(tree):
if isinstance(node, ast.Import):