Repository navigation
fix(worker-wake): stop inbox nudges from duplicating on a swallowed Enter - #736
Open
abdelnabiii wants to merge 2 commits into
Open
abdelnabiii wants to merge 2 commits into
abdelnabiii wants to merge 2 commits into
Conversation
…nter The nudge delivery sequence wrote the text, waited a fixed 140ms, then wrote "\r" with no check that either write actually reached the TUI. A swallowed Enter left the text sitting unsubmitted in the input box, and the next beat (seeing new mail, or off cooldown) typed a second full nudge on top of it, duplicating it. - Shorten the nudge to one line (hiveNudge.ts): the full "read inbox, move to inbox/.done/, act autonomously" prose is already injected once into every agent's system prompt at spawn, so restating it on every nudge only gave a slow/occluded PTY more text to swallow and more to duplicate when it did. - Add nudgeDelivery.ts: wait 400-600ms for the PTY to echo the typed text (polling, not a fixed guess) before sending Enter; after Enter, confirm the PTY reacted within 500ms; if not, resend ONLY Enter (never the text) with 300/600/1200ms backoff, up to 3 times, then give up. Every phase is logged. - Add in-flight tracking to WorkerWakeWatchdog (markNudging/clearNudging, new 'in-flight' hold) so a second delivery can never start for an agent whose first one hasn't resolved -- the actual mechanism behind the duplication. Tested: 31 new/updated unit tests (nudge-delivery.test.cjs, including the 3-concurrent-agents-one-mid-task scenario; updated worker-wake.test.cjs, hive-nudge.test.cjs), all passing. Full suite: no new regressions (25 pre-existing failures confirmed via git stash, unrelated -- Windows symlink-permission and Electron-runtime tests). tsc --noEmit clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MBNN17AULnHcT97qhTc4ja
Contributor
|
✅ Evidence received. Before and after are both attached. Thanks — this is what makes a PR reviewable in one pass. |
Referenced in the PR description's Before/After sections -- a standalone script (not part of the test suite) demonstrating the swallowed-Enter duplication bug against the removed pre-fix logic, then the same scenario against the real nudgeDelivery.ts showing it confirmed, never duplicated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MBNN17AULnHcT97qhTc4ja
Author
|
@chaitanyagiri friendly ping on this one -- CI is green (before/after evidence check passed) and it's been open since Oct 13. Happy to address any review feedback. Thanks! |
This branch has not been deployed
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
\r) never checked that either write actually reached the TUI. A swallowed Enter left the text sitting unsubmitted in the input box, and the next wake beat typed a second full nudge on top of it -- the reported "stuck in the input box, retries duplicate it" bug.hiveNudge.ts): the full "read inbox, move toinbox/.done/, act autonomously" prose is already injected once into every agent's system prompt at spawn (hive.ts's HIVE PROTOCOL block), so restating it on every nudge only gave a slow/occluded PTY more text to swallow and more to duplicate when it did.nudgeDelivery.ts: wait 400-600ms for the PTY to echo the typed text (polling, not a fixed guess) before sending Enter; after Enter, confirm the PTY actually reacted within 500ms; if not, resend only Enter (never the text) with 300/600/1200ms backoff, up to 3 times, then give up. Every phase (typed/enter-sent/confirmed/stuck/enter-retry/gave-up) is logged viahive.appendLogtolog.jsonl.WorkerWakeWatchdog(markNudging/clearNudging, new'in-flight'hold reason) so a second delivery can never start for an agent whose first one hasn't resolved -- this was the actual mechanism behind the duplication, not just the fixed-delay timing.Caveat (stated plainly, not hidden)
"Check whether the prompt line still holds the text" is done via a heuristic -- did the PTY produce any new output -- not true terminal-buffer inspection; the main process has no headless xterm reading rendered screen state (xterm.js only runs in the renderer). It's strictly better than the old fixed-delay/no-feedback sequence, but not literal line inspection.
Scoped to the main-process watchdog's own nudge path (
nudgeWorker/runWorkerWakeBeat) only. The renderer's separatesubmitToPty(useHive.ts, used for slash commands, seed prompts, work orders -- not just nudges) is untouched; flagging it as a known follow-up rather than silently leaving it inconsistent.Before
Old delivery: a swallowed Enter left the nudge text sitting unsubmitted, and the next beat retyped it -- duplicated in the input box. Reproduced in

evidence/demo-nudge-fix.cjsagainst the removed pre-fixnudgeWorkerlogic:After
Fixed delivery (nudgeDelivery.ts, this PR): the same swallowed-Enter scenario now retries Enter alone, confirms the PTY reacted, and never retypes the text:

Test plan
test/nudge-delivery.test.cjs(6 tests, including a 3-concurrent-agents-with-different-retry-depths scenario)test/worker-wake.test.cjs(added in-flight coalescing tests, incl. "3 agents nudged at once, one mid-task")test/hive-nudge.test.cjsfor the shortened textnode --test test/*.test.cjs: 970 tests, 25 pre-existing failures (confirmed viagit stashto fail identically without this change -- Windows symlink-permission and Electron-runtime tests, unrelated)npx tsc --noEmit -p tsconfig.node.json: clean🤖 Generated with Claude Code
https://claude.ai/code/session_01MBNN17AULnHcT97qhTc4ja