Commit Graph
714 Commits
Author SHA1 Message Date
Neil b16a71c7fb ci: reuse Windows hook builds and shorten test setup and shutdown (#29439)
* ci: remove Windows build and persistence test overhead

* ci: collect unit phase diagnostics during PR checks

* test(ci): seed hook reuse fixture from the canonical prebuild

The hook reuse regression first built into a missing private --output, so it
always reached Cargo (74s warm on Windows). Build through the default output
instead, which reuses a warm canonical prebuild, then copy its executable and
fingerprint into the private fixture root.

* fix(lint): clear inherited max-lines and broad object tab parameter after main merge

Combine the duplicate shared/execution-host imports in runtime-host-services
(301 -> 300 lines) and type the overlap test's tab mapper with the
RuntimeMobileSessionClientTab owner type instead of object.

* fix(ci): align inherited runtime and workflow contracts

* test: establish changed runtime probe signatures deterministically

* test: await asynchronous daemon profile cleanup

* test: shut down owned daemons before deleting profiles

* test: clean up oracle daemons during final app close

* test: recognize verified Linux zombie exit during daemon teardown

* fix: preserve folder SSH ownership when project groups conflict
2026-10-16 02:52:22 -07:00
Neil c4f1dedad4 fix(orcad): a managed SSH/WSL server falls back when port 6768 is taken; WSL lane skips the MSI on 3.0.1 images (#29522)
* ci(wsl-orcad): skip the WSL MSI when the image already has 3.0.1

windows-2025 image 20261007.264.1 ships WSL 3.0.1.0, and reinstalling the
pinned 3.0.1 MSI over it exits 1603, failing every run. Install only when the
image is older, print the msiexec log on failure, and gate on >= 3.0.1 after.

* fix(orcad): let a managed launch fall back when its default port is taken

#29432 made any --port mandatory, but managed SSH/WSL launches pass the
default 6768 as a preference and read the bound port from readiness. WSL2
distros share one VM loopback, so a second distro's orcad now failed with
pinned_port_unavailable. Only an operator --port is required now.
2026-10-16 01:23:57 -07:00
OrcaWinandOrcaWin 7d9a777a61 perf(ci): skip unused main source maps in PR build fixtures (#29512)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-16 00:48:16 -07:00
Neil 629db0a1f4 [CI] Reduce test imports, clock waits, and headless cleanup costs (#29312)
* [CI] Keep transport-only tests outside the app store graph

* [CI] Advance the updater install clock in failure tests

* [CI] Avoid descriptor formatting in replay clip counts

* [CI] Advance native-chat test observation clocks

* [CI] Restore observation timers after failed test setup

* [CI] Clean up final headless daemons during public close

* [CI] Keep serializer test oracle out of production smoke triggers

* [CI] Keep three unit fixtures out of production smoke triggers

* [CI] Bound frozen-clock close callbacks in tests

* [CI] Avoid the app-store graph in feedback dialog tests

* [CI] Keep hidden popup fixture compositor frames active

* test(ci): reuse mobile runtime fixture for pairing listeners

* test: restore native chat clocks before rig cleanup
2026-10-15 23:31:35 -07:00
OrcaWinandOrcaWin fc584d425b ci: skip checks for draft pull requests [skip ci] (#29484)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-15 23:18:13 -07:00
Neil 90849ed0c6 Enable Claude plugin images and bounded terminal file transport (#28200)
* fix: render Kitty Unicode placeholder images with bounded ownership

* Enable managed Claude plugin images and bounded host file transport

* Preserve isolated Claude evidence and paired restart diagnostics

* Resolve Windows workspace aliases before WSL image reads

* Handle split remote terminal identities and improve WSL file-read diagnostics

* Reuse native drive paths for WSL image files and preserve guest temporary roots

* Apply native Windows path restrictions to mapped drive image sources

* Preserve WSL participation evidence across image checks

* Keep WSL drive directory containment case-sensitive after canonicalization

* Negotiate managed Claude image support with the launching renderer

* Make image repaint checks independent of display profile and shell output

* Capture repaint diagnostics only after the pixel assertion fails

* Allow floating terminal image reads from host temporary folders

* Keep image stack independent of unrelated CI runner and mobile lint settings

* Reuse worktree argument builder for terminal viewer context

Remove duplicated mapping and keep the RPC method table within its existing line limit.
2026-10-15 21:43:48 -07:00
NeilandOrcaWin 7909e72d2d ci: move PR analysis and Linux unit tests to Blacksmith (#29362)
* ci: report final PR checks outside the shared runner queue

* ci: fix inherited mobile test file size failure

* ci: move PR analysis and ARM test shards to Blacksmith

* Qualify x64 Blacksmith capacity and reject incompatible runner images early

* Keep extracted mobile test adapters within the test-only lint scope

* Identify the runner profile overriding shell fixture homes

* Preserve fixture HOME through the Blacksmith login profile

* Make cache invalidation fixtures observable within one filesystem clock tick

* Scope Blacksmith system-profile preparation to Linux runners

* Wait for observable ctime in daemon hash cache fixtures

* Use the mobile test lint scope already merged on main

* Stabilize metadata and timer fixtures on fast CI runners

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-15 21:07:49 -07:00
Neil f152101010 ci: reuse prepared Windows security addon in PR packages (#29352)
* ci: reuse prepared Windows security addon in PR packages

* ci: prepare bounded Windows security reuse qualification

* ci: ignore owned Windows benchmark receipts during source checks

* test: inject Windows security qualification dependencies

* test(mobile): register chat view mocks in test roots
2026-10-15 21:05:34 -07:00
OrcaWinandOrcaWin 79d131d521 ci: move the final PR report off the busy runner pool (#29337)
* ci: report final PR checks outside the shared runner queue

* ci: retain the mobile harness test mock allowance

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-15 20:48:39 -07:00
Neil e554ef2a78 ci: cancel obsolete PR checks even when new checks are skipped (#29364)
* ci: cancel superseded PR checks even when replacement checks are filtered out

* test(ci): verify cleanup keys against every automatic PR workflow
2026-10-15 20:12:36 -07:00
OrcaWinandOrcaWin 82029e6908 ci: stop warming unused Windows package archives (#29322)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-15 19:38:23 -07:00
Žan MlakarandNeil 69ff84db23 fix(relay): check clock skew on every cell production.tfvars declares (#28786)
* Monitor clock skew on every relay cell in production.tfvars

* test(cloud): run the clock-skew monitor workflow test in Cloud Verify

---------

Co-authored-by: Neil <neil@stably.ai>
2026-10-15 19:12:48 -07:00
Neil dcdf3860e1 ci: share runtime test imports and Node 18 preparation (#29300)
* ci: share runtime test imports and Node 18 preparation

* ci: run native plugin reconciliation on Node
2026-10-15 19:05:26 -07:00
Neil f670683b22 ci: cancel superseded PR cache warmers (#29279) 2026-10-15 17:42:49 -07:00
Neil 83dcc7dcb7 [CI] Reuse costly test setup and report an explicit full result (#29228)
* ci: publish an explicit result from the PR aggregate

* test(codex): preserve review text across OSC terminators

* perf(ci): reuse worker fixtures and validated launcher output

* fix(test): use typed orchestration database access

* fix(ci): exclude test fixtures from focus ratchet
2026-10-15 16:27:26 -07:00
Žan MlakarandOrca Worker 88bd5db42e fix(windows): copy a file to the clipboard without a visible PowerShell window (#28781)
* Run clipboard file copy and TLS openssl through process-host

* refactor(clipboard): inject runProcess, pass the Windows path as data, add an e2e

- clipboard-file-copy builds the process spec itself, so the stdio policy sits
  next to the wl-copy/xclip knowledge it exists for; the IPC handler passes
  process-host's runProcess straight through and keeps no wrapper.
- A helper's exit is read as data (clean exit or not) instead of being turned
  into a throw and caught again.
- Windows runs a constant Set-Clipboard script and reads the path from the
  environment, so no path is ever parsed as PowerShell.
- Drop the dead tls-certificate rewrite; nothing in the app imports it.
- e2e: right-click Copy on Windows, then a real shell paste of the file.

* ci(e2e): run the Windows explorer file-copy spec on the Windows runner

Route it from the clipboard sources, keep it out of the Linux lanes, and run it
in the existing Windows e2e job beside the other Windows-only specs.

* refactor(clipboard): tighten the helper seam, tests and e2e after review

- runClipboardHelper takes runProcess and a plain ProcessSpec.
- One handler test pins the process-host wiring on every host; spec details
  stay in the unit tests, which now also pin the inherited environment.
- e2e: native realpath so an 8.3 runner temp path still matches, paste via
  process-host, and no toast check that could never fail.
- Route the renderer caller to the e2e too.

---------

Co-authored-by: Orca Worker <orca-worker@localhost>
2026-10-15 14:22:27 -07:00
Brennan Benson 9e04ecb101 fix(omp): start OMP on cmd.exe when setup runs first (#29176)
* fix(omp): read the cmd fresh-config path by name so the guard survives a variable hand-over

On cmd.exe, OMP's fresh-session guard referenced %ORCA_OMP_FRESH_CONFIG%,
which cmd only expands while reading the typed line. When the line reaches
cmd inside another variable (the setup gate's
`<wait> && %ORCA_SEQUENCED_STARTUP_COMMAND%`), cmd expands once, the
reference stays literal, and OMP refuses to start with "fresh OMP settings
are unavailable".

The guard now reads the variable by name with a one-pass for-variable,
`for %! in (.) do @if exist "%~$ORCA_OMP_FRESH_CONFIG:!" ...`, so typed and
handed-over lines behave the same. The older cmd prefix stays recognized
for persisted lines and older hosts. A real-cmd test runs both deliveries in
the Windows CI lane.

* test(omp): pin the cmd guard's echo suppression and type the smoke's cmd line on stdin

The real-cmd test now runs echo on, like a pane, and asserts the config
path never reaches stdout, so dropping the guard's @ fails it. The manual
Windows smoke typed the line into a batch file, where the guard's %! would
need %%!; it now feeds cmd.exe on stdin like a pane does. The guard comment
now states the real rule: only %! or %~...! text in the for body changes,
and the quoter keeps prompts from forming it.
2026-10-15 13:34:04 -07:00
Neil bf71d64746 [CI] Group skill update checks by operating system (#29021) 2026-10-15 12:29:59 -07:00
Neil f4abedd7ec ci: skip unneeded native builds for proven test-only changes (#29169)
* ci: avoid native compatibility builds for proven test-only edits

* ci: recognize existing serializer test diagnostics
2026-10-15 08:33:51 -07:00
Neil bd62269d95 ci: reuse pinned fast typecheck for Windows installer tests (#29149)
* ci: reuse pinned fast typecheck for Windows installer tests

* test: follow shared desktop assets and compiler dependency changes
2026-10-15 05:46:04 -07:00
Neil a3373af635 ci: skip unused platform runs and reduce runtime test setup (#29144)
* test: reuse automation fixtures and narrow long-poll setup

* test: load terminal RPC methods only in consuming scenarios

* ci: skip packaged Orcad lanes for unrelated unit test edits

* style: format the WSL Orcad workflow
2026-10-15 05:06:12 -07:00
Neil 02356732b0 ci: finish successful aggregate checks without a runner queue (#29136)
* ci: accept validated aggregate success without queuing a runner

* test(ci): exercise aggregate rejection of an unexpected preflight skip

* ci: restore normal preflight after hosted rejection proof
2026-10-15 04:39:30 -07:00
Neil deeadb1ab6 ci: avoid mobile runs for desktop test-only changes (#29138) 2026-10-15 04:35:45 -07:00
Neil cf0aea342b ci: reuse bundled Node for selection evidence (#29017) 2026-10-14 23:50:49 -07:00
Neil d371e2d8b6 ci: reduce runner occupancy in release and contract jobs (#28930) 2026-10-14 19:53:57 -07:00
Neil 8df0f67c82 ci: skip redundant PR platform warmers (#28917) 2026-10-14 18:48:13 -07:00
Neil f23fa8ca76 Prepare Windows natives with scoped compiler settings and measure servicing (#28881)
* Scope Windows native compiler setup and measure ARM inbox preparation

* Add a controlled Windows native preparation comparison

* Test native preparation through an injected process runner

* Guard reviewed Windows native batch runners
2026-10-14 18:18:24 -07:00
Jinwoo Hong 6e46d5ef33 feat(relay): watch a reserve cell and flip it back on the first step 5 stop rule (#28698)
* feat(relay): watch a reserve cell and flip it back on the first step 5 stop rule

A manual, inert-until-dispatched workflow samples one reserve cell every minute for up to
300 minutes against the step 5 §9 stop rules, logs one JSON line per sample, and on the
first trip (or N unreadable samples in a row) runs the flag tool's own admitMode=db write
under the flag workflow's concurrency group. dry-run logs the flag tool's plan instead.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): keep the reserve watch's flip back out of the flag group, and baseline 503s before the flip

- The flip back holds no concurrency group: GitHub keeps one pending run per group and a
  newer one cancels it. The flag tool's CAS orders it instead; a generation conflict is
  re-read and retried (5 tries, backoff) while the switch file still says reserve.
- The 503 background comes from the 10 minutes before a required flipped-at, or an explicit
  value; neither is refused.
- A failed or cancelled write-mode watch flips back too. An unreachable cell fails with the
  exact break-glass inputs.
- Missing 503 data (empty series, unpublished minute, unparseable time) is unverifiable.
- Seat-behind-row key adds the director instance and cell; six segments share one command.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): read the reserve watch's 503 publishing front from every response code

A quiet fleet has no 503 series, so the watch read it as unverifiable and flipped a healthy
cell back within minutes. The 503 read now groups request_count by response code in one
query; the newest minute any code has a point for is how far the series is published, so a
503 minute at or before it with no point is zero and minutes past it are left out.

Also: the flip-back job's steps run on always(), flipped-at ages against the watch's start
in later segments, a pending pre-flip background no longer adds to the unverifiable streak,
the flip back retries runtime-status before calling for break glass, and the concurrency
rationale lives once in the docs.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* docs(relay): state what a cancel during the flip-back lease wait can leave, and the 503 publish-skew assumption

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): fail a segment closed on a corrupt watch state file, and keep no checkout token on disk

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): alarm on a failed flip back, refuse a watch under a rollout lease, wait for reserve to apply, and control the duplicate read

- A flip back whose write or plan never finished (no ID token, a failed login, a silent cell)
  raises an ::error:: annotation and a FLIP BACK FAILED summary, as the clock-skew monitor does.
- The first segment reads the Cloud SQL rollout lease through the lease action's own reader and
  refuses to start while any run holds it, or when it cannot be read.
- A cell not yet reporting reserve is waited on for up to 10 minutes, judging nothing, before the
  watch ends refused without a write.
- The duplicate-seat read takes the per-minute ledger summary in the same query and window; with
  no fresh summary in it the sample is unverifiable, not zero duplicates.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): page on a refused reserve watch or a failed flip back

A refused watch can leave a cell in reserve and unwatched, the same as a flip back that did not
land. Both now raise an escaped ::error:: annotation through one `alarm` command, and in write
mode write orca_relay_reserve_watch_alarm with gcloud logging write. A new log-based metric and
alert policy page on any such line, per cell, through relay_alert_notification_channels, and the
deploy identity gets roles/logging.logWriter in production to write it.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): name the log-writer risk, check the alarm's project, and say a failed login cannot page

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* docs(relay): note a force-cancel can skip the reserve-watch flip-back write
2026-10-14 20:42:27 -04:00
Neil 39815a086f Reduce CI import, frame-capture, teardown, and shard costs (#28879)
* Avoid unused module imports and trim cosmetic test coverage

* Capture hidden popup frames and attach CDP before guest creation

* Overlap relay test projects within the existing worker budget

* Consolidate native preparation and add an opt-in transform cache comparison

* Release inherited debugger sockets during final E2E teardown

* Refresh unit scheduling weights from all five qualified ARM shards

* Avoid retaining unasserted RPC call history in the delivery model

* Use the supported unconditional background wait syntax

* Overlap unconditional output upload with native preparation

* Verify relay integration stays enabled for ordinary unit callers
2026-10-14 17:10:55 -07:00
Neil 6607c54984 perf(ci): cut redundant tests and reuse expensive setup (#28669)
* perf(ci): reduce test overhead and reuse expensive build work

* test(ci): keep worker startup outside failure-case deadlines

* test: isolate push fixture advisory locks

* test(ci): preserve fixed drain retry allowance

* Align CI contracts with current triggers and guide content

* Stabilize consolidated reveal scenarios and retain behavioral CI contracts

* Fix upstream lint blockers while retaining behavior and assertions

* Classify global Jira preferences in the WSL migration inventory

* Align Jira test fixtures with startup and build safety checks

* Include package-test routing dependency in CI checkouts and fixtures

* Keep native stream classes intact in transcript dependency tests
2026-10-14 16:14:27 -07:00
Jinwoo Hong d09605ee8e ci: run the Electron browser probes serially, out of the unit shards (#28799)
The three popup compatibility probes ran in the parallel unit shards and
timed out at their 14s in-process deadline when other files starved the
runner. Move them into the package job's serial Electron lifecycle step,
and stop the six probes already in that step from also running in the
shards.

Claude-Session: p2-headless
2026-10-14 15:35:39 -04:00
Jinwoo Hong 68b186e2aa fix(relay): end the restart-safe quiet at the drain's pace window, not a window after it (#28677)
* fix(relay): end the restart-safe quiet at the drain's pace window, not a window after it

A paced drain tells its last host when the window ends, so the restart-safe
wait has to see an empty runtime reaching past that point. It counted a full
window of quiet samples from the first empty one instead, and the runtime only
empties as the window ends, so every same-cap cell waited the window twice:
about 25 minutes per Asia cell at 1200 s on 2026-10-13, and 5 minutes per
300 s cell.

The window is now measured from the verifier's own start, which runs after the
cell accepted the drain and so ends no earlier than the cell's own window. A
pass still needs two consecutive restart-safe samples, the last taken at or
after that end, and any non-zero runtime counter or open migration still
restarts the count. Progress lines report paceWindowRemainingMs in place of the
old sample target.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* fix(relay): drop the same-cap drain timeout's double-wait allowance and stale quiet wording

The drain step's timeout added the window's excess over 300000 only because
restart-safe used to wait a second window after the cell emptied, so it is
now the 15-minute migration lease plus the window for every pace (35 minutes
at 1200000, unchanged at 300000 and below). Docs, workflow comments and the
shadow gate's settledAfterSeconds note now describe the window-end rule. The
always-quiet test starts its clock late, so a window measured from zero
fails it, and the overlapping late-control test is folded away.

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* docs(relay): state the restart-safe window-end rule exactly

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f

* docs(relay): the slowest restart-safe wait is now 35 minutes

Claude-Session: f2fe8cb5-4467-4a25-8aab-98598b70791f
2026-10-14 15:35:31 -04:00
Neil 9c0420fa9a fix(browser): agent clicks keep the user's keyboard focus (#28454)
Any press on a <webview> guest moves Chromium focus into it, so an agent click
took the user's terminal focus (#20595). Main now asks the hosting pane to guard
focus for each agent press (Orca's click/mouse down and the CDP proxy) and the
pane puts it back inside the webview's focus event, and again when the press
ends. Offscreen pages keep their native focus.
2026-10-14 02:40:07 -07:00
Neil c1597c3168 ci: remove recurring homepage repository checks (#28682) 2026-10-14 02:08:46 -07:00
Neil 092d6bdc76 ci: check README links and workflow configuration on main (#28678) 2026-10-14 01:52:33 -07:00
Neil f31aada5b4 Require a unique full PR gate before merging (#28632)
* Require exact-commit PR checks before agent merges

* Give full PR checks a unique required status context

* Validate required context ownership on every pull request
2026-10-14 01:25:28 -07:00
Neil f894e257e9 ci: stop daily and post-merge headless-server checks (#28664) 2026-10-14 01:13:59 -07:00
Neil b83a6f74be Finish agent-selection cleanup and restore merge validation (#28607)
* Retire newly translated None option labels

* Reserve required verify check for the complete PR gate

* Preserve headless default tab styling and stabilize import ordering test

* Restore the option mutation clock after crossing fixes

* Check both supported workflow extensions
2026-10-13 23:57:33 -07:00
Jinjing 126009d4c5 Skip Windows security addon steps when the builder is missing (#28546)
Older requested refs predate the security addon builder, so the desktop
template CI job failed trying to run a script that isn't there. Gate the
build, keep, and collect steps on that script existing in the checkout.
Add a test that pins the gating for both cases.

Also drop an unused getAppEnvironment import in orcad-entry.ts.
2026-10-13 21:48:47 -07:00
Neil 13a75d3939 [CI] Reduce redundant test work and import existing helpers directly (#28365)
* [CI] Reduce redundant test work and import existing helpers directly

* [CI] Preserve provider guards and pin the mobile browser test core

* [CI] Fix CI test setup and verify retained contracts

* [CI] Compare native media chunks without boxed byte arrays

* [CI] Detect shifted native media reads with position-sensitive bytes
2026-10-13 20:25:00 -07:00
Neil abe2e8118d perf(ci): reuse import analysis and run localization coverage with Bun (#28463)
* perf(ci): share import analysis and run localization coverage with Bun

* test(ci): recognize the shared import guard in parallelism contracts
2026-10-13 20:17:23 -07:00
Neil 3f81541188 Support restarting Windows Orca as administrator (#28073)
* feat(windows): add administrator PowerShell terminal setting

* fix(settings): localize administrator terminal search keywords

* fix(windows): restrict elevated terminal host to Orca's runtime and requesting account

* fix(windows): harden administrator terminal routing, inventory and restore

* fix(build): build the Windows agent hook when electron-builder packages Windows

* fix(build): build the packaged Windows agent hook for the target architecture

* fix(windows): accept the development terminal runtime and test real elevation in CI

* feat(windows): show administrator status and restart instructions

* fix(settings): localize administrator mode search keywords

* test(settings): isolate the desktop permission section in shell picker tests

* Add Windows administrator restart and simplify Terminal settings

* Keep administrator restart silent and settings actions within narrow panes

* Keep Windows shell choices and permission guides usable at minimum width

* Prevent later restarts from replaying administrator terminal reset

* Fix CI route resolution and transient Windows fixture cleanup
2026-10-13 18:06:05 -07:00
Neil c827ed5324 ci: run full native mobile typechecks without compiler caches (#28409) 2026-10-13 14:27:14 -07:00
Jinwoo Hong 6cfe678dbe ci(relay): use the runner's preinstalled gcloud instead of downloading the SDK (#28392)
* ci(relay): use the runner's preinstalled gcloud instead of downloading the SDK

dl.google.com downloads of google-cloud-sdk time out on the runners, failing every relay
operation at setup-gcloud. skip_install keeps the WIF cred-file login.

* ci: drop the temporary gcloud skip_install proof workflow
2026-10-13 16:24:53 -04:00
Neil b3ad227650 ci: use Bun 1.4.3 across all workflows (#28384)
* ci: share Bun 1.4.3 across current toolchain workflows

* ci: use shared Bun pin for server migration tests too
2026-10-13 13:03:19 -07:00
Neil fc7dff8ce1 ci(wsl): real WSL2 lane for WSL via orcad (C10) (#27921)
* ci(wsl): real WSL2 lane for orcad deploy, bridge, liveness and holder (WSL-via-orcad C10)

* ci(wsl): upload the template's dot-directories; save the rootfs cache on failure

* ci(wsl): update the runner's WSL to 3.0.1+ before asserting WSLInterop survives

* test(wsl): let a released holder settle before asserting it exited

* ci(wsl): install a pinned, cached WSL 3.0.1 MSI instead of wsl --update

* test(wsl): keep the lane's survival seconds typed in its assertion message
2026-10-13 07:09:02 -07:00
OrcaWinandm4air 38a4958cad feat(linux): run the AppImage terminal daemon off the mount, on the extracted copy's bundled Node (#28214)
On a validated AppImage the desktop's daemon launch first runs <generation>/resources/node-runtime/bin/node
on the generation's daemon-entry.js when the extracted copy for the file at $APPIMAGE is complete, carries
the bundled Node and the entry, and is the running release. It then falls back to the AppImage's own mount
and the current mount, logging every fallback. The copy rung records $APPIMAGE/<entry> like the own-mount
rung, so either daemon is adopted. Generation leases recognize the bundled Node. macOS, Windows, deb and
rpm never reach it.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-13 04:34:25 -07:00
Neil fba7b753ec Cache mobile typechecks and overlap CI setup (#28192)
* ci: run mobile runtime test groups on separate runners

* ci: use a lightweight runner for the mobile result gate

* ci: distribute Bun tests across both mobile runners

* ci: reuse mobile compiler state without adding runner queues

* test: verify eviction of source variants in one cache bucket

* test: baseline existing serializer limits in the capacity capture
2026-10-13 03:35:51 -07:00
Neil 3a7ec7dff1 perf: reuse verified Node and run the layout check with Bun (#28218)
* perf: overlap preflight daemon smoke and reuse verified Node executable

* Keep measured Node reuse and Bun layout wins; drop smoke scheduling experiments
2026-10-13 02:58:56 -07:00
OrcaWinandOrca Worker 4559c250b3 fix(windows): restrict secure files in-process instead of spawning icacls (#28135)
* fix(windows): restrict secure files in-process instead of spawning icacls

Every secure write on Windows spawned icacls.exe five times on the calling
thread (the Electron main thread for most stores): verify, /reset,
/inheritance:r /grant:r, verify, verify. Process creation under endpoint
security costs ~0.6 s each, so each write froze the UI for seconds (#26027).
The /reset + /inheritance:r pair is also what behavioural EDR scores as
ransomware tradecraft (#25583).

Add native/windows-security (@orca/windows-security): a small N-API addon
over advapi32 that reads and writes DACLs in-process. It exposes the token
user SID, a DACL read as SDDL, a DACL write (sync and on the thread pool),
a create-with-DACL file write, and an additive grant. Policy and
verification stay in TypeScript.

- writeSecureFile creates each temp file already carrying the protected
  user/SYSTEM/Administrators DACL (CreateFileW + SECURITY_ATTRIBUTES), reads
  it back once, and renames it. No ACL is modified on the write path and no
  process starts. Before: 5-7 spawns, 94-138 ms per write. After: 0 spawns,
  ~0.5 ms.
- A secure directory is verified once per process. It is rewritten only
  when verification fails, on the thread pool, because the write walks
  every descendant (~2 s on a 29k-entry userData).
- The verifier follows OpenSSH's rule: only the user, SYSTEM and
  Administrators may be granted anything, and the path must be protected
  (or, for a file, inherit from a secure parent). DACLs written by the
  icacls-era hardening pass unchanged, so there is no migration.
- If the addon cannot load, the write still happens and reports
  unrestricted, logged once. There is no icacls or PowerShell fallback.
- grantDirAcl, the startup userData grant, and the install-dir probe and
  package repair use the same addon, so whoami.exe and icacls.exe are no
  longer spawned anywhere at runtime.
- orcad's Windows slots ship the addon beside their bundles (built per
  arch, PE-machine checked). Its data-root privacy check fails closed, so
  without the addon a Windows orcad would not start.

Fixes #26027
Fixes #25583

* refactor(secure-file): harden existing Windows files through the sync lane

The read path called restrictWindowsPathSync directly and recorded success
itself; the existing sync lane already does both. One call site fewer.

* refactor(windows-security): one load, one rule, no fallthrough (review #28135)

- The descriptor parser is anchored, so a conditional ACE (its body holds
  parentheses) or anything else it cannot read fails closed instead of
  verifying the ACEs before it.
- findSecureDaclViolation is one flat rule: protected, allow rules only for
  the user, SYSTEM and Administrators (OpenSSH's ACE rule), and full
  control for the user. The inherits-from-a-secure-parent exception is gone:
  it accepted exactly what loosening the parent reaches.
- The addon and the user SID load once, behind one wrapper that adds the
  extended-length prefix to every path and runs async DACL writes to one
  path in order, so a startup grant cannot land after a re-lock and restore
  the broader DACL.
- With the addon loaded, a failed born-restricted create throws with the
  matching Node error code instead of falling back to a plain write.
- A grant leaves a NULL DACL untouched instead of turning 'everyone' into
  'only this SID'. WriteFile runs once and fails on a short write.
- The artifact create-intent store writes through writeSecureFile and drops
  its own temp writer, directory LRU and synchronous directory re-lock.
- Test seams the global fake makes redundant are gone.

* fix(packaging): fail a Windows build whose workspace addon binary is missing or foreign-arch

The @orca/windows-* workspace links exist on every host, so their presence
proved nothing: a missing or wrong-architecture .node only surfaced at
runtime, as unrestricted secure files or an orcad that refuses to start.
beforePack now reads each addon's PE machine against the target arch.

* refactor(windows-security): prune what the native ACL left dead (review #28135)

- Sync-spawn ratchet: hardenSecurePath and the sync-flag exemption it alone
  used are gone, and the advice and baseline header no longer say secure
  writers run icacls.
- The install-dir probe reads ACEs through parseSddlDacl, so an ACE it
  cannot parse fails the whole reading closed instead of being skipped; AC
  is a resolved alias there now.
- The packaging check reads the addon binary through node_modules, the copy
  that ships.
- No winCode-to-errno table: nothing reads .code off a failed secure write.
- The load memo is not mutated; secure-path keeps its own log-once flag.
- grantInstallDirPackageAcl is a plain function, and secure-file restricts
  a Windows directory and a POSIX path directly instead of through one
  two-platform helper.

* fix(windows-security): resolve LA in real-ACL tests; tear a file whose close fails

- The GitHub Windows runner is the built-in Administrator (RID 500), whose
  SID reads back as LA. Production already resolves it through
  localDomainSidOf; the win32 test helpers parsed without it. One shared
  readDaclOf resolves aliases for every real-ACL suite, and the verifier's
  unit test covers an LA-aliased directory and LA as a stranger.
- createFileWithDacl treats a failed CloseHandle like a failed write (lost
  data on a network volume) and deletes the torn file.
- Drop a duplicate test reset and a typo.

* fix(windows-security): load only from inside the app; read DACLs as structure (review #28135)

- Loader: orcad's staged binary first, then the workspace package only if
  its real path is inside the app (process.resourcesPath, or this
  checkout). A bare specifier otherwise walks every parent up to
  C:\node_modules, which any local user may create, and orcad holds
  credentials.
- The addon reads a DACL as { protected, aces: [{ type, flags, mask, sid }] }
  via GetAce, with a SID only for plain allow/deny ACEs and null for a NULL
  DACL. findSecureDaclViolation and the install-dir probe check that
  structure, so conditional, callback and object ACEs fail closed. The SDDL
  parser, its alias table, LA/localDomainSid resolution and getDaclSddl are
  gone; SDDL is only the write format.
- Install-dir tree pass: files flagless as before, but a directory only when
  its own DACL is protected (inheritably). Re-granting inheriting
  directories re-propagated each subtree (3.2 s for 1,093 directories). The
  root is no longer granted, or counted, twice. The two passes are plain
  functions behind a { root, tree } seam.
- One namespacing (path.win32.toNamespacedPath) at the addon boundary, also
  the per-path ordering key; the comment states the real sync-grant
  invariant.
- restrictWindowsDirectory(dir): Promise<boolean> replaces the callback
  lane; the reporter is guarded once, so the 'settle' stage is gone.
- Sync-spawn ratchet: the secure writers no longer spawn or block, so they
  leave the gate (109 -> 61 uses).
- Errors name the Win32 call and code only; a failed
  GetSecurityDescriptorControl fails the write instead of defaulting to
  unprotected.

* test(secure-file): assert the durable POSIX write's outcome, not the old chmod order

writeSecureFile now chmods the temp file to 0o600 before fsyncing it, so
the fsync also covers the mode change and the file is owner-writable when
opened. Assert what matters under umask 0o200: the write succeeds, the
temp file is fsynced read-only, and the published file is exactly 0o600.

* fix(windows-security): namespace paths with the host's toNamespacedPath

path.win32.toNamespacedPath rewrote POSIX temp paths (/tmp/x -> \tmp\x) in the
Linux runs of the Windows-logic unit tests, so the fake addon wrote to the wrong
place. The addon only runs on Windows, where the host function is the win32 one;
elsewhere it is the identity. The long-path assertion runs on Windows only.

* test(windows-security): assert the install-dir long-path prefix on Windows only

The prefix comes from the host's toNamespacedPath, which is the identity off
Windows; the Linux run of this suite expected the win32 escape.

* fix(windows-user-data-acl): grant the root even when its children cannot be listed (review #28135)

A readdir failure on userData aborted the whole grant, so the root grant
that could repair a DACL refusing the listing was never attempted. The
listing failure is now recorded, the root is still granted, and the
marker stays withheld so the next launch retries.

* test(windows-security): wait for relock propagation, accept Entra ID SIDs (review #28135)

- The large-relock test waited only for the parent to turn protected,
  which happens before propagation reaches the children, then read a child.
  It now waits on the parent and both ends of the child range.
- The token-user test rejected S-1-12-1 (Entra ID) accounts, failing the
  suite on Entra-joined dev machines.

---------

Co-authored-by: Orca Worker <orca-worker@localhost>
2026-10-13 01:56:55 -07:00