Wire observed-HE morph constraint into CognitiveTurn answer path and
unify teaching store with the same pure decision function used by the
four-arm ablation. Typed LogosConstraint IR carries rule/morph/pack/span
provenance without free meaning dicts. Executable mode abstains on
plural-vs-singular exclusivity; metadata remains bit-identical to
canonical; adversarial OOV/missing fails closed. Residual dual-system
debt documented honestly (cue-table linguistic_pipeline still parallel).
Close residual answer-authority debt: typed CoherenceRefusal/ContractViolation/
FieldFailure, structured ProofTrace (atoms→operators→closure), and Shadow Gate
paths that refuse certified answers when contract_assessment is None or geometry
is open. Add shared semantic primitives and Layers A/B/C (English/Hebrew/Koine)
as constraint producers only, with Cl(4,1) structure-sensitive embedding (no
unitize in generate/), three field outcomes, and an articulation firewall that
blocks payload-value citation bypass and uncertified content.
Non-admissible candidates no longer enter work/derived. Only admissible
base and derived edges seed fixed-point steps, so multi-step paths close
only under geometric conditions (Stage 3 exit). Updates tests that
previously locked in admissible=False-but-still-promoted behavior.
[Verification]: tests/test_stage3_epistemic_inductive.py 10 passed
- Re-export core.cli._TEST_SUITES from cli_test.TEST_SUITES so argparse
and tests cannot drift from the runtime packs/smoke/algebra pins
(Stage dual-pack draft boundary was only on cli_test).
- Align relational ablation multi-root metadata test with Stage 3
fail-closed policy: ≥2 unique roots do not emit [root:] notes.
[Verification]: Smoke suite passed locally (~133s, 180 passed);
postfix targeted 5/5; full pre-fix was 4 failed / 13281 passed
(2 env dirt/flake classified separately).
Reconcile Master Blueprint ADR-0240–0253 titles with the live Accepted
registry without renumbering history. Claim ADR-0253 for the freeze policy
itself; reserve 0254–0261 for Blueprint gaps. Document packs/data vs
packs/he|grc dual boundary and pin serve isolation in smoke/packs suites.
[Verification]: Smoke 180 passed (includes 4 dual-pack boundary pins)
Close residual failures from geometric sovereignty hardening without
restoring scalar-L2 or PASSTHROUGH authority:
- Ratify CORRECTION/COMPARISON via vocab-grounded tag and multi-token
subject anchors so teaching capture and cognition intent accuracy hold.
- Keep observational wave leakage from vetoing teaching while
identity_wave_gate is off; syntactic override still rejects.
- Surface GoldTetherViolationError as fail-closed tether residual rather
than aborting lifecycle observation.
- Replace excised legacy identity-eval path with a geometry-blind baseline.
- Align sensorium corridor and lift instrument assertions with sandwich
unitary close and honest PARITY when baseline already solves.
[Verification]: smoke 176 passed; cognition 122 passed 1 skipped;
teaching 109 passed; claim batch 34 passed
Obligation assessment required 0 < scale < 1 (scale_out_of_range) while
_versor_binding_from_scale_value admitted any positive finite scale, so
resolve_promotable_fraction_decrease could still bind and return a
negative decrease for inputs like 5/4.
Add _is_valid_fraction_decrease_scale as the single semantic-domain
predicate and enforce it in both assess_fraction_decrease and
_fraction_decrease_scale_binding so geometric VersorBinding cannot
grant permission the obligation layer denies.
The inverted-seed P2 regex treated optional "times" as optional, so
additive "8 more" on multi-entity zoo case 0361 extracted as pure S1 and
the three-gate corridor emitted 1.125 vs gold 114.0 (wrong≠0).
- Require explicit multiplicative surface (times as many / twice the …)
- Fail-closed purity gate: multi-clause markers, multi-numeric, multi-mult
- Regression tests for 0361 and bare "N more"
- measure --mode full-holdout-wrong0 over all 500 holdout cases
[Verification]: full-holdout emit_ok=9 wrong=0 refused=491; unit 37 passed
Increment 2 for ADR-0252 Track B. Extends Increment 1's structure-mapping
slice with pure-family canonicals S2–S4, overlapping-waves selector, and a
structure-mapping-owned pure-S1 text extract that recovers four real
holdout cases the serving reader misses (0148, 0228, 0234, 0441).
Bar results (command-backed via scripts/measure_trackb_inc2.py):
- generalization ratio S1 = 9.0 (9 holdout cases / 1 template)
- coverage gain organ 5 → trackb 9, wrong=0
- selector routes S1/S2/S3; refuses empty; surface≠structure
Off-serving: no organ retirement, serving reader untouched. S2–S4 holdout
ratios are 0 (parser frontier). S3/S4 emit refuses at multi-register scope
without weakening the three-gate wrong=0 path.
[Verification]: Smoke suite passed locally (~132s, 176 passed);
trackb unit tests 35 passed; measure_trackb_inc2 all modes green.
Reviewed-on: #85
---
This is the verification I promised — and Grok's report is a different animal from the last three: it self-flagged the vacuous-FP trap, found and fixed a real wrong-answer bug, and stopped at the gate. That's what honesty looks like. But the whole point is that I check the code, not the report. Pulling the integrity-critical files.Verified against the code — and this one **passes.** First PR in the entire arc where the code matches the report. Credit to Grok: it did the real thing.
What I actually confirmed in the source, not the summary:
**Blindness holds.** `map_to_s1` takes only a `RoleGraph`; it references `S1_CANONICAL.structure_id` (allowed prior knowledge) but never a gold label. In the measure script, `score_label` is called strictly *after* `_map_decision` returns. The mapper cannot see the answer. ✓
**`wrong=0` is protected by genuine defense-in-depth — three independent fail-closed gates**, and I traced each:
1. *Map-time:* the total's part-set must **equal** `{a,b}` exactly (not superset), and any `contain` on `b` or a third entity refuses. The "true 115 → emit 15" bug class can't map.
2. *Corridor agreement:* classical `solve`+`verify` AND multi-register `certified` AND `|classical − mr| ≤ 1e-6`, else refuse.
3. *Original-graph backstop:* after emit, it re-solves the **original** graph and refuses on `original_graph_disagreement`. So even a mapper bug that drops an entity gets caught here.
Every path is conjunctive and refuses by default — I found no fail-open, and the `except Exception` explicitly refuses rather than counting the crash as signal. The measure script even returns a nonzero exit code if `wrong != 0`, so it can't print success while failing. That's the discipline we asked for, actually implemented.
**Separability is honestly bounded.** Grok flagged the exact vacuous-FP trap I warned about — only 5 holdout cases parse, so it prints the vacuity note and measures real separability on synthetic negatives + **135 real non-compare graphs from the other corpora (0 false positives)** instead of hiding behind a vacuous holdout number.
Now the honest calibration, so we don't over-celebrate — this is Increment 1, and it proves the *architecture*, not yet the *value*:
- **No coverage gain yet.** It ties the S1 organ on the organ's own 5 cases (5/5 match). It doesn't yet solve anything the organ couldn't.
- **0148 still doesn't parse** — the motivating case. That confirms the old diagnosis: the bottleneck is the *reader/parser*, and structure-mapping downstream can't rescue a parse that never produces a graph.
- **The §4 bar — generalization ratio > 1 — is untested.** What we have is a precise, surface-invariant *template match* for one graph shape, not yet Gentner-style discovery of correspondence across dissimilar problems, and no families have collapsed or organs retired.
So my ruling: **this is a real GO for Increment 1 — merge it.** It's off-serving, additive, blind, fail-closed, and verified. One 1-command confirmation before you merge, so my off-serving sign-off is evidence-based rather than assumed:
```
git diff --stat main..feat/trackb-symbolic-sme-s1
```
Every path should be under `generate/structure_mapping/`, `evals/structure_mapping/`, `scripts/`, `tests/` — nothing in `math_candidate_graph.py` or the organ dispatch. If so, merge #85.
The next increment is where the paradigm has to *earn its keep*: extend to S2–S4 **and measure whether the mapper generalizes past the organs** — coverage the organs don't have, families collapsing to shared structure, at least one organ retired under the 3-part proof. If it only ever ties the organ on the organ's turf, the paradigm isn't paying yet. Want me to draft the Increment-2 handoff to that bar?
Mapper required only that total include {a,b}; rebuild-from-binding then
dropped third entities and could emit a certified wrong answer (e.g. 15
instead of 115). Require exact total part-set {a,b}, refuse any contain
outside reference a, and agree with original-graph classical solve before
emit. Adds multi-entity refuse unit tests.
ADR-0252 §5 geometric SME is NO-GO; this is Track B Increment 1.
Adds role-predicate conversion from MathProblemGraph, S1 canonical skeleton,
blind symbolic mapper (match/refuse + binding), and solve via classical
verify plus multi-register certificate. Research report and holdout measures
included. Serving reader unchanged; no S2–S4 generalization.
Trace every module/class the six retired paradigm documents introduced or
proposed, plus a general zero-importer sweep of generate/, core/, evals/.
Every candidate is one of: never built, already removed in a prior pass, or
live (imported by the serving reader / a protected dependency chain, and/or
test-covered). No code removed; no behavior change.
Baseline == final (no code touched):
smoke: 176 passed
full: 13163 passed, 111 skipped, 1 xfailed, 0 failed
holdout_dev v1: correct=5 wrong=0 refused=495 (n=500)
Archive the six competing, unratified problem-solving-paradigm formulations
(semantic-substrate master plan, state-transition blueprint, binding-graph
proposal, capability roadmap v2, eight sprint lookbacks, and ADR-0174's
deprecated dispatch prescription) to docs/paradigm-archive/, each prefixed
with a SUPERSEDED header. ADR-0164 and ADR-0174 stay in place (Accepted,
permanent record) with a Superseded-by: ADR-0252 line added. ADR-0252 itself
is a decision record only — it records the retirement and reserves the
governing paradigm content for a separate, human-led step.
No code changes; no behavior changes.
Records the reader-arc recalibration: halt bespoke-per-case regex work,
verified clean-base reset to main@854ce023, and eradication of
feat/reader-inc2-caseband's (PR #80) debt (loosened _token_in, empty
proof file, bundled provenance) without merging that branch.
Preserves the genuinely-general knowledge before the branch is retired:
the has_numeric_token multiplier-blindness bug (root cause + minimal fix
idea, deliberately not landed) and case 0148's correct-for-the-right-reason
decomposition, both independently re-verified against source rather than
copied from the branch's own claims (which included a stale narrative
about a graph-dump proof file that was actually committed empty).
Adds a file:line-cited overfit inventory (31 bespoke/single-case surface
patterns) as inventory only -- nothing removed, the existing regex reader
keeps serving unmodified.
ADR-0251 proposes (not builds) a geometric surface->canonical
normalization spike using existing off-serving primitives
(conformal_procrustes, VocabManifold, the cognition pipeline's Phase C
anti-unification telemetry), wrong=0-gated against holdout_dev/v1, with
Smith-chart algebra and any Fibonacci "dimensional cascade" explicitly
disclaimed. Awaiting ruling -- no implementation started.
Discharges Josh's Q3 ruling: defer the q:difference capability, close the
hazard now. _pattern_b_comparative_candidates is inert by construction
(returns []), so 'how many more/fewer … than …' questions refuse end-to-end
even when every statement injects cleanly. This suite LOCKS that so a future
D.5 wiring cannot reopen the guessed-direction hole without positively
determining the more/fewer direction. Verified inert-safe by 5 direct tests.
The compound discrete-count extractor's all-or-nothing tail guard is digit-
based, so a no-digit compare clause in a conjunctive list ('buys 4 lbs beans,
6 lbs milk, and twice the amount of carrots as beans') was silently DROPPED —
injecting 4+6 and losing the carrots (a wrong=0 landmine, masked only by the
case refusing elsewhere). The #78 substrate widens the compound extractor's
verb reach, so harden it: refuse the whole compound on any '<factor> the
amount/number of' / 'twice/thrice/times/half the' / 'double/triple' surface.
Verified: 0082 compound now refuses fail-closed; tune+measure wrong=0; PARSED
unchanged (3/2); smoke 176 green.
Records the increment-1 outcome straight (band-solve=0, ~30-band bet
falsified; foundations = banked byproduct not success) + the minimal-band
measurement: no small band converts; taxonomy not at bedrock (GSM8K statements
are per-sentence multi-capability); multi-compound highest-leverage (70/106
tractable needed-sets) but insufficient alone; q:complex biggest intractable
wall (~35 cases). Increment-2 recommendation = CASE-FIRST (target specific
closest cases, build their exact end-to-end needs) not capability-first, since
the taxonomy fragments. Foundations verified full-500 wrong=0, smoke 176.
The two reusable foundations of increment 1, both verified wrong=0:
- NEUTRAL_COUNT_VERBS (math_roundtrip): the shared positive-polarity ALLOWLIST
(production/acquisition/possession-count verbs), fail-closed. Extends ADD_VERBS
with curated neutral production verbs (score/write/teach/plant/harvest/produce/
draw/sing). Depletion/transfer (SUBTRACT/TRANSFER_VERBS) excluded by positive
determination — 'Alice lost twice as many' refuses, not via a blocklist.
- Seed reader: discrete_count matcher acquisition path aligned to the allowlist
(made/baked/grew/scored/wrote/taught now inject; depletion refuses).
- Comparison reader: _comparison_anchor_verb() allowlist extended to the same
NEUTRAL_COUNT_VERBS (keeps fail-closed; captures scored/caught/wrote frames).
Verified: production injects, depletion refuses; 71 pinned comparative tests
pass (polarity guards now via allowlist); tune wrong=0; smoke 176 green.
FINDING (measured 4 ways: yield harness, band map, band oracle, capability
histogram): band-1 as scoped {seed + forward-comparison + q:simple/summation}
converts 0 tune cases. Its otherwise-in-band cases STRAND on multi-compound (25)
and compare-additive (17) — capabilities outside the ~30 band. The conjunction
recurs at sub-capability granularity; the band-map taxonomy was too coarse.
Foundations validated + reuse-ready (done-when part 2); band-solve>0 (part 1)
needs the band to grow to +compare-additive(+multi-compound) — a scope/done-when
ruling for Josh. No merge until ruled.
Design-first plan, ruling before any build (same gate as #76). Band =
foundational spine core: seed-simple + comparison + question-arithmetic
(simple/summation/difference), on the shared #78 polarity substrate.
Bakes in Josh's four refinements: (1) deliberate ~30 smaller-band rationale
(first end-to-end reader conversion ever + two reusable foundations, zero new
hard capabilities beyond #78); (2) done-when reset to band-solve>0 wrong=0 +
foundations validated, ~40 bar cumulative across increments 1-3; (3) haircut
factor (real/upper-bound) as a named output; (4) TWO wrong=0 direction drivers
— #78 statement polarity AND q:difference question direction, both positively
determined + fail-closed. Grounds design on what EXISTS (question layer partly
built: summation works, q:difference partial). Schedules q:complex decomposition
next (may be corridor-tractable, could move the ~48% ceiling).