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:
parent
340f5dd3a5
commit
2d8f0e910d
7 changed files with 401 additions and 2 deletions
|
|
@ -82,6 +82,16 @@ from core.physics.holographic_vault import (
|
||||||
HolographicVaultStore,
|
HolographicVaultStore,
|
||||||
SealedMode,
|
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__ = [
|
__all__ = [
|
||||||
"SalienceOperator", "SalienceMap", "FieldRegion",
|
"SalienceOperator", "SalienceMap", "FieldRegion",
|
||||||
|
|
@ -116,4 +126,12 @@ __all__ = [
|
||||||
"assess_trajectory", "energy_boundary_ok",
|
"assess_trajectory", "energy_boundary_ok",
|
||||||
"relative_holonomy", "trajectory_divergence",
|
"relative_holonomy", "trajectory_divergence",
|
||||||
"HolographicVaultError", "HolographicVaultStore", "SealedMode",
|
"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",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class SearchTrace:
|
||||||
certificate: dict = field(default_factory=dict)
|
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."""
|
"""F_0=0, F_1=1, … standard Fibonacci. n may be 0."""
|
||||||
if n < 0:
|
if n < 0:
|
||||||
raise ValueError("fibonacci index must be non-negative")
|
raise ValueError("fibonacci index must be non-negative")
|
||||||
|
|
@ -51,6 +51,11 @@ def _fibonacci(n: int) -> int:
|
||||||
return a
|
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:
|
def _assert_sampled_unimodality(eval_values: dict[float, float]) -> None:
|
||||||
"""Fail-closed if sorted samples are not unimodal about the observed min."""
|
"""Fail-closed if sorted samples are not unimodal about the observed min."""
|
||||||
sorted_points = sorted(eval_values.keys())
|
sorted_points = sorted(eval_values.keys())
|
||||||
|
|
@ -168,6 +173,8 @@ def fibonacci_section_search(
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"fibonacci_number",
|
||||||
|
|
||||||
"BoundedUnimodalObjective",
|
"BoundedUnimodalObjective",
|
||||||
"SearchTrace",
|
"SearchTrace",
|
||||||
"fibonacci_section_search",
|
"fibonacci_section_search",
|
||||||
|
|
|
||||||
219
core/physics/wave_energy_boundary.py
Normal file
219
core/physics/wave_energy_boundary.py
Normal 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 E0–E1 → 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:
|
||||||
|
"""E0–E1 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",
|
||||||
|
]
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# ADR-0241: Wave-Field Driven Hyperbolic Atlas and Resonant Algebraic Cognition
|
# 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
|
**Date**: 2026-07-13
|
||||||
**Deciders**: Joshua Shay + multi-model R&D
|
**Deciders**: Joshua Shay + multi-model R&D
|
||||||
**Traceability**: Issue #14, parent #10
|
**Traceability**: Issue #14, parent #10
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,7 @@ PY
|
||||||
| Golden-Angle atlas packing \(d_{\min}=0.12\) | 🟢 ADR-0242 (`atlas_packing`; CGA null-point \(d\)) |
|
| Golden-Angle atlas packing \(d_{\min}=0.12\) | 🟢 ADR-0242 (`atlas_packing`; CGA null-point \(d\)) |
|
||||||
| Fibonacci κ search | 🟢 ADR-0242 (`fibonacci_search`) |
|
| Fibonacci κ search | 🟢 ADR-0242 (`fibonacci_search`) |
|
||||||
| Contemplation Trace A SPECULATIVE holographic seal (P9) | 🟢 `core/contemplation/wave_seam.py` (hypothesis vs COHERENT evidence) |
|
| 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; E0–E1 crystallization) |
|
||||||
|
|
||||||
### Subsumption map (Slice 2–3)
|
### Subsumption map (Slice 2–3)
|
||||||
| Operator | Delegation |
|
| Operator | Delegation |
|
||||||
|
|
@ -337,6 +338,7 @@ PY
|
||||||
| Durable holographic vault spectrum — 🟢 HolographicVaultStore | ADR-0241 |
|
| Durable holographic vault spectrum — 🟢 HolographicVaultStore | ADR-0241 |
|
||||||
| Entity cohesion I-01…I-05 + Trace A/B | cohesion master plan |
|
| Entity cohesion I-01…I-05 + Trace A/B | cohesion master plan |
|
||||||
| Contemplation Trace A SPECULATIVE seal (P9) — 🟢 wave_seam | ADR-0241 P9 |
|
| 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 |
|
| 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.
|
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.
|
||||||
|
|
|
||||||
151
tests/test_adr_0241_wave_energy_boundary.py
Normal file
151
tests/test_adr_0241_wave_energy_boundary.py
Normal 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).
|
||||||
|
* E0–E1 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
|
||||||
|
|
@ -62,6 +62,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
|
||||||
"fibonacci_search",
|
"fibonacci_search",
|
||||||
"atlas_packing",
|
"atlas_packing",
|
||||||
"wave_seam", # P9 Trace A — contemplation only, never serve
|
"wave_seam", # P9 Trace A — contemplation only, never serve
|
||||||
|
"wave_energy_boundary", # P10 Trace B — energy/τ gate, never serve
|
||||||
}
|
}
|
||||||
banned_substrings = (
|
banned_substrings = (
|
||||||
"wave_manifold",
|
"wave_manifold",
|
||||||
|
|
@ -69,6 +70,7 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
|
||||||
"fibonacci_search",
|
"fibonacci_search",
|
||||||
"atlas_packing",
|
"atlas_packing",
|
||||||
"wave_seam",
|
"wave_seam",
|
||||||
|
"wave_energy_boundary",
|
||||||
)
|
)
|
||||||
for node in ast.walk(tree):
|
for node in ast.walk(tree):
|
||||||
if isinstance(node, ast.Import):
|
if isinstance(node, ast.Import):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue