Tests on main had drifted from intentional substrate changes that
weren't propagated to their fixtures or pinned values. Categories:
1. PackMutationProposal missing source= arg (3 tests across
test_mutation_proposal_type, test_provenance, test_expert_demo_runnable):
add ProposalSource(kind="operator", source_id="", emitted_at_revision="test")
to the shared fixture. test_expert_demo_runnable also retargets the
"unpromoted domain" example from systems_software (now promoted) to
arithmetic (real but unpromoted).
2. Pack content grew (test_en_core_meta_v1_pack 73→77 entries, 49→53 verbs;
test_en_core_spatial_v1_pack 24→25 entries adding "places" plural surface):
bump expected counts; allow new provenance shapes from the
adr-0085-style-v2 review (including the seed:core_meta/seed:core_spatial
author-time typos on two entries each — documented inline rather than
masked).
3. Registry self-documenting "add names to the set" failures
(test_lane_sha_verifier: add curriculum_loop_closure;
test_register_runtime_threading: add gloss_aware_cause_surface,
pack_grounded_unknown_surface, teaching_grounded_surface_transitive).
4. Gloss content was seeded where tests pinned None
(test_pack_resolver_glosses TestMissingGlossesIsBackCompat): switch
the no-glosses pack from en_core_relations_v1 (since glossed) to
en_minimal_v1 (still gloss-free); narrow resolve_gloss probe to that
pack so other packs' glosses can't shadow.
5. Entry-id renumber from cognition-pack expansion
(test_language_pack_cache): en-core-cog-085 → en-core-cog-091.
6. Holdout tests fail without CORE_HOLDOUT_KEY or local plaintext
(test_eval_holdout_split + test_transitive_surface): add
_requires_holdout skip-marker mirroring _decrypt_holdout's contract;
gate the transitive_surface holdout iteration on the same check.
7. Byte-identity surface guards regressed after the gloss-aware
composer landed (test_realizer_guard_holdout, test_prompt_diversity_runner,
test_register_substantive_consumption): re-pin to current surfaces
("Light is a visible medium that reveals truth." replaces "Light is a
source of revelation that makes things knowable.", etc.). The guard's
regression-catching role is preserved by pinning current output going
forward; the new gloss-driven phrasings are visibly more grounded.
Touched 14 test files: 176 passed, 4 skipped (holdout-gated), 0 failed
on a targeted re-run. No production code touched.
Six lanes (reviewer_registry, miner_loop_closure,
domain_contract_validation, fabrication_control_summary,
demo_composition, public_demo) now have CI-enforced SHA-256 pins.
A failing job means a lane's deterministic output changed without
an explicit ADR-tracked pin update.
- new scripts/verify_lane_shas.py: single source of truth
- PINNED_SHAS dict mapping lane_id → 64-char hex SHA
- LANE_SPECS tuple wiring each lane to its runner module + canonical
report path
- accepts_report_flag handles the fabrication_control runner's
different arg shape (--lane-dir not --report)
- verify_all() runs each lane in subprocess isolation (clean Python
state per lane — relevant for adapters that cache pack loads at
module import)
- --update flag refreshes pins after intentional ADR-tracked changes;
diff is the audit trail
- --json flag emits machine-readable report
- exits non-zero on any mismatch
- new .github/workflows/lane-shas.yml:
- triggers on push to main and pull_request to main
- concurrency group cancels in-progress runs on new commits
- Python 3.11 + pip-cached deps + editable install
- runs verify_lane_shas.py; emits JSON report on failure
- 12-minute timeout (lanes take ~30s in practice)
- new tests/test_lane_sha_verifier.py: cheap local-pytest pinning
- every LaneSpec has a corresponding PINNED_SHAS entry
- no orphan pins without a LaneSpec
- every pin is a 64-char hex SHA-256
- every runner module path exists on disk
- canonical report paths are under repo root
- all six expected lanes (ADR-0092/0093/0095/0096/0098/0099) covered;
ADR-0094 and ADR-0097 are schema/ratification only, intentionally
excluded from EXPECTED_LANES
- 6 tests run in <100ms — catches drift before CI
- evals/public_demo/results/v1_dev.json: refreshed to match the new
pin (21751aaf..) — earlier pin was generated under slightly different
runner argparse defaults; --update produced the canonical bytes
Local verifier: 6/6 lanes match pinned SHAs. Smoke 67/67. Lane SHAs:
reviewer_registry 681a2aab..
miner_loop_closure 9f071733..
domain_contract_validation f9c06cde..
fabrication_control_summary 01e1b6b7..
demo_composition 27d83824..
public_demo 21751aaf..