core/docs/handoff/WAVE-NEXT-REVISED.md
Shay ecc0072ea1
chore: remove stub injector + superseded docs (cleanup-as-you-find) (#373)
Three concrete cleanup items from the day's work, per the
cleanup-as-you-find memory principle.

## 1. Remove inject_rate_with_currency stub

PR #369 (A2 rate_with_currency) shipped a function that always returns
() with an extensive docstring documenting the Rate-not-in-SentenceChoice
schema gap. The function is dead at runtime — `_INJECTORS.get(category)`
returning None has the same downstream behavior as the function
returning (). The 16 tests pinned the empty-tuple return; the case-0050
hazard pin is duplicated in test_recognizer_skip_wrong_zero.py and
test_brief_11b_step2_lexicon.py.

The schema gap is now properly documented in ADR-0170 (PR #372). A
dispatch-table comment at the removal site retains the at-code pointer
to that ADR for anyone wiring a new injector.

Removed:
- `inject_rate_with_currency` function in generate/recognizer_anchor_inject.py
- Its `_INJECTORS` dispatch table entry
- Its `__all__` export
- tests/test_injector_rate_with_currency.py (371 lines, 16 tests)

## 2. Remove docs/handoff/GPT55-MOBILE-DISPATCH.md

Single-session travel-time scaffolding. The 5 tasks it named are
complete or superseded by ADR-0170's findings. Pure historical artifact.

## 3. Remove docs/handoff/WAVE-NEXT-INJECTORS.md

Superseded by docs/handoff/WAVE-NEXT-REVISED.md, which captures
everything load-bearing from the original brief in its A1–A4 findings
table. The "kept for history" justification didn't survive scrutiny:
the document was misframed (over-promised lift; misframed schema work
as injector work). Lessons captured in REVISED + ADR-0170.

Updated cross-references:
- WAVE-NEXT-REVISED.md: removed the "supersedes ... kept for history"
  pointer; tightened cross-reference list
- ADR-0167-FOLLOWUPS.md §7: rewrote pointer to name ADR-0170 + REVISED
  as the live plan rather than "the original is retained"

## Test plan

- 219 tests passed across G.2/G.4/G.5/S1/Brief 11/B1/B11A/wiring/partition/DCS-D.2
- evals/gsm8k_math/train_sample/v1/report.json untouched (regen
  surfaces a separate stale-baseline test issue — out of cleanup scope)
- No runtime behavior change

## Net impact

- 5 files removed (~1200 lines)
- 1 file modified for explanatory comment (~30 lines)
- 2 doc files updated to remove dangling cross-references
- 0 behavioral change
2026-05-27 11:08:14 -07:00

8.4 KiB
Raw Permalink Blame History

Wave-Next Revised — DCS Sub-Shapes + Schema-Gap Backlog

Date: 2026-05-27 Supersedes: the original Wave-Next injector briefs (removed in cleanup PR; the four A-findings and pivot rationale are captured here) Why revised: The A1A4 dispatch surfaced findings that invalidate three of the four briefs' lift assumptions. This doc replaces them with the actually-tractable next steps.


What A1A4 actually found

Brief Outcome Schema gap surfaced
A1 currency_amount Sandbox-blocked write; analysis only. Real lift potential — new verbs (charges, earns) outside _INITIAL_HAS_RE coverage. Implementation ready, design intact. None
A2 rate_with_currency PR #369 opened (schema-refusal). Lift=0. Rate not in SentenceChoice = Union[CandidateInitial, CandidateOperation]
A3 multiplicative_aggregation Sandbox-blocked write; analysis only. Lift=0. Brief's CandidateOperation(multiply) spec is wrong: would compute 0 * inner = 0 with no prior InitialPossession. Correct emission is CandidateInitial(outer × inner) pre-computed product.
A4 temporal_aggregation Sandbox-blocked write; analysis only. Lift=0. Needs apply_rate primitive that doesn't exist in the algebra.

Three of four categories have schema-level prerequisites before any injector can ship. The original Wave-Next brief misframed them as injector work. The honest read: they're each their own ADR-sized schema-extension followed by an injector wave.


The actually-tractable next wave: DCS sub-shapes

The discrete_count_statement category is 21 of 47 GSM8K refusals (largest single bucket) and has a working v1 injector from #315 plus a specification document on main at docs/handoff/discrete_count_statement-injector-spec.md (from #366).

The spec recommends narrow incremental expansion — one sub-shape per PR, each carrying its own wrong=0 hazard pins. That maps cleanly to small focused PRs.

Proposed sub-shape sequence

Order by lift-per-risk:

  1. DCS-S1 — proper-noun possession with single static count, no clause split (the canonical narrow form already partially handled by the v1 injector). Expand to cases the v1 injector currently misses for surface-shape reasons.
  2. DCS-S2 — proper-noun possession with and-coordinated counted nouns (e.g. "Francine has 5 boxes and 27 loose crayons"). Requires the multi-quantity composition decision but is structurally simpler than the full multi-quantity recognizer.
  3. DCS-S3 — pronoun-subject possession (e.g. "She had 6 baskets"). Requires anaphora resolution to a prior proper noun. Higher risk surface than S1/S2.
  4. DCS-S4 — subject-anonymous possession ("There were 12 apples"). Requires anonymous-subject handling decision.

Each sub-shape PR carries:

  • A focused match-tightening + injector extension in generate/recognizer_match.py and generate/recognizer_anchor_inject.py
  • A test file pinning the new admission cases AND the wrong=0 hazard (case 0050 + any newly-revealed hazard pattern)
  • Eval delta section in audit_brief_11.md

The full DCS bucket lift potential is ~515 cases depending on sub-shape coverage. Each sub-shape PR is a small, focused increment.

Why not dispatch this as a Wave

The A1A4 dispatch demonstrated that orchestrator-launched subagents burn 50k+ tokens per cold-start with mixed PR-opening success rates. The user dispatches operators in their own UIs/CLIs where context costs amortize across the operator's session.

This document is the reference brief that operators read; the dispatch is the user's action, not the orchestrator's. See memory/feedback-no-self-dispatch-of-subagents.md for the binding principle.


Schema-gap backlog (file for separate ADRs, not Wave-Next)

The three findings from A2/A3/A4 deserve named ADRs when (and only when) the prerequisite ADRs are in place. Until then they sit as queued items.

Schema-Gap 1 — Rate in SentenceChoice union (from A2)

From: PR #369 (A2 rate_with_currency injector — refusal-only) Requires: ADR-0168.x or new ADR-0170.

A2's concrete 4-step follow-up (preserved verbatim from the PR):

  1. Add CandidateRate dataclass in generate/math_candidate_parser.py (sibling of CandidateInitial/CandidateOperation) — carries a Rate operand keyed by actor + source-span provenance.
  2. Widen SentenceChoice to include CandidateRate; update _slot_count, _collapse_per_sentence_ties, admissibility predicates, and the per-sentence admission gate.
  3. Teach parse_and_solve to compose CandidateRate with downstream apply_rate/multiply questions — unify with the existing extract_earnings_candidates short-circuit.
  4. Then inject_rate_with_currency can emit CandidateRate. The matcher already extracts (currency_symbol, amount, per_unit); needs entity extraction added.

Lift potential after schema extension: 3+ cases (the original rate_with_currency bucket). Likely 4-5 more from rate_* adjacent categories once the substrate exists.

Schema-Gap 2 — apply_rate primitive in the algebra (from A4)

From: A4 temporal_aggregation analysis (no PR) Requires: an algebra extension ADR.

The current solver has no apply_rate operation in its operator inventory. Temporal aggregation ("5 hours per day, 7 days per week") fundamentally needs this: a rate composed with a time-duration quantity yields a total. Without it, temporal aggregation has nowhere to ground.

Lift potential after primitive lands: 2 cases (the temporal_aggregation bucket).

Schema-Gap 3 — Multi-quantity composition emission shape (from A3)

From: A3 multiplicative_aggregation analysis (no PR) Requires: correction to the original Wave-Next brief, plus a multi-quantity-composition ADR coordinated with FOLLOWUPS §1 (CompositionClaim).

The brief's CandidateOperation(multiply) spec is mechanically wrong: the solver's multiply operation does state[(actor, unit)] *= value, requiring a prior InitialPossession. A standalone multiplicative statement doesn't have that, so multiply would compute 0 * inner = 0.

Correct emission: CandidateInitial(outer_count × inner_count, inner_unit) — the pre-computed product as a possession.

Lift potential after correction lands: 0 cases (zero GSM8K multiplicative_aggregation cases match the canonical narrow form even with correct emission — they all need either coordination or clause-split support). Effectively this category's bucket is empty relative to current GSM8K; the schema correction is for future problems, not for visible lift today.

Schema-Gap 4 — A1's currency_amount injector (preserved, not dropped)

From: A1 currency_amount analysis (no PR, sandbox-blocked) Requires: Only the sandbox fix + reimplementation. No schema work.

Lift potential: 24 cases (new verbs charges, earns not covered by the existing _INITIAL_HAS_RE). The implementation design is in A1's analysis — see agent transcript for details. This is the smallest, lowest-risk follow-up if anyone picks it up; the brief is sound, only execution failed.


Standing pivot

The next operator pickup should be:

  1. DCS-S1 — narrow proper-noun possession sub-shape expansion (highest lift-per-risk, smallest scope)
  2. DCS-S2 — coordinated counted-nouns (medium lift)
  3. A1 reimplementation (if sandbox config is fixed) — currency_amount with new verbs
  4. Schema-Gap 1 ADR (Rate-in-union) — unblocks 38 follow-up cases
  5. Schema-Gap 2 ADR (apply_rate) — unblocks 2 cases
  6. Schema-Gap 3 — folds into CompositionClaim ADR (FOLLOWUPS §1)

No timelines. Order is by leverage, not calendar.


What this document does NOT do

  • It does not dispatch any agents (per feedback-no-self-dispatch-of-subagents)
  • It does not modify any runtime code
  • It does not add new eval lanes (ADR-0166)
  • It does not propose any non-deterministic mechanism

Cross-references

  • docs/handoff/discrete_count_statement-injector-spec.md — the DCS sub-shape spec
  • docs/handoff/ADR-0167-FOLLOWUPS.md — parent follow-up queue
  • docs/decisions/ADR-0168-frameclaim-ratification.md — FrameClaim scoping
  • docs/decisions/ADR-0168.1-math-frameclaim-proposal-adapter.md — adapter bridge
  • PR #369 — A2's schema-refusal artifact
  • memory/feedback-no-self-dispatch-of-subagents.md — binding dispatch principle