Merge pull request 'fix(cognition): restore register axis on pipeline-served turns + Phase 0 of generalization arc' (#110) from feat/generalization-phase0 into main
Reviewed-on: #110
This commit is contained in:
commit
379e1611ac
10 changed files with 582 additions and 28 deletions
|
|
@ -36,13 +36,14 @@ is a CI failure (`.github/workflows/lane-shas.yml`).
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| ADR-0092 | `reviewer_registry` | Reviewer registry schema validates + bootstrap entry self-seals | `evals/reviewer_registry/results/v1_dev.json` | `681a2aab5aa4ffd58cd837ce5673c8b2a9545b570117aec3c02726a12f6876e6` |
|
| ADR-0092 | `reviewer_registry` | Reviewer registry schema validates + bootstrap entry self-seals | `evals/reviewer_registry/results/v1_dev.json` | `681a2aab5aa4ffd58cd837ce5673c8b2a9545b570117aec3c02726a12f6876e6` |
|
||||||
| ADR-0093 | `domain_contract_validation` | All ratified packs satisfy the 9 ADR-0091 contract predicates | `evals/domain_contract_validation/results/v1_dev.json` | `98ace04e3f02bbc5a8ad655bb6593c3f1ee64cb67014f1122fe6c3c85f48d22f` |
|
| ADR-0093 | `domain_contract_validation` | All ratified packs satisfy the 9 ADR-0091 contract predicates | `evals/domain_contract_validation/results/v1_dev.json` | `98ace04e3f02bbc5a8ad655bb6593c3f1ee64cb67014f1122fe6c3c85f48d22f` |
|
||||||
| ADR-0095 | `miner_loop_closure` | Miner-sourced proposals route through single reviewed teaching path | `evals/miner_loop_closure/results/v1_dev.json` | `9f071733abe7dcacf759f928548ce738fb639af3fd6e4c621a651b306d7e77ce` |
|
| ADR-0095 | `miner_loop_closure` | Miner-sourced proposals route through single reviewed teaching path | `evals/miner_loop_closure/results/v1_dev.json` | `537094fe21d7e6cfbaf42bfc32b82d669fa9bb05a132d2bc93c72b3ceb7762a6` |
|
||||||
| ADR-0096 | `fabrication_control_summary` | Phantom endpoints / cross-pack non-bridges / sibling collapses refuse | `evals/fabrication_control/results/v1_summary.json` | `01e1b6b711141f2b4a14551d7df3ea482d8d6dd7b364a25c509f4f8d08cda8a8` |
|
| ADR-0096 | `fabrication_control_summary` | Phantom endpoints / cross-pack non-bridges / sibling collapses refuse | `evals/fabrication_control/results/v1_summary.json` | `01e1b6b711141f2b4a14551d7df3ea482d8d6dd7b364a25c509f4f8d08cda8a8` |
|
||||||
| ADR-0098 | `demo_composition` | Demos compose from shipped modules; no parallel mechanism | `evals/demo_composition/results/v1_dev.json` | `e2ba2314d8768459fb6a8db082a4bbcf4107b5161d869804a4b2a33c3724081a` |
|
| ADR-0098 | `demo_composition` | Demos compose from shipped modules; no parallel mechanism | `evals/demo_composition/results/v1_dev.json` | `f0611a2ce41721dd40767fc6a83a08470d3c7fd7fc8f1ae8ba003abf8a25ec97` |
|
||||||
| ADR-0099 | `public_demo` | Public showcase runs deterministically under 30s; all claims supported | `evals/public_demo/results/v1_dev.json` | `7d8ba0dbae9287cfe0bf15d231fa78a75abc627121c14900439293e01e1cc1d3` |
|
| ADR-0099 | `public_demo` | Public showcase runs deterministically under 30s; all claims supported | `evals/public_demo/results/v1_dev.json` | `7d8ba0dbae9287cfe0bf15d231fa78a75abc627121c14900439293e01e1cc1d3` |
|
||||||
| ADR-0104 | `curriculum_loop_closure` | Curriculum-sourced proposals route through single reviewed teaching path | `evals/curriculum_loop_closure/results/v1_dev.json` | `b46d56b2d209172cc3ffaf3776dc8dcfe55093f13587c5cb67372be6dfa23e8d` |
|
| ADR-0104 | `curriculum_loop_closure` | Curriculum-sourced proposals route through single reviewed teaching path | `evals/curriculum_loop_closure/results/v1_dev.json` | `cb94ca0042d78ec2624129ff6493d52e767b69feea32d2997b85d88f1c0883af` |
|
||||||
| ADR-0131 | `math_teaching_corpus_v1` | Math teaching corpus replays deterministically; all chains pass exit criterion (correct_rate=1.0, wrong=0) | `evals/math_teaching_corpus/v1/report.json` | `eaf160d145da29f9050ede8d58bf111b0f651dd40aeae9201857d0b97e014dd4` |
|
| ADR-0131 | `math_teaching_corpus_v1` | Math teaching corpus replays deterministically; all chains pass exit criterion (correct_rate=1.0, wrong=0) | `evals/math_teaching_corpus/v1/report.json` | `eaf160d145da29f9050ede8d58bf111b0f651dd40aeae9201857d0b97e014dd4` |
|
||||||
| ADR-0206 | `deductive_logic_v1` | Propositional entailment scored against an independent truth-table oracle; dev+holdout+external 716/716 correct, wrong=0, refused=0 | `evals/deductive_logic/report.json` | `97a230949016e38d5e3f37a69e4245b320575ee70e5af92ff7607f7b05f74b5f` |
|
| ADR-0206 | `deductive_logic_v1` | Propositional entailment scored against an independent truth-table oracle; dev+holdout+external 716/716 correct, wrong=0, refused=0 | `evals/deductive_logic/report.json` | `97a230949016e38d5e3f37a69e4245b320575ee70e5af92ff7607f7b05f74b5f` |
|
||||||
|
| ADR-0256 | `deduction_serve_v1` | Flag-gated deduction serving decides real English/member/fused arguments end-to-end under earned SERVE licenses; wrong=0 across all splits | `evals/deduction_serve/report.json` | `b530ed99c414a6d1bdd239752b0e1c6c8c03893f402198def29122b9c2a8a8be` |
|
||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -486,6 +486,11 @@ class CognitiveTurnPipeline:
|
||||||
grounding_provenance=grounding_src,
|
grounding_provenance=grounding_src,
|
||||||
)
|
)
|
||||||
surface = resolved.surface
|
surface = resolved.surface
|
||||||
|
# Truth-path bytes for trace_hash (ADR-0069 inv C): the served
|
||||||
|
# surface carries register R6/R4 transforms and MUST NOT move the
|
||||||
|
# hash; hash_surface is the register-invariant canonical-precedence
|
||||||
|
# capture, kept in lockstep with every served-surface mutation below.
|
||||||
|
hash_surface = resolved.hash_surface or resolved.surface
|
||||||
articulation_surface = resolved.articulation_surface
|
articulation_surface = resolved.articulation_surface
|
||||||
authority_source = resolved.authority
|
authority_source = resolved.authority
|
||||||
|
|
||||||
|
|
@ -518,6 +523,7 @@ class CognitiveTurnPipeline:
|
||||||
if logos_blocks_certified_answer(logos_decision):
|
if logos_blocks_certified_answer(logos_decision):
|
||||||
refusal = decision_as_coherence_refusal(logos_decision)
|
refusal = decision_as_coherence_refusal(logos_decision)
|
||||||
surface = refusal.surface_message or refusal.message
|
surface = refusal.surface_message or refusal.message
|
||||||
|
hash_surface = surface
|
||||||
articulation_surface = surface
|
articulation_surface = surface
|
||||||
authority_source = "logos_morph_constraint"
|
authority_source = "logos_morph_constraint"
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -667,6 +673,7 @@ class CognitiveTurnPipeline:
|
||||||
# proposal (if any) is added below for FUTURE turns to see.
|
# proposal (if any) is added below for FUTURE turns to see.
|
||||||
if self._speculative_subjects and surface and self._should_mark_speculative(text, surface):
|
if self._speculative_subjects and surface and self._should_mark_speculative(text, surface):
|
||||||
surface = _SPECULATIVE_SURFACE_MARKER + surface
|
surface = _SPECULATIVE_SURFACE_MARKER + surface
|
||||||
|
hash_surface = _SPECULATIVE_SURFACE_MARKER + hash_surface
|
||||||
articulation_surface = _SPECULATIVE_SURFACE_MARKER + articulation_surface
|
articulation_surface = _SPECULATIVE_SURFACE_MARKER + articulation_surface
|
||||||
|
|
||||||
# 10. TEACHING — correction capture, review, and store
|
# 10. TEACHING — correction capture, review, and store
|
||||||
|
|
@ -705,9 +712,11 @@ class CognitiveTurnPipeline:
|
||||||
if len(tok) >= 4 and tok not in _SUBJECT_STOPWORDS:
|
if len(tok) >= 4 and tok not in _SUBJECT_STOPWORDS:
|
||||||
self._forget_speculative_subject(tok)
|
self._forget_speculative_subject(tok)
|
||||||
|
|
||||||
# Advance turn counter and remember surface for next correction binding
|
# Advance turn counter and remember surface for next correction binding.
|
||||||
|
# The truth-path surface (not the served, register-decorated bytes)
|
||||||
|
# feeds correction binding so register packs cannot perturb teaching.
|
||||||
self._turn_number += 1
|
self._turn_number += 1
|
||||||
self._prior_surface = surface
|
self._prior_surface = hash_surface
|
||||||
|
|
||||||
# 11. TRACE — deterministic hash (includes teaching IDs and any
|
# 11. TRACE — deterministic hash (includes teaching IDs and any
|
||||||
# typed-operator invocation per ADR-0018).
|
# typed-operator invocation per ADR-0018).
|
||||||
|
|
@ -787,7 +796,7 @@ class CognitiveTurnPipeline:
|
||||||
trace_hash = compute_trace_hash(
|
trace_hash = compute_trace_hash(
|
||||||
input_text=text,
|
input_text=text,
|
||||||
filtered_tokens=filtered_tokens,
|
filtered_tokens=filtered_tokens,
|
||||||
surface=surface,
|
surface=hash_surface,
|
||||||
walk_surface=response.walk_surface,
|
walk_surface=response.walk_surface,
|
||||||
articulation_surface=articulation_surface,
|
articulation_surface=articulation_surface,
|
||||||
dialogue_role=str(response.dialogue_role),
|
dialogue_role=str(response.dialogue_role),
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ from typing import TYPE_CHECKING
|
||||||
from core.cognition.fail_closed import (
|
from core.cognition.fail_closed import (
|
||||||
CoherenceRefusal,
|
CoherenceRefusal,
|
||||||
ContractViolation,
|
ContractViolation,
|
||||||
FailureClass,
|
|
||||||
ResidualState,
|
|
||||||
contract_assessment_none_violation,
|
contract_assessment_none_violation,
|
||||||
open_geometry_refusal,
|
open_geometry_refusal,
|
||||||
)
|
)
|
||||||
|
|
@ -86,6 +84,15 @@ class SurfaceResolution:
|
||||||
refusal: CoherenceRefusal | None = None
|
refusal: CoherenceRefusal | None = None
|
||||||
contract_violation: ContractViolation | None = None
|
contract_violation: ContractViolation | None = None
|
||||||
proof_trace: ProofTrace | None = None
|
proof_trace: ProofTrace | None = None
|
||||||
|
hash_surface: str = ""
|
||||||
|
"""Truth-path surface for ``trace_hash`` folding (ADR-0069 inv C).
|
||||||
|
|
||||||
|
``surface`` carries the *served* bytes (post register R6/R4);
|
||||||
|
``hash_surface`` carries the register-invariant truth-path bytes
|
||||||
|
(canonical-precedence base plus the same substrate/fold suffixes).
|
||||||
|
Empty means the served surface IS the truth-path surface (refusal,
|
||||||
|
abstention, and legacy callers) — the pipeline falls back to
|
||||||
|
``surface`` when folding the trace."""
|
||||||
|
|
||||||
|
|
||||||
def _base_runtime_surface(
|
def _base_runtime_surface(
|
||||||
|
|
@ -95,25 +102,44 @@ def _base_runtime_surface(
|
||||||
response_surface: str,
|
response_surface: str,
|
||||||
response_articulation_surface: str,
|
response_articulation_surface: str,
|
||||||
) -> tuple[str, str, str]:
|
) -> tuple[str, str, str]:
|
||||||
"""Select the runtime-owned base surface by declared precedence."""
|
"""Select the runtime-owned base surface by declared precedence.
|
||||||
|
|
||||||
if canonical_surface:
|
``response_surface`` is the runtime's final *served* bytes — post
|
||||||
return canonical_surface, response_articulation_surface, "runtime_canonical"
|
realizer-guard, post substantive register (ADR-0077 R6), post seeded
|
||||||
|
decoration (ADR-0071 R4) — and always wins when present.
|
||||||
|
``canonical_surface`` / ``pre_decoration_surface`` are truth-path
|
||||||
|
identity captures the pipeline folds into ``trace_hash``; they are
|
||||||
|
fallbacks for callers that never sealed a response surface, never a
|
||||||
|
substitute for served bytes. Preferring canonical here strips the
|
||||||
|
entire register axis from pipeline-served turns (terse/convivial
|
||||||
|
stop differing from neutral) while trace_hash stays green — the
|
||||||
|
register-tour claims are the falsifiable contract that catches it.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if response_surface:
|
||||||
|
return response_surface, response_articulation_surface, "runtime"
|
||||||
if pre_decoration_surface:
|
if pre_decoration_surface:
|
||||||
return pre_decoration_surface, response_articulation_surface, "runtime_pre_decoration"
|
return pre_decoration_surface, response_articulation_surface, "runtime_pre_decoration"
|
||||||
return response_surface, response_articulation_surface, "runtime"
|
if canonical_surface:
|
||||||
|
return canonical_surface, response_articulation_surface, "runtime_canonical"
|
||||||
|
return "", response_articulation_surface, "runtime"
|
||||||
|
|
||||||
|
|
||||||
def _assessment_residual(
|
def _truth_path_base(
|
||||||
contract_assessment: "ContractAssessment | None",
|
*,
|
||||||
) -> ResidualState | None:
|
canonical_surface: str,
|
||||||
if contract_assessment is None:
|
pre_decoration_surface: str,
|
||||||
return ResidualState(detail="contract_assessment is None")
|
response_surface: str,
|
||||||
return ResidualState(
|
) -> str:
|
||||||
missing_bindings=tuple(contract_assessment.missing_bindings),
|
"""Register-invariant base folded into ``trace_hash``.
|
||||||
unresolved_hazards=tuple(contract_assessment.unresolved_hazards),
|
|
||||||
detail=str(contract_assessment.explanation or ""),
|
Canonical-first: the composer's pre-R6 capture is the truth-path
|
||||||
)
|
identity field, byte-identical across register packs (ADR-0069
|
||||||
|
inv C / ADR-0077). Falls through to pre-decoration, then the
|
||||||
|
response itself for turns that never captured a canonical surface.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return canonical_surface or pre_decoration_surface or response_surface
|
||||||
|
|
||||||
|
|
||||||
def _abstention_resolution(
|
def _abstention_resolution(
|
||||||
|
|
@ -211,9 +237,17 @@ def _grounded_open_hedge_resolution(
|
||||||
response_surface=response_surface,
|
response_surface=response_surface,
|
||||||
response_articulation_surface=response_articulation_surface,
|
response_articulation_surface=response_articulation_surface,
|
||||||
)
|
)
|
||||||
|
truth_base = _truth_path_base(
|
||||||
|
canonical_surface=canonical_surface,
|
||||||
|
pre_decoration_surface=pre_decoration_surface,
|
||||||
|
response_surface=response_surface,
|
||||||
|
)
|
||||||
surface = (
|
surface = (
|
||||||
f"{_GROUNDED_OPEN_HEDGE_PREFIX} {base_surface}" if base_surface else base_surface
|
f"{_GROUNDED_OPEN_HEDGE_PREFIX} {base_surface}" if base_surface else base_surface
|
||||||
)
|
)
|
||||||
|
hash_surface = (
|
||||||
|
f"{_GROUNDED_OPEN_HEDGE_PREFIX} {truth_base}" if truth_base else truth_base
|
||||||
|
)
|
||||||
articulation = (
|
articulation = (
|
||||||
f"{_GROUNDED_OPEN_HEDGE_PREFIX} {base_articulation}"
|
f"{_GROUNDED_OPEN_HEDGE_PREFIX} {base_articulation}"
|
||||||
if base_articulation
|
if base_articulation
|
||||||
|
|
@ -229,6 +263,7 @@ def _grounded_open_hedge_resolution(
|
||||||
refusal=None,
|
refusal=None,
|
||||||
contract_violation=None,
|
contract_violation=None,
|
||||||
proof_trace=None,
|
proof_trace=None,
|
||||||
|
hash_surface=hash_surface,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -322,6 +357,11 @@ def resolve_surface(
|
||||||
response_surface=response_surface or "",
|
response_surface=response_surface or "",
|
||||||
response_articulation_surface=response_articulation_surface or "",
|
response_articulation_surface=response_articulation_surface or "",
|
||||||
)
|
)
|
||||||
|
hash_surface = _truth_path_base(
|
||||||
|
canonical_surface=canonical_surface or "",
|
||||||
|
pre_decoration_surface=pre_decoration_surface or "",
|
||||||
|
response_surface=response_surface or "",
|
||||||
|
)
|
||||||
|
|
||||||
# === DUAL-COMPETING SHADOW COHERENCE GATE ===
|
# === DUAL-COMPETING SHADOW COHERENCE GATE ===
|
||||||
# Forward and conjugate evaluated as independent competitors; commit
|
# Forward and conjugate evaluated as independent competitors; commit
|
||||||
|
|
@ -340,6 +380,7 @@ def resolve_surface(
|
||||||
|
|
||||||
if not gate_blocks and realized_surface and forward_ok and conjugate_ok:
|
if not gate_blocks and realized_surface and forward_ok and conjugate_ok:
|
||||||
surface = realized_surface
|
surface = realized_surface
|
||||||
|
hash_surface = realized_surface
|
||||||
articulation_surface = realized_surface
|
articulation_surface = realized_surface
|
||||||
authority = "substrate_realizer"
|
authority = "substrate_realizer"
|
||||||
elif (
|
elif (
|
||||||
|
|
@ -352,12 +393,16 @@ def resolve_surface(
|
||||||
# Transitional shim: geometric coherence holds, but graph not yet
|
# Transitional shim: geometric coherence holds, but graph not yet
|
||||||
# fully grounded. Never used when conjugate residual fails.
|
# fully grounded. Never used when conjugate residual fails.
|
||||||
surface = realized_surface
|
surface = realized_surface
|
||||||
|
hash_surface = realized_surface
|
||||||
articulation_surface = realized_surface
|
articulation_surface = realized_surface
|
||||||
authority = "realizer"
|
authority = "realizer"
|
||||||
|
|
||||||
fold_sources: list[str] = []
|
fold_sources: list[str] = []
|
||||||
if walk_surface:
|
if walk_surface:
|
||||||
surface = f"{surface} — {walk_surface}" if surface else walk_surface
|
surface = f"{surface} — {walk_surface}" if surface else walk_surface
|
||||||
|
hash_surface = (
|
||||||
|
f"{hash_surface} — {walk_surface}" if hash_surface else walk_surface
|
||||||
|
)
|
||||||
articulation_surface = (
|
articulation_surface = (
|
||||||
f"{articulation_surface} — {walk_surface}"
|
f"{articulation_surface} — {walk_surface}"
|
||||||
if articulation_surface
|
if articulation_surface
|
||||||
|
|
@ -367,6 +412,9 @@ def resolve_surface(
|
||||||
|
|
||||||
if compose_surface:
|
if compose_surface:
|
||||||
surface = f"{surface} — {compose_surface}" if surface else compose_surface
|
surface = f"{surface} — {compose_surface}" if surface else compose_surface
|
||||||
|
hash_surface = (
|
||||||
|
f"{hash_surface} — {compose_surface}" if hash_surface else compose_surface
|
||||||
|
)
|
||||||
articulation_surface = (
|
articulation_surface = (
|
||||||
f"{articulation_surface} — {compose_surface}"
|
f"{articulation_surface} — {compose_surface}"
|
||||||
if articulation_surface
|
if articulation_surface
|
||||||
|
|
@ -392,6 +440,7 @@ def resolve_surface(
|
||||||
refusal=None,
|
refusal=None,
|
||||||
contract_violation=None,
|
contract_violation=None,
|
||||||
proof_trace=proof,
|
proof_trace=proof,
|
||||||
|
hash_surface=hash_surface,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Handoff Brief — Tier O (Opus 5, MEDIUM risk)
|
||||||
|
|
||||||
|
**Read first:** `docs/plans/generalization-arc-2026-07-24.md` (the plan of
|
||||||
|
record — §4 gold contract and §6 constraint set are binding), then
|
||||||
|
`AGENTS.md`. Reference ADRs on demand: 0256–0259 (band recipe),
|
||||||
|
0175/0199 (license doctrine), 0251/0252 (math-reader guardrails).
|
||||||
|
|
||||||
|
**You own, in order:**
|
||||||
|
|
||||||
|
1. **O1 — Band v6-EX (existential `some` witnesses).** Follow the band
|
||||||
|
recipe exactly as ADR-0258/0259 executed it: reader module in
|
||||||
|
`generate/proof_chain/`, shape bands in `shape.py`, surface wiring in
|
||||||
|
`chat/deduction_surface.py`, arena templates ≥720/band in
|
||||||
|
`evals/deduction_serve/practice/gold.py`, hand-authored lane split,
|
||||||
|
ledger reseal, tests, ADR, research doc. Gotchas that bit before:
|
||||||
|
cross-module `_Reject` identity (catch both classes); band-N swallows
|
||||||
|
band-N+1 test texts (verify the prior band really refuses your
|
||||||
|
declined cases); surgical single-line pin edits only (never
|
||||||
|
`verify_lane_shas.py --update`).
|
||||||
|
2. **O2 — Phase 2 physics serve lane** per the §4 curriculum-entailment
|
||||||
|
contract. Premises come ONLY from ratified domain chains
|
||||||
|
(`teaching/domain_chains/physics_chains_v1.jsonl` + pack mounts);
|
||||||
|
anti-recall probes (gold=UNKNOWN for true-but-untaught) are mandatory
|
||||||
|
or the lane must not ship. Independent closed-world oracle first,
|
||||||
|
then the lane. Biology second, only after O3 lands.
|
||||||
|
3. **O3 — generic consumption bridge**: extract the seal→ratify→
|
||||||
|
SHA-verified-license→serve-gate pattern (models:
|
||||||
|
`chat/deduction_serve_license.py`,
|
||||||
|
`generate/determine/estimation_license.py`) into a reusable ADR-0175
|
||||||
|
Phase-5 bridge so subject arenas plug in without bespoke wiring.
|
||||||
|
4. **O4 — math reader: seeding-sentence injection** (standing ruling
|
||||||
|
#77 — the 75% "no injection" wall). Then compare unblock (4.2).
|
||||||
|
Hard guardrails: no bespoke-per-case regex growth (ADR-0251); check
|
||||||
|
every new pattern against
|
||||||
|
`docs/research/reader-arc-overfit-inventory-2026-07-19.md`; measure
|
||||||
|
on the frozen tune/measure split; wrong=0 on the full 500 is the
|
||||||
|
gate, parse-rate gain is the goal.
|
||||||
|
|
||||||
|
**Constraints (non-negotiable):** wrong=0; all flags stay default-off —
|
||||||
|
flips are Shay's ratification only; Forgejo-primary (no `gh`); worktree
|
||||||
|
per unit off `forgejo-https/main`; fresh venv per worktree
|
||||||
|
(`rm -rf .venv && uv sync --locked --offline`, then `uv run --no-sync`);
|
||||||
|
pre-push hook runs smoke+warmed_session (~4.5 min — budget timeouts);
|
||||||
|
PRs opened by Shay via the compare URL the push prints (push PAT 403s
|
||||||
|
the PR API); Shay merges — never you; branch+worktree deleted after
|
||||||
|
merge; no timelines in any doc.
|
||||||
|
|
||||||
|
**Your exit checkpoint (O→S):** v6-EX merged; ≥1 subject lane serving
|
||||||
|
wrong=0 with earned licenses; bridge merged; math increment measured and
|
||||||
|
documented (a null result is a valid checkpoint). Then update
|
||||||
|
`BRIEF-S-sonnet-low-tier.md` with actual state, update memory, and stop
|
||||||
|
for the Sonnet handoff.
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Handoff Brief — Tier S (Sonnet 5, LOW risk)
|
||||||
|
|
||||||
|
**Read first:** `docs/plans/generalization-arc-2026-07-24.md` §6
|
||||||
|
(constraint set is binding) and the Tier-O brief's constraints block —
|
||||||
|
they apply verbatim. Opus will have updated this brief with actual state
|
||||||
|
at its exit checkpoint; trust that update over anything stale below.
|
||||||
|
|
||||||
|
**You own (independent items, any order unless noted):**
|
||||||
|
|
||||||
|
1. **S1 — ratification packet for `deduction_serving_enabled`.**
|
||||||
|
Evidence collation only — the flip is Shay's decision, never yours.
|
||||||
|
Contents: 17+-band sealed ledger stats
|
||||||
|
(`chat/data/deduction_serve_ledger.json`), serve-lane results
|
||||||
|
(`evals/deduction_serve/report.json`), byte-identical-when-off proof
|
||||||
|
(cite ADR-0256 + `tests/test_deduction_surface.py` flag tests), blast
|
||||||
|
radius (exact dispatch point `chat/runtime.py` deduction branch), and
|
||||||
|
rollback (flip back, zero residue). One markdown doc in
|
||||||
|
`docs/research/`, PR'd.
|
||||||
|
2. **S2 — lane re-pins + flake documentation.** Only AFTER the Phase-0.1
|
||||||
|
drift findings doc exists and says re-pin is safe. Surgical
|
||||||
|
single-line edits in `scripts/verify_lane_shas.py` — NEVER `--update`
|
||||||
|
(it rewrites every lane and silently drops erroring lanes' pins).
|
||||||
|
Document the `public_demo` env-timeout flake where the findings doc
|
||||||
|
says.
|
||||||
|
3. **S3 — vocab-trigger instrument.** Implement the measurable test
|
||||||
|
specified in `docs/handoffs/COMPREHENSION-READER-AUDIT.md`
|
||||||
|
(§measurable-test, lines ~163–166 and ~231–238): refusal histogram
|
||||||
|
split mechanism-vs-coverage + Phase-2-admissions-per-lexicon-batch
|
||||||
|
counter. CLI or lane runner per the spec; do not invent policy — the
|
||||||
|
spec decides, you implement.
|
||||||
|
4. **S4 — HITL proposal-queue CLI.** A `core` CLI surface listing +
|
||||||
|
reviewing pending proposals from the existing sinks
|
||||||
|
(`teaching/proposals/`, contemplation/idle sinks). Read + review-state
|
||||||
|
transitions only; NO ratification automation, NO corpus mutation, NO
|
||||||
|
flag flips.
|
||||||
|
5. **S5 — housekeeping.** Promotion sweeps Opus's checkpoint notes call
|
||||||
|
for; capability-index entries for new subject lanes; docs/memory
|
||||||
|
updates; dead-code removal only when unambiguous.
|
||||||
|
|
||||||
|
**Constraints:** identical to Tier O (worktrees, fresh venv, pre-push
|
||||||
|
gate, compare-URL PRs, Shay merges, wrong=0, flags stay off, no
|
||||||
|
timelines). When any item's scope turns out larger than described here —
|
||||||
|
stop and flag it in the PR/handoff notes rather than improvising.
|
||||||
|
|
||||||
|
**Arc close:** all Tier-S PRs pushed; memory updated; note whether the
|
||||||
|
Phase-5 articulation trigger (multi-step decided content exists) has
|
||||||
|
fired, for the next arc's scoping.
|
||||||
238
docs/plans/generalization-arc-2026-07-24.md
Normal file
238
docs/plans/generalization-arc-2026-07-24.md
Normal file
|
|
@ -0,0 +1,238 @@
|
||||||
|
# Generalization Arc — GSM8K-Level Capability Across Core Subjects
|
||||||
|
|
||||||
|
**Date:** 2026-07-24 · **Status:** ACTIVE · **Base:** main @ `5224b5e0` (post ADR-0259 / Band v4-CM)
|
||||||
|
|
||||||
|
This is the ratified plan of record for the arc that takes CORE from "one
|
||||||
|
fully-closed cognitive lifecycle (deduction-serve)" to "the same lifecycle
|
||||||
|
running across core subjects at GSM8K-exam level" — articulated answers,
|
||||||
|
problem solving, comprehension, all under wrong=0 discipline.
|
||||||
|
|
||||||
|
Execution is **risk-tiered across three operators** (§6): Fable 5 does the
|
||||||
|
high-risk design + build, Opus 5 the medium tier, Sonnet 5 the low tier.
|
||||||
|
Handoff briefs live in `docs/handoff/generalization-2026-07/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Ground truth at arc start
|
||||||
|
|
||||||
|
- Exactly one lifecycle is closed end-to-end: **deduction-serve**
|
||||||
|
(comprehend → 5 band readers → ROBDD decide → sealed practice arena,
|
||||||
|
17 bands × 720, θ_SERVE=0.99 → SHA-verified ratified ledger → license
|
||||||
|
gate → render → register chain). Dark behind
|
||||||
|
`deduction_serving_enabled=False`, awaiting ratification.
|
||||||
|
- Cross-subject substrate exists but is idle: 16 unmounted domain seed
|
||||||
|
packs, 5 domain chain corpora, 6 OOD fluency lanes, five-layer
|
||||||
|
teaching-order doctrine (`docs/teaching_order.md`), capability index.
|
||||||
|
- Learning-loop organs exist but are write-only or dark: 19 default-off
|
||||||
|
flags; proposal/contemplation/promotion paths emit into review sinks
|
||||||
|
with no runtime consumer. Three real ratified-artifact consumers exist
|
||||||
|
(deduction ledger, estimation license, recognizer registry) — the
|
||||||
|
pattern to generalize.
|
||||||
|
- Math is reader-gated, not solver-gated: compiler holds 50/50 wrong=0 on
|
||||||
|
dev-1 but the reader parses ~1% of real GSM8K; the ~30-band bet was
|
||||||
|
falsified; standing ruling #77 selects **seeding-sentence injection**
|
||||||
|
as the next math move.
|
||||||
|
- ADR-0246 §3.7 identity calibration is explicitly OFF this critical
|
||||||
|
path (blocked on §11 research evidence; doctrine order:
|
||||||
|
capability → practice → calibration → serve).
|
||||||
|
|
||||||
|
## 2. Phases
|
||||||
|
|
||||||
|
### Phase 0 — Truth-substrate hygiene + first live serve *(Small)*
|
||||||
|
- **0.1** Root-cause the 3-lane pin drift (`miner_loop_closure`,
|
||||||
|
`curriculum_loop_closure`, `demo_composition`). Classify: determinism
|
||||||
|
bug (stop-the-line) vs stale pins vs local/CI byte divergence.
|
||||||
|
Re-pin surgically only after root-cause. Findings doc in
|
||||||
|
`docs/research/`.
|
||||||
|
- **0.2** Ratification packet for `deduction_serving_enabled` (evidence
|
||||||
|
collation only; the flip is Shay's decision).
|
||||||
|
|
||||||
|
**Done when:** drift explained + resolved; packet delivered.
|
||||||
|
|
||||||
|
### Phase 1 — Reading generalization: verb predicates + existentials *(Large)*
|
||||||
|
The band cascade reads only copula sentences; every other subject states
|
||||||
|
facts as verb sentences. Ordered by leverage:
|
||||||
|
|
||||||
|
- **1.1 Band v5-VP — verb predicates**: predicate atoms keyed by
|
||||||
|
(verb lemma, argument tuple); intransitive + transitive with
|
||||||
|
named/classed arguments ONLY; closed morphology; typed refusal for
|
||||||
|
everything else (voice, tense shifts, ditransitives, PP-arguments).
|
||||||
|
This band gates Phase 2.
|
||||||
|
- **1.2 Band v6-EX — existential (`some`) witnesses**: completes the
|
||||||
|
all/no/some square; witness-based lowering.
|
||||||
|
- Deferred (unchanged from ADR-0259 §5): universal-nested-in-connective
|
||||||
|
(bound-variable tracking), identity/co-reference, tense.
|
||||||
|
|
||||||
|
Recipe per band (proven 3×): reader module → shape bands → arena
|
||||||
|
templates (≥720/band) → hand-authored lane split (content-disjoint from
|
||||||
|
practice lexicon) → ledger reseal → tests → ADR → research doc.
|
||||||
|
|
||||||
|
**Done when:** verb-predicate and existential arguments decided at SERVE
|
||||||
|
wrong=0; ledger resealed; promotion sweep of previously-declined cases
|
||||||
|
done honestly (promotion = *decided correctly*, not *decided favorably*).
|
||||||
|
|
||||||
|
### Phase 2 — Port the lifecycle to two non-math subjects *(Medium-Large)*
|
||||||
|
Physics and biology first (OOD lanes, seed packs, and domain chains
|
||||||
|
already exist). Implemented strictly to the **curriculum-entailment gold
|
||||||
|
contract** (§4 — the load-bearing design of this arc):
|
||||||
|
|
||||||
|
- Mount subject packs; wire domain chains through the teaching corridor
|
||||||
|
per the five-layer order.
|
||||||
|
- Exam-shaped serve lanes: question → read (v5-VP reading) → decide
|
||||||
|
**from ratified curriculum premises only** → licensed articulated
|
||||||
|
answer.
|
||||||
|
- Per-subject band ledgers via the same arena; capability-index
|
||||||
|
coverage entries; 3-domain anti-overfit panel discipline
|
||||||
|
(independence must be in the READING).
|
||||||
|
|
||||||
|
**Done when:** two subjects serve wrong=0 on hand-authored exam-shaped
|
||||||
|
lanes with earned licenses, zero subject-specific engine code.
|
||||||
|
|
||||||
|
### Phase 3 — Close the discovery→learning loop *(Medium)*
|
||||||
|
- **3.1** Vocab-expansion trigger as code (the COMPREHENSION-READER-AUDIT
|
||||||
|
§measurable-test, made a standing instrument: refusal histogram split
|
||||||
|
mechanism-vs-coverage; admissions-per-lexicon-batch).
|
||||||
|
- **3.2** HITL proposal-queue surface (review CLI over the existing
|
||||||
|
sinks).
|
||||||
|
- **3.3** Generic consumption bridge: extract the seal → ratify →
|
||||||
|
SHA-verified license → serve-gate pattern (deduction ledger is the
|
||||||
|
model; estimation license the second instance) into the ADR-0175
|
||||||
|
Phase-5 bridge so each subject arena plugs in without bespoke wiring.
|
||||||
|
- **3.4** Feed discovery-yield with real traffic (post 0.2 flip).
|
||||||
|
|
||||||
|
**Done when:** a serve-time gap flows discovery → proposal →
|
||||||
|
ratification → runtime consumption with no manual file surgery.
|
||||||
|
|
||||||
|
### Phase 4 — Math problem-solving reader *(Medium-Large, parallel lane)*
|
||||||
|
Independent of Phases 1–3 (no shared files; production-line pattern):
|
||||||
|
|
||||||
|
- **4.1** Seeding-sentence injection (ruling #77; the 75% "no injection"
|
||||||
|
wall).
|
||||||
|
- **4.2** Compare unblock (summation-question reader + inverse compare),
|
||||||
|
queued behind 4.1 per the same ruling.
|
||||||
|
- **4.3** q:complex decomposition study (increment-1 band plan §9; 101
|
||||||
|
cases behind one label).
|
||||||
|
- Guardrails pinned: `docs/research/reader-arc-overfit-inventory-2026-07-19.md`,
|
||||||
|
ADR-0251 recalibration (no bespoke-per-case regex growth),
|
||||||
|
ADR-0252.
|
||||||
|
|
||||||
|
**Done when:** real-GSM8K parse floor materially above ~1% with wrong=0
|
||||||
|
held on the full 500; ceiling revised with evidence.
|
||||||
|
|
||||||
|
### Phase 5 — Articulation depth (`generate/` "core_logos") *(trigger-gated)*
|
||||||
|
Not queued by order. Trigger: Phases 1–2 produce multi-step decided
|
||||||
|
content (proof chains, multi-fact answers) — the evidence of where
|
||||||
|
articulation quality binds that the intelligence-loop plan's Phase 6
|
||||||
|
deferral was waiting for. Scope the arc from that evidence.
|
||||||
|
|
||||||
|
## 3. Dependencies
|
||||||
|
|
||||||
|
- Phase 1.1 gates Phase 2. Phase 0 first.
|
||||||
|
- Phase 3.3 lands before the *second* subject arena (avoid copy-paste
|
||||||
|
wiring). 3.1/3.2 interleave freely.
|
||||||
|
- Phase 4 fully parallel. Phase 5 trigger-gated on 1–2.
|
||||||
|
- §3.7 identity calibration stays downstream of the whole arc (its
|
||||||
|
calibration data comes *from* this arc's practice volume).
|
||||||
|
|
||||||
|
## 4. Curriculum-entailment gold contract (Phase-2 design, decided here)
|
||||||
|
|
||||||
|
This section is the HIGH-risk design, fixed now so the medium tier can
|
||||||
|
implement without re-litigating epistemology.
|
||||||
|
|
||||||
|
1. **Verdict domain** — every exam item resolves to
|
||||||
|
{entailed, refuted, unknown, declined}, identical to deduction-serve.
|
||||||
|
UNKNOWN is the honest verdict for untaught facts. No open-world
|
||||||
|
recall, ever.
|
||||||
|
2. **Two question shapes** — (a) self-contained arguments (premises in
|
||||||
|
the text): already owned by bands v2–v6; (b) **curriculum-grounded
|
||||||
|
questions** (the new Phase-2 shape): question text supplies only the
|
||||||
|
query; the premise set is compiled from the RATIFIED domain chain
|
||||||
|
corpus for that subject. Gold is a function of (curriculum, question)
|
||||||
|
— never of case-local hidden text. This is the decoding-not-generating
|
||||||
|
line in mechanical form.
|
||||||
|
3. **Premise provenance** — each lane case pins the chain IDs it draws
|
||||||
|
on; the runner reconstructs premises from the ratified corpus and
|
||||||
|
MUST fail the case if a pinned chain is absent or unratified.
|
||||||
|
4. **Independent oracle** — per subject, a closed-world reachability
|
||||||
|
oracle over the chain corpus (sharing no code with the serving path)
|
||||||
|
validates every gold verdict; the lane asserts corpus soundness
|
||||||
|
before any case runs (the `assert_corpus_sound()` pattern).
|
||||||
|
5. **License granularity** — bands keyed by (subject × relation family ×
|
||||||
|
chain depth), earned in the ADR-0199 arena: θ_SERVE=0.99, n≥720,
|
||||||
|
wrong=0, sealed + SHA-verified ledger per subject.
|
||||||
|
6. **Typed refusals, lifecycle-mapped** — `untaught_vocabulary`,
|
||||||
|
`unratified_chain`, `out_of_curriculum`, `ambiguous_reading`; the
|
||||||
|
OOV refusal feeds the Phase-3 proposal queue (refusals become
|
||||||
|
discovery, not dead ends).
|
||||||
|
7. **Anti-recall probes (mandatory per lane)** — cases whose answer is
|
||||||
|
true in the world but absent from the curriculum; gold = UNKNOWN.
|
||||||
|
A lane without these probes cannot prove the system decodes rather
|
||||||
|
than recalls, and MUST NOT ship.
|
||||||
|
|
||||||
|
## 5. Risks
|
||||||
|
|
||||||
|
- **HIGH — subject-gold epistemology drift**: mitigated by §4 (contract
|
||||||
|
fixed before implementation; anti-recall probes mandatory).
|
||||||
|
- **HIGH — v5-VP scope creep**: argument structure/voice/agreement are a
|
||||||
|
real jump from copula. Mitigation: two argument shapes only, closed
|
||||||
|
morphology, typed refusal for the rest — the same discipline that made
|
||||||
|
v2–v4 land clean.
|
||||||
|
- **MEDIUM — arena scale**: 720/band × growing band count on local
|
||||||
|
hardware; linear sealing time; watch, don't block.
|
||||||
|
- **MEDIUM — synthetic-overfit trap**: practice templates and lane cases
|
||||||
|
stay content-disjoint per subject (standing doctrine).
|
||||||
|
- **MEDIUM — q:complex may not decompose**: nothing gates on Phase 4.
|
||||||
|
- **LOW — drift root-cause escalates**: if Phase 0.1 finds a determinism
|
||||||
|
bug, the arc pauses until it is fixed (stop-the-line).
|
||||||
|
|
||||||
|
## 6. Risk-tiered operator assignment
|
||||||
|
|
||||||
|
Constraint set for every tier: wrong=0; flags stay default-off (flips
|
||||||
|
are Shay's ratification only); Forgejo-primary, no GitHub/`gh`; local
|
||||||
|
smoke + warmed_session gate before every push (pre-push hook); `uv`
|
||||||
|
always; branch + worktree per unit; no merge automation; one PR per
|
||||||
|
coherent solution; attribution disabled.
|
||||||
|
|
||||||
|
### Tier F — Fable 5 (HIGH risk; this session)
|
||||||
|
- F1: Phase 0.1 drift root-cause (+ surgical re-pin if benign).
|
||||||
|
- F2: this plan doc + handoff briefs.
|
||||||
|
- F3: §4 gold contract (done — it is this document).
|
||||||
|
- F4: Band v5-VP (Phase 1.1), full recipe, PR.
|
||||||
|
|
||||||
|
**Checkpoint F→O:** F1/F2/F4 PRs pushed with compare URLs; memory
|
||||||
|
updated; briefs current. Opus starts at O1 with no open design
|
||||||
|
questions.
|
||||||
|
|
||||||
|
### Tier O — Opus 5 (MEDIUM risk)
|
||||||
|
- O1: Band v6-EX existentials (Phase 1.2) — recipe + ADR-0257/0258/0259
|
||||||
|
as references.
|
||||||
|
- O2: Phase 2 physics + biology serve lanes per §4 (mount packs, wire
|
||||||
|
chains, arena, ledgers, lanes). Physics first; biology second only
|
||||||
|
after the generic bridge (O3) lands.
|
||||||
|
- O3: Phase 3.3 generic consumption bridge.
|
||||||
|
- O4: Phase 4.1 seeding-sentence injection, then 4.2; 4.3 as analysis.
|
||||||
|
Guardrail docs pinned in §2/Phase 4.
|
||||||
|
|
||||||
|
**Checkpoint O→S:** v6-EX merged; ≥1 subject lane serving wrong=0 with
|
||||||
|
earned licenses; bridge merged; math increment measured + documented
|
||||||
|
(whatever its outcome — a null result is a valid checkpoint).
|
||||||
|
|
||||||
|
### Tier S — Sonnet 5 (LOW risk)
|
||||||
|
- S1: Phase 0.2 ratification packet (evidence collation).
|
||||||
|
- S2: Post-fix lane re-pins; public_demo flake documentation.
|
||||||
|
- S3: Phase 3.1 vocab-trigger instrument (spec is pinned in
|
||||||
|
`docs/handoffs/COMPREHENSION-READER-AUDIT.md` §measurable-test).
|
||||||
|
- S4: Phase 3.2 HITL proposal-queue CLI surface.
|
||||||
|
- S5: Promotion sweeps, capability-index entries, docs/memory
|
||||||
|
housekeeping.
|
||||||
|
|
||||||
|
**Arc close:** all three tiers merged; Phase 5 trigger evaluated with
|
||||||
|
evidence in hand; next arc scoped from it.
|
||||||
|
|
||||||
|
## 7. Non-goals (this arc)
|
||||||
|
|
||||||
|
- ADR-0246 §3.7 / identity-gate calibration (evidence-blocked).
|
||||||
|
- `core/ports/` Ring-2/3 consumption (own future flag-gated units).
|
||||||
|
- Universal-nested-in-connective, co-reference, tense bands.
|
||||||
|
- Any serving-flag flip without explicit ratification.
|
||||||
|
- Zig substrate work.
|
||||||
125
docs/research/lane-drift-investigation-2026-07-24.md
Normal file
125
docs/research/lane-drift-investigation-2026-07-24.md
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# 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):
|
||||||
|
|
||||||
|
1. `ff1dcb25` (2026-05-20, #76) introduced `resolve_surface` with a
|
||||||
|
`_base_runtime_surface` precedence of **canonical-first** — the
|
||||||
|
trace-hash identity capture preferred over the runtime's served bytes.
|
||||||
|
Dormant at first.
|
||||||
|
2. `e0d1b475` (2026-07-20, #96 fail-closed linguistic governance) routed
|
||||||
|
pipeline turns through the resolver with `canonical_surface` populated
|
||||||
|
→ pipeline-served turns began serving the pre-R6 canonical. The
|
||||||
|
runtime's own `chat()` path stayed correct; `warmed_session`
|
||||||
|
telemetry-consistency went red (0.9444) because TurnEvent (correct
|
||||||
|
bytes) disagreed with pipeline (stripped bytes).
|
||||||
|
3. `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_surface` precedence 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_hash` now folds `hash_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 `FailureClass` import + `_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.
|
||||||
|
|
||||||
|
## 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.py` e2e
|
||||||
|
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.
|
||||||
|
|
@ -74,6 +74,10 @@ _LANE_ADR: dict[str, tuple[str, str]] = {
|
||||||
"ADR-0206",
|
"ADR-0206",
|
||||||
"Propositional entailment scored against an independent truth-table oracle; dev+holdout+external 716/716 correct, wrong=0, refused=0",
|
"Propositional entailment scored against an independent truth-table oracle; dev+holdout+external 716/716 correct, wrong=0, refused=0",
|
||||||
),
|
),
|
||||||
|
"deduction_serve_v1": (
|
||||||
|
"ADR-0256",
|
||||||
|
"Flag-gated deduction serving decides real English/member/fused arguments end-to-end under earned SERVE licenses; wrong=0 across all splits",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ LANE_TIMEOUT_S = int(os.environ.get("CORE_LANE_VERIFY_TIMEOUT_S", "900"))
|
||||||
|
|
||||||
PINNED_SHAS: dict[str, str] = {
|
PINNED_SHAS: dict[str, str] = {
|
||||||
"reviewer_registry": "681a2aab5aa4ffd58cd837ce5673c8b2a9545b570117aec3c02726a12f6876e6",
|
"reviewer_registry": "681a2aab5aa4ffd58cd837ce5673c8b2a9545b570117aec3c02726a12f6876e6",
|
||||||
"miner_loop_closure": "9f071733abe7dcacf759f928548ce738fb639af3fd6e4c621a651b306d7e77ce",
|
"miner_loop_closure": "537094fe21d7e6cfbaf42bfc32b82d669fa9bb05a132d2bc93c72b3ceb7762a6",
|
||||||
"curriculum_loop_closure": "b46d56b2d209172cc3ffaf3776dc8dcfe55093f13587c5cb67372be6dfa23e8d",
|
"curriculum_loop_closure": "cb94ca0042d78ec2624129ff6493d52e767b69feea32d2997b85d88f1c0883af",
|
||||||
"domain_contract_validation": "98ace04e3f02bbc5a8ad655bb6593c3f1ee64cb67014f1122fe6c3c85f48d22f",
|
"domain_contract_validation": "98ace04e3f02bbc5a8ad655bb6593c3f1ee64cb67014f1122fe6c3c85f48d22f",
|
||||||
"fabrication_control_summary": "01e1b6b711141f2b4a14551d7df3ea482d8d6dd7b364a25c509f4f8d08cda8a8",
|
"fabrication_control_summary": "01e1b6b711141f2b4a14551d7df3ea482d8d6dd7b364a25c509f4f8d08cda8a8",
|
||||||
"demo_composition": "e2ba2314d8768459fb6a8db082a4bbcf4107b5161d869804a4b2a33c3724081a",
|
"demo_composition": "f0611a2ce41721dd40767fc6a83a08470d3c7fd7fc8f1ae8ba003abf8a25ec97",
|
||||||
"public_demo": "7d8ba0dbae9287cfe0bf15d231fa78a75abc627121c14900439293e01e1cc1d3",
|
"public_demo": "7d8ba0dbae9287cfe0bf15d231fa78a75abc627121c14900439293e01e1cc1d3",
|
||||||
"math_teaching_corpus_v1": "eaf160d145da29f9050ede8d58bf111b0f651dd40aeae9201857d0b97e014dd4",
|
"math_teaching_corpus_v1": "eaf160d145da29f9050ede8d58bf111b0f651dd40aeae9201857d0b97e014dd4",
|
||||||
"deductive_logic_v1": "97a230949016e38d5e3f37a69e4245b320575ee70e5af92ff7607f7b05f74b5f",
|
"deductive_logic_v1": "97a230949016e38d5e3f37a69e4245b320575ee70e5af92ff7607f7b05f74b5f",
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,10 @@ def _open_assessment() -> ContractAssessment:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_runtime_canonical_surface_has_base_precedence() -> None:
|
def test_runtime_response_surface_has_base_precedence() -> None:
|
||||||
|
# response_surface is the served bytes (post register R6/R4 —
|
||||||
|
# ADR-0077/ADR-0071); canonical is the trace-hash identity capture
|
||||||
|
# and must never displace served bytes when a response exists.
|
||||||
resolved = resolve_surface(
|
resolved = resolve_surface(
|
||||||
canonical_surface="canonical",
|
canonical_surface="canonical",
|
||||||
pre_decoration_surface="pre-decoration",
|
pre_decoration_surface="pre-decoration",
|
||||||
|
|
@ -41,13 +44,39 @@ def test_runtime_canonical_surface_has_base_precedence() -> None:
|
||||||
contract_assessment=_closed_assessment(),
|
contract_assessment=_closed_assessment(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert resolved.surface == "canonical"
|
assert resolved.surface == "runtime"
|
||||||
assert resolved.articulation_surface == "articulation"
|
assert resolved.articulation_surface == "articulation"
|
||||||
assert resolved.authority == "runtime_canonical"
|
assert resolved.authority == "runtime"
|
||||||
assert resolved.fold_sources == ()
|
assert resolved.fold_sources == ()
|
||||||
assert resolved.authoritative is True
|
assert resolved.authoritative is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_canonical_surface_is_last_resort_fallback() -> None:
|
||||||
|
resolved = resolve_surface(
|
||||||
|
canonical_surface="canonical",
|
||||||
|
pre_decoration_surface="",
|
||||||
|
response_surface="",
|
||||||
|
response_articulation_surface="articulation",
|
||||||
|
contract_assessment=_closed_assessment(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert resolved.surface == "canonical"
|
||||||
|
assert resolved.authority == "runtime_canonical"
|
||||||
|
|
||||||
|
|
||||||
|
def test_pre_decoration_outranks_canonical_when_response_absent() -> None:
|
||||||
|
resolved = resolve_surface(
|
||||||
|
canonical_surface="canonical",
|
||||||
|
pre_decoration_surface="pre-decoration",
|
||||||
|
response_surface="",
|
||||||
|
response_articulation_surface="articulation",
|
||||||
|
contract_assessment=_closed_assessment(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert resolved.surface == "pre-decoration"
|
||||||
|
assert resolved.authority == "runtime_pre_decoration"
|
||||||
|
|
||||||
|
|
||||||
def test_useful_realizer_requires_conjugate_coherence() -> None:
|
def test_useful_realizer_requires_conjugate_coherence() -> None:
|
||||||
"""Realizer shim only when conjugate geometric contract is closed."""
|
"""Realizer shim only when conjugate geometric contract is closed."""
|
||||||
resolved = resolve_surface(
|
resolved = resolve_surface(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue