The free windows-11-arm and macos-15-intel lanes already set the matrix's wall
time; the paid 8-vCPU Blacksmith Windows lane finished minutes earlier for ~$48/day.
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
check:changed --base=<ref> resolved a merge base for the gates it drives
directly, but the flaky-test ratchet subprocess re-derived its scope from
origin/main. On a checkout whose origin is a stale fork that pulled in
unrelated files and could fail the run. check:changed now forwards its
merge base via ORCA_CODE_QUALITY_BASE (the env the other changed-code
gates already honor), and the ratchet uses it before falling back to
origin/main.
Fixes#33763
Co-authored-by: Neil <neil@stably.ai>
Both arch jobs overlapped ~2.5 min of setup with qualification, then polled
for the template for 400-560 s on the most expensive runner we use.
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Pin commit.gpgsign=false and tag.gpgsign=false in the throwaway repos
built by the release script tests so a global signing config cannot turn
lightweight fixture tags into annotated tags that abort with
"fatal: no tag message?".
The runs API serves at most 1000 results per query. On 2026-10-27 one hour
crossed that and the daily report threw. Halve any oversized interval until
each query fits.
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* feat(wsl): let an idle WSL distro stop once its orcad idle-exits
The WSL host's holder kept the distro (and the WSL VM) running after Orca quit, even with
nothing running in it. orcad now leaves a release request in ~/.orca when a managed idle stop
retired its terminal daemon; the holder waits for that orcad to exit, claims the request and
ends, so WSL can stop the distro. Live terminals, working agents, enabled automations or a
returning client keep the distro held as before. A host whose distro is stopped at startup
reads as stopped instead of unreachable, and the real-WSL lane gains a phase that proves the
release and records memory.
* fix(wsl): key the holder release on the WSL-host launch marker; name the lane phase
The real-WSL lane showed orcad idle-stopping with its daemon retired while the distro stayed
up: the setsid'd orcad's environment is not guaranteed to carry WSL_DISTRO_NAME, so the
release request was never written. Use ORCA_WSL_ORCAD_HOST, which only WSL-host launches set.
Phase 3 now carries its phase name and path filter, and records what kept a distro running.
* test(wsl): dispose the idle-release lane's guest transports
Each guest command left its exec loop running, a wsl.exe client that kept the distro up after
the holder had already let go (the receipt showed no holder, no orcad, no request left).
* test(wsl): record which wsl.exe clients keep the idle-release lane's distro up
* test(wsl): satisfy the flaky-test ratchet; feed the new idle port in the release test
* test(wsl): snapshot guest processes after launch to find what holds the session
* test(wsl): locate the step that leaves the zombie holding the idle distro
* test(wsl): log the idle-release lane's guest commands with times to place the zombie
* test(wsl): follow the remote runtime client's move
* test(wsl): record when each leftover WSL session init started
* fix(wsl): keep the distro while the user still runs anything, and never trip on the request file
Review of #33084:
- The holder now checks, before claiming a release, that no process of the user runs outside
the holder itself (session plumbing aside: systemd --user, (sd-pam), dbus-daemon). A detached
tmux, nohup job or dev server keeps the distro; it fails toward holding.
- A new holder drops any request left from before it started, so an older orcad's request can
never end a holder a client just asked for.
- orcad touches the request file only for WSL-host launches and never throws over it.
- The real-WSL lane proves a detached job keeps the holder and its request, and the distro
stops once the job ends.
* fix(wsl): a running container keeps the distro, whoever owns its shim
Docker's containerd-shim processes run as root, so the user-only scan missed them and a
release would have stopped running containers. Any containerd-shim process now keeps the hold.
* fix(wsl): read each process status only up to Uid; document what keeps the hold
Delta review of #33084: dash reads a status file a byte at a time, so stop at Uid. Document
that a root default user never releases, that per-user agents hold it, and the hidepid
exception. The lane's pkill no longer matches the shell running it.
* fix(orcad): materialize the app's agent-browser driver into the local slot
Replaces #34111's ORCA_AGENT_BROWSER_DRIVER hand-off, Windows profile copy and
claimed snapshot store. Packaging now references the app's own
resources/agent-browser-<target> from the orcad template manifest
(packagedBrowser, like packagedRipgrep), so the materialized slot carries it and
every local orcad launch finds it beside orcad-server.js. macOS signs the driver
before hashing; Windows reseals it after SignPath. The resolver now also tries
the musl driver name on Linux.
Refs #33846
* build(orcad): let a checkout keep template drivers with ORCAD_OMIT_AGENT_BROWSER=0
* fix(browser): focus newly opened image tabs
Focus the window before the webview so Command+W closes the new
image tab instead of the original tab after a plain image click.
Add tests for focus order, image loading, and close-shortcut forwarding.
Fixes#34114
* test(browser): verify image tab focus with native keyboard input
* refactor(ci): keep browser E2E routes within registry size limit
* fix(ci): enable background launch for native browser regression
* test(ci): include browser routes in isolated detector fixture
---------
Co-authored-by: Neil <neil@stably.ai>
devalue rejects Error objects, so when a NODE_RUNTIME_INCLUDE test file
failed to load, the pool's send() threw DevalueError and the run ended
without a summary. Give both ends of the IPC channel one codec with a
matching Error reducer/reviver (name, message, stack, cause) so the load
failure reaches the reporter as a normal FAIL.
Fixes#29854
Co-authored-by: Neil <neil@stably.ai>
`npx` and `npm run` set npm_execpath to npm's own npm-cli.js/npx-cli.js,
so resolvePnpmCliInvocation ran npm with pnpm's arguments. Skip npm's CLI
by file name and fall back to PNPM_HOME / pnpm on PATH. Route
build-workspace-packages and terminal layout parity through the shared
resolver instead of their own npm_execpath parsing.
Fixes#29438
Co-authored-by: Lance Woodson <65194841+woodsonl@users.noreply.github.com>
* fix(mobile): list Source Control changes with desktop's sections, sort and row rules
Conflicts get their own section in the user's group order, submodule rows lose stage and
discard like desktop, paths sort with the shared collator, and review notes go out as desktop formats them.
* fix(mobile): read the group order the host now publishes and keep submodule rows read-only
The host's paired settings projection now carries sourceControlGroupOrder, the
normalized status projection keeps submodule metadata, and conflict rows reuse the
shared conflict-kind labels.
* refactor(mobile): share Source Control grouping and row rules with desktop
Desktop and mobile group rows through one shared helper, mobile's unstage button
follows desktop's rule, and the group order resets when the host changes.