Commit graph

2170 commits

Author SHA1 Message Date
4b9dbe7236 Merge pull request 'fix(a2k): reject out-of-range fraction-decrease scales' (#89) from fix/a2k-fraction-decrease-scale-range into main
Reviewed-on: #89
2026-07-20 04:42:05 +00:00
Shay
ac4c3e04ad test(a2k): prove geometric path refuses out-of-range decrease scales
Regression coverage for the audit repro (5/4), zero/one/gt-one geometric
no-bypass, injected Fraction domain mutations, promotable resolver
refusal, and flip the PR #87 preexisting gap pin to require operator
refuse alongside baseline.
2026-07-20 04:40:35 +00:00
Shay
1a6efe0d13 fix(a2k): share fraction-decrease scale domain on geometric admission
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.
2026-07-20 04:40:35 +00:00
6b8a013280 Merge pull request 'docs(analysis): PR #87 post-merge integrity audit' (#88) from chore/postmerge-pr87-integrity-audit into main
Reviewed-on: #88
2026-07-20 04:37:04 +00:00
Shay
375da93e61 docs(analysis): PR #87 post-merge integrity audit
Evidence-led verification of merged relational-operator ablation:
canonical semantics, fixture independence, condition labels, scale>1
isolation, production/gate isolation, HE/GRC roadmap authority, and
reproducibility. Verdict: VERIFIED, no corrective PR needed.

[Verification]: Ablation 20 passed; runner digest match; organ pre-existing
37 passed; smoke 176 passed locally (~133s).
2026-07-19 21:24:34 -07:00
5fae5a67f2 Merge pull request 'feat(eval): deterministic relational operator ablation + HE/GRC Logos roadmap' (#87) from feat/deterministic-relational-operator-ablation into main
Reviewed-on: #87
---
Delivered

┌─────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────┐
│ Item                        │ Location                                                                         │
├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ Cartography ledger          │ docs/analysis/relational-operator-ablation-cartography-2026-07-19.md             │
├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ Ablation dossier            │ docs/analysis/relational-operator-ablation-dossier-2026-07-19.md                 │
├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ HE/GRC Logos roadmap        │ docs/analysis/hebrew-koine-greek-logos-pack-capability-roadmap-2026-07-19.md     │
├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ Ablation code + sealed eval │ generate/relational_operator_ablation.py, evals/relational_operator_ablation/v1/ │
├─────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────┤
│ Tests                       │ tests/test_relational_operator_ablation.py                                       │
└─────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────┘

Git

Branch: feat/deterministic-relational-operator-ablation
Remote: Forgejo core-labs/core (5 commits)

1. df029a84 — cartography ledger
2. 1d4d51bc — ablation runners
3. 87b01868 — sealed eval lane v1
4. 84f7a6f7 — tests + ablation dossier
5. 08881ab6 — HE/GRC Logos roadmap + cross-links

Pull request

#87

• Title: feat(eval): deterministic relational operator ablation + HE/GRC Logos roadmap
• Mergeable: yes
• [Verification]: smoke 176 + ablation 20 + runner n=8 wrong=0 documented on the PR

Fresh start for next PR

Roadmap recommends:

┌──────────┬──────────────────────────────────────────────────────────────────────────────┐
│ Field    │ Value                                                                        │
├──────────┼──────────────────────────────────────────────────────────────────────────────┤
│ Branch   │ feat/observed-he-morph-constraint-v0                                         │
├──────────┼──────────────────────────────────────────────────────────────────────────────┤
│ Worktree │ ../core-observed-he-morph-constraint                                         │
├──────────┼──────────────────────────────────────────────────────────────────────────────┤
│ Scope    │ Observed-Hebrew morph constraint only (not pack bulk-load, not English math) │
└──────────┴──────────────────────────────────────────────────────────────────────────────┘
2026-07-20 04:16:08 +00:00
Shay
08881ab665 docs(analysis): land HE/GRC Logos pack capability roadmap
Audit-only dossier: current-state matrices, dual pack systems, holonomy
limits, no-go list, and recommended next branch
feat/observed-he-morph-constraint-v0. Cross-link cartography and ablation
dossiers; no pack expansion or ablation fixture changes.
2026-07-19 21:14:21 -07:00
Shay
84f7a6f7cc test(eval): prove relational operator ablation invariants + dossier
Unit, integration, and adversarial tests; isolate pre-existing A2k scale>1
gap; final engineering dossier with measurement table.
2026-07-19 21:00:15 -07:00
Shay
87b01868fa feat(eval): sealed relational operator ablation lane v1
Eight-case fixture, measurement runner, and committed report for baseline
/ operator / depth / metadata_only / invalid conditions (wrong=0).
2026-07-19 21:00:15 -07:00
Shay
1d4d51bc9b feat(generate): deterministic relational operator ablation runners
Baseline scalar frame path, live geometric operator path, inactive depth
contribution provenance, metadata-only control, and fail-closed invalid
condition for fraction_decrease — without inventing EN→HE/GRC role maps.
2026-07-19 21:00:15 -07:00
Shay
df029a8485 docs(analysis): cartography ledger for relational operator ablation
Evidence matrix, live-path maps, claim corrections, and go/no-go for a
narrow fraction_decrease ablation (not ancient-language GSM8K magic).
2026-07-19 21:00:15 -07:00
d8d62b8ea3 Merge pull request 'feat(trackb): S1–S4 symbolic SME, selector, pure-S1 coverage gain (Inc2)' (#86) from feat/trackb-symbolic-sme-s2s4 into main
Reviewed-on: #86
2026-07-20 03:12:47 +00:00
Shay
2544fda6f6 fix(trackb): pure-S1 extract refuse multi-clause overmatch (0361 wrong=0)
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
2026-07-19 20:04:27 -07:00
Shay
e5643454d9 feat(trackb): S1–S4 symbolic SME, selector, pure-S1 coverage gain
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.
2026-07-19 19:49:07 -07:00
f6fd5030bb Merge pull request 'feat(trackb): S1 symbolic structure-mapping vertical slice (off-serving)' (#85) from feat/trackb-symbolic-sme-s1 into main
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?
2026-07-20 02:33:41 +00:00
Shay
85781f0f4c fix(trackb): pure-S1 gate — refuse total supersets and extra contains
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.
2026-07-19 19:10:05 -07:00
Shay
943614c522 feat(trackb): S1 symbolic structure-mapping vertical slice (off-serving)
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.
2026-07-19 19:01:23 -07:00
Shay
1ccef49130 docs(adr): land ratified ADR-0252 governing problem-solving paradigm 2026-07-19 16:09:52 -07:00
Shay
8b995ce0fb docs(paradigm): dead-code audit — zero removals, all candidates traced and verified
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)
2026-07-19 15:15:52 -07:00
Shay
7a6556e852 docs(paradigm): retire six competing unratified problem-solving paradigms under ADR-0252
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.
2026-07-19 14:46:47 -07:00
1de6dbc945 Merge pull request 'docs(reader-arc): recalibration ADR-0251 + preserved knowledge + overfit inventory' (#81) from docs/reader-arc-recalibration into main
Reviewed-on: #81
2026-07-19 20:46:39 +00:00
Shay
f8bf960d8d docs(reader-arc): recalibration ADR-0251 + preserved knowledge + overfit inventory
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.
2026-07-19 13:42:47 -07:00
854ce023d9 Merge pull request 'docs(reader-arc): increment-1 BAND plan — {seed + comparison(#78) + question-arithmetic} (for ruling)' (#79) from feat/reader-band-increment-1 into main 2026-07-19 04:58:00 +00:00
Shay
81688465a5 test(reader-arc): Q3 hazard-close — lock q:difference fail-closed (no guessed direction)
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.
2026-07-18 21:57:36 -07:00
Shay
2da1a33839 fix(reader-arc): compound extractor refuses no-digit compare clauses (wrong=0 hazard)
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.
2026-07-18 21:44:34 -07:00
Shay
c217af31ee docs(reader-arc): band-solve=0 outcome + minimal-convertible-band measurement
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.
2026-07-18 21:37:16 -07:00
Shay
387f065649 feat(reader-arc): #78 positive-polarity allowlist substrate (seed + comparison) — foundations, band-solve=0
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.
2026-07-18 21:18:02 -07:00
Shay
12098cb3d3 docs(reader-arc): increment-1 BAND plan — {seed + comparison(#78) + question-arithmetic} for ruling
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).
2026-07-18 20:54:28 -07:00
e1eb2a5ca1 Merge pull request 'feat(reader-arc): compare_multiplicative increment 1 — compiler tier + frame-anchored reader (measured delta=0, reroutes to shared-layer)' (#77) from feat/compare-mult-increment into main 2026-07-19 03:07:06 +00:00
Shay
6f1ef49018 revert(reader-arc): hold frame-anchoring out of increment 1 — defer to rate-frame increment (#77 ruling)
Reverts the c3aed13b parser change (frame-anchored comparative regexes +
verb-free connector + _COMPARE_POLARITY_BLOCK + 'as much'); the reader stays
on the _comparison_anchor_verb() whitelist (fail-closed). Increment 1 ships
the compiler tier + the funnel finding only.

Three reasons on record: (1) frame-anchoring converts 0 of 500 official cases
— zero measured benefit today; (2) its consumer is rate-frame admission, a
later increment — the next increment (seeding-sentence injection) is a shared
layer that doesn't touch it; (3) the polarity blocklist is fail-OPEN — an
unenumerated depletion verb in a complete frame is a coherent-but-inverted
graph = a wrong on the run-once sealed arbiter (round-trip guards parse
consistency, not gold-correctness), a trade the fail-closed doctrine never
takes for zero gain.

Verified before revert-merge: with the whitelist reader, the 5 real compare
parses are non-divergent — test_real_compare_cases_solved_wrong_zero still
sees 5, solves 5, wrong 0 (corridor real-reach 0->5/500 preserved).

Frame-anchoring recorded as an OPEN DESIGN TASK owned by the rate-frame
increment: frame + POSITIVE polarity determination (neutral-polarity allowlist
or small polarity classifier), not assume-safe-unless-blocklisted. Detail in
docs/research/compare-increment-funnel-2026-07-18.md.
2026-07-18 20:03:38 -07:00
Shay
c3aed13bbe feat(reader-arc): frame-anchored compare recognizer (verb-free + polarity blocklist)
Increment 1 reader half. Re-anchor the two multiplicative-comparison frame
regexes on the closed-class frame ('<factor> as many/much <unit> as <REF>')
instead of the _comparison_anchor_verb() whitelist: the verb slot becomes a
verb-free bounded connector, 'as much' joins 'as many'. Admission is now
open-class for safe verbs (scored/wrote/caught/taught/…), gated by the frame.

One closed class is NOT frame-neutral — polarity-inverting/depletion verbs
(lose/spend/give/sell/win/donate/pay/eat/drop/lend): in a compare frame they
make the compared quantity a loss, so actor=factor×reference reads backwards
→ wrong>0. _COMPARE_POLARITY_BLOCK excludes exactly that set (the sanctioned
fallback; the frame is the gate for every other verb). Pins the wrong=0
guards in test_adr_0131_G2a + test_recognizer_comparative_inject.

Develop-on-tune / measure-once held. Footprint over 500 official cases: tune
byte-identical (0 divergences, wrong=0, PARSED=3); measure 1 divergence
(0441 'Zig wrote four times as many books as Flo') which advances
frame-refusal -> question-refusal (sanctioned delta) but does not solve — the
binding wall is the shared summation-question layer. X=15 measured delta=0.
Ruling per the funnel-conditioned escalation rule: mass is in shared layers,
so the next increment is shared-layer (summation-question reader), not a
practice escalation and not more compare frames. wrong=0 held on tune (261),
measure (239), smoke (176).
2026-07-18 19:35:23 -07:00
Shay
da663d1007 docs(reader-arc): pre-register escalation rule + refusal-histogram pin + reframe
Pre-registration before the shared-layer edit (PR ruling), all in the record:

1. Refusal-histogram baseline (tune, n=261): 'no injection' = 196/261 (75%) —
   a SHARED bottleneck across every family, not a compare defect; 48 statement,
   9 question, 3 PARSED (compare). Pinned; assert stable-or-explained after —
   only sanctioned delta = compare 'no injection' -> PARSED, disclosed.
2. Funnel-conditioned escalation rule (pre-committed): X=15 miss read via the
   funnel — compare-specific mass -> practice ruling; shared-layer mass ->
   shared-layer design increment (NOT practice). Load-bearing: practice cannot
   learn past a deterministic wall (better candidates still cross the same
   pipeline), so shared bottlenecks are design work regardless of X.
3. Reframe recorded: compare is the first slice of a larger reader project
   (reader parses ~1% of real GSM8K; 'no injection' 75% is a shared wall).
   Not scope creep — the arc seeing its true size.
2026-07-18 17:42:02 -07:00
Shay
7c28bb0ba4 docs(reader-arc): record 'reader was waiting on the compiler' — intentional guard
Code archaeology before treating 'no injection' as a defect: it is a DELIBERATE
narrowing, not broken code. recognizer_anchor_inject.py's discrete-count injector
refuses comparative surfaces with the explicit comment 'Refuse here until a real
compare_multiplicative operation can be emitted' (~L324) and 'does not create any
new admitting path' (~L460). The lockstep thesis of the arc in the code's own
history: the reader refused compare shapes to protect wrong=0 + ADR-0191
completeness because nothing downstream could compile them. The compiler tier
this increment shipped IS that operation -> the fix is LIFTING a now-obsolete
guard whose reason has shipped, not patching injection.
2026-07-18 17:31:08 -07:00
Shay
4a5d0f460d docs(reader-arc): compare increment per-layer attrition funnel (diagnostic)
Instrument-first (PR #76 ruling): before touching the parser, measure where the
61 compare-marked TUNE cases die. Funnel: 57/61 die pre-enumeration; of those,
**45 at the injection layer** ('recognizer matched but produced no injection'),
8 'no admissible candidate for statement', 3 'expected exactly one question
sentence'; 3 solve today.

Finding: the leverage is INJECTION (45/61), not the candidate regexes (which
fire on clean clauses but the real multi-clause sentences never reach them) nor
segmentation writ large. Injection is an EMITTER, so the sanctioned fix is
making it inject compare candidates the recognizer already matches — never
loosening the round-trip gate. Fix order by measured mass: injection (45) ->
statement-admissibility (8) -> question-sentence (3). Tune-only development;
single measure run at the end with refusal-by-reason + delta.
2026-07-18 17:25:26 -07:00
Shay
260e56ca5c feat(reader-arc): compare compiler-side guards for inverse + chained shapes
Two shapes (PR ruling) pinned compiler-side with tests — reader direction errors
surface as refusals, never wrongs:
- Chained / ordering: a compare whose reference is neither seeded nor
  already-defined at that point refuses (compare_reference_not_a_register).
  Pinned explicitly with a test (story order != dependency order), not left to
  fall out of existing checks.
- Inverse mis-direction: a compare that would DEFINE an already-known (seeded or
  earlier-defined) register refuses (compare_redefines_register) — the reader
  must bind the unknown side as the target with a fraction factor; the compiler
  never overwrites a known quantity.

The 5 real compare cases still solve wrong=0. 27/27 (2 new guards + 25).

[Verification]: uv run python -m pytest tests/test_adr_0250_compare.py tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q
2026-07-18 17:14:16 -07:00
Shay
cd0df2019f test(reader-arc): pin deterministic tune/measure split BEFORE grammar work
AMENDMENT 3 (PR #76): the reader grammar family is developed against the TUNE
split only; increment deltas are measured on the disjoint MEASURE split only.
Split = pure function of case id (measure iff sha256(id) even, else tune), so
disjointness is enforced by construction and cannot drift. Fixed 2026-07-18,
never re-seeded. Sizes: tune=261, measure=239. This commit lands BEFORE any
grammar-tuning commit — the git history is the proof the split was pinned in
advance (criterion 3). wrong=0 is verified across the full 500 regardless of
split; only the coverage delta is attributed to the measure split.
2026-07-18 16:39:04 -07:00
Shay
9136c1819b feat(reader-arc): compare_multiplicative compiler tier (increment 1, compiler half)
Cross-register affine definition: actor := factor x reference. Reads the
reference register's field STATE, dilates by -ln(factor), writes the actor.
Reuses quantity_kernel + the multi-register framework + the 2b summation.

Amendments (PR #76):
1. Summation registers-driven: MultiRegisterProgram.register_order (seed order
   then compare-defined order); execute sums ALL registers in that order, so a
   compare-DEFINED register (no seed) is included in totals. compile validates
   the answer target AFTER ops (a concrete unknown may be compare-defined) and
   propagates the defined register's unit from the reference.
2. Compare record: RegisterTurn.reference; MultiRegisterRecord.source_entity
   (the reference) + operand_source_digest (reference state digest), both
   CONDITIONAL in the payload so affine/transfer/summation record digests are
   byte-identical to before compare. Re-verification reconstructs the source
   register from records alone.

Compare CREATES a quantity (not a transfer) -> exempt from the conservation pin.
fraction direction folded in (factor < 1). compare_additive is a later increment
(refused). Real official data: the 5 compare parses the reader emits today now
solve end-to-end wrong=0 -> corridor real-reach 0/500 -> 5/500 (loop-works proof).

25/25 (9 new + 16 existing regression, digests byte-identical).

[Verification]: uv run python -m pytest tests/test_adr_0250_compare.py tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q
2026-07-18 16:35:09 -07:00
920695bdf6 Merge pull request 'docs(reader-arc): compare_multiplicative increment plan — increment 1 (for ruling)' (#76) from feat/compare-mult-increment-plan into main 2026-07-18 23:10:29 +00:00
Shay
09172da204 docs(reader-arc): fold PR #76 amendments into compare increment plan; X=15 ratified
Four amendments (Shay, #76 review) folded:
1. Summation registers-driven (NEW CODE): summation orders by program.seeds
   (initial_state) today, so a compare-DEFINED register (no seed) is silently
   excluded from the total — all 5 real cases are totals. Fix: sum all registers
   at solve time, deterministic order (seed order then definition order);
   compile-side validation admits defined entities as answer targets with unit
   propagation from the reference. Pin: defined register in the certified sum.
2. Compare record spec: record identifies the reference entity + binds the
   reference state digest via the existing conditional operand_source_digest
   (non-compare/non-summation digests unchanged); deterministic re-verification
   reconstructs the dilation's source register from records alone.
3. Tune/measure split pinned deterministically (sha256(id)-ordered) FIRST,
   before any grammar work, documented + fixed in advance.
4. 'N times more than' pinned to N× as a disclosed convention; gold mismatches
   tracked as recorded findings, never silent wrongs.

X = 15 ratified as the arc escalation threshold (spike §7.3 updated). §6 risks
reclassified (risk 4 -> new code §3.1; risk 1 -> pinned convention §4). Build
proceeds under this ruling — no separate re-ruling.
2026-07-18 16:07:41 -07:00
Shay
c88e52c6a9 docs(reader-arc): compare_multiplicative increment plan (increment 1, for ruling)
First increment of the reader design-first arc (dev2 spike §7). Design-first,
for ruling before build.

Ground truth (5 real holdout_dev compare parses): one entity seeded, the other
DEFINED by actor = factor x reference (Comparison, direction times/fraction);
unknown = total -> existing 2b summation closes them once compare is solvable.

Compiler tier: cross-register affine definition actor := factor x reference
(dilate reference STATE by -ln factor, write to actor register). Two new bits
designed explicitly: reads-one-register-writes-another; actor is DEFINED not
seeded (compare introduces the register). NO conservation pin (compare creates,
doesn't move — transfers conserve, compare doesn't). fraction direction folded
in; compare_additive is a later increment. Immediate effect: corridor real-reach
0/500 -> the compare parses that already exist (loop-works proof).

Reader grammar family: reader emits compare for ~5/500 (narrow phrasings);
incidence ~20% (~100/500) -> broaden compare templates; most of the delta.

Measurement: holdout_dev only, wrong=0 floor, sealed untouched, tuned/measured
DISJOINT split, delta vs X=15. Risks: 'N times more' ambiguity, garbled entity
spans, ordering, defined-register-in-summation.

Nothing built; increment PR ships after this plan is ruled on.
2026-07-18 15:54:43 -07:00
dd1e4670e4 Merge pull request 'docs: dev-holdout-2 / frontier-measurement spike — verdict (for ruling)' (#75) from feat/dev2-frontier-spike into main 2026-07-18 22:50:50 +00:00
Shay
25762614c0 docs(dev2-spike): restructure per ruling — reader design-first, practice = backup
Supersedes the practice-loop recommendation (§7/§10): the arc is the reader,
DESIGN-FIRST — per-family increments, grammar family + compiler tier in LOCKSTEP
(§2 proves they can't move separately: the 5 real compare_multiplicative parses
die at the affine compiler today). Each increment = own smoke-gated PR with a
measured holdout_dev delta, wrong=0 floor, sealed test untouched.

- Increment order: compare_multiplicative FIRST (reader already emits it →
  0/500 to >0 immediately, cheapest end-to-end proof), then §3 frequency order
  (rate → fraction → compare_additive → partition).
- Escalation threshold X PROPOSED = 15 new-correct/holdout_dev per full family
  increment (Shay rules with the merge); below it → practice-lane ruling.
  Rationale: families carry 20-31% incidence, a paying design converts far more.
- Practice loop demoted to PAPER-DESIGN backup (§7.4) with leverage analysis:
  verifier = Tier-1/2 compiler stack, audit = certificate chains, consolidation
  = prepare→validate→commit generalized, hygiene = ADR-0119 sealing; genuinely
  new = candidate generator + consolidation store. Four §7 constraints carry
  over verbatim.
- Design-first work IS the backup's curriculum (§7.6): refusal taxonomies,
  tagged incidence, labeled (parse,compile,execute,gold) tuples are artifacts.
§5 floors/scoreboard + §6 sequencing affirmed unchanged; errata merge with this.
2026-07-18 15:48:13 -07:00
Shay
639616b3e5 docs(dev2-spike): errata + two-instrument reframe + incidence + reader-arc design
Folds in Shay's rulings on the spike:
- ERRATA sections added to ADR-0249, ADR-0250, and both acceptance-evidence docs
  (statuses stay Accepted): corpus label 'real GSM8K dev holdout' -> 'CORE-authored
  GSM8K-style corpus (ADR-0119.2)'. Mechanism claims (wrong=0, PARITY, conservation,
  atomicity, chain-of-custody, 200/200) all stand; reframe not retraction. Covers the
  #74 review comment that repeated the label. (Also fixed ADR-0250 evidence status ->
  RATIFIED, which the ratification housekeeping missed.)
- Two instruments named + never-blended scoreboard: authored = mechanism-correctness
  (200/200 stands as that); official holdout = generalization (5/500 symbolic / 0/500
  corridor). public/dev-1 floors relabeled MECHANISM floors, composition-disclosed.
- Censored-incidence fix: parse-INDEPENDENT tagging of 100 official cases (documented
  heuristic). 70/100 carry frontier markers (rate 31, fraction 28, compare_mult 20) ->
  (c) refuted, frontier COMMON not rare; the table is the reader-arc curriculum by
  real-world frequency.
- Reader-practice-loop design with the four non-negotiable constraints (real held-out
  data only; wrong=0 gates consolidation; sealed test untouched; holdout_dev split
  disjoint from the measured metric). Sequencing: capability->practice->calibration->
  serve; reader is the critical path for all three; serve-landing de-prioritized (0/500).

Spike verdict for ruling; nothing built.
2026-07-18 15:37:01 -07:00
Shay
ab5c663eb3 docs(research): dev-holdout-2 / frontier-measurement spike — verdict
Headline correction: evals/gsm8k_math/dev + public are CORE-AUTHORED GSM8K-style
(ADR-0119.2), NOT real GSM8K. The compiler's 200/200 is on authored, mostly
depth-1, frontier-free problems — a mechanism validation, not real-GSM8K
capability. ADR-0249/0250 'real GSM8K' language needs correcting.

Draw-protocol trace: train_sample + holdout_dev + sealed-test = real GSM8K
(deterministic seeded draws); dev/public = authored.

Real measurement (end-to-end on 500 real holdout_dev): Reader A parses 5/500
(1%, refuses 495); my compiler solves 0/500; the 5 parsed are all
compare_multiplicative (frontier), refused by the affine compiler. Corroborates
holdout_dev's historical 'real GSM8K capability 0%'.

Verdict: (a) DOMINANT — frontier + real GSM8K are READER-gated (99% parse-refusal);
(b) confirmed as authoring bias in dev/public; (c) refuted — frontier is common,
not rare. Sequencing: reader is the biggest bucket; more compiler tiers = capability
without inputs; serve-landing premature. Reader-practice-loop NAMED as leading
next-arc (reader = first learnable component; attempt-parse->compile->execute->
gold-check, wrong=0-gated on held-out real data; generalization-preserving).
Public-seal approved with authored-not-real + composition (depth/kinds) disclosure.

Spike verdict for ruling; nothing built.
2026-07-18 15:24:18 -07:00
Shay
b87cd46cf7 chore(adr-0250): ratify Accepted + fold in PR #74 review findings
Ratification: ADR-0250 Status Proposed->Accepted; §10 ruling record stamped
(Shay, citing the acceptance-evidence pack as-is; full-holdout 50/50 wrong=0
affirmed; next arc = seal dev-holdout-2, dev-1 pinned as regression floor).

Review findings (Shay, PR #74, non-blocking):
1. Instrument module docstring updated from 'Three deterministic domains' +
   'GSM8K NOT ingestible / no compiler' to the four-domain post-0250 reality
   (arithmetic-chain solves the full dev holdout; frontier surfaced in scope).
2. Restored per-case refusal reasons: _corridor_and_baseline now raises
   MultiRegisterError (not bare None); the domain loop records refusal.reason
   and distinguishes graph_parse_failed. 'Recorded, never silently dropped'
   stays literal (0 rows at refused=0, but the path is honest).
3. Tightened the Tier-1 try to wrap compile_turn_program only (execute outside),
   so a future typed execute raise surfaces as a Tier-1 failure instead of
   silently rerouting into Tier-2 and masking a regression; added the note that
   Tier-2 fails closed on non-convergence while Tier-1 records-only, gold
   comparison binding wrong=0 on both.

10/10 instrument pins green.

[Verification]: uv run python -m pytest tests/test_adr_0249_arithmetic_lift.py tests/test_generalized_lift_instrument.py -q
2026-07-18 15:07:29 -07:00
09257ed32f Merge pull request 'feat(adr-0250): instrument routes Tier-2 (50/50) + ADR-0250 — Tier-2 arc closure' (#74) from feat/adr-0250-instrument-adr into main
Reviewed-on: #74
---
The Tier-2 arc, complete

Four PRs, each smoke-gated, one per phase:

┌────────────┬───────────────────────┬──────────────────────────────────────────────────────────┐
│     PR     │         Phase         │                          Result                          │
├────────────┼───────────────────────┼──────────────────────────────────────────────────────────┤
│ #71 ✓      │ Design spike          │ multi-register model, atomicity, chain-of-custody design │
├────────────┼───────────────────────┼──────────────────────────────────────────────────────────┤
│ #72 ✓      │ T2a executor          │ 18/18 single-entity, wrong=0                             │
├────────────┼───────────────────────┼──────────────────────────────────────────────────────────┤
│ #73 ✓      │ 2b summation          │ full holdout 50/50, wrong=0                              │
├────────────┼───────────────────────┼──────────────────────────────────────────────────────────┤
│ #74 (open) │ Instrument + ADR-0250 │ coverage recorded 26→50; ADR proposed                    │
└────────────┴───────────────────────┴──────────────────────────────────────────────────────────┘

The headline, from the top

Across ADR-0249 and ADR-0250, the reader→Hamiltonian compiler went from ingesting almost nothing to solving the entire real GSM8K dev holdout — 50/50, wrong = 0 — by chained certified relaxation on the Cl(4,1) substrate:

- 26 Tier-1 single-accumulator arithmetic
- 18 T2a multi-register (multi-entity, coupled-translator transfers, conservation-gated)
- 6 certified summation over registers ("altogether")

Every step is certified, the transfers are conservation-gated (relative, hard-reject), the whole thing is transactionally atomic and tamper-evidently recorded, and it's all off-serving with no gate activated. Against a symbolic evaluator it's honest PARITY — the field matches arithmetic, it doesn't beat it — and the deliverable is exactly what the plan asked for: a decidable, real-data measurement with recorded coverage, not an inflated claim.
2026-07-18 21:55:56 +00:00
Shay
e6439bb70f feat(adr-0250): instrument routes Tier-2 + ADR-0250 (Proposed) — arc closure
Instrument: the arithmetic-chain domain now routes each real GSM8K dev case to
Tier-1 (single-accumulator) or Tier-2 (multi-register / summation) and compares
the corridor to a symbolic fold of the SAME compiled program. Recorded coverage
moves 26/50 -> 50/50, 0 refused, PARITY (wrong=0) — the measurement catching up
to the capability. Scope note corrected (full holdout closed; remaining frontier
= derived-operand transfers + non-affine kinds + >5-atom deduction, all 0 on this
holdout). Updated the ADR-0249 instrument test pins (26->50, refused 24->0).

ADR-0250 (Status Proposed, no self-Accept; §10 ruling awaits Shay) + acceptance
evidence: multi-register model, relative conservation, atomicity, certified
summation, chain-of-custody, and the full-holdout 50/50 wrong=0 result.

10/10 instrument pins green.

[Verification]: uv run python -m pytest tests/test_adr_0249_arithmetic_lift.py tests/test_generalized_lift_instrument.py -q
2026-07-18 14:43:40 -07:00
3c3dcdbe8f Merge pull request 'feat(adr-0250): 2b certified summation turn — full GSM8K dev holdout 50/50 wrong=0' (#73) from feat/adr-0250-t2b-summation into main
Reviewed-on: #73
---
Major milestone: the full real GSM8K dev holdout now solves 50/50, wrong = 0. The 2b certified summation turn is built and committed (3d7d583d), 16/16 green, smoke running. Tier-1 (26) + T2a single-entity (18) + summation (6) = the entire dev holdout, every answer correct, by chained certified relaxation — zero wrong answers.

What 2b added:

- The total-unknown case now sums instead of refusing. A unknown.entity is None graph ("how many altogether") compiles to a certified summation over all registers — the explicit typed signal driving the branch, exactly as I described. Ruling #1 honored: the summation happens in the substrate (each addition is a certified relaxation turn), never a Python sum().
- The chain-of-custody binding is real, not asserted. Each summation turn's operand is the decode of a certified register state, and the record carries operand_source_digest (the same psi_digest byte convention), so deterministic re-execution reproduces the state and its decode — the Python layer can't tamper with the intermediate value. I added that field conditionally to the record payload so the merged T2a record digests stay byte-identical.
- One honest test update: the T2a test that asserted the total-unknown refusal now asserts it sums to 8 — the behavior changed for the better, and the test reflects it.

I'll push and open the 2b PR the moment smoke lands.

What's left to close the Tier-2 arc: extend the generalized-lift instrument's arithmetic-chain domain to the multi-entity subset (so the instrument's recorded coverage moves 26 → 50 honestly), then ADR-0250 (Proposed) with acceptance evidence — after which the arc awaits your ratification, same as ADR-0249. I'll report the smoke result and the PR, then proceed to the instrument + ADR.

---

Where the arc stands — the corridor now solves the entire dev holdout

With 2b up, the reader→Hamiltonian compiler covers all 50 real GSM8K dev-holdout problems at wrong = 0, entirely by chained certified relaxation on the Cl(4,1) substrate:

- 26 Tier-1 single-accumulator (ADR-0249)
- 18 T2a single-entity multi-register
- 6 total-like via the certified summation turn

That's the honest capstone the whole two-ADR effort was building toward — from "the corridor can ingest almost nothing" to "the corridor solves the whole dev holdout, zero wrong," with every step certified, conservation-gated, and tamper-evidently recorded.

What's left to close Tier-2

Two pieces, both after #73 merges (they build on 2b):

1. T-instrument — extend the generalized-lift instrument's arithmetic-chain domain to the multi-entity subset, so the instrument's recorded coverage moves honestly from 26/50 to 50/50 (the measurement catching up to the capability).
2. ADR-0250 (Proposed) + acceptance evidence — the ratification doc for the Tier-2 arc, documenting the multi-register model, the atomicity + relative-conservation design, the chain-of-custody, and the 50/50 result. No self-Accept — it'll await your §-ruling like ADR-0249.
2026-07-18 21:33:53 +00:00
Shay
3d7d583d83 feat(adr-0250): 2b certified summation turn — full dev holdout 50/50 wrong=0
A total-like unknown (unknown.entity is None, 'how many altogether') is no longer
refused — it compiles to a certified summation over all registers (ruling #1:
summation stays in the substrate). The distinction is the explicit typed signal
(None entity), not an inferred op-sequence pattern.

Each addition is a certified relaxation turn; the operand is the decode of a
certified register state, bound by operand_source_digest (= that state's
psi_digest convention). Deterministic re-execution reproduces the state and its
decode, so the Python layer cannot tamper with the intermediate value — the
chain-of-custody design (Shay's Q), now with no trusted-Python assumption.
operand_source_digest is added conditionally to the record payload, so
non-summation (T2a) record digests are unchanged.

Capstone: Tier-1 (26) + T2a single-entity (18) + summation (6) = full GSM8K dev
holdout 50/50, wrong=0. The reader->Hamiltonian compiler now solves the entire
dev holdout by chained certified relaxation, zero wrong answers.

16/16 pins green (11 multi-register updated + 5 summation incl. capstone).

[Verification]: uv run python -m pytest tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q
2026-07-18 14:25:44 -07:00
efd5335e86 Merge pull request 'feat(adr-0250): T2a multi-register executor — multi-entity arithmetic (18/18 wrong=0)' (#72) from feat/adr-0250-t2a-executor into main
Reviewed-on: #72
---
T2a is locked in — the production evals/multi_register_program.py is committed (87f87c9b), 11/11 green, and the load-bearing pin holds: the real GSM8K single-entity refused holdout solves 18/18, wrong = 0 (coverage 26 → 44/50). The immutable prepare→validate→commit executor, the relative conservation hard-reject, the per-entity content-addressed record chain, and the fail-closed taxonomy are all in and tested. Smoke is running; I'll push and open the PR the moment it's green.

Your summation-distinction question — the signal is already in the typed graph

The compiler never infers "this is a sum" from the shape of the operation sequence — that would be exactly the implicit assumption you're warning against. The distinction is an explicit typed field: graph.unknown.entity.

- unknown.entity is a concrete entity → decode that one register. A standard sequence of independent per-register translations; the answer is one register's final null point.
- unknown.entity is None → the reader has already encoded "how many altogether" as a null-entity Unknown. That is the explicit structural demand for a multi-register certified sum.

So the branch is a single, unambiguous read of the reader's typed output. Right now T2a refuses the null-entity case with total_unknown_requires_summation (the honest boundary); 2b replaces that refusal with an emitted summation program. And I verified this signal is reliable — all 6 total-like dev cases carry unknown.entity is None (entities like ('Ivan','Sam','Nori')), nothing pattern-matched.

The set summed is graph.entities — all registers — also explicit from the graph, not guessed. (If a problem ever meant a subset total, the schema would have to say so; the current Unknown doesn't encode subsets, so "sum all registers" is the honest mapping, and a subset total would be a recorded schema-level boundary.)

The conformal mapping keeps the arithmetic in the substrate per ruling #1: the summation is a certified sequence of decode-staged T_v additions — start from register 1's certified state, then for each remaining register, decode its certified value through the §4.1 chain-of-custody staging (certificate psi_digest anchor → operand_certificate_id in the record → deterministic re-execution) and apply it as a translator T_v to the running sum, decoding once at the end. So the total is grounded in RelaxationCertificates the whole way down — never a Python sum() — and the null-entity signal maps to that exact operation with no implicit assumption anywhere.
2026-07-18 21:19:57 +00:00