Delete the re-read thrash hard stop (CL-6936) - #558
Merged
TheGreatAxios merged 1 commit intoAug 23, 2026
Merged
Conversation
This was referenced Aug 23, 2026
TheGreatAxios
force-pushed
the
cl-6936-re-read-thrash-hard-stop-at-rereadlimit-4-false-positives-on
branch
from
August 23, 2026 19:49
055690c to
928447d
Compare
reReadLimit 4 hard-stopped a worker for reading one path four times past 8 total tool calls, reported as thrash — a sticky hard block that refuses identical re-dispatch. Read pressure only decayed when a product mutation tool edited that exact path, so reading file A while editing file B, four whole-file reads spread across a long task, and re-running a grep to verify an edit all tripped it on healthy work. The fingerprint period detector in stop-policy.ts already catches a genuinely repeating read cycle, and catches it on the evidence that it repeats rather than on a raw count. Re-read counting is strictly weaker and its verdict is more severe, so this deletes it rather than retuning the number. - thrash.ts keeps only near-budget force-report plus the read/edit bookkeeping that requireEdit / requireEvidence consume; the edit-decay of read counts goes too, since an edit erasing read evidence could only ever weaken the requireEvidence check. - "thrash" and "re-read-nudge" leave SubAgentStopReason/ForcedStopReason and the SubAgentDirector wiring; the Summary-substring classifier in brief-dispatch.ts is left for CL-6939. Net -487 lines.
TheGreatAxios
force-pushed
the
cl-6936-re-read-thrash-hard-stop-at-rereadlimit-4-false-positives-on
branch
from
August 23, 2026 19:57
928447d to
d9efb08
Compare
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.
Closes CL-6936.
reReadLimit: 4hard-stopped a worker after four reads of one path (or four identical greps) past 8 total tool calls, reported asthrash— aHARD_BLOCK_SALVAGESclass, so sticky for the session and refusing identical re-dispatch. Read pressure only decayed when a product mutation tool edited that exact path, so all of these tripped it on healthy work:Justification, corrected after review
The original framing here claimed this stop was redundant with
detectToolFingerprintThrash. That is not true, and the PR should not rest on it: that function's only consumer is the primary director (src/agent/director.ts), leaf workers never call it, and its history excludes any turn carrying text. A leaf readingA,B,A,C,A— or narrating between reads — was caught by the deleted counter and is caught by nothing now except the turn budget.The honest justification is that the population this counter could legitimately catch barely exists. A scan of 3,796 local runs found 466 clusters of 4+ reads on one path:
(offset, limit)windows of one large file, forced by our own 80k result cap telling the model to paginate (filed as CL-6961). These never tripped this counter, sincereadKeyalready keyed chunked reads separately.So the counter's real target is a fraction of a percent of runs, mostly synthetic, while its cost was a sticky hard block on healthy workers. Deleting it and leaving the turn budget as the backstop is the right trade. Building leaf-side cycle detection for that population would be paying architecture for a rounding error; if it is ever wanted, the cheap version is to reuse the compactor's
path+offset+limitread identity rather than counting paths.Deleted rather than retuned:
detectToolFingerprintThrashalready catches a genuinely repeating read cycle, on the evidence that it repeats. A raw count cannot separate four reads across real progress from four reads in a loop, and its verdict is the more severe of the two.What changed
thrash.tskeeps near-budgetreport-forcedplus the read/edit bookkeepingrequireEdit/requireEvidenceconsume.reReadLimit/reReadSoftLimit/reReadMinTotalTools,thrashFromReRead,thrashSoftReReadare gone.readCountsis now therequireEvidencerecord, so an edit erasing read evidence could only ever weaken that check."thrash"and"re-read-nudge"leaveSubAgentStopReason/ForcedStopReason,forcedStopReport, and theSubAgentDirectorwiring (RE_READ_NUDGE_*,reReadNudgeFired).progressive thrashSummary-substring classifier inbrief-dispatch.tsis deliberately left in place — CL-6939 owns the matcher deletions.Net -487 lines with no coverage loss on the surviving behavior.
Verification
bun run checkgreen: 5262 pass / 0 fail across 377 files.Improvement in false-positive rate cannot be measured until CL-6938 lands — that is the gate on claiming an improvement, not on making the deletion (redundancy is the justification here, and no threshold was changed).
Review
needs-sawyer-review— Guardrail 4: touches stop/nudge policy. Not for auto-merge. Per eval policy this diff materially touches stop/nudge policy, so it wants an eval matrix run before merge.Review fix applied:
docs/PRODUCT.mdstill listed "thrash" in the same-brief hard-block salvage list; this branch deleted the thrash hard stop so nothing produces that salvage anymore. Dropped "thrash / " from the sentence.