feat(adr-0240/0243): seam S2 — chiral-composed, harness-driven biography write-path
1) chiral_conservation_precondition composed into integrate_validated_biography (ADR-0241 §2.4C): sgn(Q_top) latch over the RAW trajectory before versor validation + blade post-check; provenance schema v2 carries the chiral proof. Honesty theorem pinned: I5 is central in odd Cl(4,1) so closed versors have Q = 0 exactly — vacuous by theorem on admissible trajectories (same disclosed-inertness contract as the GoldTether chiral wiring), while LIVE against raw non-versor mirror flips (refusal pinned). 2) First real caller: evals/analogical_transfer/biography_session.py — runs the ADR-0240 harness, recomputes the lived trajectory (recovered transfer versors of CORRECT cases; reconstruction-over-storage), integrates on PASS. I-01 reboot-invariance pinned BIT-IDENTICAL across runs. 3) biography.py trajectory digest now explicit '<f8' LE bytes (ADR-0245 §2.3); byte-identical on LE targets, platform-independent everywhere. 31 passed across wiring/session/holonomy/readback suites.
This commit is contained in:
parent
19d5731a23
commit
f16b4a6054
5 changed files with 305 additions and 6 deletions
|
|
@ -59,7 +59,9 @@ def _trajectory_hash(versors: Sequence[np.ndarray]) -> str:
|
|||
|
||||
h = hashlib.sha256()
|
||||
for v in versors:
|
||||
h.update(np.asarray(v, dtype=np.float64).tobytes())
|
||||
# Explicit little-endian f64 bytes (ADR-0245 §2.3): platform-independent
|
||||
# digest. Byte-identical to the prior bare tobytes() on LE targets.
|
||||
h.update(np.ascontiguousarray(np.asarray(v, dtype=np.dtype("<f8"))).tobytes())
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@ import numpy as np
|
|||
|
||||
from algebra.backend import versor_condition
|
||||
from core.physics.biography import BiographyHolonomyBlade, integrate_biography
|
||||
from core.physics.chiral_gate import ChiralOrientationError, ChiralOrientationGate
|
||||
|
||||
_CLOSURE = 1e-6
|
||||
_PROVENANCE_SCHEMA = "biography_provenance_v1"
|
||||
_ADR_REFS = ("ADR-0240", "ADR-0243")
|
||||
_PROVENANCE_SCHEMA = "biography_provenance_v2"
|
||||
_ADR_REFS = ("ADR-0240", "ADR-0241", "ADR-0243")
|
||||
|
||||
|
||||
class BiographyIntegrationError(ValueError):
|
||||
|
|
@ -102,6 +103,7 @@ class BiographyProvenanceRecord:
|
|||
n_steps: int
|
||||
alpha: float
|
||||
closure_proof: Mapping[str, float]
|
||||
chiral_proof: Mapping[str, Any]
|
||||
adr_refs: tuple[str, ...]
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
|
|
@ -117,6 +119,10 @@ class BiographyProvenanceRecord:
|
|||
"n_steps": self.n_steps,
|
||||
"alpha": self.alpha,
|
||||
"closure_proof": dict(self.closure_proof),
|
||||
"chiral_proof": {
|
||||
k: (list(v) if isinstance(v, tuple) else v)
|
||||
for k, v in self.chiral_proof.items()
|
||||
},
|
||||
"adr_refs": list(self.adr_refs),
|
||||
}
|
||||
|
||||
|
|
@ -128,11 +134,45 @@ def _content_id(payload: Mapping[str, Any]) -> str:
|
|||
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def chiral_conservation_precondition(
|
||||
trajectory: Sequence[np.ndarray],
|
||||
) -> tuple[ChiralOrientationGate, tuple[str, ...]]:
|
||||
"""§S2 composition (ADR-0241 §2.4C): sgn(Q_top) conservation over the trajectory.
|
||||
|
||||
Runs BEFORE versor validation, so the gate is live against raw non-versor
|
||||
trajectories carrying material pseudoscalar charge — a mirror-flipped
|
||||
sequence refuses here, before any blade is computed.
|
||||
|
||||
Honesty theorem (pinned in tests/test_adr_0243_biography_wiring.py): I₅ is
|
||||
central in odd-dimensional Cl(4,1), so every CLOSED versor has
|
||||
Q = ⟨ψ I₅ ψ̃⟩₀ = ±⟨I₅⟩₀ = 0 exactly. On admissible trajectories (closed
|
||||
versors, enforced downstream by ``integrate_biography``) every observation
|
||||
is therefore ``vacuous`` and the latch never arms — the same documented
|
||||
inertness contract as chiral_gate's GoldTetherMonitor wiring. The
|
||||
provenance record discloses the verdicts rather than implying enforcement.
|
||||
"""
|
||||
gate = ChiralOrientationGate()
|
||||
verdicts: list[str] = []
|
||||
for i, v in enumerate(trajectory):
|
||||
try:
|
||||
verdicts.append(gate.observe(np.asarray(v, dtype=np.float64)).verdict)
|
||||
except ChiralOrientationError as exc:
|
||||
raise BiographyIntegrationError(
|
||||
"chiral_orientation_violation", stage=f"trajectory[{i}]", **exc.disclosure
|
||||
) from exc
|
||||
except ValueError as exc:
|
||||
raise BiographyIntegrationError(
|
||||
"trajectory_rejected", detail=str(exc), stage=f"trajectory[{i}]"
|
||||
) from exc
|
||||
return gate, tuple(verdicts)
|
||||
|
||||
|
||||
def biography_provenance_record(
|
||||
report: ValidationReportLike,
|
||||
blade: BiographyHolonomyBlade,
|
||||
*,
|
||||
alpha: float,
|
||||
chiral_proof: Mapping[str, Any],
|
||||
) -> BiographyProvenanceRecord:
|
||||
"""Build the append-only provenance record for one validated integration."""
|
||||
counts = {k: int(v) for k, v in sorted(report.counts.items())}
|
||||
|
|
@ -142,6 +182,9 @@ def biography_provenance_record(
|
|||
"blade_versor_condition": float(versor_condition(blade.blade)),
|
||||
"closure_tol": _CLOSURE,
|
||||
}
|
||||
chiral_body = {
|
||||
k: (list(v) if isinstance(v, tuple) else v) for k, v in sorted(chiral_proof.items())
|
||||
}
|
||||
body = {
|
||||
"schema_version": _PROVENANCE_SCHEMA,
|
||||
"n_cases": len(report.results),
|
||||
|
|
@ -153,6 +196,7 @@ def biography_provenance_record(
|
|||
"n_steps": int(blade.n_steps),
|
||||
"alpha": float(alpha),
|
||||
"closure_proof": closure_proof,
|
||||
"chiral_proof": chiral_body,
|
||||
"adr_refs": list(_ADR_REFS),
|
||||
}
|
||||
return BiographyProvenanceRecord(
|
||||
|
|
@ -167,6 +211,7 @@ def biography_provenance_record(
|
|||
n_steps=int(blade.n_steps),
|
||||
alpha=float(alpha),
|
||||
closure_proof=closure_proof,
|
||||
chiral_proof=dict(chiral_proof),
|
||||
adr_refs=_ADR_REFS,
|
||||
)
|
||||
|
||||
|
|
@ -203,6 +248,12 @@ def integrate_validated_biography(
|
|||
refused=sum(1 for r in report.results if r.refused),
|
||||
)
|
||||
|
||||
# §S2 strict precondition (ADR-0241 §2.4C): sgn(Q_top) conservation over the
|
||||
# raw trajectory, before any blade computation. See
|
||||
# chiral_conservation_precondition for the honesty theorem (vacuous on
|
||||
# closed versors by I₅ centrality; live against raw non-versor input).
|
||||
gate, trajectory_verdicts = chiral_conservation_precondition(trajectory)
|
||||
|
||||
try:
|
||||
blade = integrate_biography(trajectory, alpha=alpha)
|
||||
except ValueError as exc:
|
||||
|
|
@ -217,5 +268,19 @@ def integrate_validated_biography(
|
|||
closure_tol=_CLOSURE,
|
||||
)
|
||||
|
||||
record = biography_provenance_record(report, blade, alpha=alpha)
|
||||
# Post-condition: the integrated blade must hold the same orientation latch.
|
||||
try:
|
||||
blade_verdict = gate.observe(blade.blade).verdict
|
||||
except ChiralOrientationError as exc:
|
||||
raise BiographyIntegrationError(
|
||||
"chiral_orientation_violation", stage="blade", **exc.disclosure
|
||||
) from exc
|
||||
chiral_proof: dict[str, Any] = {
|
||||
"latched_sign": int(gate.latched_sign),
|
||||
"q_floor": float(gate.q_floor),
|
||||
"trajectory_verdicts": trajectory_verdicts,
|
||||
"blade_verdict": blade_verdict,
|
||||
}
|
||||
|
||||
record = biography_provenance_record(report, blade, alpha=alpha, chiral_proof=chiral_proof)
|
||||
return blade, record
|
||||
|
|
|
|||
100
evals/analogical_transfer/biography_session.py
Normal file
100
evals/analogical_transfer/biography_session.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"""ADR-0243 §2.5 — harness-driven biography session (seam S2's first real caller).
|
||||
|
||||
Runs the ADR-0240 analogical-transfer harness and, on report-level PASS,
|
||||
integrates the session's lived trajectory into the Biography Holonomy Blade
|
||||
via the PASS-gated wiring (:func:`integrate_validated_biography`; direct
|
||||
integration per the 2026-07-17 ruling — the blade is derived state, a pure
|
||||
recompute, never persisted).
|
||||
|
||||
The lived trajectory is the sequence of transfer versors the session actually
|
||||
underwent: the report carries scalar evidence only (by design), so the
|
||||
versors are RECOMPUTED here from the validated cases' point clouds via
|
||||
:func:`conformal_procrustes` — reconstruction-over-storage, deterministic,
|
||||
bound to the report by the provenance record's content hashes.
|
||||
|
||||
Eval-tier (A-04): lives under ``evals/``; never imported by serving. Failure
|
||||
at any stage is the wiring's typed :class:`BiographyIntegrationError` — a
|
||||
session with wrongs, or with nothing validated, integrates nothing.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Sequence
|
||||
|
||||
from core.physics.biography import BiographyHolonomyBlade
|
||||
from core.physics.biography_wiring import (
|
||||
BiographyProvenanceRecord,
|
||||
integrate_validated_biography,
|
||||
)
|
||||
from core.physics.dynamic_manifold import conformal_procrustes
|
||||
from core.physics.goldtether import GoldTetherMonitor
|
||||
from evals.analogical_transfer.harness import (
|
||||
AnalogicalTransferReport,
|
||||
TransferCase,
|
||||
run_analogical_transfer,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"BiographySessionArtifact",
|
||||
"run_biography_session",
|
||||
"session_trajectory",
|
||||
]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class BiographySessionArtifact:
|
||||
"""One validated session: report, integrated blade, provenance, lineage."""
|
||||
|
||||
report: AnalogicalTransferReport
|
||||
blade: BiographyHolonomyBlade
|
||||
record: BiographyProvenanceRecord
|
||||
trajectory_case_ids: tuple[str, ...]
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
"record": self.record.as_dict(),
|
||||
"trajectory_case_ids": list(self.trajectory_case_ids),
|
||||
"blade_n_steps": int(self.blade.n_steps),
|
||||
"blade_closure": float(self.blade.closure),
|
||||
"trajectory_hash": self.blade.trajectory_hash,
|
||||
}
|
||||
|
||||
|
||||
def session_trajectory(
|
||||
cases: Sequence[TransferCase], report: AnalogicalTransferReport
|
||||
) -> tuple[tuple, tuple[str, ...]]:
|
||||
"""Recompute the lived trajectory: one recovered versor per CORRECT case.
|
||||
|
||||
Report order is preserved (order is load-bearing for holonomy). Refused and
|
||||
wrong cases contribute nothing — wrong=0 gating happens in the wiring.
|
||||
"""
|
||||
by_id = {c.case_id: c for c in cases}
|
||||
versors = []
|
||||
case_ids: list[str] = []
|
||||
for result in report.results:
|
||||
if not result.correct:
|
||||
continue
|
||||
case = by_id[result.case_id]
|
||||
versor, _residual = conformal_procrustes(case.source, case.target)
|
||||
versors.append(versor)
|
||||
case_ids.append(result.case_id)
|
||||
return tuple(versors), tuple(case_ids)
|
||||
|
||||
|
||||
def run_biography_session(
|
||||
cases: Sequence[TransferCase],
|
||||
*,
|
||||
residual_threshold: float = 0.35,
|
||||
alpha: float = 0.5,
|
||||
goldtether: GoldTetherMonitor | None = None,
|
||||
) -> BiographySessionArtifact:
|
||||
"""Validate → recompute lived trajectory → integrate (PASS-gated, typed refusals)."""
|
||||
report = run_analogical_transfer(
|
||||
cases, residual_threshold=residual_threshold, goldtether=goldtether
|
||||
)
|
||||
trajectory, case_ids = session_trajectory(cases, report)
|
||||
blade, record = integrate_validated_biography(report, trajectory, alpha=alpha)
|
||||
return BiographySessionArtifact(
|
||||
report=report, blade=blade, record=record, trajectory_case_ids=case_ids
|
||||
)
|
||||
70
tests/test_adr_0240_biography_session.py
Normal file
70
tests/test_adr_0240_biography_session.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"""ADR-0243 §2.5 — harness-driven biography session pins (seam S2 closure).
|
||||
|
||||
The first real caller of the PASS-gated biography wiring: run the ADR-0240
|
||||
transfer harness, recompute the lived trajectory (recovered transfer versors
|
||||
of the CORRECT cases — reconstruction-over-storage), integrate, and prove
|
||||
I-01 reboot-invariance: the same session recomputes the identical blade and
|
||||
provenance record from scratch.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import json
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from core.physics.biography_wiring import BiographyIntegrationError
|
||||
from evals.analogical_transfer.biography_session import (
|
||||
run_biography_session,
|
||||
session_trajectory,
|
||||
)
|
||||
from evals.analogical_transfer.harness import make_fixture_pair, run_analogical_transfer
|
||||
|
||||
_CLOSURE = 1e-6
|
||||
|
||||
|
||||
def test_pass_session_integrates_lived_trajectory():
|
||||
case = make_fixture_pair()
|
||||
artifact = run_biography_session([case])
|
||||
assert artifact.report.wrong == 0
|
||||
assert artifact.trajectory_case_ids == (case.case_id,)
|
||||
assert artifact.blade.n_steps == 1
|
||||
assert artifact.blade.closure < _CLOSURE
|
||||
assert artifact.record.schema_version == "biography_provenance_v2"
|
||||
assert artifact.record.chiral_proof["blade_verdict"] == "vacuous"
|
||||
json.dumps(artifact.as_dict()) # JSON-safe session artifact
|
||||
|
||||
|
||||
def test_session_reboot_invariance_i01():
|
||||
"""Same cases → bit-identical blade, trajectory hash, and record id.
|
||||
Reconstruction-over-storage: nothing was persisted between the two runs.
|
||||
(Bit-identity is the honest I-01 claim; holonomy_similarity is not a
|
||||
normalized self-overlap and would be a weaker, misleading assert.)"""
|
||||
cases = [make_fixture_pair()]
|
||||
a = run_biography_session(cases)
|
||||
b = run_biography_session(cases)
|
||||
assert np.array_equal(a.blade.blade, b.blade.blade)
|
||||
assert a.blade.trajectory_hash == b.blade.trajectory_hash
|
||||
assert a.record.record_id == b.record.record_id
|
||||
|
||||
|
||||
def test_session_trajectory_recomputes_only_correct_cases():
|
||||
cases = [make_fixture_pair()]
|
||||
report = run_analogical_transfer(cases)
|
||||
versors, ids = session_trajectory(cases, report)
|
||||
assert len(versors) == 1 and ids == (cases[0].case_id,)
|
||||
|
||||
|
||||
def test_failing_session_integrates_nothing():
|
||||
"""A session with wrongs refuses (typed) — no confabulated wisdom.
|
||||
|
||||
The clean fixture recovers its transfer to machine precision (residual
|
||||
~1e-16), so failure is induced honestly: a corrupted expected_novel makes
|
||||
the transfer WRONG, and the wiring must refuse the whole session."""
|
||||
case = make_fixture_pair()
|
||||
corrupted = dataclasses.replace(case, expected_novel=np.roll(case.expected_novel, 1))
|
||||
with pytest.raises(BiographyIntegrationError) as exc_info:
|
||||
run_biography_session([corrupted])
|
||||
assert exc_info.value.reason == "report_not_pass"
|
||||
|
|
@ -89,7 +89,7 @@ def test_live_harness_pass_drives_integration():
|
|||
assert versor_condition(blade.blade) < _CLOSURE
|
||||
|
||||
assert record.record_id.startswith("bioprov-")
|
||||
assert record.schema_version == "biography_provenance_v1"
|
||||
assert record.schema_version == "biography_provenance_v2"
|
||||
assert record.wrong == 0
|
||||
assert record.n_cases == 1
|
||||
assert record.counts["correct"] == 1
|
||||
|
|
@ -99,8 +99,12 @@ def test_live_harness_pass_drives_integration():
|
|||
# Record binds the report to the exact trajectory that was integrated
|
||||
assert record.trajectory_hash == integrate_biography(traj).trajectory_hash
|
||||
assert record.n_steps == blade.n_steps
|
||||
assert record.adr_refs == ("ADR-0240", "ADR-0243")
|
||||
assert record.adr_refs == ("ADR-0240", "ADR-0241", "ADR-0243")
|
||||
assert record.closure_proof["blade_closure"] == blade.closure
|
||||
# §S2 chiral composition: disclosed, and vacuous-by-theorem on closed versors
|
||||
assert record.chiral_proof["latched_sign"] == 0
|
||||
assert set(record.chiral_proof["trajectory_verdicts"]) == {"vacuous"}
|
||||
assert record.chiral_proof["blade_verdict"] == "vacuous"
|
||||
|
||||
|
||||
def test_provenance_record_deterministic():
|
||||
|
|
@ -205,3 +209,61 @@ def test_wiring_imports_no_vault_store_and_no_evals():
|
|||
assert result.returncode == 0, f"probe failed: {result.stderr[-2000:]}"
|
||||
leaked = json.loads(result.stdout.strip().splitlines()[-1])
|
||||
assert leaked == [], f"biography_wiring loaded banned modules: {leaked}"
|
||||
|
||||
|
||||
# --- §S2 chiral composition (ADR-0241 §2.4C) ----------------------------------
|
||||
|
||||
|
||||
def test_chiral_charge_vanishes_on_closed_versors_theorem():
|
||||
"""Honesty theorem pin: I₅ is central in odd-dimensional Cl(4,1), so every
|
||||
closed versor has Q = ⟨ψ I₅ ψ̃⟩₀ = ±⟨I₅⟩₀ = 0 — the biography chiral
|
||||
precondition is vacuous BY THEOREM on admissible trajectories (observed
|
||||
exactly 0.0 in-tree). If this pin breaks, the inertness contract in
|
||||
chiral_conservation_precondition's docstring must be re-derived."""
|
||||
from algebra.null_point import dilator, translator
|
||||
from algebra.versor import unitize_versor
|
||||
from algebra.cl41 import geometric_product
|
||||
from core.physics.wave_manifold import WaveManifold
|
||||
|
||||
wave = WaveManifold()
|
||||
versors = [
|
||||
make_rotor_from_angle(0.7, bivector_idx=6),
|
||||
translator(np.array([0.3, -0.2, 0.5])),
|
||||
dilator(1.4),
|
||||
unitize_versor(
|
||||
geometric_product(
|
||||
translator(np.array([0.1, 0.2, 0.3])),
|
||||
geometric_product(dilator(1.2), make_rotor_from_angle(0.9, bivector_idx=8)),
|
||||
)
|
||||
),
|
||||
]
|
||||
for v in versors:
|
||||
assert abs(wave.chiral_charge(np.asarray(v, dtype=np.float64))) < 1e-12
|
||||
|
||||
|
||||
def test_chiral_flip_refuses_before_blade_computation():
|
||||
"""The precondition is LIVE against raw non-versor trajectories: a material
|
||||
sgn(Q_top) flip refuses (typed) before versor validation or any blade math."""
|
||||
report = _report([_result()])
|
||||
plus = np.zeros(32, dtype=np.float64)
|
||||
plus[0], plus[31] = 0.8, 0.6 # material Q < 0 for this orientation
|
||||
minus = plus.copy()
|
||||
minus[31] = -0.6 # mirror image: opposite material Q
|
||||
with pytest.raises(BiographyIntegrationError) as exc_info:
|
||||
integrate_validated_biography(report, [plus, minus])
|
||||
assert exc_info.value.reason == "chiral_orientation_violation"
|
||||
assert exc_info.value.disclosure["stage"] == "trajectory[1]"
|
||||
|
||||
|
||||
def test_trajectory_hash_uses_little_endian_f64_bytes():
|
||||
"""ADR-0245 §2.3 pin: the biography trajectory digest is computed over
|
||||
explicit '<f8' bytes (platform-independent replay determinism)."""
|
||||
import hashlib
|
||||
|
||||
from core.physics.biography import _trajectory_hash
|
||||
|
||||
traj = _trajectory()
|
||||
h = hashlib.sha256()
|
||||
for v in traj:
|
||||
h.update(np.asarray(v, dtype=np.dtype("<f8")).tobytes())
|
||||
assert _trajectory_hash(traj) == h.hexdigest()
|
||||
|
|
|
|||
Loading…
Reference in a new issue