diff --git a/docs/RESEARCH_STATUS.md b/docs/RESEARCH_STATUS.md index 57d41d90..24356a5a 100644 --- a/docs/RESEARCH_STATUS.md +++ b/docs/RESEARCH_STATUS.md @@ -159,6 +159,7 @@ Process Geometry solver or independent adoption. | [`am-conformal-chart-normal-forms`](../sonnet/am-conformal-chart-normal-forms/00-problem-frontier.md) | Phase 1 exact Riccati lift, Möbius covariance, scalar gauge, cubic no-go, and eight-axis cost accounting | run oracle-isolated bounded discovery (1B) before the pendulum atlas search; no economy theorem yet | | [`moving-am-observer`](../sonnet/moving-am-observer/README.md) | static-observer no-go followed by blind moving-frame recovery, held-out family selection, task-equivalence quotient, blind morphism discovery, grammar stability, and dimensionful Bellman covariance | broader non-affine/multi-family or stochastic pressure, now separated into its own Sonnet | | [`stochastic-feedback-trap-first-passage`](../sonnet/stochastic-feedback-trap-first-passage/README.md) | bounded grammar census, exact Itô task quotient, independent BVP/Monte Carlo first-passage comparison, and reset Bellman value/policy covariance complete | calibration is closed; new discovery or API incubation requires a new contract | +| [`brownian-scale-fibre`](../sonnet/brownian-scale-fibre/README.md) | S0/S1 initialized: blind centered finite-law scale balance, typed drift refusal, exact endpoint fibres, and concatenation pushforward | separate lattice point return, continuum neighbourhood recurrence, and singleton hitting before authorizing a Brownian/heat-kernel lowering | | [`lonely-runner`](../sonnet/lonely-runner/README.md) | exact upstream pruning transfer and bounded K4/K5 contact mechanisms; Phase 15A global audit complete | lift-aware initial search on solved cases, then frozen K13 validation; `LRC(13)` remains open | | [`hidden-am-noether`](../sonnet/hidden-am-noether/README.md) | bounded static-observer route reached a structural no-go; the viable moving-observer continuation is tracked separately | do not reopen static conjugation without new grammar or task semantics | | [`pcr3bp-history-cost`](../sonnet/pcr3bp-history-cost/README.md) | Phase 0/1 history, scale-jet, topology, and coding audit complete; Phase 2 contract frozen | execute converged return/absorbing ensemble and twisted partition audit; no numerical result yet | diff --git a/sonnet/README.md b/sonnet/README.md index 0afe0a37..e37fc834 100644 --- a/sonnet/README.md +++ b/sonnet/README.md @@ -80,6 +80,7 @@ deferred until its next oracle/evidence gate is affordable. | [`hidden-am-noether/`](hidden-am-noether/) | static branch closed negatively | a frozen observer in the same product-affine group cannot reveal a missing stabilizer dimension | [static-observer no-go](hidden-am-noether/03-static-observer-no-go-and-schedule-split.md); continuation moved to `moving-am-observer/` | | [`moving-am-observer/`](moving-am-observer/) | affine deterministic phase closed | bounded blind observer discovery, task-equivalent minimum slice, and dimensionful Bellman covariance on the declared family | [study ledger](moving-am-observer/README.md); stochastic continuation moved to its own Sonnet | | [`stochastic-feedback-trap-first-passage/`](stochastic-feedback-trap-first-passage/) | current calibration closed | exact Itô task quotient plus independent first-passage and reset-Bellman covariance across 242 monotone charts | [Phase-4 results](stochastic-feedback-trap-first-passage/09-phase4-reset-bellman-results.md); further work requires a new Sonnet or governed extraction proposal | +| [`brownian-scale-fibre/`](brownian-scale-fibre/) | S0/S1 active | blind centered finite-law scale balance and exact endpoint-fibre concatenation; no continuum limit or heat-kernel lowering yet | [problem frontier](brownian-scale-fibre/00-problem-frontier.md); next separate recurrence observers, then certify the continuum lowering | | [`pcr3bp-history-cost/`](pcr3bp-history-cost/) | Phases 0–1 complete; Phase 2 frozen | lifted topology and scale-jet reconstruction separate word, clock, deck, and hyperbolic costs; no Bellman/Huffman source is yet justified | [Phase-2 contract](pcr3bp-history-cost/02-return-partition-holonomy-contract.md); next run the frozen two-gate covariance and convergence gates | | [`am-conformal-chart-normal-forms/`](am-conformal-chart-normal-forms/) | T0/T1; Phase 1 mechanism calibrated | exact Riccati lift, Möbius covariance, scalar-gauge invariance, cubic no-go, and eight-axis Pareto accounting; no discovery or economy theorem | [Phase-1 results](am-conformal-chart-normal-forms/02-phase1-riccati-results.md); next freeze a blind low-height grammar and run bounded recovery | | [`effective-scale-carrier-ladder/`](effective-scale-carrier-ladder/) | T1 / NARROW | finite syntax decision eliminates a surreal runtime; symbolic height is a real C2 obstruction, but semantic evaluation and C3/C4 separation remain open | [results](effective-scale-carrier-ladder/01-results.md), [compiler](../workstreams/carrier_ladder/compiler/), and [commit--reveal audit](../workstreams/carrier_ladder/redteam/); next implement an effective normalized hyperiteration fragment, not a general surreal runtime | diff --git a/sonnet/brownian-scale-fibre/00-problem-frontier.md b/sonnet/brownian-scale-fibre/00-problem-frontier.md new file mode 100644 index 00000000..92f4731a --- /dev/null +++ b/sonnet/brownian-scale-fibre/00-problem-frontier.md @@ -0,0 +1,126 @@ +# Problem frontier: recalculate Brownian motion from process fibres + +Status: frozen S0/S1 contract for +[#158](https://github.com/mountain/process-geometry/issues/158), downstream of +[#140](https://github.com/mountain/process-geometry/issues/140) and the +native-method firewall merged in +[#157](https://github.com/mountain/process-geometry/pull/157). + +## 1. Primitive process before the continuum answer + +The first carrier is the finite history space + +\[ +\Omega_N=\{\xi_1\cdots\xi_N:\xi_j\in\{-1,+1\}\} +\] + +with chronological concatenation. The endpoint task is + +\[ +\pi_N(\omega)=\sum_{j=1}^N\xi_j, +\qquad +K_N(0,x)=\frac{|\pi_N^{-1}(x)|}{|\Omega_N|}. +\] + +The literal history, endpoint, fibre multiplicity, and pushforward probability +are different objects. For the endpoint task, concatenation gives exactly + +\[ +K_{N+M}(0,z)=\sum_x K_N(0,x)K_M(x,z). +\] + +The executable phase proves this first as an integer fibre-count identity. It +does not infer that two paths with the same endpoint are equivalent for +first-passage, maximum, occupation, or physical-decoder tasks. + +## 2. Blind scale obligation without a supplied Gaussian + +For a centered finite increment law, let + +\[ +\kappa(s)=\log\mathbb E[e^{s\xi}]. +\] + +Independence makes the aggregate response additive: the log response of +\(N\) increments at probe scale \(N^{-a}s\) is + +\[ +N\kappa(N^{-a}s). +\] + +The native calculation reads the raw law and certifies exactly + +\[ +\kappa(0)=\kappa'(0)=0, +\qquad +\kappa''(0)=\sigma^2>0. +\] + +This is not used as a truncated power series. The exact integral identity + +\[ +\kappa(s)=\int_0^s(s-u)\kappa''(u)\,du +\] + +shows that the first active centered response has order two. Population +growth and probe contraction therefore balance only when + +\[ +1-2a=0. +\] + +The software solves that equation after discovering the active order; it is +not passed \(a=1/2\). For the symmetric unit law, one may independently sharpen +the residual by + +\[ +\log\cosh s-\frac{s^2}{2} +=-\int_0^s(s-u)\tanh^2u\,du. +\] + +This phase certifies a necessary nontrivial scale and its local response +coefficient. It does **not** yet prove convergence to a Gaussian law or a +continuum path process. + +## 3. Method firewall + +S0/S1 have no allowed lowering witness. The native source contains only the +finite increment law, exact centered response, chronological histories, +endpoint fibres, and their composition. Classical local expansion, +transform, continuum PDE, and simulation routes are declared separately in +`phase0_contract.py` and cannot enter a native trace without a later +task-adequacy witness. + +This is deliberately stronger than asking an agent not to use an oracle in +prose: the merged method tool rejects the corresponding event in a native lane. + +## 4. Held-out and red-team cases + +- A biased finite law returns the typed result `centering-required`; the drift + cannot be hidden inside a fluctuation scale. +- An infinite-variance law is outside the first finite-law grammar. A later + heavy-tail phase must enlarge the carrier and rediscover its scale rather + than force the diffusive answer. +- Histories `(+1,-1)` and `(-1,+1)` share endpoint zero but have different + running maxima. Endpoint fibres are task-exact only for endpoint observers. +- Lattice return to a point, continuum return to a neighbourhood, and + continuum hitting of a singleton remain separate S2 claims; the 2D boundary + is not compressed into one word, “recurrent.” + +## 5. Relation to the larger programme + +This is the first independent scale/fibre family after the Bessel-based draft +in PR #141. It pressures U1, U2, U3, U4, and Effective Analysis because the +same construction connects raw histories, scale, measured fibres, a continuum +lowering, and later physical response. At S0/S1 it remains T1 and leaves the +Mathematical Core, Engineering Architecture, Theory Map, dependencies, and API +unchanged. + +Surreal numbers are not needed for this finite-height task. That is a negative +runtime result, not an argument against later AMP or higher-height uses. + +## 6. Claim ceiling + +No new Brownian theorem, central-limit theorem, heat-kernel theorem, +stochastic-calculus replacement, general stochastic solver, speedup, particle +size inference, or arithmetic-universality result is claimed. diff --git a/sonnet/brownian-scale-fibre/README.md b/sonnet/brownian-scale-fibre/README.md new file mode 100644 index 00000000..eae1b17c --- /dev/null +++ b/sonnet/brownian-scale-fibre/README.md @@ -0,0 +1,42 @@ +# Sonnet — Brownian scale and endpoint fibres + +Research-local calibration for +[#158](https://github.com/mountain/process-geometry/issues/158). + +This Sonnet recalculates the entrance to Brownian motion from raw increment +histories. It does not begin with the continuum process, a Gaussian density, +the heat equation, or a supplied diffusive exponent. + +Read in order: + +1. [`00-problem-frontier.md`](00-problem-frontier.md) — primitive histories, + tasks, scale argument, held-outs, and claim ceiling; +2. [`phase0_contract.py`](phase0_contract.py) — frozen executable method lanes; +3. [`brownian_native.py`](brownian_native.py) — exact scale and endpoint-fibre + calculations; +4. [`test_brownian_scale_fibre_phase0.py`](../../tests/research/test_brownian_scale_fibre_phase0.py) + — independent certificates and source firewall. + +Current S0/S1 result: + +```text +raw centered finite law -> active response order 2 -> scale balance a=1/2 +finite histories -> endpoint fibres -> exact concatenation pushforward +biased law -> typed centering-required refusal +continuum / heat-kernel lowering -> not yet authorized +``` + +The scale result is narrower than a central-limit theorem. The endpoint result +is narrower than path equivalence. S2 must next separate lattice point return, +continuum neighbourhood recurrence, and singleton hitting before S3 authorizes +a Brownian/heat-kernel lowering. + +This task is the second independent representation family requested in +[#140](https://github.com/mountain/process-geometry/issues/140). Draft +[#141](https://github.com/mountain/process-geometry/pull/141) remains an +explicit compiler dependency; no implementation from that draft is copied +while it remains unmerged. The completed stochastic feedback-trap Sonnet is +an independent downstream Itô/first-passage calibration and is not duplicated +here. + +No Experimental or Public API pressure follows from S0/S1. diff --git a/sonnet/brownian-scale-fibre/brownian_native.py b/sonnet/brownian-scale-fibre/brownian_native.py new file mode 100644 index 00000000..1f81c55e --- /dev/null +++ b/sonnet/brownian-scale-fibre/brownian_native.py @@ -0,0 +1,331 @@ +"""Native finite-increment and endpoint-fibre calculations for issue #158.""" + +from __future__ import annotations + +from dataclasses import dataclass +from fractions import Fraction +from itertools import product +from typing import Iterable + + +Point = tuple[int, ...] + + +class NativeBrownianDomainError(ValueError): + """The first finite-increment Brownian grammar does not cover the input.""" + + +class CenteringRequired(NativeBrownianDomainError): + """A nonzero drift must be represented before fluctuation scaling.""" + + def __init__(self, mean: Fraction): + self.mean = mean + super().__init__(f"centering-required: exact increment mean is {mean}") + + +class EndpointFibreBudgetError(RuntimeError): + """The declared exact endpoint-fibre update budget was exhausted.""" + + +@dataclass(frozen=True) +class FiniteIncrementLaw: + support: tuple[int, ...] + weights: tuple[Fraction, ...] + + def __post_init__(self) -> None: + if not self.support: + raise NativeBrownianDomainError("increment support must not be empty") + if len(self.support) != len(self.weights): + raise NativeBrownianDomainError("support and weight counts differ") + if len(set(self.support)) != len(self.support): + raise NativeBrownianDomainError("increment support must be unique") + if any( + not isinstance(value, int) or isinstance(value, bool) + for value in self.support + ): + raise NativeBrownianDomainError("increment support must contain integers") + if any(not isinstance(weight, Fraction) for weight in self.weights): + raise NativeBrownianDomainError("increment weights must be exact fractions") + if any(weight <= 0 for weight in self.weights): + raise NativeBrownianDomainError("increment weights must be positive") + if sum(self.weights, start=Fraction(0)) != 1: + raise NativeBrownianDomainError("increment weights must sum exactly to one") + + @classmethod + def symmetric_unit(cls) -> "FiniteIncrementLaw": + return cls((-1, 1), (Fraction(1, 2), Fraction(1, 2))) + + @property + def mean(self) -> Fraction: + return sum( + (weight * value for value, weight in zip(self.support, self.weights)), + start=Fraction(0), + ) + + def centered_moment(self, order: int) -> Fraction: + if order < 1: + raise NativeBrownianDomainError("moment order must be positive") + mean = self.mean + return sum( + ( + weight * (Fraction(value) - mean) ** order + for value, weight in zip(self.support, self.weights) + ), + start=Fraction(0), + ) + + +@dataclass(frozen=True) +class ScaleDiscoveryCost: + law_atoms: int + exact_weighted_additions: int + active_orders_tested: int + + +@dataclass(frozen=True) +class DiffusiveScaleCertificate: + increment_mean: Fraction + centered_variance: Fraction + active_response_order: int + population_power: int + scale_exponent: Fraction + balance_residual: Fraction + balanced_response_coefficient: Fraction + exact_identity: str + claim_boundary: str + cost: ScaleDiscoveryCost + + @property + def balanced(self) -> bool: + return self.balance_residual == 0 + + +def discover_diffusive_scale(law: FiniteIncrementLaw) -> DiffusiveScaleCertificate: + """Derive the first centered finite-law scale without receiving its value. + + Independent composition makes the local cumulant additive in the number + of increments. At zero, its first derivative is the exact mean and its + second derivative is the exact centered variance. The fundamental + theorem of calculus gives an exact double-integral identity, so no local + expansion is used to identify the active response order. + """ + + mean = law.mean + if mean != 0: + raise CenteringRequired(mean) + first_centered = law.centered_moment(1) + variance = law.centered_moment(2) + if first_centered != 0: # pragma: no cover - protected by exact centering + raise NativeBrownianDomainError("centered first response did not vanish") + if variance <= 0: + raise NativeBrownianDomainError( + "a nondegenerate centered second response is required" + ) + + population_power = 1 + active_order = 2 + exponent = Fraction(population_power, active_order) + residual = Fraction(population_power) - active_order * exponent + return DiffusiveScaleCertificate( + increment_mean=mean, + centered_variance=variance, + active_response_order=active_order, + population_power=population_power, + scale_exponent=exponent, + balance_residual=residual, + balanced_response_coefficient=variance / 2, + exact_identity=( + "kappa(s)=integral_0^s (s-u) kappa_second(u) du after exact " + "centering" + ), + claim_boundary=( + "scale balance only; no limit law, continuum path law, or heat " + "equation is certified" + ), + cost=ScaleDiscoveryCost( + law_atoms=len(law.support), + exact_weighted_additions=2 * len(law.support), + active_orders_tested=2, + ), + ) + + +@dataclass(frozen=True) +class EndpointFibreCost: + transition_updates: int + peak_live_fibres: int + stored_endpoint_fibres: int + literal_history_count: int + + +@dataclass(frozen=True) +class EndpointFibreDistribution: + dimension: int + horizon: int + counts: tuple[tuple[Point, int], ...] + cost: EndpointFibreCost + + def __post_init__(self) -> None: + if self.dimension < 1: + raise NativeBrownianDomainError("dimension must be positive") + if self.horizon < 0: + raise NativeBrownianDomainError("horizon must be non-negative") + points = tuple(point for point, _ in self.counts) + if tuple(sorted(points)) != points or len(set(points)) != len(points): + raise NativeBrownianDomainError("endpoint fibres must be uniquely sorted") + if any(len(point) != self.dimension for point in points): + raise NativeBrownianDomainError("endpoint dimension mismatch") + if any(count <= 0 for _, count in self.counts): + raise NativeBrownianDomainError("endpoint fibre counts must be positive") + if self.total_histories != (2 * self.dimension) ** self.horizon: + raise NativeBrownianDomainError("endpoint fibres do not conserve history mass") + + @property + def total_histories(self) -> int: + return sum(count for _, count in self.counts) + + @property + def support_size(self) -> int: + return len(self.counts) + + def count(self, point: Point) -> int: + if len(point) != self.dimension: + raise NativeBrownianDomainError("endpoint dimension mismatch") + return dict(self.counts).get(point, 0) + + def probability(self, point: Point) -> Fraction: + return Fraction(self.count(point), self.total_histories) + + +def nearest_neighbour_steps(dimension: int) -> tuple[Point, ...]: + if dimension < 1: + raise NativeBrownianDomainError("dimension must be positive") + steps: list[Point] = [] + for axis in range(dimension): + for sign in (-1, 1): + point = [0] * dimension + point[axis] = sign + steps.append(tuple(point)) + return tuple(steps) + + +def _add_points(left: Point, right: Point) -> Point: + return tuple(a + b for a, b in zip(left, right)) + + +def endpoint_fibres( + dimension: int, + horizon: int, + *, + max_transition_updates: int = 1_000_000, +) -> EndpointFibreDistribution: + """Push finite histories to endpoints by chronological process updates.""" + + if horizon < 0: + raise NativeBrownianDomainError("horizon must be non-negative") + if max_transition_updates < 0: + raise NativeBrownianDomainError("update budget must be non-negative") + steps = nearest_neighbour_steps(dimension) + origin = (0,) * dimension + counts: dict[Point, int] = {origin: 1} + transition_updates = 0 + peak_live = 1 + for _ in range(horizon): + next_counts: dict[Point, int] = {} + for point, count in counts.items(): + for step in steps: + transition_updates += 1 + if transition_updates > max_transition_updates: + raise EndpointFibreBudgetError( + "endpoint-fibre transition budget exhausted" + ) + endpoint = _add_points(point, step) + next_counts[endpoint] = next_counts.get(endpoint, 0) + count + counts = next_counts + peak_live = max(peak_live, len(counts)) + return EndpointFibreDistribution( + dimension=dimension, + horizon=horizon, + counts=tuple(sorted(counts.items())), + cost=EndpointFibreCost( + transition_updates=transition_updates, + peak_live_fibres=peak_live, + stored_endpoint_fibres=len(counts), + literal_history_count=(2 * dimension) ** horizon, + ), + ) + + +def concatenate_endpoint_fibres( + left: EndpointFibreDistribution, + right: EndpointFibreDistribution, + *, + max_transition_updates: int = 1_000_000, +) -> EndpointFibreDistribution: + """Induce history concatenation on the endpoint task fibres.""" + + if left.dimension != right.dimension: + raise NativeBrownianDomainError("cannot concatenate different dimensions") + if max_transition_updates < 0: + raise NativeBrownianDomainError("update budget must be non-negative") + counts: dict[Point, int] = {} + updates = 0 + for left_point, left_count in left.counts: + for right_point, right_count in right.counts: + updates += 1 + if updates > max_transition_updates: + raise EndpointFibreBudgetError( + "endpoint-fibre concatenation budget exhausted" + ) + endpoint = _add_points(left_point, right_point) + counts[endpoint] = counts.get(endpoint, 0) + left_count * right_count + return EndpointFibreDistribution( + dimension=left.dimension, + horizon=left.horizon + right.horizon, + counts=tuple(sorted(counts.items())), + cost=EndpointFibreCost( + transition_updates=updates, + peak_live_fibres=len(counts), + stored_endpoint_fibres=len(counts), + literal_history_count=left.total_histories * right.total_histories, + ), + ) + + +def certify_history_concatenation( + dimension: int, + left_horizon: int, + right_horizon: int, +) -> bool: + left = endpoint_fibres(dimension, left_horizon) + right = endpoint_fibres(dimension, right_horizon) + composed = concatenate_endpoint_fibres(left, right) + direct = endpoint_fibres(dimension, left_horizon + right_horizon) + return composed.counts == direct.counts + + +def literal_endpoint(history: Iterable[Point], dimension: int) -> Point: + """Evaluate one literal history without applying the endpoint quotient.""" + + endpoint = (0,) * dimension + legal = frozenset(nearest_neighbour_steps(dimension)) + for step in history: + if step not in legal: + raise NativeBrownianDomainError("history contains an illegal step") + endpoint = _add_points(endpoint, step) + return endpoint + + +def exhaustive_endpoint_counts(dimension: int, horizon: int) -> tuple[tuple[Point, int], ...]: + """Small exact certificate path; callers must keep the horizon bounded.""" + + if horizon < 0: + raise NativeBrownianDomainError("horizon must be non-negative") + if (2 * dimension) ** horizon > 100_000: + raise EndpointFibreBudgetError("literal history certificate budget exhausted") + steps = nearest_neighbour_steps(dimension) + counts: dict[Point, int] = {} + for history in product(steps, repeat=horizon): + endpoint = literal_endpoint(history, dimension) + counts[endpoint] = counts.get(endpoint, 0) + 1 + return tuple(sorted(counts.items())) diff --git a/sonnet/brownian-scale-fibre/phase0_contract.py b/sonnet/brownian-scale-fibre/phase0_contract.py new file mode 100644 index 00000000..9d2e9edb --- /dev/null +++ b/sonnet/brownian-scale-fibre/phase0_contract.py @@ -0,0 +1,193 @@ +"""Frozen S0/S1 method contract and executable audit for issue #158.""" + +from __future__ import annotations + +from dataclasses import dataclass +import importlib.util +from pathlib import Path +import sys + + +ROOT = Path(__file__).resolve().parents[2] + + +def _load(name: str, path: Path): + if name in sys.modules: + return sys.modules[name] + spec = importlib.util.spec_from_file_location(name, path) + assert spec and spec.loader + loaded = importlib.util.module_from_spec(spec) + sys.modules[name] = loaded + spec.loader.exec_module(loaded) + return loaded + + +firewall = _load( + "native_method_firewall", + ROOT / "workstreams/native_method_firewall/native_method_firewall.py", +) +native = _load("brownian_native", Path(__file__).with_name("brownian_native.py")) + + +METHOD_CONTRACT = firewall.MethodContract( + contract_id="brownian-scale-fibre-s0-s1", + problem=( + "derive the first fluctuation scale and endpoint-fibre composition " + "from raw finite increment histories" + ), + primitive_processes=( + "chronological independent finite-increment histories", + "nearest-neighbour histories on the integer lattice", + ), + tasks=( + firewall.TaskContract( + task_id="blind-scale", + observer=( + "nonzero finite response of the centered aggregate under an " + "unknown power scale" + ), + deliverable=( + "active centered response order, balance equation, and solved exponent" + ), + regime="centered nondegenerate finite-support increment laws", + accuracy="exact rational scale balance", + claim_mode=firewall.ClaimMode.EXACT_SYMBOLIC, + failure_semantics=( + "centering-required", + "degenerate-second-response", + "outside-finite-law-grammar", + ), + ), + firewall.TaskContract( + task_id="endpoint-fibre", + observer="endpoint after a declared finite horizon", + deliverable=( + "exact fibre counts, pushforward probabilities, and concatenation certificate" + ), + regime="bounded nearest-neighbour histories on the integer lattice", + accuracy="exact integer counts and rational probabilities", + claim_mode=firewall.ClaimMode.EXACT_FINITE, + failure_semantics=("invalid-history", "transition-budget-exhausted"), + ), + ), + native_charts=( + "aggregate probe scale s=N^(-a)*xi with a solved rather than supplied", + "integer-lattice endpoint chart", + ), + retained_fibres=( + "increment law and exact centering witness", + "endpoint fibre multiplicity", + "literal history remains residual for path-sensitive tasks", + ), + native_function_family=( + "finite-law cumulant atom under independent composition, with exact " + "integral response identity" + ), + native_composition=( + "chronological history concatenation; endpoint addition and exact mass pushforward" + ), + native_operators=( + "exact centering and centered response", + "scale-balance solve", + "endpoint pushforward", + "history concatenation", + ), + claim_boundary=( + "S0/S1 only: no continuum limit law, path-space limit, recurrence theorem, " + "physical decoder, efficiency theorem, or new stochastic calculus" + ), + allowed_lowerings=(), + baselines=( + firewall.BaselineSpec( + baseline_id="spectral-endpoint-check", + mechanism=firewall.MethodMechanism.FOURIER_SPECTRAL, + task_scope=("blind-scale", "endpoint-fibre"), + purpose="independent classical transform check after native discovery", + independent_reference="finite characteristic function or continuum limit", + ), + firewall.BaselineSpec( + baseline_id="local-response-check", + mechanism=firewall.MethodMechanism.POWER_SERIES, + task_scope=("blind-scale",), + purpose="post-discovery coefficient red team", + independent_reference="classical local cumulant calculation", + ), + firewall.BaselineSpec( + baseline_id="simulation-check", + mechanism=firewall.MethodMechanism.BLACK_BOX_NUMERICS, + task_scope=("endpoint-fibre",), + purpose="independent sampling comparison for later large workloads", + independent_reference="seeded random-walk simulation", + ), + ), +).validate() + + +@dataclass(frozen=True) +class Phase0Result: + scale: object + endpoint_distribution: object + concatenation_certified: bool + trace: object + + +def run_phase0() -> Phase0Result: + law = native.FiniteIncrementLaw.symmetric_unit() + scale = native.discover_diffusive_scale(law) + left = native.endpoint_fibres(1, 2) + right = native.endpoint_fibres(1, 3) + endpoint = native.endpoint_fibres(1, 5) + composed = native.concatenate_endpoint_fibres(left, right) + concatenation_certified = composed.counts == endpoint.counts + if not concatenation_certified: # pragma: no cover - fail closed + raise AssertionError("endpoint pushforward did not preserve concatenation") + + trace = firewall.MethodTrace(METHOD_CONTRACT) + scale_event = trace.record( + task_id="blind-scale", + lane=firewall.MethodLane.NATIVE_DISCOVERY, + mechanism=firewall.MethodMechanism.NATIVE_FUNCTION_FAMILY, + action="derive centered response order and solve population/scale balance", + input_semantics="raw symmetric unit increment law; no target exponent", + output_semantics="exact scale-balance certificate", + cost=firewall.CostLedger( + discovery_steps=scale.cost.exact_weighted_additions, + live_state_units=scale.cost.law_atoms, + ), + ) + fibre_event = trace.record( + task_id="endpoint-fibre", + lane=firewall.MethodLane.NATIVE_EVALUATION, + mechanism=firewall.MethodMechanism.TASK_FIBRE, + action="push chronological histories to exact endpoint fibres", + input_semantics="nearest-neighbour step grammar and finite horizon", + output_semantics="endpoint counts and rational pushforward law", + cost=firewall.CostLedger( + evaluation_steps=endpoint.cost.transition_updates, + live_state_units=endpoint.cost.peak_live_fibres, + stored_history_units=endpoint.cost.stored_endpoint_fibres, + ), + ) + certificate_event = trace.record( + task_id="endpoint-fibre", + lane=firewall.MethodLane.CERTIFICATE, + mechanism=firewall.MethodMechanism.EXACT_FINITE_ENUMERATION, + action="compare direct horizon-five fibres with the two-plus-three pushforward", + input_semantics="two independently constructed exact endpoint tables", + output_semantics="zero count residual at every endpoint", + cost=firewall.CostLedger( + evaluation_steps=composed.cost.transition_updates, + stored_history_units=composed.cost.stored_endpoint_fibres, + ), + ) + trace.claim_native_result( + task_id="blind-scale", + statement="the centered finite law forces the declared scale balance", + evidence_event_ids=(scale_event.event_id,), + ) + trace.claim_native_result( + task_id="endpoint-fibre", + statement="endpoint pushforward descends history concatenation exactly", + evidence_event_ids=(fibre_event.event_id, certificate_event.event_id), + ) + return Phase0Result(scale, endpoint, concatenation_certified, trace) diff --git a/tests/research/test_brownian_scale_fibre_phase0.py b/tests/research/test_brownian_scale_fibre_phase0.py new file mode 100644 index 00000000..912a9a83 --- /dev/null +++ b/tests/research/test_brownian_scale_fibre_phase0.py @@ -0,0 +1,181 @@ +"""S0/S1 Brownian scale and endpoint-fibre certificates for issue #158.""" + +from __future__ import annotations + +from fractions import Fraction +import importlib.util +import json +from pathlib import Path +import sys + +import pytest + + +MODULE_PATH = ( + Path(__file__).parents[2] / "sonnet/brownian-scale-fibre/phase0_contract.py" +) +SPEC = importlib.util.spec_from_file_location("brownian_phase0_contract", MODULE_PATH) +assert SPEC and SPEC.loader +module = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = module +SPEC.loader.exec_module(module) +native = module.native +firewall = module.firewall + + +def test_method_contract_has_no_s0_s1_lowering_escape_hatch() -> None: + contract = module.METHOD_CONTRACT + assert contract.contract_id == "brownian-scale-fibre-s0-s1" + assert contract.allowed_lowerings == () + assert {task.task_id for task in contract.tasks} == { + "blind-scale", + "endpoint-fibre", + } + assert contract.forbidden_premature_lowerings == firewall.CLASSICAL_MECHANISMS + + +def test_blind_scale_is_derived_from_the_raw_law() -> None: + law = native.FiniteIncrementLaw.symmetric_unit() + certificate = native.discover_diffusive_scale(law) + + assert certificate.increment_mean == 0 + assert certificate.centered_variance == 1 + assert certificate.active_response_order == 2 + assert certificate.population_power == 1 + assert certificate.scale_exponent == Fraction(1, 2) + assert certificate.balance_residual == 0 + assert certificate.balanced_response_coefficient == Fraction(1, 2) + assert "no limit law" in certificate.claim_boundary + + +def test_biased_law_requires_explicit_centering() -> None: + biased = native.FiniteIncrementLaw( + (-1, 1), + (Fraction(1, 4), Fraction(3, 4)), + ) + with pytest.raises(native.CenteringRequired, match="centering-required") as error: + native.discover_diffusive_scale(biased) + assert error.value.mean == Fraction(1, 2) + + +def test_finite_law_requires_exact_weights_and_nondegenerate_response() -> None: + with pytest.raises(native.NativeBrownianDomainError, match="exact fractions"): + native.FiniteIncrementLaw((-1, 1), (0.5, 0.5)) + + point_mass = native.FiniteIncrementLaw((0,), (Fraction(1),)) + with pytest.raises( + native.NativeBrownianDomainError, match="nondegenerate centered second" + ): + native.discover_diffusive_scale(point_mass) + + +def test_exact_one_dimensional_endpoint_fibres() -> None: + distribution = native.endpoint_fibres(1, 4) + assert distribution.counts == ( + ((-4,), 1), + ((-2,), 4), + ((0,), 6), + ((2,), 4), + ((4,), 1), + ) + assert distribution.probability((0,)) == Fraction(3, 8) + assert distribution.total_histories == 16 + + +def test_two_dimensional_return_mass_is_an_exact_fibre() -> None: + distribution = native.endpoint_fibres(2, 2) + assert distribution.count((0, 0)) == 4 + assert distribution.probability((0, 0)) == Fraction(1, 4) + assert distribution.total_histories == 16 + + +def test_endpoint_fibre_budget_exhaustion_is_typed() -> None: + with pytest.raises(native.EndpointFibreBudgetError, match="budget exhausted"): + native.endpoint_fibres(2, 4, max_transition_updates=3) + + +@pytest.mark.parametrize("dimension,horizon", ((1, 0), (1, 5), (2, 3))) +def test_endpoint_pushforward_matches_literal_history_enumeration( + dimension: int, horizon: int +) -> None: + pushed = native.endpoint_fibres(dimension, horizon) + exhaustive = native.exhaustive_endpoint_counts(dimension, horizon) + assert pushed.counts == exhaustive + + +@pytest.mark.parametrize( + "dimension,left_horizon,right_horizon", + ((1, 2, 5), (2, 2, 2), (3, 1, 2)), +) +def test_history_concatenation_descends_exactly_to_endpoint_fibres( + dimension: int, left_horizon: int, right_horizon: int +) -> None: + assert native.certify_history_concatenation( + dimension, left_horizon, right_horizon + ) + + +def test_endpoint_fibre_is_not_a_path_task_quotient() -> None: + positive = (1,) + negative = (-1,) + first = (positive, negative) + second = (negative, positive) + + def running_maximum(history): + value = 0 + maximum = 0 + for (increment,) in history: + value += increment + maximum = max(maximum, value) + return maximum + + assert native.literal_endpoint(first, 1) == native.literal_endpoint(second, 1) + assert running_maximum(first) == 1 + assert running_maximum(second) == 0 + + +def test_native_source_has_no_classical_lowering_calls() -> None: + source = ( + MODULE_PATH.with_name("brownian_native.py") + .read_text(encoding="utf-8") + .casefold() + ) + forbidden = ( + ".series(", + "fourier", + "matrix", + "koopman", + "carleman", + "gaussian", + "heat kernel", + ) + assert not {token for token in forbidden if token in source} + + +def test_phase0_trace_is_machine_readable_and_lane_separated() -> None: + result = module.run_phase0() + report = json.loads(result.trace.to_json()) + + assert result.scale.scale_exponent == Fraction(1, 2) + assert result.concatenation_certified + assert report["summary"]["lane_counts"] == { + "baseline": 0, + "certificate": 1, + "native-discovery": 1, + "native-evaluation": 1, + } + assert len(report["native_claims"]) == 2 + assert report["summary"]["cost_scalarization"] == "not-authorized" + + +def test_phase0_firewall_rejects_a_classical_discovery_oracle() -> None: + trace = firewall.MethodTrace(module.METHOD_CONTRACT) + with pytest.raises(firewall.PrematureLoweringError): + trace.record( + task_id="blind-scale", + lane=firewall.MethodLane.NATIVE_DISCOVERY, + mechanism=firewall.MethodMechanism.FOURIER_SPECTRAL, + action="supply a target scale from a classical transform", + input_semantics="raw increment law", + output_semantics="answer-shaped exponent", + )