Repository navigation
measure: relaunch to the first live chat event (relaunch-reconnect bench) - #34697
Conversation
A bench that quits and relaunches a bench build with 6 local agent chats, one streaming, in three modes (warm, update: bundle replaced so the daemon is handed off, cold), and records each phase from process start to the shown chat's first live event. Launch marks for the acpmux lookup (start, adopted, status, handoff, spawn, end) and the pane's transport open; the page records its connect path on the wall clock and its first live event (perf.ts launchTimeline). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cb01117327fc358e9ba1
…wer scenario) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cb01117327fc358e9ba1
…name the daemon they found Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cb01117327fc358e9ba1
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Stale: these images are of Gallery before/after for
States
Pick other states with a Passes: CI passes on CI passes on Written by red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base 2e0b6ac; does not block Shipped in:
|
teamleaderleo
left a comment
There was a problem hiding this comment.
Review (codex gpt-6-astra high, next-review, since=20261104T032722Z): SHIP at e8e06a6
SHIP at e8e06a6
Visual verdict: unchanged by this diff
- [P2] [follow-up] [category:correctness] [finding:F1] [outcome:pending] Reestablish a live stream before each measured quit.
scripts/cmux-next/bench_relaunch_reconnect.py:244reuses one streaming turn across every round and mode without checking that it remains active. If an update round loses that turn—as the PR’s daemon logs suggest—subsequent cold rounds measure an idle chat that cannot produce another event, falsely attributing the timeout to cold reconnect. Verify fresh streaming activity before each quit; restore the load outside the measured interval or mark dependent rounds invalid. A mocked run confirmed the loop continues after a timeout without restarting the stream.
Python syntax checks passed. Runtime tests were unavailable here because the harness requires macOS libraries and Bun is absent.
Follow-ups:
- Reestablish and verify the streaming precondition for each round.
|
Review (subagent opus-5.5 medium): SHIP at e8e06a6 Visual verdict: unchanged by this diff (no UI). Checked: Swift 6 isolation of the now thread-safe Follow-ups:
|
|
Review (codex, router-review): SHIP at e8e06a6 Reviewer: codex gpt-6.1-sol xhigh, fast tier. Follow-ups: 2. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at e8e06a6
Follow-ups:
|
aad08e5 to
e8e06a6
Compare
|
Review (codex gpt-6-astra high, router-review range): SHIP at e8e06a6 Visual verdict: no images (range review of a measurement-only change). Follow-ups:
|
|
Found 6 test failures on Blacksmith runners: Failures
|
…ng down) from its log, before the relaunched process starts Follow-up F1 of the #34697 range review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cb01117327fc358e9ba1
A newer verdict blocks 7124dfb (no independent SHIP at the head).
|
Review (codex, router-review): SHIP at 7124dfb Reviewer: codex gpt-6-astra high, fast tier. Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at 7124dfb
Follow-ups:
|
… earlier relaunch lost its turn Follow-up F1 of the #34697 review (#35091). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-cb01117327fc358e9ba1
|
The crash ratchet is red on the feat-cmux-next tip from this PR: |
…ratchet, #34697) (#35106) AgentPaneLaunchTimings (added in #34697) copied DaemonLaunchTimings, which declared @unchecked Sendable. Both hold only a Mutex of their state and an OSSignposter, and both of those are Sendable, so the compiler can check the conformance. Drop @unchecked from both: CmuxNextAgentPane unchecked goes from 3 back to 2 (the tip red), and CmuxNextDaemon from 4 to 3 (baseline row lowered so the copied pattern cannot come back). mark() is unchanged: one lock, no new allocation.
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Leo, 2026-11-04: "i feel like the restarted after nightly update does too many layout shifts/flicker renderings and takes too long to reconnect acpmux or whatever". This is the reconnect half (data: manaflow-ai/cmuxterm-hq#6338); restore layout shifts are a separate PR.
What this adds
A relaunch-reconnect scenario in the shared perf harness, beside idle-chats:
bench_power.py --scenarios relaunch-reconnect(scripts/cmux-next/bench_relaunch_reconnect.py), run on the fleet through the existing entry:It opens 6 local agent chats on the app's own acpmux (the test agent), one streaming 10 words a second and shown. Then it quits (Quit and Keep Sessions) and relaunches 3 times in each mode:
Each round records every phase, in ms since the relaunched process started, from process start to the shown chat's first live event.
Marks added for it:
debug.timings), for the acpmux lookup (start, build homes adopted, status answered, bundled build read, handoff, spawn start/ready, end) and the pane's transport open (start, listener checked, accepted checked, open). A lookup of a daemon the app does not start is markedacpmux.other.*.AgentPaneLaunchTimingsnow takes marks from any thread, since the lookup runs on the host actor, the wayDaemonLaunchTimingsalready does.process_start_epoch_msindebug.timings, so page marks line up with the launch marks.perf.tslaunchTimeline, read bydebug.agent_pane perf_statsaslaunch): first handshake start, handshake answered, connect start, connected, first event of the shown chat, and first live event. A live event is one that arrives within 1 s of when acpmux recorded it, so a replayed backlog does not count.The daemon log since the quit is kept per round.
What it found
These are medians, ms since the relaunched process started. Same harness, Mac16,11 display worker, at e8e06a6 (3 rounds per mode):
SIGTERM (a restart handoff)) or for the cold mode, and the next one starting about 6 s later. 120 s is acpmux's adoption replay ceiling (hub/hosts.rsREPLAY_CEILING). After that, the next quit's daemon finds no turn to keep it ("nothing used the daemon for 2s: no client, agent, turn or task"). The fix is a separate PR with a red/green test.AcpmuxPersonKey.enroll). It costs about 100 ms here, but every adopted agent goes through adoption again. This is a follow-up.main. This is the first launch of a new copy of the bundle, which macOS checks. It is outside the app.Performance
This PR changes no behavior. Its numbers are the baseline above. Its own cost is a handful of timestamps, each recorded once per launch or once per page, plus one
Date.now()compare per event of the shown chat until its first live event.Red/green
bun test test/agent-pane-launch-timeline.test.ts(webviews): at base it fails withTypeError: perf.markLaunch is not a function. Both tests pass at head.Risk: low. The Swift adds launch marks (signpost events plus a first-time-per-name mark) on the acpmux lookup and transport open paths.
AgentPaneLaunchTimingsbecomes aSendableclass with a lock, the same shape asDaemonLaunchTimings. The page marks are stored once per page.bench_memory.launchcan relaunch into an earlier launch's scratch; its default path is unchanged.Observed / Not run
scripts/web-lint.sh: its only failures arecheck:design-tokens(subagents.css) andvp fmt --check(cloudRun/cloudStartProgress), all in files this PR does not touch, red on base 660552b.prepush-gate.py(clean).Changelog
Agent session: agent session
🤖 Generated with Claude Code