Brennan Benson d5ef633adb fix(crash-reporting): stop post-mortem process metrics crowning a survivor as the crasher (#14662)
* fix(crash-reporting): keep a pre-gone process-metrics sample so the crashed process's working set survives its crash report

* feat(crash-reporting): renderer peak/private bytes and gone-time system memory in crash details

* fix(crash-reporting): macOS system-memory fields and an era-invariant pin for peak/private metrics

* test(crash-reporting): kill five mutation survivors in the pre-gone sampler coverage

Adversarial review found these mutations survived the suite:
- dropping the immediate sample at startPreGoneProcessMetricsSampling()
- removing the double-start idempotence guard
- widening renderer peak/private aggregation to all buckets
- a failed sweep erasing the previous good sample
- the recorder hardcoding 'renderer' instead of event.processType

Each now has a binding assertion; also documents that the
crashed-process-absent flag is bucket-level only.

* fix(crash-reporting): prove crasher absence by vanished pid, not bucket count alone

The absent flag was bucket-level, so any surviving same-type process (a
webview guest, the dashboard popout, another utility) silently cleared it
— and webviewTag guests make multi-renderer sessions the norm. The pre-gone
sample now keeps per-process pid/bucket/workingSet identities; a sampled
same-bucket pid missing from the live set proves absence and reports the
vanished process's own working set (processMetricsVanished*), so the
crasher's size is no longer summed with surviving guests.

Also: split gone-time system memory into its own module (max-lines), pin
peak/private aggregation as a true max, clamp garbage negative working
sets and backwards clocks, pin live-metrics precedence over incoming
detail keys, and verify the sampler timer is unref'd by behavior.

* fix(crash-reporting): bucket-aware vanished-pid check with consume-once attribution

Loop-3 hardening of the vanished-pid logic:
- Live pids now carry their bucket: a recycled pid living on as a different
  process type still reads as a vanished sampled process (the bare pid set
  misread the crasher as alive).
- Vanished pids are attributed once. In a crash loop with no sweep between
  deaths, record #2 confidently inherited the FIRST crasher's pid and
  working set (dedupe window is only 2s, so both records ship); it now
  degrades to the honest bucket-count arm instead.
- An ambiguous multi-process VanishedWorkingSetMB sum is bounded by
  VanishedLargestWorkingSetMB so no single-process reading of the sum
  survives triage.
- Killer tests for the remaining mutation survivors: unreadable gone-time
  metrics prove nothing (flag/vanished stay off), pid-less sampled metrics
  never vanish, fractional-MB rounding, negative system-memory clamp, and
  full per-family precedence over colliding incoming detail keys.

* fix(crash-reporting): flag consumed and blind-era vanished attribution instead of going silent

Loop-4 hardening of the consume-once attribution:
- processMetricsVanishedAlreadyReportedCount: a record whose vanished pids
  were consumed by a prior report now says so, instead of being
  indistinguishable from "nothing vanished" while its PreGone mirrors still
  show the prior crasher's era.
- processMetricsVanishedAmbiguousWithEarlierCrash: consume-once only consumed
  when the gone-time read succeeded; a crash recorded blind (getAppMetrics
  threw) left its pid unconsumed, so the next record in the same era
  confidently emitted THAT crash's pid and working set as its own. Blind
  buckets now taint the era until a fresh sweep.
- Pin two behaviors that were correct but unpinned: a failed sweep must not
  clear attribution state, and an ambiguous vanished pair is consumed too.
- Document gone-time system memory reading healthier than at kill time, and
  the bound on the attribution set.
- Split the suppressed-breadcrumb builder into its own module (max-lines).

* fix(crash-reporting): extend vanished ambiguity to consumed eras and pin two unpinned behaviors

Loop-5 findings:
- processMetricsVanishedAmbiguousWithEarlierCrash fired only for the
  blind era; a partially-consumed era has the same shape (an earlier
  crash's unsampled respawn is as plausible a crasher as the newly
  vanished pid), yet emitted a confident VanishedPid with no flag.
- Pin the > largest tie-break (first-enumerated wins) instead of
  re-accepting it as an equivalent mutant every loop.
- The suppressed-breadcrumb type field had zero coverage after the
  module split — removing the whole block passed the suite.

* refactor(crash-reporting): cut per-pid vanished attribution, keep the stateless absence proof

Five review loops found defects in the same subsystem: the per-pid
vanished attribution outputs (consume-once set, blind-era taint,
consumed-era ambiguity). The absence proof they fed does not need any
of it — a sampled same-bucket pid missing from the live enumeration
(including cross-bucket pid recycle) is stateless and idempotent, so
it stays true for every record of a crash loop with zero module-level
attribution state.

Dropped: processMetricsVanished{Count,WorkingSetMB,Pid,
LargestWorkingSetMB,AlreadyReportedCount,AmbiguousWithEarlierCrash},
attributedVanishedPids, metricsBlindCrashBuckets, and the tests that
existed only to defend them.

Kept and still pinned: the 60s pre-gone sampler and its lifecycle,
PreGone* mirrors + SampleAgeMs, renderer peak/private, gone-time
system memory, the recorder processType binding, the live/PreGone era
invariant, and the browser-pane case (webview guests keep the renderer
bucket alive) that motivated the PR — now asserted via the absence
flag plus PreGone mirrors alone. Documented the two honest limits:
PreGone values are sample-time (up-to-60s understatement, bounded by
AgeMs and lifetime peaks), and same-bucket pid recycle inside the
sweep window is a false negative for the absence proof.

* test(crash-reporting): pin PreGoneLargest to the crasher's own size, not the bucket's running sum

Loop-6 mutation battery found one survivor in the cut's re-anchored
suite: mutating Largest to carry the bucket's running sum survived every
test, because no fixture put a same-bucket sibling BEFORE the largest
process. That is the summing-bug family loop 2 found live. The
webview-guest test now enumerates the guest first and asserts
PreGoneLargest{Pid,Type,WorkingSetMB} carry the crasher's individual
4380, alongside the 4680 bucket total.

Also restores the false-positive caveat the cut's comment dropped: a
legitimately closed sampled process can trip the absence flag if the
crasher's row somehow survives the live enumeration (pre-existing,
unchanged by the cut).

* fix(crash-reporting): mark pre-gone attribution ambiguous

PreGone mirrors are whole-app snapshots, so a larger surviving Tab can own Largest and renderer-wide peak/private fields. Emit an explicit ambiguity boundary, prove the counterexample, and use Electron's pid plus creationTime identity to catch same-bucket PID reuse without adding stateful attribution.
2026-08-16 15:43:21 -07:00
2026-07-11 20:53:20 -07:00
2026-05-04 20:42:03 -07:00
2026-03-16 22:27:51 -07:00
2026-03-28 10:19:14 -07:00

Orca Orca

GitHub stars Total downloads across all releases License: MIT Join the Orca Discord Follow Orca on X Supported platforms: macOS, Windows, and Linux

中文 · 日本語 · 한국어 · Español · Français · Português

The AI Orchestrator for 100x builders.
Run Codex, ClaudeCode, OpenCode or Pi side-by-side — each in its own worktree, tracked in one place.

Download Orca

Orca desktop app running agents in parallel worktrees, with the Orca mobile companion app in the corner

Features

Mobile Companion

Monitor and steer your agents from your phone — get notified when an agent finishes and send follow-ups from anywhere.

iOS App Store · TestFlight · Android APK 0.0.43 · Docs →

Orca desktop with the mobile companion app

Parallel Worktrees

Fan one prompt across five agents, each in its own isolated git worktree — compare the results and merge the winner.

Docs →

Parallel worktree orchestration

Terminal Splits

Ghostty-class terminals with WebGL rendering, infinite splits, and scrollback that survives restarts.

Docs →

Terminal splits

Design Mode

Click any UI element in a real Chromium window to send its HTML, CSS, and a cropped screenshot straight into your agent's prompt.

Docs →

Embedded browser and Design Mode

GitHub & Linear, Native

Browse PRs, issues, and project boards in-app — open a worktree from any task and review without a context switch.

Docs →

GitHub and Linear task workflows in Orca

SSH Worktrees

Run agents on a beefy remote box with full file editing, git, and terminals — auto-reconnect and port forwarding included.

Docs →

Remote worktrees over SSH

Annotate AI Diffs

Drop comments on any diff line and ship them back to the agent — review, edit, and commit without leaving Orca.

Docs →

Annotate AI-generated diffs

Drag Files to Agents

VS Code's editor with autosave everywhere — drag files or images straight into an agent prompt.

Docs →

Drag files and images into an agent prompt

Orca CLI

Agents drive Orca too — script every workflow with orca worktree create, snapshot, click, and fill.

Docs →

Script Orca from the CLI

Also in the box:

  • Quick open — Search across worktrees, files, agents, commands, and repo context without leaving your flow.
  • Account switcher & usage tracking — See Claude and Codex usage and rate-limit resets, and hot-swap accounts without re-logging in.
  • Rich repo previews — Preview Markdown, images, PDFs, and repo docs in the workspace.
  • Computer Use — Let agents operate desktop apps and visible UI when a workflow needs real interaction.
  • Notifications and unread state — Know when an agent finishes or needs attention, then mark threads unread to come back later.
  • And many, many more — we ship daily, so this list is perpetually behind. The changelog is the real feature list.

Supported Agents

Works with any CLI agent — if it runs in a terminal, it runs in Orca.

Claude Code logo Claude Code   Codex logo Codex   Grok logo Grok   Cursor logo Cursor   GitHub Copilot logo GitHub Copilot   OpenCode logo OpenCode   MiMo Code logo MiMo Code   Amp logo Amp   OpenClaude logo OpenClaude   Antigravity logo Antigravity   Pi logo Pi   oh-my-pi logo oh-my-pi   Hermes Agent logo Hermes Agent   Devin logo Devin   Goose logo Goose   Auggie logo Auggie   Autohand Code logo Autohand Code   Charm logo Charm   Cline logo Cline   Codebuff logo Codebuff   Command Code logo Command Code   Continue logo Continue   Droid logo Droid   Kilocode logo Kilocode   Kimi logo Kimi   Kiro logo Kiro   Mistral Vibe logo Mistral Vibe   Qwen Code logo Qwen Code   Rovo Dev logo Rovo Dev   + any CLI agent


Install

Desktop — macOS, Windows, Linux

Or via a package manager:

# macOS (Homebrew)
brew install --cask stablyai/orca/orca

# Arch Linux (AUR) — or stably-orca-git to build from source
yay -S stably-orca-bin

Mobile Companion — iOS, Android

Pair with your desktop app to monitor and steer your agents from your phone.


Community & Support

  • Discord: Join the community on Discord.

  • Twitter / X: Follow @orca_build for updates and announcements.

  • WeChat: Scan to join the Orca community WeChat group 7.

    WeChat group 7 QR code for the Orca community
  • Feedback & Ideas: We ship fast. Missing something? Request a new feature.

  • Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.

  • Show Support: Star this repo to follow along with our daily ships.


Developing

Want to contribute or run locally? See our CONTRIBUTING.md guide.

Orca contributors

GitHub star history chart for stablyai/orca

Signed Builds

Windows code signing sponored/provided by SignPath.io, certificate by SignPath Foundation.

License

Orca is free and open source under the MIT License.

S
Description
Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.
Readme MIT
1.5 GiB
Languages
TypeScript 95.2%
JavaScript 4%
Swift 0.2%
CSS 0.2%
HCL 0.1%