Uh oh!
There was an error while loading. Please reload this page.
refactor(desktop): collapse two observation clocks into one 60s clock - #692
Conversation
Merges SESSION_REFRESH_INTERVAL_MS (was 5s) and BRAIN_ROSTER_WAKE_INTERVAL_MS (was 60s) into a single 60s observation clock. The brain's roster look is now driven by the observation pass's completion (afterRun) rather than its own independent timer. **Behavioral changes to call out** The roster look now runs under observationGate (runMode.observesProviders && accountCapabilitiesActive()). BrainAgent's own timer was not subject to this gate. That is believed correct — a brain looking at a roster nobody is observing is odd — but it is a deliberate change. **Act validation staleness (fix)** brainActableSessions() is validated "at the moment of the act". At 5s that was roughly true; at 60s an act could be validated against a roster up to a minute old. The fix: performSession now calls refreshSessions() before reading the session list, triggering a fresh observation pass. This applies to all session acts (messages, renames, controls/deletes, creates, opens). For creates and opens the staleness of the session list is less critical, but a fresh pass also updates the project offers they validate against, so the overhead is justified. If the observation loop is already running, refresh() queues the next pass and returns immediately; the validation then uses the most recent completed pass's data, which is close to fresh. **CREATED_WORKSPACE_OPEN_WINDOW_MS** Widened from 2 minutes to 5 minutes. At 60s intervals, 2 minutes gave only 2 chances for a newly-created workspace to be reported with an address. 5 minutes gives 5 chances, matching the tolerance for providers slow to publish their deep link. **broadcastCodexCloudConnection** Still rides afterRun with nothing else behind it. Codex CLI login changes now take up to 60s to propagate. This is acceptable — the user logged in or out by hand, and a 60s delay in noticing does not affect anything safety-bearing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 809900c. Configure here.
| // is closed (observesProviders && accountCapabilitiesActive()). | ||
| afterRun: () => { | ||
| void broadcastCodexCloudConnection(); | ||
| brain?.rosterLook(); |
There was a problem hiding this comment.
Hook wakes split from roster looks
Medium Severity
Hook handling awaits refresh() and only then calls wake(), but afterRun now starts rosterLook() as soon as that pass finishes. The look runs first, reads live transcripts and advances cursors, while the hook events are still queued. Those wakes then open a second turn with empty deltas, so the hook kind no longer rides with the transcript it belongs to and the brain pays for two turns instead of one.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 809900c. Configure here.
Uh oh!
There was an error while loading. Please reload this page.


Summary
SESSION_REFRESH_INTERVAL_MS5 000 → 60 000. TheBRAIN_ROSTER_WAKE_INTERVAL_MSconstant andBrainAgent's internal timer are removed entirely; the roster look is now driven byafterRunon the observation pass instead.BrainAgent.rosterLook()replacesstart(): the host calls it after each observation pass completes;start()/stop()are simplified —stop()remains to drain the queue at shutdown,start()is gone. The agent remains fully testable without Electron.performSessioncallsrefreshSessions()(→sessionObservationLoop.refresh()) before reading the session list. A fresh pass before every session act closes the staleness window from ≤60 s to effectively zero for messages, renames, controls (including delete), creates, and opens. If the loop is already running,refresh()queues the next pass and returns immediately; validation then uses the most recent completed-pass data, which is close to fresh.CREATED_WORKSPACE_OPEN_WINDOW_MS: 2 min → 5 min. At 60 s per pass, 2 minutes was only 2 chances; 5 minutes gives 5, covering providers that are slow to publish a deep link.Behavioral changes
Observation gate on the roster look (deliberate)
The roster look now runs inside
afterRun, which is only called whenisCurrent(generation)holds — meaningrunMode.observesProviders && accountCapabilitiesActive().BrainAgent's own timer was not subject to this gate. That is believed correct — a brain looking at a roster nobody is observing is odd — but it is a deliberate change from the previous behaviour where the timer ran independently.Codex CLI login latency
broadcastCodexCloudConnection()still ridesafterRunwith nothing else behind it; Codex CLI login changes now take up to 60 s to propagate. This is acceptable — the user manually rancodex loginorcodex logoutin their own terminal, and a 60 s delay does not affect anything safety-bearing.All session acts refresh, not only writes
The fresh pass fires before creates and opens too, not only before messages, renames, and deletes. Creates validate against project offers (which the refreshed adapters also update); opens and read-transcript are read-only but cheap to gate. The overhead of one extra observation pass per brain act is acceptable given the correctness benefit at 60 s intervals.
Test plan
./scripts/check.shpasses: 0 errors (20 pre-existing CSS specificity warnings in unchanged files), all 798 desktop tests pass, 34 brain tests pass, 57 session tests pass, all typechecks clean🤖 Generated with Claude Code
Open workspace in Conductor
Open in Alchemize
Automated visual evidence
Download the deterministic macOS evidence · workflow run
809900c5f5dca85442e14d8952b84b1ac6b4798esmoke