Merge pull request 'feat(wave): P9 Trace A contemplation → SPECULATIVE holographic seal' (#38) from feat/adr-0241-p9-contemplation-trace-a into main
This commit is contained in:
commit
9e1455b9a0
40 changed files with 3080 additions and 163 deletions
2
.github/workflows/lane-shas.yml
vendored
2
.github/workflows/lane-shas.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
verify:
|
||||
name: verify pinned lane SHAs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
|
|
|
|||
|
|
@ -48,9 +48,36 @@ def _build_cga_inner_metric() -> np.ndarray:
|
|||
_CGA_INNER_METRIC: np.ndarray = _build_cga_inner_metric()
|
||||
|
||||
|
||||
def _f32_1d32(x: np.ndarray) -> np.ndarray:
|
||||
"""Contiguous f32 (32,) for core_rs PyReadonlyArray1 bindings."""
|
||||
return np.ascontiguousarray(
|
||||
np.asarray(x, dtype=np.float32).reshape(-1)[:32], dtype=np.float32
|
||||
)
|
||||
|
||||
|
||||
def _is_f32_workload(*arrays: np.ndarray) -> bool:
|
||||
"""True when all arrays are float32 (Rust f32 kernel is parity-safe).
|
||||
|
||||
float64 wave residual pins require Python SOT (or future f64 Rust GP).
|
||||
Forcing f64→f32 would break 1e-9 chiral / leakage pins (ADR-0241).
|
||||
"""
|
||||
return all(np.asarray(a).dtype == np.float32 for a in arrays)
|
||||
|
||||
|
||||
def geometric_product(A: np.ndarray, B: np.ndarray) -> np.ndarray:
|
||||
if _RUST:
|
||||
return np.asarray(_rs.geometric_product(A, B), dtype=np.float32)
|
||||
"""Cl(4,1) geometric product via Rust f32 when enabled, else Python.
|
||||
|
||||
float64 inputs always use the pure-Python product (semantic SOT for
|
||||
wave-field residual math). float32 field-graph workloads get Rust.
|
||||
"""
|
||||
if _RUST and _is_f32_workload(A, B):
|
||||
try:
|
||||
return np.asarray(
|
||||
_rs.geometric_product(_f32_1d32(A), _f32_1d32(B)),
|
||||
dtype=np.float32,
|
||||
)
|
||||
except (AttributeError, TypeError, ValueError, Exception):
|
||||
pass
|
||||
from algebra.cl41 import geometric_product as _gp
|
||||
return _gp(A, B)
|
||||
|
||||
|
|
@ -67,25 +94,34 @@ def versor_apply(V: np.ndarray, F: np.ndarray) -> np.ndarray:
|
|||
"""
|
||||
if _RUST:
|
||||
try:
|
||||
Vc = np.ascontiguousarray(V, dtype=np.float64)
|
||||
Fc = np.ascontiguousarray(F, dtype=np.float64)
|
||||
return np.asarray(_rs.versor_apply_with_closure_f64(Vc, Fc), dtype=np.float64)
|
||||
except (AttributeError, Exception):
|
||||
Vc = np.ascontiguousarray(V, dtype=np.float64).reshape(-1)[:32]
|
||||
Fc = np.ascontiguousarray(F, dtype=np.float64).reshape(-1)[:32]
|
||||
return np.asarray(
|
||||
_rs.versor_apply_with_closure_f64(Vc, Fc), dtype=np.float64
|
||||
)
|
||||
except (AttributeError, TypeError, ValueError, Exception):
|
||||
pass
|
||||
from algebra.versor import versor_apply as _va
|
||||
return _va(V, F)
|
||||
|
||||
|
||||
def versor_condition(F: np.ndarray) -> float:
|
||||
if _RUST:
|
||||
return float(_rs.versor_condition(F))
|
||||
"""Versor residual. Rust f32 path only for float32 inputs (see GP note)."""
|
||||
if _RUST and _is_f32_workload(F):
|
||||
try:
|
||||
return float(_rs.versor_condition(_f32_1d32(F)))
|
||||
except (AttributeError, TypeError, ValueError, Exception):
|
||||
pass
|
||||
from algebra.versor import versor_condition as _vc
|
||||
return _vc(F)
|
||||
|
||||
|
||||
def cga_inner(X: np.ndarray, Y: np.ndarray) -> float:
|
||||
if _RUST:
|
||||
return float(_rs.cga_inner(X, Y))
|
||||
if _RUST and _is_f32_workload(X, Y):
|
||||
try:
|
||||
return float(_rs.cga_inner(_f32_1d32(X), _f32_1d32(Y)))
|
||||
except (AttributeError, TypeError, ValueError, Exception):
|
||||
pass
|
||||
from algebra.cga import cga_inner as _ci
|
||||
return _ci(X, Y)
|
||||
|
||||
|
|
|
|||
82
algebra/topological_reasoning/README.md
Normal file
82
algebra/topological_reasoning/README.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Topological Reasoning — ADR-0242 Vector 5 (D6) Research Quarantine
|
||||
|
||||
**Status**: 🔴 RESEARCH ONLY — blocked from production
|
||||
**Authority**: ADR-0242 Vector 5 (topological anyon / braid holonomy)
|
||||
**Related**: `docs/adr/ADR-0242-atlas-packing-and-fibonacci.md`,
|
||||
`docs/analysis/fibonacci_applications_in_core_substrate.md` §2.2
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Isolated study surface for Fibonacci anyon fusion and braid holonomy as a
|
||||
**topological composition research program**. The canonical fusion rule under
|
||||
study is:
|
||||
|
||||
\[
|
||||
\tau \otimes \tau = \mathbf{1} \oplus \tau
|
||||
\]
|
||||
|
||||
This package exists so research stubs, notes, and future proof-carrying
|
||||
algebra can land **without** contaminating the live cognitive path:
|
||||
|
||||
```text
|
||||
listen → comprehend → recall → think → articulate → learn → replay
|
||||
```
|
||||
|
||||
## Hard quarantine (do not violate)
|
||||
|
||||
Until algebraic **and** numerical proofs exist, and until an explicit ADR
|
||||
promotion gate is Accepted by human review, this package is **BLOCKED** from:
|
||||
|
||||
| Surface | Rule |
|
||||
|---------|------|
|
||||
| Production runtime | No imports from serve / hot path |
|
||||
| `chat/` | Not for import by chat or `chat/runtime.py` |
|
||||
| Serve / FFI | Must not enter serve or FFI bindings |
|
||||
| `core/physics/` | Not a production physics operator |
|
||||
| `generate/` | Not for articulation / planner / cognitive turns |
|
||||
| `vault/` | Not for vault standing, seal, or COHERENT promotion |
|
||||
| `teaching/` | Not for reviewed teaching or pack mutation |
|
||||
| GoldTether / κ paths | Not for production residual / κ optimization |
|
||||
| `algebra` public surface | Not re-exported from `algebra/__init__.py` |
|
||||
|
||||
Architectural pin: `tests/test_adr_0242_topological_quarantine.py` scans
|
||||
production packages for any import of `topological_reasoning` and must find
|
||||
none.
|
||||
|
||||
## Sovereignty (ADR-0242)
|
||||
|
||||
Fibonacci / topological operators may **never** dictate proposition truth,
|
||||
safety policy, identity, or authorize autonomous COHERENT promotion. Active
|
||||
reasoning remains governed by versor closure, exact CRDT recall, and
|
||||
human-gated review.
|
||||
|
||||
## What is allowed here
|
||||
|
||||
- Research constants and docstring contracts (e.g. fusion rule labels)
|
||||
- Future proof sketches, numerical experiments under tests/evals only when
|
||||
explicitly gated
|
||||
- Documentation of open questions and proof obligations
|
||||
|
||||
## What is not allowed here
|
||||
|
||||
- Production logic wired into cognition, serve, or vault truth
|
||||
- Stochastic / approximate substitutes for exact CGA recall
|
||||
- Hidden normalization or drift repair outside owned algebra boundaries
|
||||
- Silent promotion of research results into COHERENT standing
|
||||
|
||||
## API note
|
||||
|
||||
The package may expose minimal docstring / constant stubs (e.g. `FUSION_RULE`).
|
||||
No production operators, no side effects, no I/O.
|
||||
|
||||
## Promotion path
|
||||
|
||||
1. Algebraic + numerical proofs land and are reviewable.
|
||||
2. ADR update records evidence and remaining risks.
|
||||
3. Human Accept of a production promotion gate.
|
||||
4. Only then may a **separate**, reviewed integration surface be designed —
|
||||
still subject to serve quarantine and sovereignty invariant.
|
||||
|
||||
Until then: this directory is a quarantine box, not a feature.
|
||||
21
algebra/topological_reasoning/__init__.py
Normal file
21
algebra/topological_reasoning/__init__.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"""ADR-0242 V5 (D6) — topological anyon / braid holonomy research quarantine.
|
||||
|
||||
Fibonacci anyon fusion research surface. BLOCKED from production, serve, FFI,
|
||||
chat/runtime, vault COHERENT, teaching mutation, and GoldTether production
|
||||
paths until algebraic and numerical proofs exist (see package README).
|
||||
|
||||
This module intentionally re-exports nothing into ``algebra``'s public API
|
||||
and must not be imported by production packages.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
# Canonical Fibonacci anyon fusion rule under study (research label only).
|
||||
# τ ⊗ τ = 1 ⊕ τ — not a production operator; no evaluation semantics.
|
||||
FUSION_RULE: str = "tau_otimes_tau_eq_1_oplus_tau"
|
||||
"""Research label for the Fibonacci anyon fusion rule τ⊗τ = 1⊕τ.
|
||||
|
||||
Docstring / constant only. Does not implement fusion, braiding, or holonomy.
|
||||
"""
|
||||
|
||||
__all__ = ["FUSION_RULE"]
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
ADR-0080: contemplation can emit speculative findings about current
|
||||
substrate/report evidence, but it cannot ratify, promote, or mutate packs.
|
||||
|
||||
ADR-0241 P9: Trace A wave seam may SPECULATIVE-seal standing-wave modes and
|
||||
emit RESONANT_MODE_CANDIDATE findings — never COHERENT, never serve-wired.
|
||||
"""
|
||||
|
||||
from .runner import contemplate_frontier_reports, run_contemplation
|
||||
|
|
@ -12,6 +15,13 @@ from .schema import (
|
|||
FindingKind,
|
||||
)
|
||||
from .snapshot import ContemplationSubstrate
|
||||
from .wave_seam import (
|
||||
WaveModeHypothesis,
|
||||
WaveReconstructResult,
|
||||
reconstruct_as_evidence,
|
||||
reconstruct_as_hypothesis,
|
||||
speculative_seal_from_contemplation,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"ContemplationEvidenceRef",
|
||||
|
|
@ -19,6 +29,11 @@ __all__ = [
|
|||
"ContemplationRun",
|
||||
"ContemplationSubstrate",
|
||||
"FindingKind",
|
||||
"WaveModeHypothesis",
|
||||
"WaveReconstructResult",
|
||||
"contemplate_frontier_reports",
|
||||
"reconstruct_as_evidence",
|
||||
"reconstruct_as_hypothesis",
|
||||
"run_contemplation",
|
||||
"speculative_seal_from_contemplation",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class FindingKind(Enum):
|
|||
OOV_GAP = "oov_gap"
|
||||
PLANNER_GAP = "planner_gap"
|
||||
PACK_MUTATION_CANDIDATE = "pack_mutation_candidate"
|
||||
# ADR-0241 P9 Trace A: speculative standing-wave mode sealed for review.
|
||||
RESONANT_MODE_CANDIDATE = "resonant_mode_candidate"
|
||||
|
||||
|
||||
def _canonical_json(payload: dict[str, Any]) -> str:
|
||||
|
|
|
|||
193
core/contemplation/wave_seam.py
Normal file
193
core/contemplation/wave_seam.py
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
"""P9 Trace A seam — contemplation → SPECULATIVE holographic standing-wave seal.
|
||||
|
||||
ADR-0241 cohesion package P9:
|
||||
|
||||
1. Contemplation may **SPECULATIVE-seal** standing-wave modes via
|
||||
:meth:`HolographicVaultStore.seal_mode` only.
|
||||
2. Never writes COHERENT — teaching corridor / authorized
|
||||
``seal_mode_reviewed`` remains outside this module.
|
||||
3. Resonant reconstruct is available as a **hypothesis** over the full
|
||||
spectrum, or as **evidence** only when ``min_status=COHERENT``.
|
||||
4. Serve path stays quarantined (no import from ``chat/runtime.py``).
|
||||
5. No direct ``VaultStore.store`` — INV-21 writes stay in holographic_vault.
|
||||
|
||||
This module is the living-system bridge for Trace A without collapsing
|
||||
the teaching / serve containment boundary.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Literal
|
||||
|
||||
import numpy as np
|
||||
|
||||
from core.contemplation.schema import (
|
||||
ContemplationEvidenceRef,
|
||||
ContemplationFinding,
|
||||
FindingKind,
|
||||
)
|
||||
from core.physics.holographic_vault import (
|
||||
HolographicVaultError,
|
||||
HolographicVaultStore,
|
||||
SealedMode,
|
||||
)
|
||||
from teaching.epistemic import EpistemicStatus
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class WaveModeHypothesis:
|
||||
"""SPECULATIVE seal + contemplation finding for teaching review."""
|
||||
|
||||
sealed: SealedMode
|
||||
finding: ContemplationFinding
|
||||
standing: Literal["hypothesis"] = "hypothesis"
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"standing": self.standing,
|
||||
"mode_id": self.sealed.mode_id,
|
||||
"vault_index": self.sealed.vault_index,
|
||||
"epistemic_status": self.sealed.epistemic_status.value,
|
||||
"finding": self.finding.as_dict(),
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class WaveReconstructResult:
|
||||
"""Reconstructed field with honest epistemic standing label."""
|
||||
|
||||
psi_hat: np.ndarray
|
||||
coeffs: np.ndarray
|
||||
energies: np.ndarray
|
||||
spectrum: tuple[SealedMode, ...]
|
||||
standing: Literal["hypothesis", "evidence"]
|
||||
min_status: EpistemicStatus | None
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"standing": self.standing,
|
||||
"min_status": None if self.min_status is None else self.min_status.value,
|
||||
"mode_ids": [s.mode_id for s in self.spectrum],
|
||||
"coeff_count": int(self.coeffs.shape[0]),
|
||||
}
|
||||
|
||||
|
||||
def speculative_seal_from_contemplation(
|
||||
store: HolographicVaultStore,
|
||||
psi: np.ndarray,
|
||||
*,
|
||||
substrate_hash: str,
|
||||
subject: str,
|
||||
mode_id: str | None = None,
|
||||
notes: str = "",
|
||||
predicate: str = "propose_standing_wave_mode",
|
||||
) -> WaveModeHypothesis:
|
||||
"""SPECULATIVE-seal a closed mode and emit a contemplation finding.
|
||||
|
||||
Fail-closed on non-closed / high-drift ψ (delegates to holographic admit).
|
||||
Does **not** accept an authorization flag — COHERENT promotion is not
|
||||
available on this seam.
|
||||
"""
|
||||
if not str(substrate_hash).strip():
|
||||
raise ValueError("substrate_hash is required for Trace A provenance")
|
||||
if not str(subject).strip():
|
||||
raise ValueError("subject is required")
|
||||
|
||||
meta: dict[str, Any] = {
|
||||
"source": "contemplation_trace_a",
|
||||
"substrate_hash": substrate_hash,
|
||||
"notes": notes,
|
||||
"adr_refs": ["ADR-0241", "ADR-0080"],
|
||||
}
|
||||
sealed = store.seal_mode(psi, mode_id=mode_id, metadata=meta)
|
||||
if sealed.epistemic_status is not EpistemicStatus.SPECULATIVE:
|
||||
# Defensive: seal_mode contract is SPECULATIVE-only; never promote here.
|
||||
raise RuntimeError(
|
||||
"Trace A seam integrity breach: seal_mode returned non-SPECULATIVE"
|
||||
)
|
||||
|
||||
mid = sealed.mode_id
|
||||
finding = ContemplationFinding(
|
||||
kind=FindingKind.RESONANT_MODE_CANDIDATE,
|
||||
subject=subject,
|
||||
predicate=predicate,
|
||||
object=mid,
|
||||
evidence_refs=(
|
||||
ContemplationEvidenceRef(
|
||||
source_type="holographic_vault",
|
||||
source_id=mid,
|
||||
pointer=f"vault_index:{sealed.vault_index}",
|
||||
summary=(
|
||||
"SPECULATIVE standing-wave mode sealed for teaching review; "
|
||||
"not admissible as COHERENT evidence"
|
||||
),
|
||||
),
|
||||
),
|
||||
proposed_action="review_standing_wave_mode",
|
||||
substrate_hash=substrate_hash,
|
||||
epistemic_status=EpistemicStatus.SPECULATIVE,
|
||||
)
|
||||
return WaveModeHypothesis(sealed=sealed, finding=finding, standing="hypothesis")
|
||||
|
||||
|
||||
def reconstruct_as_hypothesis(
|
||||
store: HolographicVaultStore,
|
||||
psi_query: np.ndarray,
|
||||
) -> WaveReconstructResult:
|
||||
"""Superposition reconstruct over the full spectrum (incl. SPECULATIVE).
|
||||
|
||||
Result standing is always ``hypothesis`` — never claim reviewed evidence.
|
||||
"""
|
||||
psi_hat, coeffs, energies, spectrum = store.resonant_reconstruct(psi_query)
|
||||
return WaveReconstructResult(
|
||||
psi_hat=psi_hat,
|
||||
coeffs=coeffs,
|
||||
energies=energies,
|
||||
spectrum=spectrum,
|
||||
standing="hypothesis",
|
||||
min_status=None,
|
||||
)
|
||||
|
||||
|
||||
def reconstruct_as_evidence(
|
||||
store: HolographicVaultStore,
|
||||
psi_query: np.ndarray,
|
||||
) -> WaveReconstructResult:
|
||||
"""Superposition reconstruct over COHERENT modes only.
|
||||
|
||||
SPECULATIVE modes are excluded. Empty COHERENT spectrum refuses so
|
||||
unreviewed hypothesis mass cannot masquerade as evidence.
|
||||
"""
|
||||
try:
|
||||
psi_hat, coeffs, energies, spectrum = store.resonant_reconstruct(
|
||||
psi_query,
|
||||
min_status=EpistemicStatus.COHERENT,
|
||||
)
|
||||
except HolographicVaultError as exc:
|
||||
if exc.reason == "empty_spectrum":
|
||||
raise HolographicVaultError(
|
||||
"empty_spectrum",
|
||||
detail=(
|
||||
"evidence reconstruct requires COHERENT standing-wave modes; "
|
||||
"SPECULATIVE hypothesis mass is excluded"
|
||||
),
|
||||
) from exc
|
||||
raise
|
||||
return WaveReconstructResult(
|
||||
psi_hat=psi_hat,
|
||||
coeffs=coeffs,
|
||||
energies=energies,
|
||||
spectrum=spectrum,
|
||||
standing="evidence",
|
||||
min_status=EpistemicStatus.COHERENT,
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"WaveModeHypothesis",
|
||||
"WaveReconstructResult",
|
||||
"reconstruct_as_evidence",
|
||||
"reconstruct_as_hypothesis",
|
||||
"speculative_seal_from_contemplation",
|
||||
]
|
||||
|
|
@ -33,6 +33,7 @@ from core.physics.goldtether import (
|
|||
GoldTetherMonitor,
|
||||
OperatingMode,
|
||||
coherence_residual,
|
||||
propose_kappa_line_search,
|
||||
)
|
||||
from core.physics.dynamic_manifold import (
|
||||
AxisClassification,
|
||||
|
|
@ -82,6 +83,31 @@ 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 (
|
||||
BASELINE_KAPPA,
|
||||
BoundedUnimodalObjective,
|
||||
FibonacciSearchCertificate,
|
||||
OptimizationFailure,
|
||||
fibonacci_number,
|
||||
fibonacci_section_search,
|
||||
propose_kappa_from_search,
|
||||
)
|
||||
from core.physics.multi_scale_energy import (
|
||||
comparative_residual_separation,
|
||||
dyadic_tau_schedule,
|
||||
multi_scale_energy_for_schedule,
|
||||
multi_scale_energy_vector,
|
||||
schedule_mid_span_fraction,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"SalienceOperator", "SalienceMap", "FieldRegion",
|
||||
|
|
@ -116,4 +142,24 @@ __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",
|
||||
"BASELINE_KAPPA",
|
||||
"BoundedUnimodalObjective",
|
||||
"FibonacciSearchCertificate",
|
||||
"OptimizationFailure",
|
||||
"fibonacci_section_search",
|
||||
"propose_kappa_from_search",
|
||||
"propose_kappa_line_search",
|
||||
"comparative_residual_separation",
|
||||
"dyadic_tau_schedule",
|
||||
"multi_scale_energy_for_schedule",
|
||||
"multi_scale_energy_vector",
|
||||
"schedule_mid_span_fraction",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -22,11 +22,15 @@ from typing import Sequence
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cga import cga_inner, embed_point
|
||||
from algebra.backend import cga_inner
|
||||
from algebra.cga import embed_point
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
PHI = (1.0 + math.sqrt(5.0)) / 2.0
|
||||
DEFAULT_MIN_D = 0.12
|
||||
# Reconstruction-over-storage: layout regenerates from identity + ordinal k.
|
||||
ALLOCATOR_IDENTITY = "golden_angle"
|
||||
ALLOCATOR_VERSION = "golden_angle_v1"
|
||||
|
||||
|
||||
class AtlasPackingError(ValueError):
|
||||
|
|
@ -54,6 +58,9 @@ def golden_angle_pack(
|
|||
(x,y) = (r cos θ, r sin θ) → embed_point → null 32-vector
|
||||
|
||||
Rejects with :class:`AtlasPackingError` if any pairwise separation < min_d.
|
||||
|
||||
Layout is reconstructible from :data:`ALLOCATOR_VERSION` and ordinals
|
||||
``0..n-1`` (no opaque mutable coordinate table as truth).
|
||||
"""
|
||||
if n < 1:
|
||||
raise AtlasPackingError("n must be >= 1")
|
||||
|
|
@ -83,6 +90,24 @@ def golden_angle_pack(
|
|||
return modes
|
||||
|
||||
|
||||
def allocator_layout_descriptor(
|
||||
n: int,
|
||||
alpha: float,
|
||||
*,
|
||||
min_d: float = DEFAULT_MIN_D,
|
||||
) -> dict[str, object]:
|
||||
"""Content-free reconstruction metadata for packing (no coordinate leak)."""
|
||||
return {
|
||||
"allocator_identity": ALLOCATOR_IDENTITY,
|
||||
"allocator_version": ALLOCATOR_VERSION,
|
||||
"n": int(n),
|
||||
"alpha": float(alpha),
|
||||
"min_d": float(min_d),
|
||||
"metric": "cga_null_point_euclidean_d",
|
||||
"note": "not_full_H2_geodesic",
|
||||
}
|
||||
|
||||
|
||||
def register_packed_modes(
|
||||
modes: Sequence[np.ndarray],
|
||||
manifold: WaveManifold,
|
||||
|
|
@ -101,8 +126,11 @@ def register_packed_modes(
|
|||
__all__ = [
|
||||
"PHI",
|
||||
"DEFAULT_MIN_D",
|
||||
"ALLOCATOR_IDENTITY",
|
||||
"ALLOCATOR_VERSION",
|
||||
"AtlasPackingError",
|
||||
"null_point_separation",
|
||||
"golden_angle_pack",
|
||||
"allocator_layout_descriptor",
|
||||
"register_packed_modes",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@ from typing import Any, Sequence
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.backend import versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS
|
||||
from algebra.holonomy import holonomy_encode, holonomy_similarity
|
||||
from algebra.versor import unitize_versor, versor_condition
|
||||
from algebra.versor import unitize_versor
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
_CLOSURE_TOL = 1e-6
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ from typing import Optional, Sequence, Tuple, Union
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.backend import geometric_product, versor_condition
|
||||
from algebra.cga import is_null
|
||||
from algebra.cl41 import N_COMPONENTS, geometric_product, grade_project, reverse
|
||||
from algebra.cl41 import N_COMPONENTS, grade_project, reverse
|
||||
from algebra.null_point import (
|
||||
NullPointRecoveryError,
|
||||
dilator,
|
||||
|
|
@ -26,7 +27,6 @@ from algebra.null_point import (
|
|||
translator,
|
||||
)
|
||||
from algebra.rotor import rotor_power, word_transition_rotor
|
||||
from algebra.versor import versor_condition
|
||||
|
||||
_CLOSURE_TOL = 1e-6
|
||||
_NEAR_ZERO = 1e-12
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
"""core.physics.fibonacci_search — fixed-budget Fibonacci section search (ADR-0242).
|
||||
"""core.physics.fibonacci_search — evidence-gated Fibonacci section search (ADR-0242 V1).
|
||||
|
||||
Deterministic 1D unimodal minimization for construction / calibration /
|
||||
GoldTether κ-style scalar brackets. Not a serve-path operator (A-04 quarantine).
|
||||
|
||||
Public result is always a typed ``FibonacciSearchCertificate`` or
|
||||
``OptimizationFailure`` — never a bare float (Drive evidence discipline).
|
||||
|
||||
Fail-closed on:
|
||||
* nonfinite objective values
|
||||
* invalid bounds / budget
|
||||
|
|
@ -12,9 +15,11 @@ Fail-closed on:
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Callable
|
||||
from typing import Callable, Union
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
|
|
@ -32,8 +37,65 @@ class BoundedUnimodalObjective:
|
|||
raise ValueError("upper bound must be strictly greater than lower bound")
|
||||
if not math.isfinite(self.lower) or not math.isfinite(self.upper):
|
||||
raise ValueError("bounds must be finite")
|
||||
if not str(self.objective_id).strip():
|
||||
raise ValueError("objective_id is required")
|
||||
if not str(self.objective_version).strip():
|
||||
raise ValueError("objective_version is required")
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class FibonacciSearchCertificate:
|
||||
"""Cryptographically content-addressed, replayable optimization result."""
|
||||
|
||||
minimizer: float
|
||||
final_interval: tuple[float, float]
|
||||
evaluations: int
|
||||
ordered_points: tuple[float, ...]
|
||||
ordered_values: tuple[float, ...]
|
||||
objective_id: str
|
||||
objective_version: str
|
||||
cert_id: str = field(default="")
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not self.cert_id:
|
||||
object.__setattr__(self, "cert_id", _cert_digest(self))
|
||||
|
||||
def as_dict(self) -> dict[str, object]:
|
||||
return {
|
||||
"kind": "FibonacciSearchCertificate",
|
||||
"cert_id": self.cert_id,
|
||||
"minimizer": self.minimizer,
|
||||
"final_interval": list(self.final_interval),
|
||||
"evaluations": self.evaluations,
|
||||
"ordered_points": list(self.ordered_points),
|
||||
"ordered_values": list(self.ordered_values),
|
||||
"objective_id": self.objective_id,
|
||||
"objective_version": self.objective_version,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class OptimizationFailure:
|
||||
"""Typed failure — never silently accept a candidate minimizer."""
|
||||
|
||||
reason: str
|
||||
final_interval: tuple[float, float]
|
||||
evaluations: int
|
||||
objective_id: str
|
||||
objective_version: str
|
||||
|
||||
def as_dict(self) -> dict[str, object]:
|
||||
return {
|
||||
"kind": "OptimizationFailure",
|
||||
"reason": self.reason,
|
||||
"final_interval": list(self.final_interval),
|
||||
"evaluations": self.evaluations,
|
||||
"objective_id": self.objective_id,
|
||||
"objective_version": self.objective_version,
|
||||
}
|
||||
|
||||
|
||||
# Backward-compat view (cohesion sketches). Prefer Certificate | Failure.
|
||||
@dataclass(slots=True)
|
||||
class SearchTrace:
|
||||
best_observed_point: float
|
||||
|
|
@ -41,7 +103,12 @@ class SearchTrace:
|
|||
certificate: dict = field(default_factory=dict)
|
||||
|
||||
|
||||
def _fibonacci(n: int) -> int:
|
||||
SearchResult = Union[FibonacciSearchCertificate, OptimizationFailure]
|
||||
|
||||
BASELINE_KAPPA: float = 1.0
|
||||
|
||||
|
||||
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,9 +118,28 @@ def _fibonacci(n: int) -> int:
|
|||
return a
|
||||
|
||||
|
||||
def _assert_sampled_unimodality(eval_values: dict[float, float]) -> None:
|
||||
"""Fail-closed if sorted samples are not unimodal about the observed min."""
|
||||
def _fibonacci(n: int) -> int:
|
||||
return fibonacci_number(n)
|
||||
|
||||
|
||||
def _cert_digest(cert: FibonacciSearchCertificate) -> str:
|
||||
payload = {
|
||||
"minimizer": cert.minimizer,
|
||||
"final_interval": list(cert.final_interval),
|
||||
"evaluations": cert.evaluations,
|
||||
"ordered_points": list(cert.ordered_points),
|
||||
"ordered_values": list(cert.ordered_values),
|
||||
"objective_id": cert.objective_id,
|
||||
"objective_version": cert.objective_version,
|
||||
}
|
||||
raw = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
||||
return hashlib.sha256(raw).hexdigest()
|
||||
|
||||
|
||||
def _unimodality_ok(eval_values: dict[float, float]) -> bool:
|
||||
sorted_points = sorted(eval_values.keys())
|
||||
if len(sorted_points) < 2:
|
||||
return True
|
||||
min_idx = 0
|
||||
min_val = float("inf")
|
||||
for i, x in enumerate(sorted_points):
|
||||
|
|
@ -61,60 +147,119 @@ def _assert_sampled_unimodality(eval_values: dict[float, float]) -> None:
|
|||
if v < min_val:
|
||||
min_val = v
|
||||
min_idx = i
|
||||
|
||||
# Strictly non-increasing toward min (allow float ties).
|
||||
for i in range(min_idx):
|
||||
left = eval_values[sorted_points[i]]
|
||||
right = eval_values[sorted_points[i + 1]]
|
||||
if left < right - 1e-9:
|
||||
raise ValueError(
|
||||
"unimodality violation detected (multiple extrema): "
|
||||
"values not decreasing before minimum."
|
||||
)
|
||||
|
||||
# Strictly non-decreasing after min (allow float ties).
|
||||
return False
|
||||
for i in range(min_idx, len(sorted_points) - 1):
|
||||
left = eval_values[sorted_points[i]]
|
||||
right = eval_values[sorted_points[i + 1]]
|
||||
if left > right + 1e-9:
|
||||
raise ValueError(
|
||||
"unimodality violation detected (multiple extrema): "
|
||||
"values not increasing after minimum."
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _failure(
|
||||
objective: BoundedUnimodalObjective,
|
||||
*,
|
||||
reason: str,
|
||||
a: float,
|
||||
b: float,
|
||||
evaluations: int,
|
||||
) -> OptimizationFailure:
|
||||
return OptimizationFailure(
|
||||
reason=reason,
|
||||
final_interval=(float(a), float(b)),
|
||||
evaluations=int(evaluations),
|
||||
objective_id=objective.objective_id,
|
||||
objective_version=objective.objective_version,
|
||||
)
|
||||
|
||||
|
||||
def fibonacci_section_search(
|
||||
objective: BoundedUnimodalObjective,
|
||||
func: Callable[[float], float],
|
||||
) -> SearchTrace:
|
||||
"""Fibonacci section search: exactly ``evaluation_budget`` function evals.
|
||||
) -> SearchResult:
|
||||
"""Fibonacci section search with evidence-gated result.
|
||||
|
||||
Returns :class:`SearchTrace` with ``best_observed_point``, ``eval_sequence``,
|
||||
and a small certificate dict (budget, ids, bounds).
|
||||
Returns :class:`FibonacciSearchCertificate` on success or
|
||||
:class:`OptimizationFailure` on any fail-closed condition.
|
||||
Never returns a bare float.
|
||||
"""
|
||||
n = int(objective.evaluation_budget)
|
||||
a = float(objective.lower)
|
||||
b = float(objective.upper)
|
||||
a0 = float(objective.lower)
|
||||
b0 = float(objective.upper)
|
||||
a, b = a0, b0
|
||||
|
||||
if n < 2:
|
||||
return _failure(
|
||||
objective,
|
||||
reason="budget_too_low_for_unimodal_search",
|
||||
a=a0,
|
||||
b=b0,
|
||||
evaluations=0,
|
||||
)
|
||||
|
||||
f_n_plus_1 = _fibonacci(n + 1)
|
||||
f_n_minus_1 = _fibonacci(n - 1)
|
||||
f_n = _fibonacci(n)
|
||||
if f_n_plus_1 == 0:
|
||||
return _failure(
|
||||
objective,
|
||||
reason="degenerate_fibonacci_schedule",
|
||||
a=a0,
|
||||
b=b0,
|
||||
evaluations=0,
|
||||
)
|
||||
|
||||
c = a + (f_n_minus_1 / f_n_plus_1) * (b - a)
|
||||
d = a + (f_n / f_n_plus_1) * (b - a)
|
||||
|
||||
def _eval(x: float) -> float:
|
||||
points: list[float] = []
|
||||
values: list[float] = []
|
||||
eval_values: dict[float, float] = {}
|
||||
|
||||
def _eval(x: float) -> float | OptimizationFailure:
|
||||
if x < objective.lower - 1e-12 or x > objective.upper + 1e-12:
|
||||
raise ValueError(f"bounds violation: evaluated {x} outside [{objective.lower}, {objective.upper}]")
|
||||
y = float(func(x))
|
||||
return _failure(
|
||||
objective,
|
||||
reason=f"bounds_violation: evaluated {x} outside [{objective.lower}, {objective.upper}]",
|
||||
a=a,
|
||||
b=b,
|
||||
evaluations=len(points),
|
||||
)
|
||||
try:
|
||||
y = float(func(x))
|
||||
except Exception as exc: # noqa: BLE001 — typed failure surface
|
||||
return _failure(
|
||||
objective,
|
||||
reason=f"evaluation_error: {type(exc).__name__}: {exc}",
|
||||
a=a,
|
||||
b=b,
|
||||
evaluations=len(points),
|
||||
)
|
||||
if not math.isfinite(y):
|
||||
raise ValueError(f"Objective function returned nonfinite value {y} at {x}")
|
||||
return _failure(
|
||||
objective,
|
||||
reason=f"nonfinite_objective_value_at_{x}",
|
||||
a=a,
|
||||
b=b,
|
||||
evaluations=len(points),
|
||||
)
|
||||
return y
|
||||
|
||||
fc = _eval(c)
|
||||
fd = _eval(d)
|
||||
eval_sequence = [c, d]
|
||||
eval_values: dict[float, float] = {c: fc, d: fd}
|
||||
r_c = _eval(c)
|
||||
if isinstance(r_c, OptimizationFailure):
|
||||
return r_c
|
||||
r_d = _eval(d)
|
||||
if isinstance(r_d, OptimizationFailure):
|
||||
return r_d
|
||||
fc, fd = r_c, r_d
|
||||
points.extend([c, d])
|
||||
values.extend([fc, fd])
|
||||
eval_values[c] = fc
|
||||
eval_values[d] = fd
|
||||
|
||||
best_x = c if fc < fd else d
|
||||
best_f = min(fc, fd)
|
||||
|
|
@ -128,8 +273,12 @@ def fibonacci_section_search(
|
|||
f_n_minus_k_minus_1 = _fibonacci(n - k - 1)
|
||||
f_n_minus_k_plus_1 = _fibonacci(n - k + 1)
|
||||
c = a + (f_n_minus_k_minus_1 / f_n_minus_k_plus_1) * (b - a)
|
||||
fc = _eval(c)
|
||||
eval_sequence.append(c)
|
||||
r_c = _eval(c)
|
||||
if isinstance(r_c, OptimizationFailure):
|
||||
return r_c
|
||||
fc = r_c
|
||||
points.append(c)
|
||||
values.append(fc)
|
||||
eval_values[c] = fc
|
||||
if fc < best_f:
|
||||
best_f = fc
|
||||
|
|
@ -141,34 +290,88 @@ def fibonacci_section_search(
|
|||
f_n_minus_k = _fibonacci(n - k)
|
||||
f_n_minus_k_plus_1 = _fibonacci(n - k + 1)
|
||||
d = a + (f_n_minus_k / f_n_minus_k_plus_1) * (b - a)
|
||||
fd = _eval(d)
|
||||
eval_sequence.append(d)
|
||||
r_d = _eval(d)
|
||||
if isinstance(r_d, OptimizationFailure):
|
||||
return r_d
|
||||
fd = r_d
|
||||
points.append(d)
|
||||
values.append(fd)
|
||||
eval_values[d] = fd
|
||||
if fd < best_f:
|
||||
best_f = fd
|
||||
best_x = d
|
||||
k += 1
|
||||
|
||||
_assert_sampled_unimodality(eval_values)
|
||||
if not _unimodality_ok(eval_values):
|
||||
return _failure(
|
||||
objective,
|
||||
reason="unimodality_violation_multiple_extrema_detected",
|
||||
a=a,
|
||||
b=b,
|
||||
evaluations=len(points),
|
||||
)
|
||||
|
||||
certificate = {
|
||||
"budget": objective.evaluation_budget,
|
||||
"objective_id": objective.objective_id,
|
||||
"objective_version": objective.objective_version,
|
||||
"lower_bound": objective.lower,
|
||||
"upper_bound": objective.upper,
|
||||
"best_value": best_f,
|
||||
"n_evals": len(eval_sequence),
|
||||
}
|
||||
# Drive cert uses midpoint of final bracket; track also retains best sample.
|
||||
minimizer = 0.5 * (a + b)
|
||||
# Prefer best sample if it lies inside final bracket (more accurate under noise).
|
||||
if a - 1e-15 <= best_x <= b + 1e-15:
|
||||
minimizer = float(best_x)
|
||||
|
||||
return FibonacciSearchCertificate(
|
||||
minimizer=float(minimizer),
|
||||
final_interval=(float(a), float(b)),
|
||||
evaluations=len(points),
|
||||
ordered_points=tuple(float(p) for p in points),
|
||||
ordered_values=tuple(float(v) for v in values),
|
||||
objective_id=objective.objective_id,
|
||||
objective_version=objective.objective_version,
|
||||
)
|
||||
|
||||
|
||||
def propose_kappa_from_search(
|
||||
result: SearchResult,
|
||||
*,
|
||||
baseline: float = BASELINE_KAPPA,
|
||||
) -> tuple[float, SearchResult]:
|
||||
"""Evidence-gated κ: cert → minimizer; failure → baseline (default 1.0).
|
||||
|
||||
Never promotes COHERENT standing or mutates identity — caller telemetry only.
|
||||
"""
|
||||
if isinstance(result, FibonacciSearchCertificate):
|
||||
return float(result.minimizer), result
|
||||
return float(baseline), result
|
||||
|
||||
|
||||
def search_trace_from_result(result: SearchResult) -> SearchTrace:
|
||||
"""Legacy adapter for sketches that expect SearchTrace (raises on failure)."""
|
||||
if isinstance(result, OptimizationFailure):
|
||||
raise ValueError(result.reason)
|
||||
return SearchTrace(
|
||||
best_observed_point=float(best_x),
|
||||
eval_sequence=list(eval_sequence),
|
||||
certificate=certificate,
|
||||
best_observed_point=result.minimizer,
|
||||
eval_sequence=list(result.ordered_points),
|
||||
certificate={
|
||||
"budget": result.evaluations,
|
||||
"objective_id": result.objective_id,
|
||||
"objective_version": result.objective_version,
|
||||
"lower_bound": result.final_interval[0],
|
||||
"upper_bound": result.final_interval[1],
|
||||
"best_value": None,
|
||||
"n_evals": result.evaluations,
|
||||
"cert_id": result.cert_id,
|
||||
"kind": "FibonacciSearchCertificate",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"BASELINE_KAPPA",
|
||||
"BoundedUnimodalObjective",
|
||||
"FibonacciSearchCertificate",
|
||||
"OptimizationFailure",
|
||||
"SearchResult",
|
||||
"SearchTrace",
|
||||
"fibonacci_number",
|
||||
"fibonacci_section_search",
|
||||
"propose_kappa_from_search",
|
||||
"search_trace_from_result",
|
||||
]
|
||||
|
|
|
|||
106
core/physics/fibonacci_word_schedule.py
Normal file
106
core/physics/fibonacci_word_schedule.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"""core.physics.fibonacci_word_schedule — ADR-0242 V4 (D5) observability choreography.
|
||||
|
||||
Fibonacci-word scheduler for telemetry / sealed-holdout sampling only.
|
||||
|
||||
Drive recurrence
|
||||
----------------
|
||||
W_0 = B
|
||||
W_1 = A
|
||||
W_{n+1} = W_n W_{n-1} (string concatenation)
|
||||
|
||||
where:
|
||||
* A — low-cost local measurement
|
||||
* B — high-cost cross-band check
|
||||
|
||||
Length formula
|
||||
--------------
|
||||
With the standard Fibonacci sequence F_0 = 0, F_1 = 1, F_2 = 1, F_3 = 2, …:
|
||||
|
||||
|W_n| = F_{n+1} for n >= 0
|
||||
(equivalently |W_0|=1, |W_1|=1, |W_2|=2, |W_3|=3, |W_4|=5, …)
|
||||
|
||||
Sovereignty (ADR-0242 absolute invariant)
|
||||
----------------------------------------
|
||||
This module is **outside the cognitive truth path**. It schedules
|
||||
observability / telemetry actions only. It MUST NOT:
|
||||
|
||||
* mutate vault standing or call VaultStore.store
|
||||
* mutate field state or authorize COHERENT promotion
|
||||
* dictate proposition truth, safety policy, or identity
|
||||
* be imported from the serve hot path (A-04 quarantine)
|
||||
|
||||
Pure and deterministic: no I/O, no randomness, no field/vault side effects.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
class Action(str, Enum):
|
||||
"""Observability action labels (telemetry only; not cognitive truth)."""
|
||||
|
||||
A = "A" # low-cost local measurement
|
||||
B = "B" # high-cost cross-band check
|
||||
|
||||
|
||||
def _require_nonneg_int(n: int, *, name: str = "n") -> int:
|
||||
if not isinstance(n, int) or isinstance(n, bool):
|
||||
raise TypeError(f"{name} must be an int, got {type(n).__name__}")
|
||||
if n < 0:
|
||||
raise ValueError(f"{name} must be non-negative, got {n}")
|
||||
return n
|
||||
|
||||
|
||||
def fibonacci_word(n: int) -> str:
|
||||
"""Return the Fibonacci word W_n as a string of 'A'/'B' characters.
|
||||
|
||||
W_0 = \"B\", W_1 = \"A\", W_{k+1} = W_k + W_{k-1}.
|
||||
Length |W_n| = F_{n+1} with F_0=0, F_1=1.
|
||||
"""
|
||||
n = _require_nonneg_int(n)
|
||||
if n == 0:
|
||||
return Action.B.value
|
||||
if n == 1:
|
||||
return Action.A.value
|
||||
# Iterative doubling: O(n) concatenations, O(F_{n+1}) total chars.
|
||||
prev = Action.B.value # W_0
|
||||
curr = Action.A.value # W_1
|
||||
for _ in range(2, n + 1):
|
||||
prev, curr = curr, curr + prev
|
||||
return curr
|
||||
|
||||
|
||||
def schedule_actions(n: int) -> tuple[str, ...]:
|
||||
"""Return the action sequence for W_n as an immutable tuple of \"A\"/\"B\".
|
||||
|
||||
Same recurrence and length as :func:`fibonacci_word`; form convenient for
|
||||
iteration without splitting a string.
|
||||
"""
|
||||
word = fibonacci_word(n)
|
||||
return tuple(word)
|
||||
|
||||
|
||||
def iter_schedule_actions(n: int) -> Iterator[str]:
|
||||
"""Iterate actions of W_n without building an intermediate tuple."""
|
||||
yield from fibonacci_word(n)
|
||||
|
||||
|
||||
def word_length(n: int) -> int:
|
||||
"""Return |W_n| = F_{n+1} (F_0=0, F_1=1) without building the word."""
|
||||
n = _require_nonneg_int(n)
|
||||
# F_{n+1}: a,b walk F_0=0, F_1=1 for (n+1) steps → a = F_{n+1}
|
||||
a, b = 0, 1
|
||||
for _ in range(n + 1):
|
||||
a, b = b, a + b
|
||||
return a
|
||||
|
||||
|
||||
__all__ = [
|
||||
"Action",
|
||||
"fibonacci_word",
|
||||
"schedule_actions",
|
||||
"iter_schedule_actions",
|
||||
"word_length",
|
||||
]
|
||||
|
|
@ -28,9 +28,10 @@ from typing import Any, Literal, Optional, Tuple
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cl41 import N_COMPONENTS, geometric_product, reverse
|
||||
from algebra.backend import geometric_product, versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS, reverse
|
||||
from algebra.rotor import rotor_power, word_transition_rotor
|
||||
from algebra.versor import versor_condition, versor_unit_residual
|
||||
from algebra.versor import versor_unit_residual
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
_CLOSURE_TOL = 1e-6
|
||||
|
|
@ -521,3 +522,40 @@ class GoldTetherMonitor:
|
|||
for h in self.history[-16:]
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ADR-0242 V1 — evidence-gated κ line search (optional, off-serve)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def propose_kappa_line_search(
|
||||
residual_fn,
|
||||
*,
|
||||
lower: float = 0.1,
|
||||
upper: float = 2.0,
|
||||
evaluation_budget: int = 16,
|
||||
objective_id: str = "goldtether_kappa",
|
||||
objective_version: str = "v1",
|
||||
) -> tuple[float, object]:
|
||||
"""Optional κ search via Fibonacci section (ADR-0242 Phase 1 seam).
|
||||
|
||||
Returns ``(kappa, cert_or_failure)``. On failure, kappa is baseline 1.0.
|
||||
Does **not** mutate GoldTetherMonitor state, COHERENT standing, or serve
|
||||
autonomy — caller may record the result as telemetry only.
|
||||
"""
|
||||
from core.physics.fibonacci_search import (
|
||||
BoundedUnimodalObjective,
|
||||
fibonacci_section_search,
|
||||
propose_kappa_from_search,
|
||||
)
|
||||
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=float(lower),
|
||||
upper=float(upper),
|
||||
evaluation_budget=int(evaluation_budget),
|
||||
objective_id=str(objective_id),
|
||||
objective_version=str(objective_version),
|
||||
)
|
||||
result = fibonacci_section_search(objective, residual_fn)
|
||||
return propose_kappa_from_search(result)
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ from typing import Any, Optional
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.backend import versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS
|
||||
from algebra.versor import versor_condition
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
from teaching.epistemic import EpistemicStatus
|
||||
from vault.store import VaultStore, _parse_entry_status, _status_admits
|
||||
|
|
@ -222,14 +222,7 @@ class HolographicVaultStore:
|
|||
Empty spectrum / cold start without modes → refuse (no confabulation).
|
||||
Uses algebraic reverse-product energy via WaveManifold.
|
||||
"""
|
||||
if min_status is not None:
|
||||
# Rebuild filtered view so COHERENT-tier evidence excludes SPECULATIVE.
|
||||
spectrum = list(self.load_spectrum(min_status=min_status))
|
||||
else:
|
||||
spectrum = list(self._sealed)
|
||||
if not spectrum:
|
||||
# Cold start: attempt unfiltered load once.
|
||||
spectrum = list(self.load_spectrum())
|
||||
spectrum = self._spectrum_for_status(min_status)
|
||||
if not spectrum:
|
||||
raise HolographicVaultError(
|
||||
"empty_spectrum",
|
||||
|
|
@ -240,6 +233,47 @@ class HolographicVaultStore:
|
|||
mode, energy, idx = self._manifold.resonant_recall(query, modes=modes)
|
||||
return mode, float(energy), int(idx), spectrum[int(idx)]
|
||||
|
||||
def resonant_reconstruct(
|
||||
self,
|
||||
psi_query: np.ndarray,
|
||||
*,
|
||||
min_status: EpistemicStatus | None = None,
|
||||
) -> tuple[np.ndarray, np.ndarray, np.ndarray, tuple[SealedMode, ...]]:
|
||||
"""Superposition reconstruct over the durable spectrum.
|
||||
|
||||
``min_status=COHERENT`` excludes SPECULATIVE modes so hypothesis
|
||||
mass cannot masquerade as reviewed evidence (Trace A / INV-24).
|
||||
Empty filtered spectrum refuses (no confabulation).
|
||||
"""
|
||||
spectrum = self._spectrum_for_status(min_status)
|
||||
if not spectrum:
|
||||
raise HolographicVaultError(
|
||||
"empty_spectrum",
|
||||
detail=(
|
||||
"no standing-wave modes for resonant reconstruct "
|
||||
f"(min_status={getattr(min_status, 'value', min_status)!r})"
|
||||
),
|
||||
)
|
||||
query = _as_mv(psi_query, "ψ_query")
|
||||
modes = [s.mode for s in spectrum]
|
||||
psi_hat, coeffs, energies = self._manifold.resonant_reconstruct(
|
||||
query, modes=modes
|
||||
)
|
||||
return psi_hat, coeffs, energies, tuple(spectrum)
|
||||
|
||||
def _spectrum_for_status(
|
||||
self,
|
||||
min_status: EpistemicStatus | None,
|
||||
) -> list[SealedMode]:
|
||||
if min_status is not None:
|
||||
# Rebuild filtered view so COHERENT-tier evidence excludes SPECULATIVE.
|
||||
return list(self.load_spectrum(min_status=min_status))
|
||||
spectrum = list(self._sealed)
|
||||
if not spectrum:
|
||||
# Cold start: attempt unfiltered load once.
|
||||
spectrum = list(self.load_spectrum())
|
||||
return spectrum
|
||||
|
||||
def spectrum_size(self) -> int:
|
||||
"""Number of standing-wave modes currently in the reconstruction cache."""
|
||||
return len(self._sealed)
|
||||
|
|
|
|||
178
core/physics/multi_scale_energy.py
Normal file
178
core/physics/multi_scale_energy.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
"""ADR-0242 V2 — multi-scale temporal energy basis (research prototype).
|
||||
|
||||
Drive formula:
|
||||
|
||||
E_n(t) = E_n(t_0) * exp(-(t - t_0) / (F_n * τ_0))
|
||||
|
||||
with Fibonacci scale factors F_n (n ≥ 1) and base time constant τ_0.
|
||||
|
||||
This module is **research-only**:
|
||||
- pure helpers for comparative study vs a dyadic (2^{n-1} τ_0) baseline
|
||||
- **not** a production default inside ``FieldEnergyOperator.compute``
|
||||
- serve-quarantined (A-04): must not be imported from ``chat/runtime.py``
|
||||
|
||||
Reuses ``fibonacci_number`` / ``fibonacci_tau_schedule`` — no parallel Fibonacci.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from math import exp, isfinite
|
||||
from typing import Sequence
|
||||
|
||||
from core.physics.fibonacci_search import fibonacci_number
|
||||
from core.physics.wave_energy_boundary import fibonacci_tau_schedule
|
||||
|
||||
_DEFAULT_TAU0 = 1.0
|
||||
|
||||
|
||||
def _validate_tau0(tau0: float) -> float:
|
||||
t0 = float(tau0)
|
||||
if not (t0 > 0.0) or not isfinite(t0):
|
||||
raise ValueError("tau0 must be a positive finite scalar")
|
||||
return t0
|
||||
|
||||
|
||||
def _validate_levels(levels: int) -> int:
|
||||
n = int(levels)
|
||||
if n < 1:
|
||||
raise ValueError("levels must be >= 1")
|
||||
return n
|
||||
|
||||
|
||||
def _validate_age(age: float) -> float:
|
||||
a = float(age)
|
||||
if a < 0.0 or not isfinite(a):
|
||||
raise ValueError("age must be a non-negative finite scalar")
|
||||
return a
|
||||
|
||||
|
||||
def _validate_e0(e0: float) -> float:
|
||||
e = float(e0)
|
||||
if not isfinite(e):
|
||||
raise ValueError("e0 must be a finite scalar")
|
||||
return e
|
||||
|
||||
|
||||
def dyadic_tau_schedule(
|
||||
tau0: float = _DEFAULT_TAU0,
|
||||
*,
|
||||
levels: int = 8,
|
||||
) -> tuple[float, ...]:
|
||||
"""Dyadic comparison baseline τ_n = 2^{n-1} · τ_0 for n = 1..levels.
|
||||
|
||||
ADR-0242 Phase 2 comparative hypothesis baseline (not a production default).
|
||||
"""
|
||||
t0 = _validate_tau0(tau0)
|
||||
n = _validate_levels(levels)
|
||||
return tuple(float(t0 * (2 ** (i - 1))) for i in range(1, n + 1))
|
||||
|
||||
|
||||
def multi_scale_energy_for_schedule(
|
||||
e0: float,
|
||||
age: float,
|
||||
taus: Sequence[float],
|
||||
) -> tuple[float, ...]:
|
||||
"""Apply E = e0 · exp(-age / τ) for each positive finite τ in ``taus``.
|
||||
|
||||
``age`` is (t − t_0). ``e0`` is the shared E_n(t_0) research default.
|
||||
"""
|
||||
e = _validate_e0(e0)
|
||||
a = _validate_age(age)
|
||||
if not taus:
|
||||
raise ValueError("taus must be non-empty")
|
||||
out: list[float] = []
|
||||
for raw in taus:
|
||||
tau = float(raw)
|
||||
if not (tau > 0.0) or not isfinite(tau):
|
||||
raise ValueError("each tau must be a positive finite scalar")
|
||||
out.append(float(e * exp(-a / tau)))
|
||||
return tuple(out)
|
||||
|
||||
|
||||
def multi_scale_energy_vector(
|
||||
e0: float,
|
||||
age: float,
|
||||
*,
|
||||
tau0: float = _DEFAULT_TAU0,
|
||||
levels: int = 8,
|
||||
) -> tuple[float, ...]:
|
||||
"""Fibonacci multi-scale energies E_n for n = 1..levels.
|
||||
|
||||
Drive form with shared E_n(t_0) = e0:
|
||||
|
||||
E_n = e0 * exp(-age / (F_n * tau0))
|
||||
|
||||
Equivalent to ``multi_scale_energy_for_schedule`` over
|
||||
``fibonacci_tau_schedule(tau0, levels=levels)``.
|
||||
"""
|
||||
t0 = _validate_tau0(tau0)
|
||||
n = _validate_levels(levels)
|
||||
# Explicit F_n path keeps the Drive formula visible at the callsite layer.
|
||||
e = _validate_e0(e0)
|
||||
a = _validate_age(age)
|
||||
return tuple(
|
||||
float(e * exp(-a / float(fibonacci_number(i) * t0)))
|
||||
for i in range(1, n + 1)
|
||||
)
|
||||
|
||||
|
||||
def comparative_residual_separation(
|
||||
e0: float,
|
||||
age: float,
|
||||
*,
|
||||
tau0: float = _DEFAULT_TAU0,
|
||||
levels: int = 8,
|
||||
) -> dict[str, object]:
|
||||
"""Deterministic Fibonacci vs dyadic multi-scale energy comparison.
|
||||
|
||||
Pure research helper — no I/O. Returns both schedules, both energy
|
||||
vectors, and per-index energy gaps (fib − dyadic). Promotion of
|
||||
Fibonacci multi-band energy into production requires evidence from
|
||||
this (or richer) comparative surface.
|
||||
"""
|
||||
t0 = _validate_tau0(tau0)
|
||||
n = _validate_levels(levels)
|
||||
fib_taus = fibonacci_tau_schedule(t0, levels=n)
|
||||
dyad_taus = dyadic_tau_schedule(t0, levels=n)
|
||||
fib_e = multi_scale_energy_for_schedule(e0, age, fib_taus)
|
||||
dyad_e = multi_scale_energy_for_schedule(e0, age, dyad_taus)
|
||||
gaps = tuple(float(f - d) for f, d in zip(fib_e, dyad_e, strict=True))
|
||||
return {
|
||||
"tau0": t0,
|
||||
"levels": n,
|
||||
"age": float(age),
|
||||
"e0": float(e0),
|
||||
"fibonacci_taus": fib_taus,
|
||||
"dyadic_taus": dyad_taus,
|
||||
"fibonacci_energies": fib_e,
|
||||
"dyadic_energies": dyad_e,
|
||||
"energy_gap_fib_minus_dyadic": gaps,
|
||||
}
|
||||
|
||||
|
||||
def schedule_mid_span_fraction(taus: Sequence[float], *, index: int | None = None) -> float:
|
||||
"""Fraction of max(τ) occupied by τ at mid (or given) index.
|
||||
|
||||
Used by comparative pins: Fibonacci mid-scale bands sit further along
|
||||
the normalized span than pure dyadic 2^{n-1} (slower φ-growth).
|
||||
"""
|
||||
if not taus:
|
||||
raise ValueError("taus must be non-empty")
|
||||
vals = tuple(float(t) for t in taus)
|
||||
for t in vals:
|
||||
if not (t > 0.0) or not isfinite(t):
|
||||
raise ValueError("each tau must be a positive finite scalar")
|
||||
peak = max(vals)
|
||||
i = len(vals) // 2 if index is None else int(index)
|
||||
if i < 0 or i >= len(vals):
|
||||
raise ValueError("index out of range for taus")
|
||||
return float(vals[i] / peak)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"comparative_residual_separation",
|
||||
"dyadic_tau_schedule",
|
||||
"multi_scale_energy_for_schedule",
|
||||
"multi_scale_energy_vector",
|
||||
"schedule_mid_span_fraction",
|
||||
]
|
||||
|
|
@ -9,8 +9,8 @@ from typing import Any, Mapping, Sequence
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.backend import versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS
|
||||
from algebra.versor import versor_condition
|
||||
from core.physics.dynamic_manifold import conformal_procrustes
|
||||
from core.physics.goldtether import GoldTetherMonitor, coherence_residual
|
||||
from core.physics.surprise import dual_procrustes_surprise, surprise_residual
|
||||
|
|
|
|||
141
core/physics/sensorium_wave_feed.py
Normal file
141
core/physics/sensorium_wave_feed.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
"""D7 sensorium → ψ feed (I-04 boundary).
|
||||
|
||||
Thin construction-boundary adapter: modality surface packets become Cl(4,1)
|
||||
wave fields for algebraic multimodal resonance.
|
||||
|
||||
Real modality compilers remain in ``sensorium/*``. This module only standardizes
|
||||
the feed into the wave substrate:
|
||||
|
||||
* :class:`ModalityPacket` (or dict) — modality id + 32-float coefficients
|
||||
* :func:`compile_packet_to_psi` — validate / lift to shape ``(32,)``
|
||||
* :func:`superpose_packets` — ``ψ_total = Σ ψ_i``
|
||||
* :func:`phase_correlate` — delegates **only** to
|
||||
:meth:`WaveManifold.phase_correlation` (metric-exact ρ; no cosine / ANN)
|
||||
|
||||
Honest test fixtures via :func:`fake_deterministic_packet` use closed rotors
|
||||
from :func:`algebra.rotor.make_rotor_from_angle` when live compilers are not
|
||||
under test. That is a fixture, not a claim that audio/vision compilers ran.
|
||||
|
||||
Off-serve: must not be imported by ``chat/runtime.py`` (A-04 quarantine).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Mapping, Sequence, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cl41 import N_COMPONENTS
|
||||
from algebra.rotor import make_rotor_from_angle
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
PacketLike = Union["ModalityPacket", Mapping[str, Any]]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ModalityPacket:
|
||||
"""Construction-boundary packet: modality tag + 32 Cl(4,1) coefficients.
|
||||
|
||||
After compile, the field has no modality concept (Logos recovery).
|
||||
``modality_id`` is provenance only.
|
||||
"""
|
||||
|
||||
modality_id: str
|
||||
coefficients: np.ndarray # shape (N_COMPONENTS,)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
mid = str(self.modality_id).strip()
|
||||
if not mid:
|
||||
raise ValueError("modality_id must be non-empty")
|
||||
arr = np.asarray(self.coefficients, dtype=np.float64).reshape(-1)
|
||||
if arr.shape != (N_COMPONENTS,):
|
||||
raise ValueError(
|
||||
f"coefficients must have shape ({N_COMPONENTS},); got {arr.shape}"
|
||||
)
|
||||
object.__setattr__(self, "modality_id", mid)
|
||||
object.__setattr__(self, "coefficients", arr.copy())
|
||||
|
||||
|
||||
def _coerce_packet(packet: PacketLike) -> ModalityPacket:
|
||||
if isinstance(packet, ModalityPacket):
|
||||
return packet
|
||||
if isinstance(packet, Mapping):
|
||||
mid = packet.get("modality_id", packet.get("modality"))
|
||||
coeffs = packet.get("coefficients")
|
||||
if coeffs is None:
|
||||
coeffs = packet.get("coeffs")
|
||||
if coeffs is None:
|
||||
coeffs = packet.get("psi")
|
||||
if mid is None or coeffs is None:
|
||||
raise ValueError(
|
||||
"packet mapping requires modality_id (or modality) and "
|
||||
"coefficients (or coeffs / psi)"
|
||||
)
|
||||
return ModalityPacket(modality_id=str(mid), coefficients=np.asarray(coeffs))
|
||||
raise TypeError(
|
||||
f"packet must be ModalityPacket or mapping; got {type(packet).__name__}"
|
||||
)
|
||||
|
||||
|
||||
def compile_packet_to_psi(packet: PacketLike) -> np.ndarray:
|
||||
"""Lift a modality packet to a wave field ψ of shape ``(32,)``.
|
||||
|
||||
Construction-boundary only: validates shape/dtype and returns a fresh
|
||||
float64 copy. Does not repair non-unit packets (no hidden unitize).
|
||||
"""
|
||||
p = _coerce_packet(packet)
|
||||
return p.coefficients.astype(np.float64, copy=True)
|
||||
|
||||
|
||||
def superpose_packets(packets: Sequence[PacketLike]) -> np.ndarray:
|
||||
"""Linear superposition ``ψ_total = Σ_i compile_packet_to_psi(packet_i)``.
|
||||
|
||||
Empty input refuses (no confabulated zero field as resonance truth).
|
||||
"""
|
||||
if not packets:
|
||||
raise ValueError("superpose_packets: empty packet list")
|
||||
total = np.zeros(N_COMPONENTS, dtype=np.float64)
|
||||
for packet in packets:
|
||||
total = total + compile_packet_to_psi(packet)
|
||||
return total
|
||||
|
||||
|
||||
def phase_correlate(
|
||||
psi_a: np.ndarray,
|
||||
psi_b: np.ndarray,
|
||||
*,
|
||||
manifold: WaveManifold | None = None,
|
||||
) -> float:
|
||||
"""Algebraic multimodal resonance ρ(A,B) for I-04.
|
||||
|
||||
Delegates solely to :meth:`WaveManifold.phase_correlation`.
|
||||
Forbidden: cosine similarity, ANN, sklearn neighbors, embedding ranking.
|
||||
"""
|
||||
m = manifold if manifold is not None else WaveManifold()
|
||||
return float(m.phase_correlation(psi_a, psi_b))
|
||||
|
||||
|
||||
def fake_deterministic_packet(
|
||||
modality_id: str,
|
||||
*,
|
||||
angle: float = 0.3,
|
||||
plane: int = 6,
|
||||
) -> ModalityPacket:
|
||||
"""Honest deterministic fixture when real modality compilers are absent.
|
||||
|
||||
Builds a closed unit rotor via :func:`make_rotor_from_angle`. This is a
|
||||
test/construction fixture — not a live audio/vision compile path.
|
||||
"""
|
||||
coeffs = make_rotor_from_angle(float(angle), bivector_idx=int(plane))
|
||||
return ModalityPacket(modality_id=modality_id, coefficients=coeffs)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"ModalityPacket",
|
||||
"PacketLike",
|
||||
"compile_packet_to_psi",
|
||||
"superpose_packets",
|
||||
"phase_correlate",
|
||||
"fake_deterministic_packet",
|
||||
]
|
||||
|
|
@ -39,9 +39,8 @@ from typing import Optional, Sequence, Tuple, Union
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cga import cga_inner
|
||||
from algebra.backend import cga_inner, versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS, grade_project
|
||||
from algebra.versor import versor_condition
|
||||
from core.physics.dynamic_manifold import conformal_procrustes
|
||||
from core.physics.wave_manifold import WaveManifold, WaveSpectralLeakageError
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@ from typing import Sequence
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cl41 import N_COMPONENTS, geometric_product, reverse
|
||||
from algebra.versor import versor_condition, versor_unit_residual
|
||||
from algebra.backend import geometric_product, versor_condition
|
||||
from algebra.cl41 import N_COMPONENTS, reverse
|
||||
from algebra.versor import versor_unit_residual
|
||||
|
||||
_CLOSURE_TOL = 1e-6
|
||||
_DEFAULT_EPS_TRAJECTORY = 1e-5
|
||||
|
|
|
|||
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",
|
||||
]
|
||||
|
|
@ -12,6 +12,12 @@ Continuous multivector wave fields ψ ∈ ℝ³² under:
|
|||
|
||||
Algebra-native only (algebra/*). No scipy-as-truth. No teaching/vault imports.
|
||||
Off-serving until explicit gates; dual-checked unitary residual.
|
||||
|
||||
**Backend dispatch (P11a / ADR-0235):** Cl(4,1) hot ops go through
|
||||
``algebra.backend`` so ``CORE_BACKEND=rust`` can accelerate them when
|
||||
``core_rs`` is built. Python remains semantic source of truth when Rust
|
||||
is unset. Helpers without a Rust path (``reverse``, ``scalar_part``,
|
||||
``versor_unit_residual``) stay on pure algebra modules.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -20,9 +26,14 @@ from typing import Any, Sequence, Tuple
|
|||
|
||||
import numpy as np
|
||||
|
||||
from algebra.cga import cga_inner
|
||||
from algebra.cl41 import N_COMPONENTS, geometric_product, reverse, scalar_part
|
||||
from algebra.versor import versor_apply, versor_condition, versor_unit_residual
|
||||
from algebra.backend import (
|
||||
cga_inner,
|
||||
geometric_product,
|
||||
versor_apply,
|
||||
versor_condition,
|
||||
)
|
||||
from algebra.cl41 import N_COMPONENTS, reverse, scalar_part
|
||||
from algebra.versor import versor_unit_residual
|
||||
|
||||
_CLOSURE_TOL = 1e-6
|
||||
_NEAR_ZERO = 1e-12
|
||||
|
|
|
|||
26
docs/RUST.md
26
docs/RUST.md
|
|
@ -1,5 +1,31 @@
|
|||
# Rust Extension (core-rs)
|
||||
|
||||
## Physics hot-path hygiene (P11a)
|
||||
|
||||
Third-Door / ADR-0241 physics modules must import Cl(4,1) multiplies and
|
||||
closure residual helpers from **`algebra.backend`**, not directly from
|
||||
`algebra.cl41` / `algebra.versor` / `algebra.cga` for:
|
||||
|
||||
- `geometric_product`
|
||||
- `versor_apply`
|
||||
- `versor_condition`
|
||||
- `cga_inner`
|
||||
|
||||
Pinned by `tests/test_physics_backend_dispatch_hygiene.py`.
|
||||
|
||||
```bash
|
||||
# Default: pure Python (semantic SOT)
|
||||
uv run pytest tests/test_adr_0241_wave_manifold.py -q
|
||||
|
||||
# Apple Silicon / native acceleration (after maturin build)
|
||||
export CORE_BACKEND=rust
|
||||
uv run --with maturin maturin develop --release --manifest-path core-rs/Cargo.toml
|
||||
uv run python -c "from algebra.backend import using_rust; assert using_rust()"
|
||||
```
|
||||
|
||||
MLX remains an **exploratory** UMA lane (ADR-0235); not required for serving.
|
||||
|
||||
|
||||
## Why Rust
|
||||
|
||||
The active Rust extension is an opt-in native substrate for parity-gated hot
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# ADR-0241: Wave-Field Driven Hyperbolic Atlas and Resonant Algebraic Cognition
|
||||
|
||||
**Status**: Proposed — substrate + Slice-2/3 subsumption complete on branch (`wave_manifold`, operator delegates, multi-pair conjugacy thin wrap, resonant recall); acceptance path: Joshua review + merge
|
||||
**Status**: Proposed — **implementation complete (P0–P10)**; ready for Joshua acceptance review (do not self-Accept). Optional P11 Rust deferred. Checklist: `docs/audit/adr_0241_cohesion_acceptance_checklist.md`.
|
||||
**Date**: 2026-07-13
|
||||
**Deciders**: Joshua Shay + multi-model R&D
|
||||
**Traceability**: Issue #14, parent #10
|
||||
|
|
|
|||
|
|
@ -1,75 +1,128 @@
|
|||
# ADR-0242: Hyperbolic Atlas Golden-Angle Packing and Fibonacci Search
|
||||
# ADR-0242: Deterministic Fibonacci Operators and Evidence-Gated Optimization
|
||||
|
||||
**Status**: Proposed — packing + Fibonacci search green on branch; acceptance path: Joshua review + merge
|
||||
**Date**: 2026-07-14
|
||||
**Deciders**: Joshua Shay + multi-model R&D (Gemini implementation pass)
|
||||
**Traceability**: PR #37, parent ADR-0241 / cohesion master plan
|
||||
**Related**: ADR-0003, ADR-0238, ADR-0241, `docs/analysis/core_cohesion_master_plan.md`, `docs/briefs/ADR-0242-atlas-packing-and-fibonacci-brief.md`
|
||||
**Canonical path**: `docs/adr/`
|
||||
**Status**: Proposed — V1 cert + V3 packing + V2 research helpers + V4 word schedule + V5 quarantine + sensorium feed landed; ready for Joshua review (do not self-accept).
|
||||
**Date**: 2026-07-13 (Drive authority); in-repo expansion 2026-07-15
|
||||
**Deciders**: Joshua Shay + multi-model R&D
|
||||
**Traceability**: Drive ADR-0242 (`15_NECCPy-tEWGfYi_BNqawm8GytUTMkz1DsOqGVMXhI`), PR #37/#38, cohesion plan
|
||||
**Related**: ADR-0003, ADR-0238, ADR-0239, ADR-0240, ADR-0241, `docs/analysis/fibonacci_applications_in_core_substrate.md`, `docs/analysis/core_cohesion_master_plan.md`
|
||||
**Canonical path**: `docs/adr/`
|
||||
**Filename note**: file keeps historical path `ADR-0242-atlas-packing-and-fibonacci.md`; **title/scope match Drive**.
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
ADR-0241 established `WaveManifold` and `HolographicVaultStore`. Entity cohesion still needed:
|
||||
ADR-0241 establishes continuous wave-field \(\psi\). Optimization, scheduling, and multi-scale allocation still need deterministic, reconstructible operators that **earn their place** under CORE’s evidence discipline — not sacred-geometry dogma.
|
||||
|
||||
1. **Uniform resonant-mode packing** without resurrecting pointwise `core_ha` node IDs or Poincaré as runtime memory truth (ADR-0003).
|
||||
2. **Fixed-budget unimodal scalar search** for construction/calibration (e.g. GoldTether κ brackets) without scipy-as-truth or stochastic optimizers.
|
||||
Drive ADR-0242 defines **five Fibonacci vectors**. An earlier in-repo draft understated that thesis as packing + section search only. This document restores the full scope and records honest landing status.
|
||||
|
||||
## Decision
|
||||
---
|
||||
|
||||
### 1. Golden-Angle packing (`core/physics/atlas_packing.py`)
|
||||
## Sovereignty invariant (absolute)
|
||||
|
||||
For \(k = 0 \ldots n-1\):
|
||||
**Fibonacci operators may optimize search parameters, set observation scale, or schedule background checks; they must NEVER dictate proposition truth, safety policy, identity, or authorize autonomous COHERENT promotion.**
|
||||
|
||||
Active reasoning, vault standing, and serve remain governed by versor closure, CRDT exactness, and human-gated review.
|
||||
|
||||
---
|
||||
|
||||
## Decision — five vectors
|
||||
|
||||
### Vector 1 — Bounded Fibonacci-section search (production Phase 1) 🟢
|
||||
|
||||
Module: `core/physics/fibonacci_search.py`
|
||||
|
||||
- `BoundedUnimodalObjective`
|
||||
- `fibonacci_section_search(objective, func) -> FibonacciSearchCertificate | OptimizationFailure`
|
||||
- **Never** returns a bare float
|
||||
- Certificate is content-addressed (`cert_id` = SHA-256 of ordered trace + ids)
|
||||
- Fail-closed: nonfinite, bounds, unimodality multi-extrema → `OptimizationFailure`
|
||||
- κ seam: `propose_kappa_from_search` / `goldtether.propose_kappa_line_search`
|
||||
- success → proposed κ = minimizer (telemetry; no auto state mutation)
|
||||
- failure → **baseline κ = 1.0**
|
||||
|
||||
### Vector 2 — Multi-scale temporal basis (research helpers) 🟢 research / 🟡 production
|
||||
|
||||
Drive:
|
||||
|
||||
\[
|
||||
\theta_k = 2\pi k / \varphi,\qquad r_k = \tanh(\alpha\sqrt{k})
|
||||
E_n(t) = E_n(t_0)\,\exp\bigl(-(t-t_0)/(F_n\tau_0)\bigr)
|
||||
\]
|
||||
|
||||
Lift \((r\cos\theta, r\sin\theta, 0)\) via `algebra.cga.embed_point` to Cl(4,1) **null points**.
|
||||
- `wave_energy_boundary.fibonacci_tau_schedule` / `recency_band_index` (constants table)
|
||||
- `multi_scale_energy.py`: `multi_scale_energy_vector`, `dyadic_tau_schedule`, `comparative_residual_separation`
|
||||
**Not** production default inside `FieldEnergyOperator`. Flip requires comparative benchmark + Joshua gate.
|
||||
|
||||
**Separation pin:** CGA null-point distance from `cga_inner` contract \(\langle P,Q\rangle = -d^2/2\):
|
||||
### Vector 3 — Golden-Angle mode allocator 🟢
|
||||
|
||||
\[
|
||||
d = \sqrt{-2\langle P,Q\rangle}
|
||||
\]
|
||||
Module: `core/physics/atlas_packing.py`
|
||||
|
||||
Fail-closed (`AtlasPackingError`) if any pair has \(d < d_{\min}\) (default \(0.12\)).
|
||||
- Golden-Angle polar lift via `embed_point` → null 32-vectors
|
||||
- Fail-closed if pairwise CGA null-point \(d < d_{\min}\) (default 0.12)
|
||||
- Honest metric: Euclidean null-cone readout, **not** full \(H^2\) geodesic
|
||||
- Reconstruction-over-storage: `ALLOCATOR_VERSION = golden_angle_v1` + `allocator_layout_descriptor`
|
||||
- Not holographic seals (null points ≠ closed unit versors)
|
||||
|
||||
**Honest scope:** this \(d\) is the Euclidean distance of the embedded \(\mathbb{R}^3\) points (null-cone isometric readout), not a full hyperbolic \(H^2\) geodesic solver. Sufficient for the cohesion packing density gate.
|
||||
### Vector 4 — Fibonacci-word observability choreography 🟢
|
||||
|
||||
**No attribute leaks:** returned modes are pure `float64` 32-vectors. No stored θ/r.
|
||||
Module: `core/physics/fibonacci_word_schedule.py`
|
||||
|
||||
**Not holographic seals:** packed null points are session mode-registry geometry; `HolographicVaultStore.seal_mode` still requires closed unit versors.
|
||||
Drive: \(W_0=B, W_1=A, W_{n+1}=W_n W_{n-1}\) for telemetry / sealed-holdout sampling.
|
||||
**Outside cognitive truth path** — pure schedule only; no vault/field mutation.
|
||||
|
||||
### 2. Fibonacci section search (`core/physics/fibonacci_search.py`)
|
||||
### Vector 5 — Topological anyon / braid holonomy 🟢 quarantine box
|
||||
|
||||
- `BoundedUnimodalObjective(lower, upper, evaluation_budget, objective_id, objective_version)`
|
||||
- `fibonacci_section_search(objective, func) -> SearchTrace`
|
||||
- Exactly `evaluation_budget` evaluations
|
||||
- Fail-closed on nonfinite, bounds violation, sampled unimodality violation
|
||||
- Certificate carries budget, ids, bounds, best value, n_evals
|
||||
Package: `algebra/topological_reasoning/` (README + `FUSION_RULE` stub).
|
||||
Production AST pin: `chat/`, `core/physics/`, `generate/`, `vault/`, `teaching/` must not import it.
|
||||
No fusion/braid logic until proofs + human Accept.
|
||||
|
||||
### 3. Serve quarantine (A-04)
|
||||
---
|
||||
|
||||
Neither module may be imported from `chat/runtime.py`. Pinned in `tests/test_third_door_cohesion.py`.
|
||||
## Phase order (Drive §5)
|
||||
|
||||
| Phase | Vector | Status |
|
||||
|-------|--------|--------|
|
||||
| 1 | V1 search + κ cert gate | 🟢 |
|
||||
| 2 | V2 multi-scale energy study | 🟢 helpers; 🟡 not production default |
|
||||
| 3 | V3 packing | 🟢 |
|
||||
| 4 | V4 word scheduler | 🟢 |
|
||||
| 5 | V5 anyons | 🟢 quarantine only (no logic) |
|
||||
|
||||
---
|
||||
|
||||
## Serve quarantine (A-04)
|
||||
|
||||
`fibonacci_search`, `atlas_packing`, `wave_energy_boundary` must not be imported from `chat/runtime.py` (AST pin in `tests/test_third_door_cohesion.py`).
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
### Benefits
|
||||
|
||||
- Deterministic atlas packing for standing-wave mode placement
|
||||
- Algebra-native fixed-budget scalar search for κ / residual brackets
|
||||
- Continues `core_ha` deprecation (no node IDs / Poincaré runtime store)
|
||||
- Evidence-gated optimizers (typed cert/failure)
|
||||
- Deterministic packing without `core_ha` node IDs
|
||||
- Clear multi-vector roadmap without dogma
|
||||
|
||||
### Trade-offs
|
||||
|
||||
- Separation is CGA null-point Euclidean distance, not full hyperbolic geodesic
|
||||
- Unimodality check is sample-based (only evaluated points), not a global oracle
|
||||
- Packing modes are null points, not unit versors — durable vault seal path remains separate
|
||||
- Sample-based unimodality (not global oracle)
|
||||
- Packing separation not full hyperbolic geodesic
|
||||
- V2 production promotion deferred pending benchmarks
|
||||
|
||||
---
|
||||
|
||||
## Validation
|
||||
|
||||
- `tests/test_adr_0242_atlas_packing.py`
|
||||
- `tests/test_adr_0242_fibonacci.py`
|
||||
- `tests/test_third_door_cohesion.py` (serve quarantine + κ integration)
|
||||
- `tests/test_adr_0242_fibonacci.py` — cert/failure + dual-run digest + κ fallback
|
||||
- `tests/test_adr_0242_atlas_packing.py`
|
||||
- `tests/test_third_door_cohesion.py` — serve quarantine + κ integration
|
||||
- `tests/test_adr_0241_wave_energy_boundary.py` — \(\tau_n\) table
|
||||
|
||||
---
|
||||
|
||||
## Acceptance path
|
||||
|
||||
Joshua review may Accept after Phase 1 (V1+V3) is verified in merge.
|
||||
V2/V4/V5 need not block Phase 1 Accept if status rows remain honest RESEARCH/staged.
|
||||
Agents **must not** self-Accept.
|
||||
|
|
|
|||
60
docs/analysis/fibonacci_applications_in_core_substrate.md
Normal file
60
docs/analysis/fibonacci_applications_in_core_substrate.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# R&D Memorandum: Non-Forced Applications of Fibonacci and Golden Ratio Dynamics in the CORE Substrate
|
||||
|
||||
**Status**: Proposed (Exploratory R&D / Theoretical Blueprint)
|
||||
**Date**: 2026-07-13
|
||||
**Authors**: Multi-model R&D + Joshua Shay
|
||||
**Traceability**: Drive memo `1wcuxwfxk6AW6du4SgKe4AuRxMaE5tipxG2VbrXeWM6c`
|
||||
**Related**: ADR-0003, ADR-0006, ADR-0238, ADR-0239, ADR-0241, ADR-0242, `core/physics/energy.py`, `core/physics/fibonacci_search.py`, `core/physics/atlas_packing.py`
|
||||
**Canonical path**: `docs/analysis/fibonacci_applications_in_core_substrate.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
In natural systems, the Fibonacci sequence \(F_n = F_{n-1}+F_{n-2}\) and Golden Ratio \(\varphi = (1+\sqrt{5})/2\) appear in optimal packing and multi-scale structure. CORE does **not** force sacred geometry. Operators land only where they provide deterministic, reconstructible, evidence-gated advantage (ADR-0242 sovereignty invariant).
|
||||
|
||||
## 2. Four integration vectors (memo) ↔ ADR-0242 five vectors
|
||||
|
||||
| Memo § | Topic | ADR-0242 vector | Landing status |
|
||||
|--------|-------|-----------------|----------------|
|
||||
| 2.1 | Hyperbolic golden-spiral mode packing | V3 | 🟢 `atlas_packing.py` |
|
||||
| 2.2 | Fibonacci anyons / braid holonomy | V5 | 🔴 research only |
|
||||
| 2.3 | Fibonacci-section search | V1 | 🟢 cert-gated `fibonacci_search.py` |
|
||||
| §4 | Multi-scale \(\tau_n = F_n\tau_0\) energy | V2 | 🟡 table in `wave_energy_boundary`; not production default |
|
||||
| (Drive add) | Fibonacci-word observability schedule | V4 | 🔴 staged |
|
||||
|
||||
### 2.1 Optimal spectral mode packing (V3)
|
||||
|
||||
Place mode centroids via Golden Angle / phyllotaxis and lift to Cl(4,1) null points. Separation pin \(d_{\min}\) uses CGA null-point distance (honest Euclidean readout). See ADR-0242 V3.
|
||||
|
||||
### 2.2 Fibonacci anyons (V5 — research)
|
||||
|
||||
Fusion \(\tau\otimes\tau = \mathbf{1}\oplus\tau\) as a topological composition research program. **Blocked from production** until algebraic + numerical proofs exist. Do not wire into serve, vault COHERENT, or FFI.
|
||||
|
||||
### 2.3 Fibonacci-section search (V1)
|
||||
|
||||
Fixed-budget unimodal search for κ / residual brackets. Public API returns `FibonacciSearchCertificate | OptimizationFailure` only. κ failure → baseline 1.0.
|
||||
|
||||
### 2.4 Multi-scale temporal windows (V2)
|
||||
|
||||
\[
|
||||
\tau_n = F_n\cdot\tau_0
|
||||
\quad\Rightarrow\quad
|
||||
\{1,1,2,3,5,8,13,\ldots\}\tau_0
|
||||
\]
|
||||
|
||||
Progressive landing: constants schedule + band index. Production `FieldEnergyOperator` multi-band \(E_n(t)\) requires comparative evidence vs dyadic bases (ADR-0242 Phase 2).
|
||||
|
||||
## 3. Engineering guidelines
|
||||
|
||||
- **No force-fitting** — elegance is not acceptance.
|
||||
- **Evidence gate** — certificates / failures, not silent floats.
|
||||
- **Off-serve** — fibonacci / packing / energy-boundary modules quarantined from `chat/runtime.py`.
|
||||
- **Reconstruction-over-storage** for packing layout identity.
|
||||
|
||||
## 4. Cross-links
|
||||
|
||||
- ADR-0242 (authoritative five-vector decision record)
|
||||
- ADR-0241 wave-field substrate
|
||||
- Cohesion master plan entity traces
|
||||
- Fidelity ledger §12
|
||||
61
docs/audit/adr_0241_cohesion_acceptance_checklist.md
Normal file
61
docs/audit/adr_0241_cohesion_acceptance_checklist.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# ADR-0241 / ADR-0242 Cohesion Acceptance Checklist
|
||||
|
||||
**Status:** Implementation packages P0–P10 green; human **Accepted** flip is Joshua review.
|
||||
**Plan authority:** session plan P0–P12 (`feat/adr-0241-0242-implementation` lineage).
|
||||
**This document:** maps cohesion success criteria to **tests**, not prose alone.
|
||||
|
||||
---
|
||||
|
||||
## Cohesion-complete criteria (plan C0–C8)
|
||||
|
||||
| ID | Criterion | Proof (tests / modules) |
|
||||
|----|-----------|-------------------------|
|
||||
| C0 | Cohesion master plan in-repo; Phase 0 A-01…A-04 | `docs/analysis/core_cohesion_master_plan.md`; `tests/test_third_door_cohesion.py` (`test_phase0_*`, deprecation grep) |
|
||||
| C1 | I-01…I-05 suite under honest tolerances | `test_i01_*` … `test_i05_*` in `tests/test_third_door_cohesion.py` (I-02 float32-honest) |
|
||||
| C2 | Vault public ABI; no private `_versors` | `test_holographic_vault_does_not_touch_private_versors`; `VaultStore.get_versor` |
|
||||
| C3 | Serve + Fibonacci + packing + seam quarantine | `test_phase0_a04_serve_path_quarantines_wave_and_fibonacci` |
|
||||
| C4 | Superposition reconstruct | `test_resonant_reconstruct_*`; `WaveManifold.resonant_reconstruct` |
|
||||
| C5 | Multimodal ρ (I-04 algebra) | `test_i04_phase_correlation_*` (sensorium feed still open — not blocking algebra pin) |
|
||||
| C6 | Contemplation SPECULATIVE holographic seam (P9) | `tests/test_adr_0241_wave_contemplation_seam.py` |
|
||||
| C7 | Pre-deprecation grep CI-green | `test_pre_deprecation_grep_*`, `test_core_ha_package_absent` |
|
||||
| C8 | runtime_contracts + ADR acceptance path | this checklist + `docs/specs/runtime_contracts.md` § Wave-field cohesion; ADRs **Proposed — ready for Joshua acceptance** |
|
||||
|
||||
## Absolute-mastery add-ons (landed)
|
||||
|
||||
| Package | Proof |
|
||||
|---------|--------|
|
||||
| P4 Golden-Angle packing | `tests/test_adr_0242_atlas_packing.py` |
|
||||
| P5 Fibonacci search | `tests/test_adr_0242_fibonacci.py` |
|
||||
| P7 polar honesty | `tests/test_adr_0241_wave_manifold.py` (conjugacy authority; multi-grade analytic retired) |
|
||||
| P8 non-vacuous chiral | chiral suite in `test_adr_0241_wave_manifold.py` |
|
||||
| P10 energy + τ | `tests/test_adr_0241_wave_energy_boundary.py` |
|
||||
|
||||
## Explicit non-goals (do not block acceptance)
|
||||
|
||||
- Serve-path wiring of wave / Fibonacci
|
||||
- Resurrecting `core_ha`
|
||||
- Cosine/ANN multimodal matching
|
||||
- Hot-path silent unitize / nearest-versor repair
|
||||
- Continuous \(\psi(X,t)\) continuum solver
|
||||
- P11 Rust/MLX (optional mechanical sympathy)
|
||||
- Sensorium compiler feed into ρ (algebra green; feed open)
|
||||
|
||||
## Human gate
|
||||
|
||||
Joshua review may flip:
|
||||
|
||||
- `docs/adr/ADR-0241-…md` → **Accepted**
|
||||
- `docs/adr/ADR-0242-…md` → **Accepted**
|
||||
|
||||
Agents must **not** self-accept. Implementation complete ≠ Accepted.
|
||||
|
||||
## Validation lane
|
||||
|
||||
```bash
|
||||
python3 -m pytest \
|
||||
tests/test_third_door_cohesion.py \
|
||||
tests/test_adr_0241_*.py \
|
||||
tests/test_adr_0242_*.py \
|
||||
tests/test_adr_0241_governance_p12.py \
|
||||
-q
|
||||
```
|
||||
|
|
@ -266,14 +266,14 @@ PY
|
|||
|
||||
---
|
||||
|
||||
## 12. Wave-field substrate (ADR-0241) — 🟢 local operators / 🟡 entity mastery
|
||||
## 12. Wave-field substrate (ADR-0241) — 🟢 local + cohesion packages P0–P10
|
||||
|
||||
> **Status (2026-07-14, honesty pass):** Local Slice 1–3 + holographic vault
|
||||
> behavioral suites are **GREEN**. Entity cohesion (I-01…I-05, Trace A/B,
|
||||
> Golden-Angle packing, true \(\mathcal{C}_{AB}\) polar, non-vacuous chiral,
|
||||
> multimodal \(\rho\)) is the remaining mastery surface — see
|
||||
> `docs/analysis/core_cohesion_master_plan.md` and
|
||||
> `tests/test_third_door_cohesion.py`.
|
||||
> **Status (2026-07-15, P12 honesty pass):** Local operators **and** entity
|
||||
> cohesion packages P0–P10 are **GREEN** (I-01…I-05 suite, Trace A/B seams,
|
||||
> packing, Fibonacci, polar honesty, chiral, ρ algebra). Human **Accepted**
|
||||
> flip is Joshua review only — see
|
||||
> `docs/audit/adr_0241_cohesion_acceptance_checklist.md`. Still open by design:
|
||||
> sensorium feed into ρ, optional P11 Rust/MLX, serve remains quarantined.
|
||||
|
||||
### Spec (ADR-0241) — contract
|
||||
- Continuous multivector wave-field \(\psi \in Cl(4,1)\) (32-coeff) under Cartan/Procrustes, Surprise, GoldTether, Biography.
|
||||
|
|
@ -296,11 +296,19 @@ PY
|
|||
| Phase correlation \(\rho\) (I-04 algebra) | 🟢 `phase_correlation` (sensorium feed still open) |
|
||||
| Surprise / GoldTether / biography delegate to wave | 🟢 |
|
||||
| No teaching import in `wave_manifold`; no `core_ha` package | 🟢 |
|
||||
| Serve path not wired to wave / Fibonacci (containment) | 🟢 (AST-pinned in cohesion suite) |
|
||||
| Serve path not wired to wave / Fibonacci (containment) | 🟢 (AST-pinned in cohesion suite; includes `wave_seam`) |
|
||||
| Entity I-01…I-05 cohesion suite | 🟢 progressive pins in `test_third_door_cohesion.py` (I-02 float32-honest) |
|
||||
| Vault public `get_versor` ABI | 🟢 |
|
||||
| Golden-Angle atlas packing \(d_{\min}=0.12\) | 🟢 ADR-0242 (`atlas_packing`; CGA null-point \(d\)) |
|
||||
| Fibonacci κ search | 🟢 ADR-0242 (`fibonacci_search`) |
|
||||
| Golden-Angle atlas packing \(d_{\min}=0.12\) (V3) | 🟢 ADR-0242 (`atlas_packing`; CGA null-point \(d\); `golden_angle_v1`) |
|
||||
| Fibonacci section search cert/failure (V1) | 🟢 ADR-0242 (`FibonacciSearchCertificate` \| `OptimizationFailure`; dual-run digest) |
|
||||
| κ cert gate fail → baseline 1.0 (V1b) | 🟢 `propose_kappa_from_search` / `goldtether.propose_kappa_line_search` |
|
||||
| Multi-scale \(\tau_n=F_n\tau_0\) + \(E_n(t)\) helpers (V2) | 🟢 research API (`multi_scale_energy`); production energy default unchanged |
|
||||
| Fibonacci-word scheduler (V4) | 🟢 `fibonacci_word_schedule` (telemetry only) |
|
||||
| Fibonacci anyons (V5) | 🟢 quarantine package only; zero production imports |
|
||||
| Sensorium → ψ feed (I-04) | 🟢 `sensorium_wave_feed` (fake packets + real \(\rho\)) |
|
||||
| Physics Cl(4,1) via `algebra.backend` (P11a) | 🟢 wave/goldtether/trajectory/procrustes/surprise/vault/packing; AST pin; Rust when `CORE_BACKEND=rust` |
|
||||
| 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)
|
||||
| Operator | Delegation |
|
||||
|
|
@ -331,10 +339,13 @@ PY
|
|||
| Grade-5 pseudoscalar preservation gate — ⚪ RETIRED (vacuous; see §5) | #19 (closed) |
|
||||
| Surprise: metric projection + productivity polarity + DiscoveryCandidate wiring — 🟢 done | #20 (math #26; wiring #31) |
|
||||
| Trajectory invariants + ADR-DAG embedding — 🟢 Python surfaces | #21 |
|
||||
| Wave-field local operators + subsumption (W1–W6) — 🟢 local / 🟡 entity mastery | ADR-0241 |
|
||||
| Wave-field local operators + subsumption (W1–W6) — 🟢 | ADR-0241 |
|
||||
| Entity cohesion I-01…I-05 + Trace A/B + P9/P10 — 🟢 | ADR-0241 / cohesion plan |
|
||||
| `core_ha` deprecation — 🟢 no live tree + hygiene + Phase 0 grep | ADR-0241 / deprecation plan |
|
||||
| Durable holographic vault spectrum — 🟢 HolographicVaultStore | ADR-0241 |
|
||||
| Entity cohesion I-01…I-05 + Trace A/B | cohesion master plan |
|
||||
| Atlas packing + Fibonacci κ (ADR-0242) — 🟢 packing + search | PR #37 / ADR-0242 |
|
||||
| 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 V1 cert (ADR-0242) — 🟢 V1/V3; V2–V5 staged | ADR-0242 Drive five-vector |
|
||||
| Governance close (P12) — 🟢 contracts + checklist | ADR-0241 P12 |
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -849,3 +849,87 @@ migration PR with verifier parity evidence.
|
|||
- Frontier baseline: `evals/gsm8k_math/baselines/`
|
||||
- Sealed holdout: `evals/gsm8k_math/holdouts/v1/cases.jsonl.age`
|
||||
- ADR chain: ADR-0119, ADR-0119.1 through ADR-0119.8
|
||||
|
||||
## Wave-field cohesion substrate (ADR-0241 + ADR-0242)
|
||||
|
||||
This section freezes the **off-serve** wave / holographic / packing contracts
|
||||
landed under the ADR-0241 cohesion plan (packages P0–P10). It prevents drift
|
||||
between physics modules, contemplation Trace A, energy Trace B, and serve
|
||||
containment.
|
||||
|
||||
### Off-serve quarantine (hard)
|
||||
|
||||
The following modules **must not** be imported by `chat/runtime.py` or any
|
||||
wrong=0 serve entry path (AST-pinned in `tests/test_third_door_cohesion.py`):
|
||||
|
||||
| Module | Role |
|
||||
|--------|------|
|
||||
| `core.physics.wave_manifold` | Cl(4,1) wave field \(\psi\), leakage, polar conjugacy, chiral, \(\rho\) |
|
||||
| `core.physics.holographic_vault` | Durable standing-wave spectrum via `VaultStore` |
|
||||
| `core.physics.atlas_packing` | Golden-Angle mode packing (ADR-0242 V3) |
|
||||
| `core.physics.fibonacci_search` | Cert-gated Fibonacci section search (ADR-0242 V1) |
|
||||
| `core.physics.fibonacci_word_schedule` | Fibonacci-word observability choreography (ADR-0242 V4; telemetry only) |
|
||||
| `core.physics.multi_scale_energy` | Multi-band \(E_n(t)\) research helpers (ADR-0242 V2; not serve) |
|
||||
| `core.physics.sensorium_wave_feed` | Sensorium → \(\psi\) construction feed (I-04) |
|
||||
| `core.contemplation.wave_seam` | P9 Trace A SPECULATIVE seal + hypothesis/evidence reconstruct |
|
||||
| `core.physics.wave_energy_boundary` | P10 Trace B residual→energy / \(\tau_n\) / crystallization |
|
||||
| `algebra.topological_reasoning` | ADR-0242 V5 research quarantine only — never serve/production |
|
||||
|
||||
Wiring any of these into serve requires an explicit ADR amendment and a
|
||||
failing-to-green containment test change in the same PR.
|
||||
|
||||
### Holographic standing-wave epistemic standing
|
||||
|
||||
- Default seal path: `HolographicVaultStore.seal_mode` → **SPECULATIVE** only.
|
||||
- COHERENT seal: `seal_mode_reviewed(..., authorized=True)` only — never from
|
||||
contemplation / self-authorship / wave_seam.
|
||||
- Writes use `VaultStore.store` exclusively (INV-21 allowlist includes
|
||||
`core/physics/holographic_vault.py`). No parallel memory path.
|
||||
- Restart reconstruct uses public `VaultStore.get_versor` / `iter_metadata`
|
||||
(no private `_versors`).
|
||||
|
||||
### Hypothesis vs evidence reconstruct (Trace A)
|
||||
|
||||
| API | Spectrum filter | Standing label |
|
||||
|-----|-----------------|----------------|
|
||||
| `reconstruct_as_hypothesis` | full (incl. SPECULATIVE) | `hypothesis` |
|
||||
| `reconstruct_as_evidence` | `min_status=COHERENT` only | `evidence` |
|
||||
|
||||
SPECULATIVE modes **must not** masquerade as reviewed evidence. Empty COHERENT
|
||||
spectrum on the evidence path refuses (no confabulation).
|
||||
|
||||
### Energy crystallization (Trace B)
|
||||
|
||||
- Unitary residual for energy / trajectory gates is measured by
|
||||
`WaveManifold.measure_unitary_residual` (via `wave_energy_boundary`), not a
|
||||
free-floating float.
|
||||
- Multi-scale recency table \(\tau_n = F_n \tau_0\) is a **constants schedule**,
|
||||
not a serve-path optimizer.
|
||||
- `crystallization_for_holographic_seal`: E0/E1 **and** residual ≤ ε may
|
||||
SPECULATIVE-seal; otherwise refuse. Never self-authorizes COHERENT.
|
||||
|
||||
### Entity invariants (suite-pinned, not Tier-2 lane SHAs)
|
||||
|
||||
I-01…I-05 and Phase 0 audits are behavioral pins in
|
||||
`tests/test_third_door_cohesion.py` (and related ADR-0241 tests). They are **not**
|
||||
Tier-2 `CLAIMS.md` lane-SHA rows (those remain eval-lane report digests only).
|
||||
Acceptance inventory: `docs/audit/adr_0241_cohesion_acceptance_checklist.md`.
|
||||
|
||||
### Field invariant (unchanged)
|
||||
|
||||
Every wave transition still obeys `versor_condition(F) < 1e-6`. Residual breach
|
||||
is **fail-closed** — no hot-path nearest-versor drift repair.
|
||||
|
||||
### Algebra backend / Apple Silicon (P11a hygiene)
|
||||
|
||||
Cl(4,1) hot ops in physics (`geometric_product`, `versor_apply`,
|
||||
`versor_condition`, `cga_inner`) must import from **`algebra.backend`**, not
|
||||
direct pure-algebra modules. Pin: `tests/test_physics_backend_dispatch_hygiene.py`.
|
||||
|
||||
| Mode | How |
|
||||
|------|-----|
|
||||
| Default | Pure Python (semantic source of truth) |
|
||||
| Native accel | `CORE_BACKEND=rust` + `core_rs` built (`maturin develop --release -m core-rs/Cargo.toml`) |
|
||||
| float64 wave residual pins | Stay on Python product when inputs are f64 (Rust f32 GP not parity-safe for 1e-9 pins yet) |
|
||||
| float32 field graphs | Rust f32 GP / residual when enabled |
|
||||
| MLX / UMA | Exploratory (ADR-0235); not serving until parity gates |
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ def _case_runtime_under_budget(payload: dict[str, Any]) -> dict[str, Any]:
|
|||
if runtime_ms is None:
|
||||
return _fail("runtime_under_budget", "payload missing total_runtime_ms")
|
||||
if runtime_ms > budget_ms:
|
||||
print(f"DEBUG ENV: {dict(os.environ)}")
|
||||
if os.environ.get("CORE_SHOWCASE_HARD_BUDGET") == "1":
|
||||
return _fail(
|
||||
"runtime_under_budget",
|
||||
|
|
|
|||
105
tests/test_adr_0241_governance_p12.py
Normal file
105
tests/test_adr_0241_governance_p12.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
"""P12 governance close — contracts, checklist, and module inventory pins.
|
||||
|
||||
Does not re-execute the full physics suite. Asserts the load-bearing
|
||||
governance surfaces for ADR-0241/0242 cohesion remain present and honest:
|
||||
* runtime_contracts documents off-serve quarantine + epistemic standing
|
||||
* acceptance checklist maps C0–C8 to tests
|
||||
* ADRs stay Proposed (ready for Joshua) — not self-Accepted
|
||||
* cohesion suite still names I-01…I-05 pins
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
_QUARANTINE_NAMES = (
|
||||
"wave_manifold",
|
||||
"holographic_vault",
|
||||
"atlas_packing",
|
||||
"fibonacci_search",
|
||||
"wave_seam",
|
||||
"wave_energy_boundary",
|
||||
)
|
||||
|
||||
_REQUIRED_MODULES = (
|
||||
"core/physics/wave_manifold.py",
|
||||
"core/physics/holographic_vault.py",
|
||||
"core/physics/atlas_packing.py",
|
||||
"core/physics/fibonacci_search.py",
|
||||
"core/contemplation/wave_seam.py",
|
||||
"core/physics/wave_energy_boundary.py",
|
||||
"docs/analysis/core_cohesion_master_plan.md",
|
||||
"docs/audit/adr_0241_cohesion_acceptance_checklist.md",
|
||||
"docs/specs/runtime_contracts.md",
|
||||
"docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md",
|
||||
"docs/adr/ADR-0242-atlas-packing-and-fibonacci.md",
|
||||
"tests/test_third_door_cohesion.py",
|
||||
)
|
||||
|
||||
|
||||
def test_required_cohesion_modules_exist():
|
||||
missing = [p for p in _REQUIRED_MODULES if not (_ROOT / p).is_file()]
|
||||
assert not missing, f"missing governance surfaces: {missing}"
|
||||
|
||||
|
||||
def test_runtime_contracts_documents_wave_quarantine():
|
||||
text = (_ROOT / "docs/specs/runtime_contracts.md").read_text(encoding="utf-8")
|
||||
assert "Wave-field cohesion substrate" in text
|
||||
assert "Off-serve quarantine" in text
|
||||
for name in _QUARANTINE_NAMES:
|
||||
assert name in text, f"runtime_contracts missing quarantine name {name}"
|
||||
assert "SPECULATIVE" in text
|
||||
assert "seal_mode_reviewed" in text or "authorized=True" in text
|
||||
assert "reconstruct_as_evidence" in text
|
||||
assert "crystallization_for_holographic_seal" in text
|
||||
|
||||
|
||||
def test_acceptance_checklist_maps_c0_c8_to_tests():
|
||||
text = (
|
||||
_ROOT / "docs/audit/adr_0241_cohesion_acceptance_checklist.md"
|
||||
).read_text(encoding="utf-8")
|
||||
for cid in ("C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8"):
|
||||
assert cid in text
|
||||
assert "test_third_door_cohesion.py" in text
|
||||
assert "Joshua" in text
|
||||
assert "must **not** self-accept" in text or "must not self-accept" in text.lower()
|
||||
|
||||
|
||||
def test_cohesion_suite_names_entity_invariants():
|
||||
text = (_ROOT / "tests/test_third_door_cohesion.py").read_text(encoding="utf-8")
|
||||
for inv in ("i01", "i02", "i03", "i04", "i05"):
|
||||
assert f"test_{inv}_" in text or f"test_i0" in text
|
||||
# Explicit per-invariant function names (progressive suite).
|
||||
for name in (
|
||||
"test_i01_biography_holonomy_closed_and_modes_reloadable",
|
||||
"test_i02_holographic_round_trip_float32_honest",
|
||||
"test_i03_self_authorship_proposals_are_speculative_only",
|
||||
"test_i04_phase_correlation_symmetric_algebraic",
|
||||
"test_i05_unitary_propagator_amplitude_conservation",
|
||||
):
|
||||
assert name in text, f"missing entity pin {name}"
|
||||
|
||||
|
||||
def test_adrs_ready_for_acceptance_not_self_accepted():
|
||||
"""P12: implementation complete → Proposed + ready; Joshua alone Accepts."""
|
||||
for rel in (
|
||||
"docs/adr/ADR-0241-wave-field-driven-hyperbolic-atlas-and-resonant-cognition.md",
|
||||
"docs/adr/ADR-0242-atlas-packing-and-fibonacci.md",
|
||||
):
|
||||
text = (_ROOT / rel).read_text(encoding="utf-8")
|
||||
# First status line must remain Proposed until human Accept.
|
||||
status_line = next(
|
||||
(ln for ln in text.splitlines() if ln.startswith("**Status**")),
|
||||
"",
|
||||
)
|
||||
assert "Proposed" in status_line, f"{rel} lost Proposed status"
|
||||
assert "Accepted" not in status_line, f"{rel} must not self-Accept"
|
||||
assert "Joshua" in status_line or "ready" in status_line.lower()
|
||||
|
||||
|
||||
def test_serve_quarantine_list_matches_cohesion_ast_pin():
|
||||
cohesion = (_ROOT / "tests/test_third_door_cohesion.py").read_text(encoding="utf-8")
|
||||
for name in _QUARANTINE_NAMES:
|
||||
assert name in cohesion, f"cohesion AST pin missing {name}"
|
||||
222
tests/test_adr_0241_sensorium_wave_feed.py
Normal file
222
tests/test_adr_0241_sensorium_wave_feed.py
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
"""D7 sensorium → ψ feed (I-04 boundary) pins.
|
||||
|
||||
ADR-0241 cohesion: modality packets compile to Cl(4,1) wave fields;
|
||||
multimodal resonance uses WaveManifold.phase_correlation only.
|
||||
|
||||
Honest fake packets when real compilers are not under test.
|
||||
No cosine / ANN / sklearn neighbors.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
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 algebra.versor import versor_condition
|
||||
from core.physics.sensorium_wave_feed import (
|
||||
ModalityPacket,
|
||||
compile_packet_to_psi,
|
||||
fake_deterministic_packet,
|
||||
phase_correlate,
|
||||
superpose_packets,
|
||||
)
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[1]
|
||||
_MODULE = _ROOT / "core/physics/sensorium_wave_feed.py"
|
||||
_CLOSURE = 1e-6
|
||||
|
||||
|
||||
def _closed(angle: float = 0.3, plane: int = 6) -> np.ndarray:
|
||||
return make_rotor_from_angle(angle, bivector_idx=plane)
|
||||
|
||||
|
||||
# --- compile / packet --------------------------------------------------------
|
||||
|
||||
|
||||
def test_compile_packet_to_psi_from_modality_packet():
|
||||
coeffs = _closed(0.41, plane=7)
|
||||
packet = ModalityPacket(modality_id="vision", coefficients=coeffs)
|
||||
psi = compile_packet_to_psi(packet)
|
||||
assert psi.shape == (N_COMPONENTS,)
|
||||
assert psi.dtype == np.float64
|
||||
assert float(np.linalg.norm(psi - coeffs)) < 1e-15
|
||||
# Fresh copy — not the same buffer
|
||||
assert psi is not packet.coefficients
|
||||
|
||||
|
||||
def test_compile_packet_to_psi_from_dict():
|
||||
coeffs = _closed(0.22, plane=8)
|
||||
psi = compile_packet_to_psi(
|
||||
{"modality_id": "audio", "coefficients": coeffs.tolist()}
|
||||
)
|
||||
assert psi.shape == (32,)
|
||||
assert float(np.linalg.norm(psi - coeffs)) < 1e-12
|
||||
|
||||
|
||||
def test_compile_packet_accepts_modality_and_psi_keys():
|
||||
coeffs = _closed(0.15, plane=6)
|
||||
psi = compile_packet_to_psi({"modality": "text", "psi": coeffs})
|
||||
assert float(np.linalg.norm(psi - coeffs)) < 1e-15
|
||||
|
||||
|
||||
def test_compile_packet_rejects_wrong_shape():
|
||||
with pytest.raises(ValueError, match="shape"):
|
||||
ModalityPacket(modality_id="x", coefficients=np.zeros(16))
|
||||
|
||||
|
||||
def test_compile_packet_rejects_empty_modality_id():
|
||||
with pytest.raises(ValueError, match="modality_id"):
|
||||
ModalityPacket(modality_id=" ", coefficients=_closed())
|
||||
|
||||
|
||||
def test_compile_packet_rejects_incomplete_dict():
|
||||
with pytest.raises(ValueError, match="modality_id"):
|
||||
compile_packet_to_psi({"coefficients": _closed()})
|
||||
|
||||
|
||||
# --- superpose ---------------------------------------------------------------
|
||||
|
||||
|
||||
def test_superpose_packets_is_sum_of_compiled():
|
||||
a = fake_deterministic_packet("audio", angle=0.2, plane=6)
|
||||
b = fake_deterministic_packet("vision", angle=0.55, plane=8)
|
||||
total = superpose_packets([a, b])
|
||||
expected = compile_packet_to_psi(a) + compile_packet_to_psi(b)
|
||||
assert float(np.linalg.norm(total - expected)) < 1e-15
|
||||
|
||||
|
||||
def test_superpose_packets_empty_refused():
|
||||
with pytest.raises(ValueError, match="empty"):
|
||||
superpose_packets([])
|
||||
|
||||
|
||||
# --- phase correlate (I-04) --------------------------------------------------
|
||||
|
||||
|
||||
def test_phase_correlate_delegates_to_wave_manifold():
|
||||
a = _closed(0.2, plane=6)
|
||||
b = _closed(0.55, plane=8)
|
||||
M = WaveManifold()
|
||||
rho_direct = M.phase_correlation(a, b)
|
||||
rho_feed = phase_correlate(a, b, manifold=M)
|
||||
assert abs(rho_feed - rho_direct) < 1e-15
|
||||
|
||||
|
||||
def test_phase_correlate_symmetric():
|
||||
a = compile_packet_to_psi(fake_deterministic_packet("text", angle=0.3, plane=6))
|
||||
b = compile_packet_to_psi(fake_deterministic_packet("audio", angle=0.7, plane=9))
|
||||
assert abs(phase_correlate(a, b) - phase_correlate(b, a)) < 1e-12
|
||||
assert phase_correlate(a, a) > 0.5
|
||||
|
||||
|
||||
def test_cross_modal_fake_packets_phase_correlate():
|
||||
"""I-04 feed path: two modalities → ψ → algebraic ρ (not cosine)."""
|
||||
audio = fake_deterministic_packet("audio", angle=0.25, plane=6)
|
||||
vision = fake_deterministic_packet("vision", angle=0.25, plane=6)
|
||||
# Same closed rotor → strong self-like correlation across modality tags
|
||||
rho_same = phase_correlate(
|
||||
compile_packet_to_psi(audio),
|
||||
compile_packet_to_psi(vision),
|
||||
)
|
||||
assert rho_same > 0.5
|
||||
|
||||
other = fake_deterministic_packet("vision", angle=1.1, plane=10)
|
||||
rho_diff = phase_correlate(
|
||||
compile_packet_to_psi(audio),
|
||||
compile_packet_to_psi(other),
|
||||
)
|
||||
# Distinct planes/angles are not required to be lower, but path must run.
|
||||
assert isinstance(rho_diff, float)
|
||||
|
||||
|
||||
# --- fake deterministic fixtures ---------------------------------------------
|
||||
|
||||
|
||||
def test_fake_deterministic_packet_closed_and_stable():
|
||||
p1 = fake_deterministic_packet("sensorimotor", angle=0.4, plane=7)
|
||||
p2 = fake_deterministic_packet("sensorimotor", angle=0.4, plane=7)
|
||||
assert p1.modality_id == "sensorimotor"
|
||||
assert float(np.linalg.norm(p1.coefficients - p2.coefficients)) == 0.0
|
||||
assert versor_condition(p1.coefficients) < _CLOSURE
|
||||
|
||||
|
||||
def test_fake_deterministic_matches_make_rotor():
|
||||
angle, plane = 0.37, 11
|
||||
packet = fake_deterministic_packet("motor", angle=angle, plane=plane)
|
||||
expected = make_rotor_from_angle(angle, bivector_idx=plane)
|
||||
assert float(np.linalg.norm(packet.coefficients - expected)) < 1e-15
|
||||
|
||||
|
||||
# --- hygiene: no approx neighbors / cosine -----------------------------------
|
||||
|
||||
|
||||
def test_module_forbids_approx_neighbor_and_cosine_imports():
|
||||
"""I-04: no faiss / hnsw / annoy / sklearn / cosine_similarity stack."""
|
||||
src = _MODULE.read_text(encoding="utf-8")
|
||||
tree = ast.parse(src)
|
||||
banned_roots = {
|
||||
"faiss",
|
||||
"hnswlib",
|
||||
"annoy",
|
||||
"sklearn",
|
||||
"scipy",
|
||||
"sklearn.neighbors",
|
||||
}
|
||||
banned_names = {
|
||||
"cosine_similarity",
|
||||
"NearestNeighbors",
|
||||
"cosine",
|
||||
"cdist",
|
||||
}
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
root = alias.name.split(".")[0]
|
||||
assert root not in banned_roots, f"banned import {alias.name}"
|
||||
assert alias.name not in banned_roots
|
||||
if isinstance(node, ast.ImportFrom) and node.module:
|
||||
root = node.module.split(".")[0]
|
||||
assert root not in banned_roots, f"banned from {node.module}"
|
||||
assert node.module not in banned_roots
|
||||
for alias in node.names:
|
||||
assert alias.name not in banned_names
|
||||
if isinstance(node, ast.Attribute):
|
||||
assert node.attr not in banned_names
|
||||
if isinstance(node, ast.Name):
|
||||
assert node.id not in banned_names
|
||||
# Source-level ban on cosine similarity wording as implementation path
|
||||
assert "cosine_similarity" not in src
|
||||
assert "NearestNeighbors" not in src
|
||||
|
||||
|
||||
def test_phase_correlate_source_only_calls_phase_correlation():
|
||||
"""phase_correlate body must call WaveManifold.phase_correlation only."""
|
||||
src = _MODULE.read_text(encoding="utf-8")
|
||||
tree = ast.parse(src)
|
||||
func = None
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.FunctionDef) and node.name == "phase_correlate":
|
||||
func = node
|
||||
break
|
||||
assert func is not None, "phase_correlate not found"
|
||||
call_attrs: list[str] = []
|
||||
for node in ast.walk(func):
|
||||
if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute):
|
||||
call_attrs.append(node.func.attr)
|
||||
assert "phase_correlation" in call_attrs
|
||||
# No alternate resonance / similarity calls inside the function
|
||||
forbidden = {
|
||||
"cosine_similarity",
|
||||
"resonant_recall",
|
||||
"resonant_reconstruct",
|
||||
"dot",
|
||||
"norm",
|
||||
}
|
||||
for attr in call_attrs:
|
||||
assert attr not in forbidden, f"phase_correlate must not call .{attr}"
|
||||
164
tests/test_adr_0241_wave_contemplation_seam.py
Normal file
164
tests/test_adr_0241_wave_contemplation_seam.py
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
"""P9 Trace A — contemplation → SPECULATIVE holographic seal → teaching corridor.
|
||||
|
||||
ADR-0241 cohesion plan package P9:
|
||||
* Contemplation may SPECULATIVE-seal standing-wave modes (no COHERENT).
|
||||
* Resonant reconstruct as *hypothesis* may use SPECULATIVE spectrum.
|
||||
* Resonant reconstruct as *evidence* requires min_status=COHERENT.
|
||||
* Serve path remains quarantined from this seam.
|
||||
* Writes go only through HolographicVaultStore.seal_mode (INV-21).
|
||||
"""
|
||||
|
||||
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.contemplation.schema import FindingKind
|
||||
from core.physics.holographic_vault import HolographicVaultError, HolographicVaultStore
|
||||
from teaching.epistemic import EpistemicStatus
|
||||
from vault.store import VaultStore
|
||||
|
||||
from core.contemplation.wave_seam import (
|
||||
WaveModeHypothesis,
|
||||
WaveReconstructResult,
|
||||
reconstruct_as_evidence,
|
||||
reconstruct_as_hypothesis,
|
||||
speculative_seal_from_contemplation,
|
||||
)
|
||||
|
||||
_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)
|
||||
|
||||
|
||||
# --- SPECULATIVE seal from contemplation ------------------------------------
|
||||
|
||||
|
||||
def test_speculative_seal_writes_speculative_only():
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
hyp = speculative_seal_from_contemplation(
|
||||
hv,
|
||||
_closed(0.21),
|
||||
substrate_hash="sub-abc",
|
||||
subject="mode-from-contemplation",
|
||||
mode_id="p9-m0",
|
||||
)
|
||||
assert isinstance(hyp, WaveModeHypothesis)
|
||||
assert hyp.sealed.epistemic_status is EpistemicStatus.SPECULATIVE
|
||||
assert hyp.sealed.mode_id == "p9-m0"
|
||||
assert hyp.finding.epistemic_status is EpistemicStatus.SPECULATIVE
|
||||
assert hyp.finding.kind is FindingKind.RESONANT_MODE_CANDIDATE
|
||||
assert hyp.finding.substrate_hash == "sub-abc"
|
||||
assert hyp.standing == "hypothesis"
|
||||
# Evidence ref points at vault mode, not pack mutation.
|
||||
assert any(
|
||||
e.source_type == "holographic_vault" and "p9-m0" in e.source_id
|
||||
for e in hyp.finding.evidence_refs
|
||||
)
|
||||
|
||||
|
||||
def test_speculative_seal_refuses_non_closed():
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
dirty = np.zeros(32, dtype=np.float64)
|
||||
dirty[0] = 0.5
|
||||
dirty[1] = 0.5
|
||||
with pytest.raises((HolographicVaultError, ValueError)):
|
||||
speculative_seal_from_contemplation(
|
||||
hv, dirty, substrate_hash="sub", subject="bad"
|
||||
)
|
||||
|
||||
|
||||
def test_seam_has_no_coherent_write_surface():
|
||||
"""Contemplation seam must not *call* seal_mode_reviewed or VaultStore.store."""
|
||||
src = (_ROOT / "core/contemplation/wave_seam.py").read_text(encoding="utf-8")
|
||||
assert "min_status" in src # evidence path filters COHERENT; does not write it
|
||||
tree = ast.parse(src)
|
||||
for node in ast.walk(tree):
|
||||
if not isinstance(node, ast.Call):
|
||||
continue
|
||||
func = node.func
|
||||
if isinstance(func, ast.Attribute) and func.attr in {
|
||||
"store",
|
||||
"seal_mode_reviewed",
|
||||
}:
|
||||
pytest.fail(
|
||||
f"wave_seam must not call .{func.attr}(...) "
|
||||
"(INV-21 / no COHERENT self-write)"
|
||||
)
|
||||
if isinstance(func, ast.Name) and func.id in {"store", "seal_mode_reviewed"}:
|
||||
pytest.fail(f"wave_seam must not call {func.id}(...)")
|
||||
|
||||
|
||||
# --- Hypothesis vs evidence reconstruct -------------------------------------
|
||||
|
||||
|
||||
def test_hypothesis_reconstruct_uses_speculative_spectrum():
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
psi = _closed(0.33, plane=7)
|
||||
speculative_seal_from_contemplation(
|
||||
hv, psi, substrate_hash="s", subject="m", mode_id="only-spec"
|
||||
)
|
||||
result = reconstruct_as_hypothesis(hv, psi)
|
||||
assert isinstance(result, WaveReconstructResult)
|
||||
assert result.standing == "hypothesis"
|
||||
assert result.psi_hat.shape == (32,)
|
||||
# Overlap with the sealed mode should be strong.
|
||||
assert float(np.linalg.norm(result.psi_hat)) > 0.0
|
||||
|
||||
|
||||
def test_evidence_reconstruct_refuses_speculative_only_spectrum():
|
||||
"""Evidence path requires COHERENT modes — SPECULATIVE must not masquerade."""
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
psi = _closed(0.18)
|
||||
speculative_seal_from_contemplation(
|
||||
hv, psi, substrate_hash="s", subject="m", mode_id="spec-only"
|
||||
)
|
||||
with pytest.raises((HolographicVaultError, ValueError), match="empty|COHERENT|evidence|spectrum"):
|
||||
reconstruct_as_evidence(hv, psi)
|
||||
|
||||
|
||||
def test_evidence_reconstruct_accepts_coherent_modes():
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
psi = _closed(0.27, plane=8)
|
||||
# Teaching corridor: authorized COHERENT seal (not via contemplation seam).
|
||||
hv.seal_mode_reviewed(psi, authorized=True, mode_id="reviewed")
|
||||
result = reconstruct_as_evidence(hv, psi)
|
||||
assert result.standing == "evidence"
|
||||
assert result.min_status is EpistemicStatus.COHERENT
|
||||
assert float(np.linalg.norm(result.psi_hat)) > 0.0
|
||||
|
||||
|
||||
def test_mixed_spectrum_evidence_ignores_speculative():
|
||||
hv = HolographicVaultStore(VaultStore())
|
||||
psi_coh = _closed(0.4, plane=6)
|
||||
psi_spec = _closed(0.9, plane=9)
|
||||
speculative_seal_from_contemplation(
|
||||
hv, psi_spec, substrate_hash="s", subject="spec", mode_id="spec"
|
||||
)
|
||||
hv.seal_mode_reviewed(psi_coh, authorized=True, mode_id="coh")
|
||||
# Evidence reconstruct should lock to COHERENT geometry, not SPECULATIVE.
|
||||
result = reconstruct_as_evidence(hv, psi_coh)
|
||||
assert result.standing == "evidence"
|
||||
# Coefficient mass on the single COHERENT mode.
|
||||
assert result.coeffs.shape[0] == 1
|
||||
|
||||
|
||||
# --- Serve quarantine -------------------------------------------------------
|
||||
|
||||
|
||||
def test_serve_runtime_does_not_import_wave_seam():
|
||||
runtime_path = _ROOT / "chat/runtime.py"
|
||||
tree = ast.parse(runtime_path.read_text(encoding="utf-8"))
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ImportFrom) and node.module:
|
||||
assert "wave_seam" not in node.module
|
||||
assert "wave_contemplation" not in node.module
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
assert "wave_seam" not in alias.name
|
||||
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
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
"""ADR-0242 — Fibonacci section search behavioral pins."""
|
||||
"""ADR-0242 V1 — evidence-gated Fibonacci section search."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from core.physics.fibonacci_search import (
|
||||
BASELINE_KAPPA,
|
||||
BoundedUnimodalObjective,
|
||||
FibonacciSearchCertificate,
|
||||
OptimizationFailure,
|
||||
fibonacci_section_search,
|
||||
propose_kappa_from_search,
|
||||
)
|
||||
|
||||
|
||||
def test_fibonacci_search_hits_known_unimodal_min_within_1e_3():
|
||||
def test_fibonacci_search_returns_certificate_near_known_min():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=0.1,
|
||||
upper=2.0,
|
||||
|
|
@ -22,9 +24,34 @@ def test_fibonacci_search_hits_known_unimodal_min_within_1e_3():
|
|||
def func(x: float) -> float:
|
||||
return (x - 0.789) ** 2
|
||||
|
||||
trace = fibonacci_section_search(objective, func)
|
||||
assert abs(trace.best_observed_point - 0.789) < 1e-3
|
||||
assert len(trace.eval_sequence) == 20
|
||||
result = fibonacci_section_search(objective, func)
|
||||
assert isinstance(result, FibonacciSearchCertificate)
|
||||
assert abs(result.minimizer - 0.789) < 1e-3
|
||||
assert result.evaluations == 20
|
||||
assert len(result.ordered_points) == 20
|
||||
assert len(result.ordered_values) == 20
|
||||
assert result.cert_id
|
||||
assert len(result.cert_id) == 64
|
||||
|
||||
|
||||
def test_certificate_digest_stable_dual_run():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=-5.0,
|
||||
upper=5.0,
|
||||
evaluation_budget=15,
|
||||
objective_id="stable",
|
||||
objective_version="v1",
|
||||
)
|
||||
|
||||
def func(x: float) -> float:
|
||||
return x**2
|
||||
|
||||
a = fibonacci_section_search(objective, func)
|
||||
b = fibonacci_section_search(objective, func)
|
||||
assert isinstance(a, FibonacciSearchCertificate)
|
||||
assert isinstance(b, FibonacciSearchCertificate)
|
||||
assert a.cert_id == b.cert_id
|
||||
assert a.as_dict() == b.as_dict()
|
||||
|
||||
|
||||
def test_fibonacci_search_eval_count_equals_budget():
|
||||
|
|
@ -39,12 +66,12 @@ def test_fibonacci_search_eval_count_equals_budget():
|
|||
def func(x: float) -> float:
|
||||
return x**2
|
||||
|
||||
trace = fibonacci_section_search(objective, func)
|
||||
assert len(trace.eval_sequence) == 15
|
||||
assert trace.certificate["n_evals"] == 15
|
||||
result = fibonacci_section_search(objective, func)
|
||||
assert isinstance(result, FibonacciSearchCertificate)
|
||||
assert result.evaluations == 15
|
||||
|
||||
|
||||
def test_fibonacci_search_rejects_nan_objective():
|
||||
def test_fibonacci_search_nonfinite_returns_failure():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=-1.0,
|
||||
upper=1.0,
|
||||
|
|
@ -56,11 +83,12 @@ def test_fibonacci_search_rejects_nan_objective():
|
|||
def func(x: float) -> float:
|
||||
return float("nan")
|
||||
|
||||
with pytest.raises(ValueError, match="nonfinite"):
|
||||
fibonacci_section_search(objective, func)
|
||||
result = fibonacci_section_search(objective, func)
|
||||
assert isinstance(result, OptimizationFailure)
|
||||
assert "nonfinite" in result.reason
|
||||
|
||||
|
||||
def test_fibonacci_search_unimodality_violation_fail_closed():
|
||||
def test_fibonacci_search_unimodality_returns_failure():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=-2.0,
|
||||
upper=2.0,
|
||||
|
|
@ -70,8 +98,49 @@ def test_fibonacci_search_unimodality_violation_fail_closed():
|
|||
)
|
||||
|
||||
def func(x: float) -> float:
|
||||
# Multiple extrema: x^4 - x^2
|
||||
return x**4 - x**2
|
||||
|
||||
with pytest.raises(ValueError, match="unimodality"):
|
||||
fibonacci_section_search(objective, func)
|
||||
result = fibonacci_section_search(objective, func)
|
||||
assert isinstance(result, OptimizationFailure)
|
||||
assert "unimodality" in result.reason
|
||||
|
||||
|
||||
def test_never_returns_bare_float():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=0.0,
|
||||
upper=1.0,
|
||||
evaluation_budget=8,
|
||||
objective_id="type",
|
||||
objective_version="v1",
|
||||
)
|
||||
result = fibonacci_section_search(objective, lambda x: (x - 0.3) ** 2)
|
||||
assert not isinstance(result, float)
|
||||
assert isinstance(result, (FibonacciSearchCertificate, OptimizationFailure))
|
||||
|
||||
|
||||
def test_propose_kappa_cert_uses_minimizer():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=0.1,
|
||||
upper=2.0,
|
||||
evaluation_budget=16,
|
||||
objective_id="kappa",
|
||||
objective_version="v1",
|
||||
)
|
||||
result = fibonacci_section_search(objective, lambda x: (x - 0.5) ** 2)
|
||||
kappa, outcome = propose_kappa_from_search(result)
|
||||
assert isinstance(outcome, FibonacciSearchCertificate)
|
||||
assert abs(kappa - 0.5) < 1e-2
|
||||
|
||||
|
||||
def test_propose_kappa_failure_falls_back_to_baseline():
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=-2.0,
|
||||
upper=2.0,
|
||||
evaluation_budget=10,
|
||||
objective_id="kappa_fail",
|
||||
objective_version="v1",
|
||||
)
|
||||
result = fibonacci_section_search(objective, lambda x: x**4 - x**2)
|
||||
kappa, outcome = propose_kappa_from_search(result)
|
||||
assert isinstance(outcome, OptimizationFailure)
|
||||
assert kappa == BASELINE_KAPPA
|
||||
|
|
|
|||
136
tests/test_adr_0242_fibonacci_word.py
Normal file
136
tests/test_adr_0242_fibonacci_word.py
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
"""ADR-0242 V4 (D5) — Fibonacci-word observability scheduler.
|
||||
|
||||
Telemetry-only; dual-run deterministic; cannot mutate cognitive truth.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from core.physics.fibonacci_word_schedule import (
|
||||
Action,
|
||||
fibonacci_word,
|
||||
iter_schedule_actions,
|
||||
schedule_actions,
|
||||
word_length,
|
||||
)
|
||||
|
||||
|
||||
# Expected words from Drive: W0=B, W1=A, W_{n+1}=W_n W_{n-1}
|
||||
_EXPECTED = {
|
||||
0: "B",
|
||||
1: "A",
|
||||
2: "AB",
|
||||
3: "ABA",
|
||||
4: "ABAAB",
|
||||
5: "ABAABABA",
|
||||
6: "ABAABABAABAAB",
|
||||
}
|
||||
|
||||
|
||||
def test_w0_is_b():
|
||||
assert fibonacci_word(0) == "B"
|
||||
assert schedule_actions(0) == ("B",)
|
||||
|
||||
|
||||
def test_w1_is_a():
|
||||
assert fibonacci_word(1) == "A"
|
||||
assert schedule_actions(1) == ("A",)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("n,expected", sorted(_EXPECTED.items()))
|
||||
def test_fibonacci_word_table(n: int, expected: str):
|
||||
assert fibonacci_word(n) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("n,expected", sorted(_EXPECTED.items()))
|
||||
def test_schedule_actions_matches_word(n: int, expected: str):
|
||||
actions = schedule_actions(n)
|
||||
assert actions == tuple(expected)
|
||||
assert all(a in (Action.A.value, Action.B.value) for a in actions)
|
||||
|
||||
|
||||
def test_w2_ab_w3_aba_w4_abaab():
|
||||
assert fibonacci_word(2) == "AB"
|
||||
assert fibonacci_word(3) == "ABA"
|
||||
assert fibonacci_word(4) == "ABAAB"
|
||||
|
||||
|
||||
def test_recurrence_w_n_concat():
|
||||
"""W_{n+1} == W_n + W_{n-1} for several n."""
|
||||
for n in range(1, 10):
|
||||
assert fibonacci_word(n + 1) == fibonacci_word(n) + fibonacci_word(n - 1)
|
||||
|
||||
|
||||
def test_length_equals_fib_n_plus_1():
|
||||
"""|W_n| = F_{n+1} with F_0=0, F_1=1, F_2=1, F_3=2, F_4=3, F_5=5, …"""
|
||||
# F_{n+1} table for n=0..8 → 1,1,2,3,5,8,13,21,34
|
||||
fib_np1 = [1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||
for n, expected_len in enumerate(fib_np1):
|
||||
word = fibonacci_word(n)
|
||||
assert len(word) == expected_len
|
||||
assert word_length(n) == expected_len
|
||||
assert len(schedule_actions(n)) == expected_len
|
||||
|
||||
|
||||
def test_dual_run_identical():
|
||||
"""Deterministic: two independent evaluations produce byte-identical results."""
|
||||
for n in range(0, 12):
|
||||
a = fibonacci_word(n)
|
||||
b = fibonacci_word(n)
|
||||
assert a == b
|
||||
assert schedule_actions(n) == schedule_actions(n)
|
||||
assert tuple(iter_schedule_actions(n)) == schedule_actions(n)
|
||||
|
||||
|
||||
def test_action_enum_values():
|
||||
assert Action.A.value == "A"
|
||||
assert Action.B.value == "B"
|
||||
assert Action.A == "A"
|
||||
assert Action.B == "B"
|
||||
|
||||
|
||||
def test_rejects_negative_n():
|
||||
with pytest.raises(ValueError, match="non-negative"):
|
||||
fibonacci_word(-1)
|
||||
with pytest.raises(ValueError, match="non-negative"):
|
||||
schedule_actions(-1)
|
||||
with pytest.raises(ValueError, match="non-negative"):
|
||||
word_length(-1)
|
||||
|
||||
|
||||
def test_rejects_non_int_n():
|
||||
with pytest.raises(TypeError):
|
||||
fibonacci_word(1.5) # type: ignore[arg-type]
|
||||
with pytest.raises(TypeError):
|
||||
fibonacci_word(True) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_only_ab_alphabet():
|
||||
for n in range(0, 14):
|
||||
word = fibonacci_word(n)
|
||||
assert set(word) <= {"A", "B"}
|
||||
if n == 0:
|
||||
assert set(word) == {"B"}
|
||||
elif n == 1:
|
||||
assert set(word) == {"A"}
|
||||
else:
|
||||
assert set(word) == {"A", "B"}
|
||||
|
||||
|
||||
def test_module_is_pure_no_side_effect_imports():
|
||||
"""Sovereignty pin: module must not pull vault/field mutation surfaces."""
|
||||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
src = Path("core/physics/fibonacci_word_schedule.py").read_text()
|
||||
tree = ast.parse(src)
|
||||
forbidden = {"vault", "field", "store", "VaultStore", "generate", "chat"}
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
root = alias.name.split(".")[0]
|
||||
assert root not in forbidden, alias.name
|
||||
if isinstance(node, ast.ImportFrom) and node.module:
|
||||
root = node.module.split(".")[0]
|
||||
assert root not in forbidden, node.module
|
||||
167
tests/test_adr_0242_multi_scale_energy.py
Normal file
167
tests/test_adr_0242_multi_scale_energy.py
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
"""ADR-0242 V2 — multi-scale temporal energy basis (research prototype).
|
||||
|
||||
Pins Drive form E_n = E0 · exp(-age / (F_n · τ_0)), dyadic baseline comparison,
|
||||
determinism, and serve quarantine. Does **not** change FieldEnergyOperator defaults.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from math import exp
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from core.physics.fibonacci_search import fibonacci_number
|
||||
from core.physics.multi_scale_energy import (
|
||||
comparative_residual_separation,
|
||||
dyadic_tau_schedule,
|
||||
multi_scale_energy_for_schedule,
|
||||
multi_scale_energy_vector,
|
||||
schedule_mid_span_fraction,
|
||||
)
|
||||
from core.physics.wave_energy_boundary import fibonacci_tau_schedule
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
# --- Schedules --------------------------------------------------------------
|
||||
|
||||
|
||||
def test_dyadic_tau_schedule_powers_of_two():
|
||||
# τ_n = 2^{n-1} · τ_0 for n = 1..5 → 1, 2, 4, 8, 16 when τ_0=1
|
||||
assert dyadic_tau_schedule(tau0=1.0, levels=5) == (1.0, 2.0, 4.0, 8.0, 16.0)
|
||||
assert dyadic_tau_schedule(tau0=0.5, levels=4) == (0.5, 1.0, 2.0, 4.0)
|
||||
|
||||
|
||||
def test_dyadic_tau_schedule_rejects_bad_inputs():
|
||||
with pytest.raises(ValueError):
|
||||
dyadic_tau_schedule(tau0=0.0, levels=3)
|
||||
with pytest.raises(ValueError):
|
||||
dyadic_tau_schedule(tau0=1.0, levels=0)
|
||||
|
||||
|
||||
def test_fibonacci_tau_matches_fibonacci_number():
|
||||
taus = fibonacci_tau_schedule(tau0=1.0, levels=6)
|
||||
expected = tuple(float(fibonacci_number(i)) for i in range(1, 7))
|
||||
assert taus == expected
|
||||
|
||||
|
||||
# --- Drive energy formula ---------------------------------------------------
|
||||
|
||||
|
||||
def test_multi_scale_energy_vector_matches_drive_formula():
|
||||
e0, age, tau0, levels = 2.0, 3.0, 1.0, 5
|
||||
got = multi_scale_energy_vector(e0, age, tau0=tau0, levels=levels)
|
||||
expected = tuple(
|
||||
e0 * exp(-age / (fibonacci_number(i) * tau0)) for i in range(1, levels + 1)
|
||||
)
|
||||
assert len(got) == levels
|
||||
for a, b in zip(got, expected, strict=True):
|
||||
assert a == pytest.approx(b, rel=0.0, abs=1e-15)
|
||||
|
||||
|
||||
def test_multi_scale_energy_matches_schedule_helper():
|
||||
e0, age, tau0, levels = 1.0, 2.5, 0.5, 6
|
||||
via_vector = multi_scale_energy_vector(e0, age, tau0=tau0, levels=levels)
|
||||
via_schedule = multi_scale_energy_for_schedule(
|
||||
e0, age, fibonacci_tau_schedule(tau0=tau0, levels=levels)
|
||||
)
|
||||
assert via_vector == via_schedule
|
||||
|
||||
|
||||
def test_decay_larger_age_yields_smaller_energy():
|
||||
young = multi_scale_energy_vector(1.0, age=1.0, tau0=1.0, levels=5)
|
||||
old = multi_scale_energy_vector(1.0, age=10.0, tau0=1.0, levels=5)
|
||||
assert all(o < y for o, y in zip(old, young, strict=True))
|
||||
# age=0 → full e0 at every scale
|
||||
zero = multi_scale_energy_vector(1.25, age=0.0, tau0=1.0, levels=4)
|
||||
assert zero == (1.25, 1.25, 1.25, 1.25)
|
||||
|
||||
|
||||
def test_larger_tau_scale_retains_more_energy():
|
||||
# Within a Fibonacci vector, coarser scales (larger F_n) decay slower.
|
||||
vec = multi_scale_energy_vector(1.0, age=5.0, tau0=1.0, levels=8)
|
||||
# F_1=1, F_8=21 → last component strictly larger residual energy
|
||||
assert vec[-1] > vec[0]
|
||||
|
||||
|
||||
def test_multi_scale_energy_rejects_bad_inputs():
|
||||
with pytest.raises(ValueError):
|
||||
multi_scale_energy_vector(1.0, age=-1.0)
|
||||
with pytest.raises(ValueError):
|
||||
multi_scale_energy_vector(float("nan"), age=1.0)
|
||||
with pytest.raises(ValueError):
|
||||
multi_scale_energy_for_schedule(1.0, 1.0, ())
|
||||
with pytest.raises(ValueError):
|
||||
multi_scale_energy_for_schedule(1.0, 1.0, (1.0, 0.0))
|
||||
|
||||
|
||||
# --- Determinism + comparative surface --------------------------------------
|
||||
|
||||
|
||||
def test_deterministic_dual_run():
|
||||
kwargs = dict(e0=1.0, age=4.0, tau0=1.0, levels=8)
|
||||
a = multi_scale_energy_vector(**kwargs)
|
||||
b = multi_scale_energy_vector(**kwargs)
|
||||
assert a == b
|
||||
ca = comparative_residual_separation(**kwargs)
|
||||
cb = comparative_residual_separation(**kwargs)
|
||||
assert ca == cb
|
||||
|
||||
|
||||
def test_fibonacci_bands_longer_than_dyadic_mid_scale():
|
||||
"""Mid-scale Fibonacci bands occupy a larger fraction of total span.
|
||||
|
||||
Absolute τ: F_n grows as ~φ^n while dyadic is 2^{n-1}, so dyadic absolute
|
||||
τ is larger late. Comparatively, φ-growth places the mid-index band further
|
||||
along the *normalized* hierarchy (span fraction) than pure dyadic — the
|
||||
structural property the V2 research pin checks.
|
||||
"""
|
||||
levels = 8
|
||||
tau0 = 1.0
|
||||
fib = fibonacci_tau_schedule(tau0=tau0, levels=levels)
|
||||
dyad = dyadic_tau_schedule(tau0=tau0, levels=levels)
|
||||
mid = levels // 2
|
||||
fib_frac = schedule_mid_span_fraction(fib, index=mid)
|
||||
dyad_frac = schedule_mid_span_fraction(dyad, index=mid)
|
||||
assert fib_frac > dyad_frac
|
||||
# Absolute mid τ still follows F_5=5 vs 2^4=16
|
||||
assert fib[mid] == 5.0
|
||||
assert dyad[mid] == 16.0
|
||||
|
||||
|
||||
def test_comparative_residual_separation_shape():
|
||||
report = comparative_residual_separation(1.0, age=3.0, tau0=1.0, levels=5)
|
||||
assert report["levels"] == 5
|
||||
assert len(report["fibonacci_taus"]) == 5
|
||||
assert len(report["dyadic_taus"]) == 5
|
||||
assert len(report["fibonacci_energies"]) == 5
|
||||
assert len(report["dyadic_energies"]) == 5
|
||||
assert len(report["energy_gap_fib_minus_dyadic"]) == 5
|
||||
# age=0 → identical unit energies regardless of schedule
|
||||
zero = comparative_residual_separation(1.0, age=0.0, tau0=1.0, levels=4)
|
||||
assert zero["fibonacci_energies"] == (1.0, 1.0, 1.0, 1.0)
|
||||
assert zero["dyadic_energies"] == (1.0, 1.0, 1.0, 1.0)
|
||||
assert zero["energy_gap_fib_minus_dyadic"] == (0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
|
||||
# --- Serve quarantine (A-04) ------------------------------------------------
|
||||
|
||||
|
||||
def test_serve_runtime_does_not_import_multi_scale_energy():
|
||||
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 "multi_scale_energy" not in node.module
|
||||
assert "wave_energy_boundary" not in node.module
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
assert "multi_scale_energy" not in alias.name
|
||||
|
||||
|
||||
def test_field_energy_operator_untouched_by_multi_scale_module():
|
||||
"""Production energy operator must not import the research multi-scale path."""
|
||||
energy_src = (_ROOT / "core/physics/energy.py").read_text(encoding="utf-8")
|
||||
assert "multi_scale_energy" not in energy_src
|
||||
assert "fibonacci_tau_schedule" not in energy_src
|
||||
124
tests/test_adr_0242_topological_quarantine.py
Normal file
124
tests/test_adr_0242_topological_quarantine.py
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
"""ADR-0242 V5 (D6) — topological_reasoning research quarantine pins.
|
||||
|
||||
Authority: docs/adr/ADR-0242-atlas-packing-and-fibonacci.md Vector 5.
|
||||
Package may exist under algebra/topological_reasoning/ for isolated study.
|
||||
Production packages must not import it.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
# Production surfaces that must never import the research quarantine package.
|
||||
_PRODUCTION_PACKAGES = (
|
||||
"chat",
|
||||
"core/physics",
|
||||
"generate",
|
||||
"vault",
|
||||
"teaching",
|
||||
)
|
||||
|
||||
_BANNED_MARKERS = (
|
||||
"topological_reasoning",
|
||||
"algebra.topological_reasoning",
|
||||
)
|
||||
|
||||
|
||||
def _iter_python_files(package_rel: str) -> list[Path]:
|
||||
base = _ROOT / package_rel
|
||||
if not base.is_dir():
|
||||
return []
|
||||
return sorted(p for p in base.rglob("*.py") if p.is_file())
|
||||
|
||||
|
||||
def _import_mentions_topological(tree: ast.AST) -> list[str]:
|
||||
"""Return import module strings that reference topological_reasoning."""
|
||||
hits: list[str] = []
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
name = alias.name
|
||||
if any(m in name for m in _BANNED_MARKERS):
|
||||
hits.append(name)
|
||||
elif isinstance(node, ast.ImportFrom):
|
||||
mod = node.module or ""
|
||||
if any(m in mod for m in _BANNED_MARKERS):
|
||||
hits.append(mod)
|
||||
# from algebra import topological_reasoning
|
||||
if mod == "algebra" or mod.endswith(".algebra"):
|
||||
for alias in node.names:
|
||||
if alias.name == "topological_reasoning" or (
|
||||
alias.name and "topological_reasoning" in alias.name
|
||||
):
|
||||
hits.append(f"{mod}.{alias.name}")
|
||||
return hits
|
||||
|
||||
|
||||
def test_topological_reasoning_package_imports_in_isolation() -> None:
|
||||
"""Package is importable on its own without production wiring."""
|
||||
import algebra.topological_reasoning as tr
|
||||
|
||||
assert hasattr(tr, "FUSION_RULE")
|
||||
assert isinstance(tr.FUSION_RULE, str)
|
||||
assert tr.FUSION_RULE == "tau_otimes_tau_eq_1_oplus_tau"
|
||||
# Research label only — no callable production fusion API required.
|
||||
assert "FUSION_RULE" in tr.__all__
|
||||
|
||||
|
||||
def test_algebra_public_import_still_works() -> None:
|
||||
"""Quarantine package must not break the algebra package surface."""
|
||||
import algebra
|
||||
from algebra import versor_condition, word_transition_rotor
|
||||
|
||||
assert callable(versor_condition)
|
||||
assert callable(word_transition_rotor)
|
||||
# Research package is not re-exported on algebra's public surface.
|
||||
assert not hasattr(algebra, "topological_reasoning") or "topological_reasoning" not in getattr(
|
||||
algebra, "__all__", ()
|
||||
)
|
||||
|
||||
|
||||
def test_topological_reasoning_package_directory_may_exist() -> None:
|
||||
"""Algebraic research quarantine box is allowed to exist on disk."""
|
||||
pkg = _ROOT / "algebra" / "topological_reasoning"
|
||||
assert pkg.is_dir()
|
||||
assert (pkg / "__init__.py").is_file()
|
||||
assert (pkg / "README.md").is_file()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("package_rel", _PRODUCTION_PACKAGES)
|
||||
def test_production_packages_do_not_import_topological_reasoning(
|
||||
package_rel: str,
|
||||
) -> None:
|
||||
"""Architectural: production trees must not import topological_reasoning."""
|
||||
files = _iter_python_files(package_rel)
|
||||
assert files, f"expected python sources under {package_rel}"
|
||||
|
||||
violations: list[str] = []
|
||||
for path in files:
|
||||
# Never scan the quarantine package itself (it lives under algebra/).
|
||||
rel = path.relative_to(_ROOT).as_posix()
|
||||
if "topological_reasoning" in rel.split("/"):
|
||||
continue
|
||||
try:
|
||||
src = path.read_text(encoding="utf-8")
|
||||
except OSError as exc:
|
||||
violations.append(f"{rel}: unreadable ({exc})")
|
||||
continue
|
||||
try:
|
||||
tree = ast.parse(src, filename=rel)
|
||||
except SyntaxError as exc:
|
||||
violations.append(f"{rel}: syntax error ({exc})")
|
||||
continue
|
||||
for hit in _import_mentions_topological(tree):
|
||||
violations.append(f"{rel}: imports {hit}")
|
||||
|
||||
assert not violations, (
|
||||
"ADR-0242 V5 quarantine violated — production import(s) of "
|
||||
"topological_reasoning:\n" + "\n".join(violations)
|
||||
)
|
||||
92
tests/test_physics_backend_dispatch_hygiene.py
Normal file
92
tests/test_physics_backend_dispatch_hygiene.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
"""P11a — physics hot paths must dispatch Cl(4,1) ops via algebra.backend.
|
||||
|
||||
Prevents silent drift back to pure-Python-only imports for geometric_product /
|
||||
versor_apply / cga_inner / versor_condition in wave-field and related modules.
|
||||
Python remains default when CORE_BACKEND is unset; Rust accelerates when
|
||||
CORE_BACKEND=rust and core_rs is built (ADR-0235).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[1]
|
||||
_PHYSICS = _ROOT / "core" / "physics"
|
||||
|
||||
# Modules that perform Cl(4,1) multiplies / residuals in the cognitive physics
|
||||
# layer — must take the load-bearing ops from algebra.backend.
|
||||
_BACKEND_HOT_MODULES = (
|
||||
"wave_manifold.py",
|
||||
"goldtether.py",
|
||||
"trajectory_invariants.py",
|
||||
"dynamic_manifold.py",
|
||||
"surprise.py",
|
||||
"holographic_vault.py",
|
||||
"atlas_packing.py",
|
||||
"biography.py",
|
||||
"self_authorship.py",
|
||||
)
|
||||
|
||||
# Names that must not be imported from algebra.cl41 / algebra.versor / algebra.cga
|
||||
# in those modules (use backend instead).
|
||||
_BANNED_FROM_PURE = frozenset(
|
||||
{
|
||||
"geometric_product",
|
||||
"versor_apply",
|
||||
"versor_condition",
|
||||
"cga_inner",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _imports_from(module: str, path: Path) -> set[str]:
|
||||
tree = ast.parse(path.read_text(encoding="utf-8"))
|
||||
names: set[str] = set()
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ImportFrom) and node.module == module:
|
||||
for alias in node.names:
|
||||
names.add(alias.name)
|
||||
return names
|
||||
|
||||
|
||||
def test_hot_modules_import_backend_for_algebra_ops():
|
||||
for name in _BACKEND_HOT_MODULES:
|
||||
path = _PHYSICS / name
|
||||
assert path.is_file(), f"missing {path}"
|
||||
backend_names = _imports_from("algebra.backend", path)
|
||||
# Each file should pull at least one of the dispatch ops.
|
||||
assert backend_names & _BANNED_FROM_PURE, (
|
||||
f"{name} must import Cl(4,1) hot ops from algebra.backend; "
|
||||
f"got backend imports {sorted(backend_names)}"
|
||||
)
|
||||
|
||||
|
||||
def test_hot_modules_do_not_import_hot_ops_from_pure_algebra():
|
||||
pure_modules = ("algebra.cl41", "algebra.versor", "algebra.cga")
|
||||
for name in _BACKEND_HOT_MODULES:
|
||||
path = _PHYSICS / name
|
||||
for mod in pure_modules:
|
||||
pure_names = _imports_from(mod, path)
|
||||
offenders = pure_names & _BANNED_FROM_PURE
|
||||
assert not offenders, (
|
||||
f"{name} imports {sorted(offenders)} from {mod}; "
|
||||
"route through algebra.backend for CORE_BACKEND=rust"
|
||||
)
|
||||
|
||||
|
||||
def test_wave_manifold_uses_backend_geometric_product_and_versor_apply():
|
||||
path = _PHYSICS / "wave_manifold.py"
|
||||
backend = _imports_from("algebra.backend", path)
|
||||
assert "geometric_product" in backend
|
||||
assert "versor_apply" in backend
|
||||
assert "versor_condition" in backend
|
||||
assert "cga_inner" in backend
|
||||
|
||||
|
||||
def test_backend_using_rust_api_exists():
|
||||
from algebra.backend import using_rust
|
||||
|
||||
# Default env: Python path (no silent force of Rust).
|
||||
assert using_rust() is False or using_rust() is True # bool only
|
||||
assert isinstance(using_rust(), bool)
|
||||
|
|
@ -60,16 +60,31 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci():
|
|||
"wave_manifold",
|
||||
"holographic_vault",
|
||||
"fibonacci_search",
|
||||
"fibonacci_word_schedule",
|
||||
"atlas_packing",
|
||||
"wave_seam", # P9 Trace A — contemplation only, never serve
|
||||
"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
|
||||
}
|
||||
banned_substrings = (
|
||||
"wave_manifold",
|
||||
"holographic_vault",
|
||||
"fibonacci_search",
|
||||
"fibonacci_word_schedule",
|
||||
"atlas_packing",
|
||||
"wave_seam",
|
||||
"wave_energy_boundary",
|
||||
"multi_scale_energy",
|
||||
"sensorium_wave_feed",
|
||||
)
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
leaf = alias.name.split(".")[-1]
|
||||
assert leaf not in banned_roots, f"banned import {alias.name}"
|
||||
assert "wave_manifold" not in alias.name
|
||||
assert "holographic_vault" not in alias.name
|
||||
assert "fibonacci_search" not in alias.name
|
||||
for ban in banned_substrings:
|
||||
assert ban not in alias.name
|
||||
if isinstance(node, ast.ImportFrom) and node.module:
|
||||
mod = node.module
|
||||
for ban in banned_roots:
|
||||
|
|
@ -266,12 +281,19 @@ def test_resonant_reconstruct_empty_refused():
|
|||
M.resonant_reconstruct(_closed(0.1))
|
||||
|
||||
|
||||
# --- ADR-0242 placeholder (Fibonacci not yet landed) --------------------------
|
||||
# --- ADR-0242 V1 evidence-gated Fibonacci + κ fallback ------------------------
|
||||
|
||||
|
||||
def test_fibonacci_search_goldtether_integration():
|
||||
"""Asserts Fibonacci search can optimize kappa and return a valid certificate."""
|
||||
from core.physics.fibonacci_search import BoundedUnimodalObjective, fibonacci_section_search
|
||||
"""Fibonacci search optimizes κ; cert-gated propose never silent-fails."""
|
||||
from core.physics.fibonacci_search import (
|
||||
BASELINE_KAPPA,
|
||||
BoundedUnimodalObjective,
|
||||
FibonacciSearchCertificate,
|
||||
OptimizationFailure,
|
||||
fibonacci_section_search,
|
||||
propose_kappa_from_search,
|
||||
)
|
||||
|
||||
objective = BoundedUnimodalObjective(
|
||||
lower=0.1,
|
||||
|
|
@ -284,7 +306,22 @@ def test_fibonacci_search_goldtether_integration():
|
|||
def synthetic_objective(kappa: float) -> float:
|
||||
return (kappa - 0.789) ** 2 # unimodal minimum at 0.789
|
||||
|
||||
trace = fibonacci_section_search(objective, synthetic_objective)
|
||||
assert abs(trace.best_observed_point - 0.789) < 1e-3
|
||||
assert len(trace.eval_sequence) == 20
|
||||
assert trace.certificate.get("budget") == 20
|
||||
result = fibonacci_section_search(objective, synthetic_objective)
|
||||
assert isinstance(result, FibonacciSearchCertificate)
|
||||
kappa, outcome = propose_kappa_from_search(result)
|
||||
assert isinstance(outcome, FibonacciSearchCertificate)
|
||||
assert abs(kappa - 0.789) < 1e-3
|
||||
assert outcome.evaluations == 20
|
||||
|
||||
# Failure path: multi-extrema → baseline κ=1.0 (Drive Phase 1).
|
||||
fail_obj = BoundedUnimodalObjective(
|
||||
lower=-2.0,
|
||||
upper=2.0,
|
||||
evaluation_budget=10,
|
||||
objective_id="kappa_fail",
|
||||
objective_version="v1.0",
|
||||
)
|
||||
fail = fibonacci_section_search(fail_obj, lambda x: x**4 - x**2)
|
||||
k_fail, out_fail = propose_kappa_from_search(fail)
|
||||
assert isinstance(out_fail, OptimizationFailure)
|
||||
assert k_fail == BASELINE_KAPPA
|
||||
|
|
|
|||
Loading…
Reference in a new issue