Repository navigation
fix(bot-mode): pin the stranded-reply harvest window to the turn hard cap (contract + coverage) - #113313
Closed
Finn763 wants to merge 1 commit into
Closed
fix(bot-mode): pin the stranded-reply harvest window to the turn hard cap (contract + coverage)#113313Finn763 wants to merge 1 commit into
Finn763 wants to merge 1 commit into
Conversation
Author
|
Closing: this branch already exists from my earlier attempt (PR #107193, |
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.
Read this first: the behaviour the issue reports is already fixed at
HEADThe 60-tick / 5-minute harvest window that loses late replies is gone on this base: upstream
e80642df6003("keep group follow-ups ordered and late answers visible") replacedHARVEST_MAX_TRIES = 60with an inline bound derived from the turn hard cap —Math.ceil((GROUP_TURN_HARD_CAP_MS + 60000) / HARVEST_INTERVAL_MS)≈ 252 ticks ≈ 21 min. That commit itself cites the harvest-budget approach from #107193, so the fix for the reported symptom is in. On a pristineHEADthe behaviour tests are green; only a test for the not-yet-extracted helper is red.So this PR is not a behaviour flip — and it does not pretend to be one. What was genuinely missing:
groupStrandedHarvestMaxTries(intervalMs) = max(60, ceil((hardCap + 60s) / interval)), exported fromgroup-turns.ts(whereGROUP_TURN_HARD_CAP_MSis declared) and consumed by the harvest watcher ingroup-rounds.ts. Window and cap can no longer drift apart silently — which is precisely how the original 5-minute value survived against a 20-minute cap in the first place.group-rounds.harvest-window.test.tspins a busy member whose reply lands past the old five minutes (the reported loss), the new bound (watch length ≥ hard cap), and the stopping conditions. The strand marker mechanism and every non-stranded path are untouched; no scheduler was added.Evidence
RED → GREEN (my own sabotage, not the author's): forcing the helper back to the issue's old value (
return 60) fails 3 of 94:With the delivery assertion held back, the reported symptom fails verbatim too (
expect(await watch.tryTick()).toBe(true)→expected false to be true— the watch had already given up, so the late reply never reaches the room log). Restored → 94/94 passed.The in-window protection case (a reply inside five minutes is delivered exactly once) stays green under sabotage. No unstoppable loop: the bounded-watch case throws
the harvest watch never stopspast 1000 ticks and then assertswatch.pending()).toBe(0); the settled/consumed case asserts no timer is left scheduled; a room with nothing stranded asserts the watch was never armed.tsc --noEmit: 0 errors undersrc/plugins/hermes-bots.(The desktop
node_modulesjunction was repointed at a sibling tree's real install for these runs and restored to its original target; the worktree is clean.)Refs #105247.
Not done
turnTimeoutMs/turnHardCapMs/spawnRetries/spawnRetryDelayMs) not added.session.resumesnapshot reports a detached/reaped session with no new messages; the watch is not re-armed after a Stop-superseded drive or a renderer reload with durable markers.eslintis not installed in the borrowed tree, so the plugin hygiene suite stood in for lint.