docs(reader-arc): increment-1 BAND plan — {seed + comparison(#78) + question-arithmetic} (for ruling) #79

Merged
core-labs merged 5 commits from feat/reader-band-increment-1 into main 2026-07-19 04:58:05 +00:00
Owner

Design-first plan for ruling before any build — same gate as PR #76. Full doc: docs/research/increment-1-band-plan-2026-07-19.md.

The band (approved)

{ seed-simple + comparison (#78 polarity) + question-arithmetic (simple/summation/difference) } — the tractable spine's foundational core. Adds zero new hard capabilities beyond #78. Band-map upper bound ≈ 30 cases.

What EXISTS today (increment 1 EXTENDS, not rebuilds)

The question layer is partially built: q:summation works (aggregate-cue → entity=None → 2b compiler; 0101 solved this way), q:simple works, q:difference is partial (peer_count, but direction not yet fail-closed). Compare compiler merged (#77); its reader frame is on the whitelist (issue #78). Seed injector refuses all non-whitelist verbs + existential.

The gap increment 1 builds

  1. #78 polarity substrate (shared foundation) — a neutral-polarity ALLOWLIST (fail-closed, NOT the reverted fail-open blocklist): production/possession → seed; depletion → refuse; unknown → refuse. Closes #78 for seed and comparison, built once.
  2. Seed-simple injection — extend base injector via the substrate + existential "There are N X in C".
  3. Comparison frame-anchoring — re-land the verb-free frame gated by the allowlist (not blocklist); reuses the merged compiler.
  4. q:difference direction — "more…than" → A−B, "fewer…than" → B−A, ambiguous → refuse.

Josh's four refinements (baked in)

  1. Deliberate ~30 band (not 42): increment 1 is the first end-to-end reader conversion the arc has ever landed (corridor real-reach still 5/500, all from the compiler tier — no reader increment has converted a case). Ships two reusable foundations, zero new hard capabilities beyond #78. The 42 band adds multi-compound (new hard capability) — stacking it onto the first-conversion attempt raises the odds of another ~0. Smaller-but-foundational maximizes the critical first win. Recorded so it is not read as under-ambition.
  2. Done-when reset (X=15-per-layer retired): band-solve > 0 wrong=0 + both foundations validated/reuse-ready. The ~40 bar is cumulative across increments 1–3 (foundation → +multi-compound≈42 → +currency/rate≈63), not increment 1 alone.
  3. Haircut factor (real band-solve ÷ ~30 upper bound) = a named increment-1 output — recalibrates every future band's projected yield.
  4. TWO wrong=0 direction drivers: #78 statement polarity and q:difference question direction. Both positively determined, fail-closed (a wrong direction is a coherent-but-inverted answer on the run-once arbiter — the #77 fail-open hazard resurfacing).

Discipline

Develop-on-tune / measure-once; funnel re-runs; refusal-histogram pin; depletion-confuser suite proves the allowlist fail-closed; single measure run → triple + haircut factor + delta.

Out of scope / roadmap

Intractable-now 52% (q:complex 101, percent, simultaneous, fraction) OUT; multi-compound/currency-rate = increments 2–3; tractable ceiling ≈48% pending the scheduled q:complex decomposition (averaging = sum-over-count, multi-step = turn program — may be corridor-tractable, hiding in the 101; could move the ceiling).

Open questions for the ruling (§10)

  • Q1: depletion verbs — refuse (plan default) vs model-as-subtract now?
  • Q2: existential entity binding — container-bound only (refuse container-less), confirm?
  • Q3: keep q:difference in increment 1 (recommended — foundational) or defer to 1.5 to shrink first-conversion risk?

No build starts until this is ruled.

Design-first plan for **ruling before any build** — same gate as PR #76. Full doc: `docs/research/increment-1-band-plan-2026-07-19.md`. ## The band (approved) `{ seed-simple + comparison (#78 polarity) + question-arithmetic (simple/summation/difference) }` — the tractable spine's foundational core. Adds **zero new hard capabilities beyond #78**. Band-map upper bound ≈ **30 cases**. ## What EXISTS today (increment 1 EXTENDS, not rebuilds) The question layer is **partially built**: `q:summation` works (aggregate-cue → `entity=None` → 2b compiler; 0101 solved this way), `q:simple` works, `q:difference` is partial (`peer_count`, but direction not yet fail-closed). Compare **compiler** merged (#77); its reader frame is on the whitelist (issue #78). Seed injector refuses all non-whitelist verbs + existential. ## The gap increment 1 builds 1. **#78 polarity substrate (shared foundation)** — a **neutral-polarity ALLOWLIST** (fail-closed, NOT the reverted fail-open blocklist): production/possession → seed; depletion → refuse; unknown → refuse. Closes #78 for seed **and** comparison, built once. 2. **Seed-simple injection** — extend base injector via the substrate + existential "There are N X in C". 3. **Comparison frame-anchoring** — re-land the verb-free frame gated by the *allowlist* (not blocklist); reuses the merged compiler. 4. **q:difference direction** — "more…than" → `A−B`, "fewer…than" → `B−A`, ambiguous → **refuse**. ## Josh's four refinements (baked in) 1. **Deliberate ~30 band** (not 42): increment 1 is the **first end-to-end reader conversion the arc has ever landed** (corridor real-reach still 5/500, all from the compiler tier — no reader increment has converted a case). Ships two reusable foundations, zero new hard capabilities beyond #78. The 42 band adds multi-compound (new hard capability) — stacking it onto the first-conversion attempt raises the odds of another ~0. Smaller-but-foundational maximizes the critical first win. *Recorded so it is not read as under-ambition.* 2. **Done-when reset** (X=15-per-layer retired): band-solve **> 0 wrong=0** + both foundations validated/reuse-ready. The ~40 bar is **cumulative across increments 1–3** (foundation → +multi-compound≈42 → +currency/rate≈63), not increment 1 alone. 3. **Haircut factor** (`real band-solve ÷ ~30 upper bound`) = a **named increment-1 output** — recalibrates every future band's projected yield. 4. **TWO wrong=0 direction drivers**: #78 statement polarity **and** q:difference question direction. Both positively determined, fail-closed (a wrong direction is a coherent-but-inverted answer on the run-once arbiter — the #77 fail-open hazard resurfacing). ## Discipline Develop-on-tune / measure-once; funnel re-runs; refusal-histogram pin; depletion-confuser suite proves the allowlist fail-closed; single measure run → triple + haircut factor + delta. ## Out of scope / roadmap Intractable-now 52% (q:complex 101, percent, simultaneous, fraction) OUT; multi-compound/currency-rate = increments 2–3; tractable ceiling ≈48% **pending** the scheduled **q:complex decomposition** (averaging = sum-over-count, multi-step = turn program — may be corridor-tractable, hiding in the 101; could move the ceiling). ## Open questions for the ruling (§10) - **Q1**: depletion verbs — refuse (plan default) vs model-as-subtract now? - **Q2**: existential entity binding — container-bound only (refuse container-less), confirm? - **Q3**: keep q:difference in increment 1 (recommended — foundational) or defer to 1.5 to shrink first-conversion risk? No build starts until this is ruled.
core-labs added 1 commit 2026-07-19 03:55:07 +00:00
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).
Author
Owner

Review — approved to build, with rulings on §10 Q1–Q3. Faithful to all four directives (§4 two drivers, §5 deliberate-band rationale, §6 cumulative done-when, §7 haircut factor); the allowlist-not-blocklist #78 fix is exactly right; the grounding discovery that the question layer is partially built lowers risk.

Q1 — depletion verbs: REFUSE (confirmed). Fail-closed, smallest scope; depletion-as-subtract is a prior-state capability, out of band. Rider: any nominal ~30-band case whose seed is actually a depletion will haircut out — expected, count it in the haircut analysis, not a bug.

Q2 — existential: admit container-bound only, refuse container-less (confirmed). "There are N X" is genuinely ambiguous between seed and aggregate/total (the "two-numbers → aggregate" trap from the seeding analysis); refusing it is correct. Rider: a container-bound existential can still be a total that's partitioned downstream — if tune surfaces one as a mis-seed, refuse that sub-form too. Fail-closed, verified on tune.

Q3 — q:difference: DEFER the capability; CLOSE the hazard now (overriding the lean). The ~30 band converts on q:simple/q:summation — q:difference's 23 cases are a different set, and the band map pairs them with multi-compound (increment 2). If they co-require multi-compound, building q:difference in increment 1 adds the 2nd wrong=0 direction driver to the first-ever conversion attempt for ~0 in-band yield — risk without yield, the exact trade §5 avoids, and the generalized #77 lesson (never build a wrong=0-risk capability an increment before its cases convert). So defer the q:difference conversion capability to the increment where its cases solve; verify the co-occurrence to confirm. Separately and NOW: make the existing partial Pattern-B path fail-closed — if it can currently emit a difference with an assumed (not positively-determined) direction, that's a latent wrong=0 hazard in merged code; make it refuse on undetermined direction. Closing the hazard ≠ building the capability; do the former in increment 1 regardless.

Three build sharpenings:

  1. _NEUTRAL_SEED_VERBS is fail-closed and therefore incomplete — record allowlist-miss refusals as curriculum (they name the next verbs to add).
  2. The measure split stays the FIXED sha256-parity split across increments 1–3 — the ~40 bar is cumulative, so a re-split would corrupt it. Confirm continuity.
  3. With q:difference deferred, increment 1 ships exactly ONE wrong=0 driver (#78) — the minimal first-conversion risk surface §5 argued for.

Approved to build under these rulings. Measure-once; bring the triple + the haircut factor.

**Review — approved to build, with rulings on §10 Q1–Q3.** Faithful to all four directives (§4 two drivers, §5 deliberate-band rationale, §6 cumulative done-when, §7 haircut factor); the allowlist-not-blocklist #78 fix is exactly right; the grounding discovery that the question layer is partially built lowers risk. **Q1 — depletion verbs: REFUSE (confirmed).** Fail-closed, smallest scope; depletion-as-subtract is a prior-state capability, out of band. Rider: any nominal ~30-band case whose seed is actually a depletion will haircut out — expected, count it in the haircut analysis, not a bug. **Q2 — existential: admit container-bound only, refuse container-less (confirmed).** "There are N X" is genuinely ambiguous between seed and aggregate/total (the "two-numbers → aggregate" trap from the seeding analysis); refusing it is correct. Rider: a container-bound existential can still be a total that's partitioned downstream — if tune surfaces one as a mis-seed, refuse that sub-form too. Fail-closed, verified on tune. **Q3 — q:difference: DEFER the capability; CLOSE the hazard now (overriding the lean).** The ~30 band converts on q:simple/q:summation — q:difference's 23 cases are a different set, and the band map pairs them with multi-compound (increment 2). If they co-require multi-compound, building q:difference in increment 1 adds the 2nd wrong=0 direction driver to the first-ever conversion attempt for ~0 in-band yield — risk without yield, the exact trade §5 avoids, and the generalized #77 lesson (never build a wrong=0-risk capability an increment before its cases convert). So **defer the q:difference conversion capability to the increment where its cases solve; verify the co-occurrence to confirm.** Separately and NOW: make the existing partial Pattern-B path **fail-closed** — if it can currently emit a difference with an assumed (not positively-determined) direction, that's a latent wrong=0 hazard in merged code; make it refuse on undetermined direction. Closing the hazard ≠ building the capability; do the former in increment 1 regardless. Three build sharpenings: 1. `_NEUTRAL_SEED_VERBS` is fail-closed and therefore incomplete — record allowlist-miss refusals as curriculum (they name the next verbs to add). 2. The measure split stays the FIXED sha256-parity split across increments 1–3 — the ~40 bar is cumulative, so a re-split would corrupt it. Confirm continuity. 3. With q:difference deferred, increment 1 ships exactly ONE wrong=0 driver (#78) — the minimal first-conversion risk surface §5 argued for. Approved to build under these rulings. Measure-once; bring the triple + the haircut factor.
core-labs added 1 commit 2026-07-19 04:18:14 +00:00
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.
core-labs added 1 commit 2026-07-19 04:37:27 +00:00
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.
core-labs added 1 commit 2026-07-19 04:44:47 +00:00
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.
Author
Owner

This PR is now the FOUNDATIONS PR — band-solve=0, conversion re-scoped to increment 2

Per the ruling: keeping band-solve=0 as the headline, not relabeling it a success. Increment 1 as scoped ({seed + forward-comparison + q:simple/summation}) is falsified on its conversion goal — 0 tune conversions, measured four ways (yield harness, band map, band oracle, capability histogram). The two verified foundations below are its banked byproduct, not its success.

What ships (verified, wrong=0-safe)

The #78 positive-polarity allowlist substrateNEUTRAL_COUNT_VERBS (math_roundtrip.py), shared by the seed matcher and the comparison _comparison_anchor_verb(). Production/acquisition verbs (made/baked/grew/scored/wrote/taught) inject as seeds; depletion/transfer refuse by positive determination (not a blocklist — the allowlist resolution the #77 split intended). This closes issue #78's hazard, built once for both readers.

Merge gate (met)

  • full-500 wrong=0 (tune 261 + measure 239); PARSED unchanged (3 / 2 — no regression, no conversion); refusal histogram stable-or-explained (widens statement injection, zero case-level change).
  • 71 pinned comparative tests pass; smoke 176 green.

wrong=0 hazard found + fixed (per the mis-injection caution)

A mis-injection sweep over tune found the substrate nearly clean (2 flagged; 1 a false positive). The one real hazard: the compound extractor silently dropped a no-digit compare clause ("buys 4 lbs beans, 6 lbs milk, and twice the amount of carrots as beans" → injected 4+6, lost the carrots). The #78 substrate widens the compound extractor's reach, so it's hardened here: any <factor> the amount/number of / twice/times/half the / double/triple surface in a conjunctive list now refuses the whole compound (fail-closed). Verified: 0082 refuses, wrong=0 preserved.

Next (increment 2 — the first-conversion increment)

The minimal-convertible-band measurement shows no small capability band converts and the taxonomy is not at bedrock (real GSM8K statements are individually multi-capability — "spends 30 minutes twice a day" is one sentence needing rate+temporal+unit-conversion). multi-compound is highest-leverage (70/106 tractable needed-sets) but insufficient alone; q:complex is the biggest intractable wall (~35 cases). Recommendation: increment 2 is case-first — target specific closest cases, build their exact end-to-end needs — not capability-first. Full detail in docs/research/increment-1-band-plan-2026-07-19.md (BUILD OUTCOME section). Awaiting review.

## This PR is now the FOUNDATIONS PR — band-solve=0, conversion re-scoped to increment 2 Per the ruling: keeping band-solve=0 as the headline, not relabeling it a success. Increment 1 as scoped (`{seed + forward-comparison + q:simple/summation}`) is **falsified on its conversion goal** — 0 tune conversions, measured four ways (yield harness, band map, band oracle, capability histogram). The two verified foundations below are its **banked byproduct, not its success**. ### What ships (verified, wrong=0-safe) The **#78 positive-polarity allowlist substrate** — `NEUTRAL_COUNT_VERBS` (`math_roundtrip.py`), shared by the seed matcher and the comparison `_comparison_anchor_verb()`. Production/acquisition verbs (made/baked/grew/**scored/wrote/taught**) inject as seeds; depletion/transfer refuse by **positive determination** (not a blocklist — the allowlist resolution the #77 split intended). This closes issue #78's hazard, built once for both readers. ### Merge gate (met) - **full-500 wrong=0** (tune 261 + measure 239); PARSED unchanged (3 / 2 — no regression, no conversion); refusal histogram **stable-or-explained** (widens statement injection, zero case-level change). - **71 pinned comparative tests pass**; **smoke 176 green**. ### wrong=0 hazard found + fixed (per the mis-injection caution) A mis-injection sweep over tune found the substrate nearly clean (2 flagged; 1 a false positive). The one real hazard: the compound extractor silently **dropped a no-digit compare clause** ("buys 4 lbs beans, 6 lbs milk, **and twice the amount of carrots as beans**" → injected 4+6, lost the carrots). The #78 substrate widens the compound extractor's reach, so it's hardened here: any `<factor> the amount/number of` / `twice/times/half the` / `double/triple` surface in a conjunctive list now **refuses the whole compound** (fail-closed). Verified: 0082 refuses, wrong=0 preserved. ### Next (increment 2 — the first-conversion increment) The minimal-convertible-band measurement shows **no small capability band converts** and the **taxonomy is not at bedrock** (real GSM8K statements are individually multi-capability — "spends 30 minutes twice a day" is one sentence needing rate+temporal+unit-conversion). `multi-compound` is highest-leverage (70/106 tractable needed-sets) but insufficient alone; `q:complex` is the biggest intractable wall (~35 cases). Recommendation: increment 2 is **case-first** — target specific closest cases, build their exact end-to-end needs — not capability-first. Full detail in `docs/research/increment-1-band-plan-2026-07-19.md` (BUILD OUTCOME section). Awaiting review.
core-labs added 1 commit 2026-07-19 04:57:47 +00:00
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.
core-labs merged commit 854ce023d9 into main 2026-07-19 04:58:05 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: core-labs/core#79
No description provided.