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.
103 lines
4.6 KiB
Markdown
103 lines
4.6 KiB
Markdown
# Case 0148 — correct-for-the-right-reason graph dump (preserved evidence)
|
||
|
||
**Status**: Reference artifact — not a build, not landed on `main`. Preserved per the recalibration
|
||
(ADR-0251) after abandoning `feat/reader-inc2-caseband` (PR #80). See
|
||
`docs/research/reader-arc-recalibration-preserved-knowledge-2026-07-19.md` §2 for full context.
|
||
|
||
The abandoned branch committed this file **empty** (0 bytes) while its own session summary claimed a
|
||
graph dump had been committed here. That claim was false. This file replaces the empty placeholder with
|
||
the real artifact, generated fresh and independently re-verified — not copied from the branch's claims.
|
||
|
||
## Case
|
||
|
||
- **id**: `gsm8k-holdout-dev-v1-0148`
|
||
- **problem**: "At a people counting station, the number of people counted on the first day was twice
|
||
the total number counted on the second day. If 500 people were counted on the second day, how many
|
||
people were counted on the two days?"
|
||
- **expected_answer**: `1500.0`
|
||
|
||
## Provenance
|
||
|
||
Generated by running `generate.math_candidate_graph.parse_and_solve(text)` against
|
||
`origin/feat/reader-inc2-caseband @ e3da148d` (the abandoned branch's tip — the only place this surface
|
||
form parses; `main` correctly refuses this case, see below), in a throwaway detached worktree that has
|
||
since been removed. Command:
|
||
|
||
```
|
||
uv run python -c "
|
||
from dataclasses import asdict
|
||
from generate.math_candidate_graph import parse_and_solve
|
||
import json
|
||
text = 'At a people counting station, the number of people counted on the first day was twice the total number counted on the second day. If 500 people were counted on the second day, how many people were counted on the two days?'
|
||
r = parse_and_solve(text)
|
||
print('answer:', r.answer)
|
||
print('is_admitted:', r.is_admitted)
|
||
if r.selected_graph: print(json.dumps(asdict(r.selected_graph), indent=2, default=str))
|
||
"
|
||
```
|
||
|
||
## Result (branch code)
|
||
|
||
```json
|
||
{
|
||
"answer": 1500.0,
|
||
"is_admitted": true,
|
||
"refusal_reason": null,
|
||
"branches_enumerated": 1,
|
||
"branches_admissible": 1,
|
||
"selected_graph": {
|
||
"entities": ["the first day", "the second day"],
|
||
"initial_state": [
|
||
{
|
||
"entity": "the second day",
|
||
"quantity": {"value": 500, "unit": "people"}
|
||
}
|
||
],
|
||
"operations": [
|
||
{
|
||
"actor": "the first day",
|
||
"kind": "compare_multiplicative",
|
||
"operand": {
|
||
"reference_actor": "the second day",
|
||
"delta": null,
|
||
"factor": 2.0,
|
||
"direction": "times"
|
||
},
|
||
"target": null
|
||
}
|
||
],
|
||
"unknown": {"entity": null, "unit": "people"}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Reading the graph — the 3-part correct-for-the-right-reason proof
|
||
|
||
1. **The conditional-seed bound the *named* reference.** `initial_state` seeds `"the second day" = 500`
|
||
— the entity named in "If 500 people were counted **on the second day**" — not a nearest/other/
|
||
unnamed entity.
|
||
2. **The compare op reads forward.** `operations[0]` binds `actor = "the first day"`,
|
||
`reference_actor = "the second day"`, `factor = 2.0`, `direction = "times"` — i.e. *first day = 2 ×
|
||
second day*, matching the source's "the number... on the first day **was twice**... on the second
|
||
day" directly (not an inverted/guessed direction).
|
||
3. **The unknown resolves via summation over exactly these two registers.** `unknown.unit = "people"`
|
||
with no entity restriction → sums both days: `500 + (2 × 500) = 1500`. This matches
|
||
`expected_answer` because of the binding above, not by coincidence — swapping which day were seeded
|
||
would still total 1500 under plain summation, so the answer alone never proves correctness; the
|
||
graph's bindings (steps 1–2) are what's being verified here.
|
||
|
||
## Cross-check: `main` refuses this case (verified, current tip)
|
||
|
||
```
|
||
$ uv run python -c "
|
||
from generate.math_candidate_graph import parse_and_solve
|
||
text = 'At a people counting station, the number of people counted on the first day was twice the total number counted on the second day. If 500 people were counted on the second day, how many people were counted on the two days?'
|
||
r = parse_and_solve(text)
|
||
print(r.answer, r.is_admitted, r.refusal_reason)
|
||
"
|
||
None False recognizer matched but produced no injection for statement: 'At a people counting station, the number of people counted on the first day was twice the total number counted on the second day.' (category=descriptive_setup_no_quantity)
|
||
```
|
||
|
||
`main` has no mass-noun compare actor-binding, so it correctly refuses rather than guessing — consistent
|
||
with `wrong=0` discipline. This case remains an open, documented target for a future (non-bespoke)
|
||
increment; nothing here re-lands the branch's code.
|