feat(llm-reach): the in-pass split-and-retry for dropped batches — a malformed batch re-issued once as two halves, the recovery carrying its own provenance (#558) - #575
Open
gadievron wants to merge 1 commit into
Conversation
…malformed batch re-issued once as two halves, the recovery carrying its own provenance (#558) The post-lift measurement (the issue's step 1, run 2026-09-09): 4 malformed batches in ~95 at the DEFAULT_MAX_TOKENS cap — ALL the end_turn broken-JSON finish class (0 max_tokens; the cap lift eliminated the truncation-at-cap class). The close-out rule failed: the residual is the model's own structurally-broken finishes, a fresh-roll class — re-generation usually recovers. The implementation (the issue's direction 3 — split-and-retry, NEVER the JSON corrector: it cannot recover signals the model never emitted, and on the truncation class it would freeze partial batches as reviewed, defeating absence-as-retry): - a dropped or truncated batch of >= 2 units re-issues ONCE as two halves — smaller outputs (less likely to exhaust a cap or break mid-structure) AND a fresh roll. Bounded: one split level, no recursion; a still-dropped half stays dropped (its units re-run on the next resume via absence-as-retry); - the ORIGINAL drop's counters are REVISED (subtracted) so the halves count their own outcomes — the coverage truth never double-counted; - the recovery's own provenance counters (batches_split_recovered / batches_split_lost, direction 4 — a recovered batch never silently overwrites the units_not_reviewed count); - the recovered halves' units persist checkpoint records (they were reviewed this pass); the still-dropped leave none. The batch loop is restructured into a _attempt() helper (call+parse+ counters per sub-batch) — the same behavior for the non-split paths, with the split at the loop level.
gadievron
requested review from
dgeyshis,
shahar-davidson and
sounil
as code owners
September 10, 2026 19:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The post-lift measurement (this issue's step 1, run 2026-09-09, receipts in the issue comment): 4 malformed batches in ~95 at the
DEFAULT_MAX_TOKENScap — all the end_turn broken-JSON finish class, 0 max_tokens — the cap lift eliminated the truncation-at-cap class; the residual is the model's own structurally-broken finishes, a fresh-roll class. The close-out rule failed → the in-pass recovery proceeds.The implementation (this issue's direction 3 — split-and-retry, never the JSON corrector: it cannot recover signals the model never emitted, and on the truncation class it would freeze partial batches as reviewed, defeating absence-as-retry):
batches_split_recovered/batches_split_lost— distinct counters, surfaced in the step summary; the original drop's counters are revised by the attempt's exact applied deltas (the adversarial review's catch: an inferred-shape subtraction drovebatches_truncatednegative on the max_tokens+prose shape);failed) is deliberately not split — not output-size-shaped; the llm-reachability: provider-exception batches are never counted in batches_dropped/units_not_reviewed — the step report can read success/0/0 for a pass that reviewed nothing #541 counters + the resume own it.Closes #558.
Test plan
7 new tests (the #558 class): full recovery via halves (the counters revised to 0, the provenance counted); the recovered units persist; a 1-unit batch never splits; the mixed half-recovered/half-lost shape (the coverage truth exact); the max_tokens+prose no-brace shape never drives a counter negative (the deltas pin); the usage spans the recovery; plus the 3 old-behavior pins updated (a still-dropped batch needs the halves to also fail).
Verification evidence
pytest tests/test_issue532_llr_resume.py tests/test_issue294_reach_batch_diagnostics.py tests/test_llm_reachability.py -qpytest tests/ -q