Archaeology (six worktree measurements) shows public_demo's stale pin (7d8ba0db..., last set 2026-07-14) predates two commits that changed its content deterministically:e7d116c9(trace-hash format widening, benign) ande0d1b475(the register-axis regression's introduction, benign for this lane at that point). But starting at5a343b49(T13's back-stamp, 2026-07-22) public_demo's own all_claims_supported case genuinely FAILS and stays failing through5224b5e0(2026-07-24), fixed only as a side effect of PR #110's unrelated register-axis restoration (f95ac26e) — public_demo embeds the same register-tour scene demo_composition does. The standing "public_demo red = the env-timeout flake, ignore it" memory was true only for the runtime_under_budget case; it caused this real all_claims_supported regression to hide for two days behind the same label. Corrected the memory to triage by which case failed, not by lane name. Re-pinned to da7fad65... (current main, 4/4 passing, verified stable across three independent measurements) and regenerated CLAIMS.md.
6.9 KiB
Lane-Pin Drift Investigation — miner / curriculum / demo_composition
Date: 2026-07-24 · Worktree: core-wt-gen off main @ 5224b5e0
Verdict: two distinct causes; no determinism bug; one real serving
regression found and fixed (register axis stripped from pipeline-served
turns).
Context: during the Band v4-CM arc (2026-07-23), a verify_lane_shas.py --update dry run showed three lanes' pins stale. This investigation
root-causes all three before any re-pin (generalization-arc Phase 0.1).
Determinism check
Each drifted lane was run twice in a fresh worktree (fresh
uv sync --locked venv, hermetic CORE_ENGINE_STATE_DIR): byte-identical
SHAs across runs for miner_loop_closure (537094fe…) and
curriculum_loop_closure (cb94ca00…). Not a determinism bug.
Cause 1 — content-digest widening (miner + curriculum): benign, stale pins
Commit 5c69b741 (2026-07-17, ADR-0244 Phase 5a "§2.7 content-id
semantic rigor") widened core/contemplation/schema.py::_content_digest
from 16-hex truncation to the full 64-hex sha256 (birthday-collision
rigor). Both lanes' reports embed finding_id / derived proposal_id
values from that digest: the fresh finding_id is the 64-hex extension
of the exact pinned 16-hex prefix (4d6b8b5e1d46eb60 →
4d6b8b5e1d46eb60ea7a…), and every downstream proposal_id cascades.
The commit re-pinned nothing. Intentional, ADR-tracked, benign → both
pins re-pinned surgically in this branch (single-line edits; never
--update, which rewrites every lane and silently drops erroring
lanes' pins).
Cause 2 — demo_composition: a REAL serving regression (found via the drift)
The fresh lane report flipped register-tour all_claims_supported
true→false (plus composite_supported, which is audit ∧ register).
Isolation showed the register tour's two substantive-differentiation
claims failing while the three invariance claims held: terse/convivial
registers no longer differed from neutral on pack-grounded definitions
— the entire register axis (ADR-0077 R6 substantive + ADR-0071 R4
decoration) was missing from pipeline-served surfaces.
Mechanism (three commits, each individually defensible):
ff1dcb25(2026-05-20, #76) introducedresolve_surfacewith a_base_runtime_surfaceprecedence of canonical-first — the trace-hash identity capture preferred over the runtime's served bytes. Dormant at first.e0d1b475(2026-07-20, #96 fail-closed linguistic governance) routed pipeline turns through the resolver withcanonical_surfacepopulated → pipeline-served turns began serving the pre-R6 canonical. The runtime's ownchat()path stayed correct;warmed_sessiontelemetry-consistency went red (0.9444) because TurnEvent (correct bytes) disagreed with pipeline (stripped bytes).5a343b49(2026-07-22, T13) "fixed" the telemetry red by back-stamping the pipeline's (stripped) surface onto TurnEvent — making telemetry consistent with the regressed serving. The register tour's claims — the falsifiable contract for the register axis — then failed, which is exactly the byte drift the lane pin caught.
Why no gate caught it: the e2e tests that pin this behavior
(tests/test_register_substantive_consumption.py::test_e2e_terse_*)
are red on main but are not in the curated smoke suite; the lane-shas CI
job is the only gate that runs the demo lanes, and its failures were
conflated with the known public_demo env flake.
Fix (this branch)
core/cognition/surface_resolution.py + core/cognition/pipeline.py:
_base_runtime_surfaceprecedence corrected to response-first (served bytes = post-guard, post-R6, post-R4), canonical demoted to last-resort fallback.- New
SurfaceResolution.hash_surface: the truth-path (canonical-precedence) bytes, kept in lockstep through substrate overrides, folds, hedge prefix, logos-morph override, and the speculative marker.compute_trace_hashnow foldshash_surface, so trace_hash stays register-invariant (ADR-0069 inv C) while the served surface carries the register._prior_surface(correction binding) also stays on the truth path so register packs cannot perturb teaching. - Removed dead
FailureClassimport +_assessment_residual(repo-wide unreferenced).
Verification: register tour 6/6 claims (both substantive-differs
claims restored AND all_trace_hashes_identical held);
tests/test_surface_resolution.py (updated precedence tests + 2 new
fallback tests), test_register_substantive_consumption.py (previously
red e2e tests now green), test_grounded_open_hedge_arm.py,
test_cognitive_turn_pipeline.py, test_warmed_session_lane.py (T13
consistency) — all green; smoke suite via pre-push gate.
demo_composition pin disposition (measured)
After the fix, every claims-supported flag in the lane report matches
the committed report again (all_claims_supported_a/b true,
composite_supported true). The only residual delta vs the 2026-07-14
pin is the two tours' inner payload sha256 values — those payloads
embed per-prompt trace_hash values whose format legitimately changed
post-pin (e7d116c9, 2026-07-20: Phase-B graph-topology inclusion in
compute_trace_hash). Semantics restored, embedded hash format
evolved → re-pinned to f0611a2c… with this diff as the audit trail.
public_demo (not one of the three, for completeness)
Unchanged: its known failure mode is the env-timeout flake
(all_claims_supported=False under cold/slow runs), documented in
memory and the lane-shas remediation text. Do not re-pin from a laptop
run; adjudicate on the Act runner.
Correction (Tier S, 2026-07-24): this framing was incomplete. public_demo
carries the SAME register-tour scene as demo_composition and was
independently root-caused as drifted for the same reasons documented above
(e7d116c9 benignly, then e0d1b475/5a343b49 as a REAL two-day
all_claims_supported regression, fixed by the same f95ac26e) — the
env-timeout flake is real but is a different failure mode
(runtime_under_budget) than the one that was actually red. Full
archaeology, measured timeline, and the re-pin:
docs/research/public-demo-lane-drift-2026-07-24.md.
Bonus latent break found while re-pinning
scripts/generate_claims.py raised on every run since the
deduction_serve_v1 pin landed (2026-07-23): the pin was added to
PINNED_SHAS without the required _LANE_ADR entry, so the lane-shas
CI's generate_claims.py --check step has been red since then. Fixed
here (ADR-0256 row added; CLAIMS.md regenerated, check green).
Follow-ups (assigned in the generalization-arc plan)
- Tier S: add
tests/test_register_substantive_consumption.pye2e tests to the curated smoke suite so this axis can never silently regress again (small, mechanical). - Tier S: document the lane-shas CI expectation that a red lane job is triaged per-lane, never assumed to be the public_demo flake.