Repository navigation
Conversation
Typing for a mention run stopped 30 minutes after its first pulse, even while the agent kept working, so a long goose turn looked like it had dropped. The half hour is now an idle limit: every step the run reports, and every mention that joins the shared pulse, starts it again. A run that goes quiet for half an hour still stops typing; settling and aborting end it as before. Co-authored-by: claude00 <fb8b76a01257932b8ca35060862c29bd09b2137638573731c2d5074fc02c5385@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4f9addaabc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| active: () => { | ||
| if (!stopped && joined) joined.active = Date.now(); | ||
| }, |
There was a problem hiding this comment.
Restart typing when activity follows idle expiry
When a tool call lasts longer than IDLE_MS, pulse() stops its interval and removes the shared entry, but this active() callback still updates the now-detached joined object. Consequently, the next reported step cannot restart typing, and the agent remains permanently silent for the rest of the turn even if it continues through many subsequent tools. Rejoin or recreate the conversation pulse when activity arrives after expiry.
Useful? React with 👍 / 👎.
| /** A run that shows no activity for this long stops looking busy, so one that | ||
| * never settles does not type forever. */ | ||
| const IDLE_MS = 30 * 60_000; |
There was a problem hiding this comment.
Update the documented typing timeout semantics
This changes the timeout from an unconditional 30-minute cap to 30 minutes since the latest step or joining turn, but docs/agents.md:478-485 still specifies that typing stops “after 30 minutes.” That owning lifecycle documentation now gives runtime maintainers and reviewers the wrong protocol behavior; update it to describe the idle timeout and its reset conditions.
AGENTS.md reference: AGENTS.md:L76-L79
Useful? React with 👍 / 👎.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/user flows) reviews.
No required code changes found; 9/10 for the stated scope. Reviewed head 4f9adda against base 16ca8d3.
The shared activity timestamp and runner step wiring address active turns crossing the old absolute cutoff. I checked all four changed files, the Goose/Claude/Codex step producers, reference counting, stop-before-join, settlement/abort, slow publication and the three-failure cutoff. The existing pulse owner and interval are reused; no new timer is added. The added fake-clock tests cover idle expiry, activity, joining turns and service wiring. No changed focus/interaction controls were found. The public description has no attachments; no disclosure issue found in the reviewed description/diff/commit.
Optional documentation clarification: expand the Known gap to say that after 30 idle minutes, typing stays off for the rest of that turn even if later steps resume. In typing.ts:87–89, activity updates the retired shared entry; it does not recreate the cleared interval. A later mention creates its own pulse. This retains the prior terminal-cutoff behavior and is not a request to expand this fix. docs/agents.md:483–485 also still describes the cutoff as simply “after 30 minutes”; “after 30 minutes without reported activity” would match this change.
Validation limits: source-only; no tests, builds, app launches or live relay/runtime execution performed. A single hosted-check snapshot showed both JavaScript jobs and Vitest flake checks passing, but WebKit shard 1/9 and CI required failed. The failed shard had 89 passes and one failure: channel-archive-delete-pane.spec.mjs:350 expected the Close Channel settings tab button to regain focus. Its relationship to this change is unestablished; this review does not establish green CI or merge readiness. Long-tool/repeated-Goose-step behavior, cross-device display, runtime performance and human acceptance remain unverified. This is a non-blocking COMMENT review, not approval.
Problem
Typing for an agent's mention run stopped 30 minutes after the pulse started, even when the agent was still working. On 2026-10-17 mbot (goose) worked without a break from 18:38, but its typing went away around 19:08 and again around 19:40, so it looked like mbot had dropped. The 30-minute cap (
LONGEST_MS) came in with #998 and was measured from the first pulse.Change
The 30 minutes is now an idle limit (
IDLE_MS). These reset it:stepthe run reports. The runtimes call it on tool calls: gooseGooseSession.update, Claude, Codex.runner.tssends that step to the turn's typing.pulseTypingnow returns{ active, stop }. The last-active time is stored on the shared pulse entry, so activity from any turn in that conversation keeps the pulse alive. Nothing else changes about how pulses are shared or stopped: typing still ends when the last turn settles, when the runner aborts, or after three failed pulses in a row.Tests
typing.test.tsactive()is called, then stops 30 minutes after the last callservice.test.ts: a run that callsdelivery.stepat minute 20 is still typing at minute 40, and stops 30 minutes after that.active, the runner'sstepwiring), and the matching test failed each time.--testTimeout=30000).Known gap
A single tool call that runs longer than 30 minutes reports no steps while it runs, so its typing still stops at 30 minutes. That covers mbot's 19:48 Chromium run under
timeout 3000. goose also skips a step when it repeats the previous one exactly. Fixing either one means the runtime has to report progress during a tool call, which this PR doesn't do.🤖 Generated with Claude Code