ADR-0174 Phase 3a — substrate for held-hypothesis lookback.
Score unchanged at 3/47/0 (this PR is correctly-engineered
infrastructure; eval impact gated on ADR-0163.x recognizer expansion
documented in the follow-up brief).
Adds generate/comprehension/lookback.py:
- VALID_REFINEMENT_KINDS, VALID_UNRESOLVED_SLOTS — closed sets
contracted with reader_trace consumer
- PronounResolution refinement dataclass (pronoun + resolved_to +
evidence_source, all validated)
- Refinement Union (Phase 3b will widen with CompoundClauseExpansion)
- ReevaluateResult dataclass with admit/eliminate consistency
- reevaluate(hypothesis, refinement) operator — applies refinement,
re-runs check_constraints, returns refined Hypothesis or None.
- _rebuild_candidate_with_resolved_actor — rebuilds
CandidateOperation / CandidateInitial replacing the semantic actor
field (op.actor / initial.entity) while preserving matched_actor_token
/ matched_entity_token as the pronoun (so grounding still passes
against the held statement's source span).
Modifies generate/recognizer_match.py:
- _try_extract_discrete_count_anchor: pronoun-subject statements now
emit anchors with subject_role=<pronoun> + requires_pronoun_resolution
marker, rather than refusing at the _REFUSED_SUBJECT_TOKENS check.
The other narrowness layers (clause split, verb whitelist) still
refuse; only the pronoun layer changes.
Modifies generate/math_candidate_graph.py:
- After inject_from_match, when any parsed_anchor carries
requires_pronoun_resolution, the candidates are held as Hypothesis
objects with unresolved=('actor_pronoun',). The lookback path then
resolves via the existing _discourse_prior_subjects map and runs
PronounResolution refinements through reevaluate. Resolved
hypotheses flow into per_sentence_choices as if the regex parser
had produced them; unresolved hypotheses drop cleanly (refusal-
preferring). Emits 'lookback' JSON trace events with
outcome ∈ {admitted, eliminated, no_antecedent}.
Tests:
- tests/test_adr_0174_phase3_lookback.py — 17 acceptance tests
covering operator semantics on Operation/Initial, dataclass
invariants, closed-set constants, end-to-end wiring on synthetic
problems, and wrong=0 preservation on train_sample.
Phase 3.1 follow-up brief:
- docs/handoff/PHASE-3.1-FOLLOWUP-RECOGNIZER-EXPANSION.md documents
the empirical finding that the train_sample bottleneck is
verb-coverage (recognizer scope, ADR-0163.x) not lookback
(ADR-0174 scope). 11 verbs identified for HITL contemplation pass.
Recommends sequencing: Phase 3a now (substrate), ADR-0163.x verb
expansion next, Phase 3b after coverage matures.
Acceptance verified:
- 17/17 Phase 3a tests pass
- 95/95 existing tests pass (Phase 1 + Phase 2 + brief_11 + reader_phase2)
- Smoke 67/67, packs 141/141, lanes 8/8
- wrong=0 preserved, score unchanged 3/47/0 (intentional per brief)
Stacks on Phase 2 (PR #420). Rebases onto main after #416 + #420 land.
8.2 KiB
Phase 3.1 Follow-up — Verb-coverage bottleneck on train_sample/v1
Status: Open recommendation Date: 2026-05-28 Author: Shay (analysis surfaced during ADR-0174 Phase 3a) Parent: ADR-0174 — Held-Hypothesis Comprehension Related ADRs: ADR-0163 (path to GSM8K mastery), ADR-0167 (audit-as-teaching-evidence), ADR-0150/0152/0155/0161 (HITL corridor)
Context
ADR-0174 Phase 3 specified a correct ≥ 8 lift target on
evals/gsm8k_math/train_sample/v1 (≥ 5 of the 21 currently-empty
discrete_count_statement anchors admitted via lookback). Empirical
analysis during Phase 3a implementation found this target is
not achievable through lookback alone on this corpus. The
substrate is built correctly; the bottleneck is elsewhere.
What Phase 3a shipped
generate/comprehension/lookback.py— thereevaluateoperator,PronounResolutionrefinement type,ReevaluateResultdataclass.- Held-anchor emission in
recognizer_match._try_extract_discrete_count_anchor(pronoun-subject statements carryrequires_pronoun_resolution=Truerather than refusing). - Lookback wiring at
math_candidate_graph.parse_and_solve's recognizer-injection branch — appliesPronounResolutionagainst the existing_discourse_prior_subjectsmap; emitslookbackJSON trace events withoutcome ∈ {admitted, eliminated, no_antecedent}. - 17 acceptance tests proving the wiring works on synthetic problems
(
tests/test_adr_0174_phase3_lookback.py). wrong = 0invariant preserved; score unchanged at 3/47/0.
Why Phase 3a did not lift the score
The 21 empty-anchor discrete_count_statement refusals on
train_sample/v1 break down as:
| Structural cause | Cases |
|---|---|
| Pronoun-only (no compound clause) | 2 — 0002, 0034 |
| Compound-only | 8 |
| Pronoun + compound | 5 |
| Other narrowness fail (verb/structure) | 6 |
For Phase 3a to lift any case, three conditions must all hold:
- The matcher's recognizer registry recognises the statement.
- The extractor passes every narrowness layer before the pronoun
check. Specifically the verb must be in
_POSSESSION_VERBS(has,have,had) or_ACQUISITION_VERBS(collected,collects,collect,received,receives,receive,bought,buys,buy,got,gets,get). - The candidate-graph's regex path (
_filtered_statement_choices) must return empty for the same statement — otherwise the regex path commits the candidate (with the pronoun still as actor) and the recognizer-injection branch never runs.
Verb checks against the 13 cases with compound/pronoun structure:
| Case | Statement (excerpt) | Verb | In whitelist? |
|---|---|---|---|
| 0002 | She splits it up... | splits | No |
| 0034 | He can run 40 yards... | run | No |
| 0020 | Two puppies, two kittens... were for sale... | were | No |
| 0021 | He bench presses 15 pounds... | presses | No |
| 0027 | Malcolm has 240 followers... | has | Yes |
| 0033 | Rachel is 12 years old... | is | No |
| 0040 | He now has 2 horses... | has | Yes |
| 0041 | Troy bakes 2 pans... | bakes | No |
| 0044 | John invests in a bank... | invests | No |
| 0045 | On Monday he finished 3 surveys... | finished | No |
| 0047 | John bakes 12 coconut macaroons... | bakes | No |
| ... |
Only two cases (0027, 0040) cross the verb whitelist. Both also fail at the compound-clause narrowness layer (which comes earlier than the pronoun check), so even adding compound-clause held hypotheses (Phase 3b) would have to fire first.
Conclusion: the empirical bottleneck on train_sample/v1 is verb-set coverage, not lookback or held hypotheses. ADR-0174 is the wrong tool for moving this score.
Recommended path forward
ADR-0163 is the correct scope for verb-coverage expansion via the HITL corridor. The path:
-
Run
core eval math-contemplationon the 11 failing verbs —splits,run,bench presses,is,bakes,invests,finished,donated,wants,gained,eat. These surface asMathReaderRefusalEvidenceaudit rows that the contemplation lane already consumes (ADR-0167). -
Operator review in workbench — categorise each verb:
- Acquisition-class (engine should treat as
add):received,bought, etc. — verbs that grammatically gain quantity to actor. Candidates from list:gained,won,earned,saved,accumulated,acquired. - Depletion-class (engine should treat as
subtract):gives,loses,spends. Candidates:donated,gave,eats,consumed,lost,spent. - Non-arithmetic verbs (engine should refuse and ask):
is,wants,bench presses,splits,run,bakes,invests. These do not carry possession/acquisition semantics; the right answer is a different intent (rate / capacity / descriptive), not a wideradd/subtractwhitelist.
The first two classes ratify into the registry via the existing ADR-0150/0152 corridor (proposal → review → packed). The third class becomes refusal-typed evidence that informs whether a separate recognizer category is needed (e.g. a
capacity_statementrecognizer for "He can run 40 yards in 5 seconds" rather than forcing it intodiscrete_count_statement). - Acquisition-class (engine should treat as
-
After verb widening lands — re-run Phase 3a's lookback wiring on the corpus. The cases that were previously verb-blocked now reach the pronoun-check layer, and the held-hypothesis path admits them. Expected lift from this combination: roughly the 13 cases with pronoun/compound structure that have an arithmetic-class verb under the widened whitelist.
What this means for ADR-0174
The held-hypothesis substrate (Phase 1 + 2 + 3a) is correct architecture and load-bearing for Phase 4 (in-loop contemplation) and Phase 5 (legacy-parser removal). Its eval impact depends on upstream recognizer coverage maturing through the ADR-0163.x corridor. These two efforts are complementary, not competing — the substrate makes lookback possible, the recognizer expansion gives lookback something to fire on.
The cleanest sequencing is:
- ADR-0174 Phase 3a (this PR) — substrate landed.
- ADR-0163.x verb expansion (this brief's recommendation) — widens the corpus surface that the substrate can act on.
- ADR-0174 Phase 3b — compound-clause held hypotheses. Once the verb-coverage bottleneck is gone, compound-clause expansion surfaces real cases. Currently it would surface zero on train_sample for the same reason Phase 3a does: most compound cases also fail the verb check before reaching the clause-split narrowness layer.
- ADR-0174 Phase 4 — in-loop contemplation. Builds on Phase 3 substrate.
- ADR-0174 Phase 5 — legacy parser removal.
Decision needed (from operator)
-
Authorise the ADR-0163.x verb-expansion contemplation pass? Concretely: run
core eval math-contemplationagainst the 11 failing verbs above; review the proposals in workbench; ratify acquisition/depletion entries that are unambiguous. -
Re-scope ADR-0174 Phase 3b to "post-recognizer-expansion re-measurement" rather than "compound-clause held hypotheses"? Phase 3b should land only after verb expansion exposes cases that exercise its compound-clause logic.
No timelines are proposed; this is a sequencing recommendation. The substrate work in Phase 3a is already merged on its own merits (correctness and Phase 4/5 prerequisite); Phase 3b waits on recognizer coverage.
Cross-references
- ADR-0174 §Phase 3 acceptance — the criteria this brief documents as unmet (with structural-cause analysis).
tests/test_adr_0174_phase3_lookback.py— proves the substrate works on synthetic problems even though no train_sample case exercises it.feedback-wrong-zero-hazard-case-0050memory — verb expansion must preserve the case-0050 canary; the recommended depletion-class additions should be reviewed against this hazard before ratification.thesis-decoding-not-generating— the verb-class contemplation/HITL path is the right "teach the engine to find better" mechanism; widening the static whitelist directly would be "storing another found thing."