core/generate/comprehension
Shay 619cd62227 fix(adr-0174-phase3a): multi-actor pronoun hazard defense + test backfills + ADR amendment
All findings from the 2026-05-28 Phase 1-3a lookback review addressed
in one commit on the Phase 3a branch:

Wrong=0 hazard defense (the load-bearing fix):
- generate/math_candidate_graph.py: Phase 3a wiring now collects the
  set of distinct proper-noun subjects seen in prior context. When
  more than one exists, refuses with no_antecedent_ambiguous trace
  event rather than guessing the most-recent (which was gender-blind
  single-binding — wrong attribution in multi-actor problems).
- Refusals from the statement loop now preserve _statement_trace via
  reader_trace in CandidateGraphResult (pre-existing latent issue:
  Phase 2/3 trace events were dropped on early statement refusal).
- New tests assert: ambiguous case refuses with correct trace; single-
  actor case still resolves normally.

Test coverage backfills (closes the 13 untested predicate-name gaps):
- TestCheckConstraintsInitialPredicateNames — 3 tests asserting the
  exact predicate name on initial.value_grounds / initial.unit_grounds
  / initial.entity_grounds failure paths.
- TestCheckConstraintsOperationPredicateNames — 3 tests asserting
  operation.verb_grounds / operation.value_grounds / operation.unit_grounds
  failure-predicate-name parity.
- TestCheckConstraintsComposedInitialPath — 4 tests for the RAT-1
  composed_initial path which was entirely untested in Phase 2
  (parity manually verified during lookback review; now automated).

ADR amendment (honest doc vs impl drift):
- docs/decisions/ADR-0174-held-hypothesis-comprehension.md: appended
  'Implementation Notes' section documenting:
  - reevaluate signature differs from spec text (shipped is more
    composable; treat as amended)
  - Phase 2 wires per-candidate, not per-token (per-token is Phase 5)
  - Lookback recompute is candidate-level, not token-level
  - Hypothesis.constraint_state is never populated by Phase 2
  - Multi-actor pronoun hazard defense rationale
  - Honest LOC accounting: Phases 1-3a net +1,500 lines (Phase 5
    delivers the projected net removal)
  - Test coverage backfill summary

Cosmetic:
- lookback.py:297 unreachable raise — added # type: ignore[unreachable]
  with comment explaining defensive future-proofing for Phase 3b.

Acceptance verified:
- 124/124 Phase 1+2+3a + reader tests pass (was 95/95 before backfills)
- Smoke 67/67, packs 141/141
- train_sample 3/47/0 preserved (wrong=0 invariant held)
- Multi-actor hazard live-tested: parse_and_solve refuses the
  Alice/Bob/She case with no_antecedent_ambiguous trace event

See CLAUDE.md §Lookback Review Discipline and memory
feedback-lookback-review-discipline for the doctrine that surfaced
all of these issues at the right time.
2026-05-28 10:49:20 -07:00
..
__init__.py feat(comprehension): add ComprehensionState skeleton (#321) 2026-05-26 19:32:22 -07:00
audit.py feat(brief-11/11B): reader closure audit artifact — full taxonomy + rejected naive fix (#345) 2026-05-27 05:35:06 -07:00
composition_registry.py feat(consumption-wiring): CW-1 + CW-2 — Frame + Composition registry loaders (#398) 2026-05-27 16:17:03 -07:00
constraint_propagation.py feat(adr-0174-phase2): continuous constraint propagation in comprehension reader 2026-05-28 10:16:33 -07:00
frame_registry.py feat(consumption-wiring): CW-1 + CW-2 — Frame + Composition registry loaders (#398) 2026-05-27 16:17:03 -07:00
lexeme_primitives.py feat(comprehension/8.2): universal proper_noun_token primitive (#333) 2026-05-26 22:16:34 -07:00
lexicon.py feat(comprehension): operational lexicon loader for en_core_math_v1 (ADR-0164 §Decision §1) (#325) 2026-05-26 20:08:27 -07:00
lifecycle.py feat(comprehension/10): Phase 2 statement-frame reader (ADR-0164.4) (#335) 2026-05-27 05:03:56 -07:00
lifecycle_runtime_adapter.py feat(ADR-0164.P1): reader/regex hybrid coexistence + Phase 1 measurement gate (#331) 2026-05-26 21:14:11 -07:00
lookback.py fix(adr-0174-phase3a): multi-actor pronoun hazard defense + test backfills + ADR amendment 2026-05-28 10:49:20 -07:00
state.py feat(adr-0174-phase1): held-hypothesis state primitive in comprehension reader 2026-05-28 08:09:00 -07:00