From c8160cacba946fe8d36d826402c1789fcb1b0546 Mon Sep 17 00:00:00 2001 From: Shay Date: Wed, 15 Jul 2026 12:48:45 -0700 Subject: [PATCH] =?UTF-8?q?fix(physics):=20close=20A-04=20transitive=20ser?= =?UTF-8?q?ve=20breach=20=E2=80=94=20lazy=20Tier-2=20barrel=20exports=20+?= =?UTF-8?q?=20process-level=20guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Importing chat.runtime transitively loaded 5 off-serving modules (wave_manifold, holographic_vault, fibonacci_search, multi_scale_energy, wave_energy_boundary) through the core/physics package barrel — falsifying the 'serve path not wired' acceptance row while the direct-AST A-04 pin stayed green. Reconciliation (ruled 2026-07-15): one substrate, two tiers. - T1 sanctioned serve substrate: wave_manifold (goldtether/surprise/ biography delegate to it) — stays eager, removed from the A-04 ban list. - T2 off-serving (holographic_vault, fibonacci_search, wave_energy_boundary, multi_scale_energy): converted to PEP 562 lazy __getattr__ exports so the serve process never loads them; 'from core.physics import X' still works for off-serving callers. TYPE_CHECKING block keeps static analysis intact. - New tests/test_serve_quarantine_transitive.py enforces the process-level invariant via a clean-interpreter sys.modules probe (RED against the old barrel, GREEN now). Evidence: docs/research/adr-0241-0242-adversarial-and-fidelity-findings.md (Finding #2). 179 affected tests green. --- core/physics/__init__.py | 118 ++++++++++++++++------ tests/test_serve_quarantine_transitive.py | 60 +++++++++++ tests/test_third_door_cohesion.py | 7 +- 3 files changed, 153 insertions(+), 32 deletions(-) create mode 100644 tests/test_serve_quarantine_transitive.py diff --git a/core/physics/__init__.py b/core/physics/__init__.py index 70546831..81c583c9 100644 --- a/core/physics/__init__.py +++ b/core/physics/__init__.py @@ -78,36 +78,81 @@ from core.physics.trajectory_invariants import ( relative_holonomy, trajectory_divergence, ) -from core.physics.holographic_vault import ( - HolographicVaultError, - 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, -) +# --- Off-serving (Tier-2) LAZY exports — serve quarantine (ADR-0241/0242) -------- +# These are OFF-SERVING extensions: durable memory (holographic_vault) and +# evidence-gated optimization / research thermodynamics (fibonacci_search, +# wave_energy_boundary, multi_scale_energy). Eager-importing them here would drag +# the whole substrate into the serve process (chat.runtime) via this package barrel +# — the A-04 transitive breach documented in +# docs/research/adr-0241-0242-adversarial-and-fidelity-findings.md (Finding #2). +# They stay importable as `from core.physics import X` via PEP 562 __getattr__, but +# resolve lazily only on explicit off-serving access. Guarded by +# tests/test_serve_quarantine_transitive.py. +# +# NOTE (Joshua ruling 2026-07-15): wave_manifold is Tier-1 sanctioned serve +# substrate (goldtether/surprise/biography delegate to it) and stays eager above. +_LAZY_EXPORTS: dict[str, str] = { + # holographic_vault — durable memory (L10 / persistence gate) + "HolographicVaultError": "core.physics.holographic_vault", + "HolographicVaultStore": "core.physics.holographic_vault", + "SealedMode": "core.physics.holographic_vault", + # wave_energy_boundary — P10 Trace B energy/τ gate (never serve) + "CrystallizationDecision": "core.physics.wave_energy_boundary", + "assess_wave_trajectory": "core.physics.wave_energy_boundary", + "crystallization_for_holographic_seal": "core.physics.wave_energy_boundary", + "energy_profile_from_wave": "core.physics.wave_energy_boundary", + "fibonacci_tau_schedule": "core.physics.wave_energy_boundary", + "recency_band_index": "core.physics.wave_energy_boundary", + "wave_unitary_residual": "core.physics.wave_energy_boundary", + # fibonacci_search — V1 evidence-gated optimization (never serve) + "BASELINE_KAPPA": "core.physics.fibonacci_search", + "BoundedUnimodalObjective": "core.physics.fibonacci_search", + "FibonacciSearchCertificate": "core.physics.fibonacci_search", + "OptimizationFailure": "core.physics.fibonacci_search", + "fibonacci_number": "core.physics.fibonacci_search", + "fibonacci_section_search": "core.physics.fibonacci_search", + "propose_kappa_from_search": "core.physics.fibonacci_search", + # multi_scale_energy — V2 research multi-band E_n(t) (never serve) + "comparative_residual_separation": "core.physics.multi_scale_energy", + "dyadic_tau_schedule": "core.physics.multi_scale_energy", + "multi_scale_energy_for_schedule": "core.physics.multi_scale_energy", + "multi_scale_energy_vector": "core.physics.multi_scale_energy", + "schedule_mid_span_fraction": "core.physics.multi_scale_energy", +} + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: # static-analysis only — never imported at runtime (serve quarantine) + from core.physics.holographic_vault import ( + HolographicVaultError, + 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", @@ -163,3 +208,16 @@ __all__ = [ "multi_scale_energy_vector", "schedule_mid_span_fraction", ] + + +def __getattr__(name: str): # PEP 562 — lazy off-serving (Tier-2) exports + module = _LAZY_EXPORTS.get(name) + if module is None: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + import importlib + + return getattr(importlib.import_module(module), name) + + +def __dir__() -> list[str]: + return sorted(set(globals()) | set(_LAZY_EXPORTS)) diff --git a/tests/test_serve_quarantine_transitive.py b/tests/test_serve_quarantine_transitive.py new file mode 100644 index 00000000..cc254dd6 --- /dev/null +++ b/tests/test_serve_quarantine_transitive.py @@ -0,0 +1,60 @@ +"""A-04 (transitive) — the serve process must not LOAD the wave/fibonacci substrate. + +The existing `test_phase0_a04_serve_path_quarantines_wave_and_fibonacci` walks only +`chat/runtime.py`'s own AST import nodes, so it catches DIRECT imports only. The +stated invariant is process-level ("serve path stays quarantined"; modules labelled +"never serve"). This pin enforces the stated invariant: importing `chat.runtime` in +a clean interpreter must not pull any banned module into `sys.modules`. + +RED until the `core/physics/__init__.py` barrel stops eagerly importing the +off-serving substrate (Finding #2, docs/research/adr-0241-0242-adversarial-and-fidelity-findings.md). +""" + +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path + +_ROOT = Path(__file__).resolve().parents[1] + +# Genuinely off-serving; must never load into the serve process. +_BANNED = ( + "core.physics.holographic_vault", + "core.physics.fibonacci_search", + "core.physics.fibonacci_word_schedule", + "core.physics.atlas_packing", + "core.physics.wave_seam", + "core.physics.wave_energy_boundary", + "core.physics.multi_scale_energy", + "core.physics.sensorium_wave_feed", + # NOTE: core.physics.wave_manifold is intentionally excluded pending the + # Joshua design ruling (goldtether delegates to it). Add it here if the + # ruling is "quarantine wave_manifold for real". +) + + +def test_import_chat_runtime_does_not_load_offserving_substrate(): + probe = ( + "import importlib, sys, json;" + "importlib.import_module('chat.runtime');" + f"banned={list(_BANNED)!r};" + "leaked=sorted(m for m in sys.modules for b in banned if m==b or m.startswith(b+'.'));" + "print(json.dumps(leaked))" + ) + result = subprocess.run( + [sys.executable, "-c", probe], + cwd=str(_ROOT), + capture_output=True, + text=True, + env={"PYTHONPATH": str(_ROOT), "PATH": ""}, + ) + assert result.returncode == 0, f"probe failed: {result.stderr[-2000:]}" + leaked = result.stdout.strip().splitlines()[-1] + import json as _json + + leaked_list = _json.loads(leaked) + assert not leaked_list, ( + "serve process transitively loaded off-serving modules " + f"(A-04 breach via core/physics barrel): {leaked_list}" + ) diff --git a/tests/test_third_door_cohesion.py b/tests/test_third_door_cohesion.py index 7b2c88dc..9a9eed13 100644 --- a/tests/test_third_door_cohesion.py +++ b/tests/test_third_door_cohesion.py @@ -56,8 +56,12 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci(): runtime_path = _ROOT / "chat/runtime.py" src = runtime_path.read_text() tree = ast.parse(src) + # Tier-2 OFF-SERVING modules only. wave_manifold is Tier-1 sanctioned serve + # substrate (goldtether/surprise/biography delegate to it) per the 2026-07-15 + # reconciliation — see docs/research/adr-0241-0242-adversarial-and-fidelity-findings.md. + # Process-level (transitive) quarantine of these is enforced by + # tests/test_serve_quarantine_transitive.py; this pin catches direct imports. banned_roots = { - "wave_manifold", "holographic_vault", "fibonacci_search", "fibonacci_word_schedule", @@ -68,7 +72,6 @@ def test_phase0_a04_serve_path_quarantines_wave_and_fibonacci(): "sensorium_wave_feed", # D7 I-04 sensorium→ψ feed, never serve } banned_substrings = ( - "wave_manifold", "holographic_vault", "fibonacci_search", "fibonacci_word_schedule",