Repository navigation
Keep the Bot queued-message retry pause when its timer fires early - #683
Conversation
… early The retry timer opened the pause outright when it fired. A busy event loop schedules timers from a stale loop time, so the timer can fire before the classifier's own clock reaches the end of the pause, and the next frame then classified again too soon. That is the live-projection 'retries are throttled' flake seen on many PRs' macOS runtime-subagents lane. The pause is now set only when a classification fails or comes back incomplete, and an early timer waits out the remainder before asking for a retry. A new test drives the classifier with a clock that lags the timers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018VA6RFoM21JGeMe45njSXW
Hermes Review BotConfidence: 4 Engine: SummaryThe change reworks the queued-message classifier's retry timing in Confidence Score: 4/5Every branch of 📁 Important Files Changed
FindingsNo findings. 📊 Sequence DiagramsequenceDiagram
participant Caller
participant Classifier
participant Timer
Caller->>Classifier: personal(docs), now >= notBefore
Classifier->>Classifier: classify() fails / id unanswered
Classifier->>Classifier: notBefore = now() + retryMs
Classifier->>Timer: armTimer(notBefore - now())
Note over Timer: fires before now() reaches notBefore
Timer->>Classifier: remaining > 0, armTimer(remaining)
Note over Timer: fires at or after notBefore
Timer->>Classifier: remaining <= 0, deps.retry()
Classifier->>Caller: requeue -> personal(docs)
Machine-Readable Findings[]
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes in the shared queued-input classifier and its regression coverage, including desktop and Remote callers.
- Stable retry deadline: Failed or incomplete classification starts the pause; incoming frames no longer extend it.
- Early-timer handling: The timer checks the classifier's clock and waits out any remainder before requesting another projection.
- Deterministic regression coverage: The new test verifies that an early timer neither permits classification nor requests a retry, then confirms recovery at the deadline without another frame.
- Validation: All 144 desktop and Remote session tests passed, as did
npx tsc --noEmitand ESLint on both changed files. Native consumers were inspected but native mobile suites were not run; hosted CI was still pending/in progress when checked.
gpt-6.1-sol | 𝕏
|
Electron E2E (2/3) failed on Generated by Claude Code |

What
The Bot live view classifies queued messages, so a routine's input stays hidden and the person's own message is listed. When classification fails, it pauses for
classifyRetryMsbefore trying again. When the retry timer fired, it opened that pause outright (notBefore = 0).Node schedules timers from the event loop's cached time. On a busy loop, a timer can fire before
now()reaches the end of the pause, so the next frame classified again too soon. That is thelive-projection.test.ts"retries are throttled, saw 3 calls" failure. It is a real bug, not only a test timing problem: under load, a failing classification is retried faster than its pause.Change
notBefore) is set only when a classification fails or comes back incomplete. Frames that arrive during the pause no longer push it forward.retry().Tests
live-projection.test.tscase: "a retry timer that fires early never opens the classification pause before its time". It drives the classifier with mocked timers and a clock that lags them. It fails on the old code (a second classification inside the pause) and passes now.live-projection.test.tspasses locally (54/54).tsc --noEmitand eslint pass on the touched files.Flake record (why this PR exists)
The "while classifying fails, a cached routine stays hidden…" test failed on macOS
Desktop tests (runtime-subagents):No doc changes: this is internal retry timing with no user-facing behavior change.
Generated by Claude Code
Flaky test record
tests/e2e/workspace-panel.spec.ts:436"browser creation and background selection preserve address focus while strip navigation moves it" failed in Electron E2E (2/3): the browser address field stayed "inactive" instead of focused for 10 s, and passed on retry, so--fail-on-flaky-testsfailed the job. This PR changes only the live-projection classifier timer. Failed job; failed jobs rerun once.Generated by Claude Code