core/docs/handoffs/AUDIT-ADR-0179-EX-RECONCILE.md
Shay 54e6bfc0d0
docs: reorganize docs landscape
Implements the 4-phase documentation reorganization master plan.

- Consolidation: Merged brief/, handoff/, planning/, and decisions/ into briefs/, handoffs/, plans/, and adr/ respectively (101 ADRs relocated)
- Root Cleanup: Relocated HANDOFF-gpt55-*.md and key top-level docs (runtime_contracts.md, etc.) to canonical folders. Added superseded alerts.
- Indices & Navigation: Created docs/README.md navigation document, docs/sessions/README.md index, docs/adr/README.md index
- Note: Also includes prior commit adding ADR-0200+ corpus hygiene governance (ADR-0225, dependency map, backfilled cross-references)
2026-06-30 16:59:36 -07:00

70 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-0179 EX-1/3/4/5 reconciliation (Claude, at the library)
Reconciles the four sealed-lane extraction PRs ChatGPT opened from the remote
brief (`docs/handoff/CHATGPT-REMOTE-BRIEF.md`) into one coherent
`generate/derivation/extract.py`. Each PR was branched independently off `main`
and rewrote the *same* file + the *same* new test, so they conflict pairwise and
could not be merged as-is — they needed integration, not a fast-forward.
## Disposition
| PR | Sub-phase | Verdict | Action |
|----|-----------|---------|--------|
| #452 | EX-1 word-numbers | **Integrated** | folded in (reuses `WORD_NUMBERS`, factor-words excluded) |
| #453 | EX-3 multi-word units | **Deferred — regressed GB-2** | not integrated; see below |
| #451 | EX-4 list-unit inheritance | **Integrated** | folded in (span-tracked; does not flip real 0024) |
| #454 | EX-5 sentence-final numbers | **Integrated** | folded in (empty unit, span-excluded) |
| #450 | Stream A lookback audit | **Sound** | merged (read-only, feeds GB-3) |
The four EX source PRs are superseded by the integration commit and closed with a
pointer here; their authored content survives in the merged file/tests.
## Why EX-3 (multi-word units) was deferred
The brief required "keep units tight" and "don't regress GB-1/GB-2 tests." EX-3's
greedy lowercase unit span (`[a-z]+(?:\s+[a-z]+)*`) does both wrongs:
- **Regresses GB-2.** `compose_sequential("She picked 6 apples and 4 apples.")`
expects `10.0`. Greedy units read the first unit as `"apples and"` (it swallows
the connective up to the next digit), so `_same_unit` sees two distinct units
and the composer refuses. The existing test `test_same_unit_list_sums` flips
from pass to fail.
- **Doesn't even recover real multi-word units.** Real gold case 0024 is
`"20 jumping jacks on Monday, 36 on Tuesday, …"`. Greedy lowercase reads
`"jumping jacks on"` (stops only at the capital `Monday`), so the intended
`"jumping jacks"` unit is never produced anyway.
EX-3's own tests pass only because they place the unit at a clause end (`"12
jumping jacks."`) where punctuation halts the greedy run. That is a contrived
shape, not the GSM8K shape. A correct multi-word-unit extractor needs a tighter,
non-connective-crossing rule; tracked as future work, not shipped here.
## Honest note on EX-4 and case 0024
EX-4's PR test asserted it "unblocks 0024" using a *fabricated* input
(`"20, 36, 40 and 50 jumping-jacks"`). The real case interleaves numbers with
temporal phrases (`"36 on Tuesday, 40 on Wednesday"`), so the bare-list regex
never fires and 36/40/50 do not inherit the unit. EX-4 is still a real, safe
orthographic primitive (some GSM8K problems do state a unit once after a bare
list), but it does **not** flip 0024. `TestRealCase0024StillBlocked` pins this so
no future change silently re-claims the unblock without proving 438 end-to-end.
## Verification (run at the library)
- **Serving frozen:** lane-SHA gate 8/8 match; `scripts/generate_claims.py
--check` OK → serving `3/47/0` byte-identical. wrong=0 held.
- **No new test failures:** the 3 failures present (`0163` pronoun, telemetry
round-trip, and the now-fixed `ms3` decimal-deferred) all pre-existed on `main`.
- **Sealed practice improved:** `build_search_report` went **4/2/44 → 4/1/45**
(one wrong eliminated, no correct lost). Case **0025** flipped wrong→refused:
EX-1 now reads `"three"`, so the completeness check sees a quantity the 6×50
chain doesn't consume and refuses the spurious `300` (gold is `1200`). Richer
reading → the gate refuses rather than commits a wrong answer. This is the
intended direction.
## Drift fixed in passing (cleanup-as-you-find)
`tests/test_adr_0176_ms3_search.py::TestDecimalGroundingGapIsDeferred` asserted
decimals were "currently refused." EX-2 (#447) landed decimal grounding and made
that case resolve to the correct `864`; the test was stale on `main`. Renamed to
`TestDecimalGroundingResolves` and updated to assert the flip.