Repository navigation
feat(performance): ship local evidence, history, and profiling - #958
Merged
Merged
Conversation
Address both round-1 reviews of the monitoring system: - Register windows at creation; per-scope incident captures; loss is coverage, not an incident; staleness judged on receive and source clocks. - Drain all queued batches before the quit flush; worker persists final interrupted captures and open rollup buckets; Clear History resets in-memory evidence and histograms. - History store: in-memory index, coalesced bounded writer, peak rollups, threshold compaction, expired run deletion, torn-tail repair, age and coverage resolution, per-run report operations, app-owned export scratch. - Bounded query FIFO with refunded query timeouts; validated limits; producer loss generations; threshold producer flushes. - First-output armed by provider acceptance; local-only renderer cancel. - One transcript.parse observation per read call. - Heap snapshot picker, app-owned capture scratch swept at startup, and palette commands that open Recordings with path and Reveal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
Reading `delivery.acceptance.kind` threw for a provider result without acceptance, and the surrounding catch turned a successful delivery into a transport failure. Read acceptance defensively so instrumentation can only observe the outcome, never change it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
History safety: gate retention on a completed startup index, index each file independently, re-arm tail repair after a failed append, recreate a missing run folder, and never truncate a destination on cross-volume moves. Incident accuracy: key captures by rule and scope, detect windows that hang before first show (15 s boot grace), deliver heartbeats and main samples in a priority lane, ignore silence right after dropped records, handle wall-clock rollback in the engine and rollups, and baseline the first loss count. Helper resilience: abandon slow queries instead of killing the helper, admit only the flush during shutdown, abandon an in-flight export at quit, and rebuild incident details only when their summary changes. Loss is tracked per producer generation. The Timeline never shows a page for another range and retries while paused. Clear History reports its outcome. First-output timing starts at Enter for every provider and is settled once. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
Stall detection now excuses a missing heartbeat only for loss that can hold heartbeats (priority-lane evictions and failed batches) and only for one staleness interval, so unrelated drops cannot hide a frozen renderer. Report exports and history clears are never abandoned at their deadline; the helper is restarted instead, and in-memory evidence resets only after a clear succeeds. Clear History distinguishes "not sent" from "sent, unconfirmed". A scan that never answers restarts the helper instead of stacking stuck reads. Rollups merge only small backward clock steps, readdir errors other than ENOENT are no longer treated as "no runs", a run pruned mid-write is never recreated, and Codex submits are always settled in main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
Shutdown no longer abandons an in-flight export or history clear: the flush waits for it through the drain window and is skipped if it never replies, so a quit cannot re-persist cleared history or race an export onto the user's file. Clear History reports "sent" only once the request was dispatched. A failed partial clear forces the next snapshot to rewrite surviving incidents and operations, and current-run incidents are mirrored in memory only after their write succeeded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
Resolve the single conflict in src/main/index.ts by keeping both additions at window creation: the app.startup timing observation, then the extension platform's startup activation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M
Juliusolsson05
added a commit
that referenced
this pull request
Sep 20, 2026
Main gained three quit-time owners after this branch was cut, and each had to be placed in the committed-shutdown composition rather than left on before-quit, which runs before the renderer's unload vote: - The extension runtime (#577). Its PAUSE stays on before-quit: it is the one preparation that must finish before windows unload, and it is reversible (Keep Editing resumes it). Its disposal is a new committed stage, `stopExtensions`, which runs beside sessions and workflows — extensions run user code — and only AFTER startup settles, because startup creates the runtime and an earlier stop would complete against nothing and keep that receipt. - The performance monitor and trace drain (#958), with its 1.8s/2s bounded race, folded into the `performance` stage. Main also ran monitor/watchdog/performanceService stops in will-quit; those are already stages here, so the duplicates are dropped. - tmux recovery now goes through restoration's canonical envelope decoder. A quit committed mid-read must not authorize killing tmux sessions, so the startup assertion moved inside the reader, where it becomes the decoder's read-failure path and withholds cleanup. `workflowShutdownPromise`/`Complete` are gone with the before-quit handler that used them; workflow stop is a committed stage. The shutdown diagram was rewritten as a flowchart in main's current convention (accTitle/accDescr/scope, #954) and says what the composition actually does: the editor decides first and Keep Editing leaves every service live; only a committed quit stops execution; a failed stop keeps the app and its process lock. Re-rendered with the pinned toolchain; every other SVG restored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 20, 2026
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.
The existing live dashboard explains current load, but it cannot answer what made an earlier interaction slow or collect a bounded diagnostic artifact. This change completes the local performance system: Agent Code continuously retains bounded metrics and incident evidence, exposes history and profiles in the Performance monitor and command palette, and saves privacy-filtered reports only to a destination the user chooses.
What changed
Reports are local-only. There is no upload or sharing path, and reports exclude prompts, transcript text, paths, audio, environment values, stacks, credentials, and raw run IDs.
Review round 1 resolutions
Two reviewers (correctness and performance) reported 26 findings on
fd14a227. All valid findings are fixed in this head:limitis validated. The timeline keeps its last page when a read is delayed. (Round 2 replaced crash-budget refunds for slow queries with query abandonment.)transcript.parseis one observation per read call instead of one per line.Review round 2 resolutions
Two reviewers re-reviewed
43cefe77. Both requested changes, with no blockers. All valid findings are fixed:Review round 3 resolutions
Both reviewers confirmed their round-2 findings as resolved on
6db43987and reported follow-ups. All valid follow-ups are fixed:Validation
tsc -b(node + web projects)npm run build,npm run smoke:monitoring(three consecutive packaged-helper runs),npm run benchmark:monitoring(100,000 records, 1.458 µs p99, zero drops),npm run qualify:monitoring(all 120 maximum-fleet process generations, zero process-record drops, queue and batch bytes below 2 MiB).The cold Electron/Node helper measured 67.94–68.06 MiB RSS, below the revised 80 MiB helper target documented in the qualification record. Eight-hour active use, 24-hour disk growth, signed arm64, and Intel measurements remain rollout qualification evidence.
Closes #956
Part of #944
🤖 Generated with Claude Code
https://claude.ai/code/session_01WKUB1nGkTZW1BhtNSXuR6M