fix(gateway): keep timeout messaging accurate when an approval send is in flight#805
Conversation
fro-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS
The fix is well-reasoned and correct. The pending-visibility counter pattern solves the race cleanly: mark in-flight synchronously, settle on resolution, retract on failure. The one-shot guard on the settle handle prevents double-decrement. The classification ordering (flush first, then read hasVisibleOutput()) is preserved correctly.
Blocking issues
None.
Non-blocking concerns
-
onDeadlineSettledmarksvisibleOutputSentonly when the send succeeds. Inrun.ts:402-407,onDeadlineSettledcallssafeSendthensink?.markVisibleOutputSent(). IfsafeSendrejects,markVisibleOutputSentis never reached — which is the correct behavior (the comment "markVisibleOutputSent AFTER the send succeeds" is accurate). No action required; just noting that the comment is the spec. -
Two separate pending claims per
onPendingevent. The waiting-status send and the embed send each callmarkVisibleOutputPending()independently (correct — two sends, two claims). The one-shot settle guard keeps this safe, but a future third fire-and-forget send inonPendingwithout a matching pending claim would undercount. Low risk given the narrow call site. -
sinkcaptured as nullable inonDeadlineSettledclosure (sink?.markVisibleOutputSent()). By the timeonDeadlineSettledfires,sinkis guaranteed non-null. The optional chain is defensive but harmless.
Missing tests
None. The test matrix is comprehensive: pending-unresolved, send-rejects, send-resolves, no-approval baseline, flush suppression while pending, concurrent handles, one-shot settle, double-settle first-wins, and the onDeadlineSettled path. All 846 tests pass.
Risk assessment (LOW): Change is narrowly scoped to one counter and two call sites in onPending. The one-shot settle guard protects counter arithmetic. The only observable behavioral change is in the timeout-messaging path during the specific race window. No new async coordination surfaces added; existing releaseLock/concurrency finally-block invariants are untouched.
Run Summary
| Field | Value |
|---|---|
| Event | pull_request |
| Repository | fro-bot/agent |
| Run ID | 27081751827 |
| Cache | hit |
| Session | ses_15fd38f0fffe9AXBlnKxIQTmVg |
Summary
Follow-up to the v0.55.3 timeout-messaging fix. When a Discord mention run times out while an approval or status message is still in flight to Discord, the timeout copy could fall back to the "no output" wording even though the approval marker lands moments later — and in the worst case the user could see both the "no output" line and the "posted updates above" line together.
What changed
A timeout is still treated as a failure — this only makes the messaging accurate.
Tests