Skip to content

perf(runtime): gate PTY path-candidate extraction on mobile-connected#9422

Draft
nwparker wants to merge 1 commit into
mainfrom
nwparker/perf-path-candidate-gate
Draft

perf(runtime): gate PTY path-candidate extraction on mobile-connected#9422
nwparker wants to merge 1 commit into
mainfrom
nwparker/perf-path-candidate-gate

Conversation

@nwparker

@nwparker nwparker commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

TITLE: perf(runtime): gate PTY path-candidate extraction on mobile-connected
BRANCH: nwparker/perf-path-candidate-gate

Description

Terminal path provenance for the mobile file-tap feature runs a 3-regex path extractor (appendRecentPtyPathCandidates) on every PTY chunk of every session, inside recordRecentPtyOutputForPathProvenance (src/main/runtime/orca-runtime.ts:8121). The sole consumer of the extracted candidates is hasRecentTerminalOutputPath (orca-runtime.ts:8163), reached only from the mobile file-tap provenance check in orca-runtime-files.ts:695. Desktop-only sessions — which never open that path — pay the full extraction cost for nothing.

This change gates the extraction behind a sticky "a mobile/remote client has authenticated this session" flag:

  • orca-runtime.ts — new private recentPtyPathCandidateTrackingActive = false. In recordRecentPtyOutputForPathProvenance the raw RecentPtyOutputBuffer.append(data) stays unconditional (it also feeds terminal replay at :15790); only the appendRecentPtyPathCandidates call is wrapped in the flag. New idempotent activateRecentPtyPathCandidateTracking() sets the flag and synchronously backfills candidates from every retained raw buffer, replaying each buffer's original chunk boundaries (via new RecentPtyOutputBuffer.retainedChunks()) so the candidate set matches per-chunk extraction. hasRecentTerminalOutputPath lazily activates on first call as a safety net.
  • recent-pty-output-buffer.ts — adds retainedChunks()/compact() to expose original chunk boundaries for backfill parity while preserving the read-time collapse/defrag invariant.
  • runtime-rpc.ts:894 — the MobileSocketWiring onReady chokepoint now calls activateRecentPtyPathCandidateTracking(). Direct WS transport and the cloud relay transport (relay/relay-control-origin.ts:56) both attach to this same wiring, so one hook covers all mobile/remote/SSH-hosted PTY paths (recentPtyOutputById is keyed by ptyId regardless of host).

Over-limit chunks (>64KiB) are still extracted eagerly at append, since their original text is unrecoverable after the buffer pre-slices them.

Documented, accepted best-effort loss (not hidden): output that scrolled past the 64KiB raw window before the first-ever mobile connect no longer yields candidates. This is unreachable for real taps except for stale pre-connect scrolled-off output, where provenance is already best-effort. It is codified in a dedicated boundary test.

Evidence

Measured with an in-repo throwaway bench (path-candidate-gate.bench.test.ts, deleted before merge): 10,000 representative ~2.3KB build-log chunks (compiler lines, ls-style listings, a path every 7th chunk), median of 3 runs.

Path Per-chunk cost Per-MB throughput
Before (extraction on every chunk) ~28.6 µs/chunk (median 283–288 ms / 10k) ~12.8 ms/MB
After — desktop, no mobile (flag off) ~0.06 µs/chunk (0.5–0.6 ms / 10k) ~0.03 ms/MB
After — mobile, post-activation (flag on) identical to Before (same code path) identical to Before
  • ~28.5 µs/chunk saved (~99.8% of extraction cost) on the desktop-only PTY hot path; ~12.7 ms/MB less CPU during a build-log flood.
  • The cost does not vanish for mobile users — it moves to a single one-time first-connect backfill of ~0.13 ms/pty over the 64KiB window.
  • Post-activation steady-state read+append measured at 2.91 µs/iter (the old collapse-on-read defrag is preserved).

What this does NOT help: mobile-connected sessions see no per-chunk savings (parity by construction) and additionally pay the sub-ms per-pty backfill spike at first connect. The win is entirely for desktop-only sessions.

Proof of no regressions

  • Typecheck: npx tsc --noEmit -p config/tsconfig.node.json --composite false → exit 0, 0 errors.
  • Targeted tests: orca-runtime.test.ts + orca-runtime-files.test.ts = 837 passed; recent-pty-output-buffer.test.ts + runtime-rpc.test.ts = 65 passed. 902 passed, 0 failed. New/updated coverage:
    • lazy safety net: query with no mobile connect ever → true;
    • backfill parity: pre-activation path → activate → raw window scrolled >64KiB → still true purely via backfilled candidates;
    • post-activation live streaming: path → >64KiB scroll → true via candidate tier + double-activation idempotence;
    • documented-loss boundary: pre-activation path scrolled past 64KiB then activate → false;
    • edge parity: 4KiB line-length guard, window-trimmed head prefix, pre-sliced oversized chunk;
    • full-E2E runtime-rpc test: real E2EE mobile session → onReady backfill → pathless flood scrolls the raw window → files.resolveTerminalPath still grants;
    • existing direct-call tests at orca-runtime.test.ts:8390/:8415 pass unmodified.
  • Lint: npx oxlint on all changed files → exit 0, clean; oxfmt applied. pnpm run check:max-lines-ratchet → OK, no new suppressions.
  • Behavior-equivalence for the critical risk (mobile tap must not regress): Tier-1 raw-window read in hasRecentTerminalOutputPath is unchanged and always active, so any path still inside the retained 64KiB window resolves identically to pre-gate. Tier-2 candidates are backfilled per original chunk boundary at first onReady (direct WS + relay share the wiring), synchronously before any file RPC from that authenticated socket can dispatch; over-limit chunks stay eagerly extracted; a lazy fallback covers any query that never saw onReady. The full-E2E test proves a real mobile file tap still grants after the raw window scrolls past the path.
  • Adversarial review: 5 rounds run. Rounds 1–3 raised chunk-boundary / oversized-head parity and integration-coverage findings (backfill originally joined the raw window instead of replaying original chunk boundaries; tests bypassed the authenticated-connect trigger). These were fixed via retainedChunks()/compact() per-chunk backfill, eager over-limit handling, and the full-E2E runtime-rpc test. Converged to 2 consecutive clean verdicts (rounds 4 and 5) with only non-blocking notes (delete the throwaway bench; keep untracked node_modules out of the change).

ELI5

The app used to scan every line of every terminal for file paths, all the time, just so your phone could tap a path later — even when no phone was connected. Now it only starts scanning once a phone actually connects, and it catches up on the recent scrollback at that moment so nothing you tap goes missing. If you never use your phone, your computer skips a bunch of pointless work on every burst of terminal output.

Made with Orca 🐋

The 3-regex path extractor ran on every PTY chunk of every session for a mobile-only consumer. Now gated behind a sticky mobile-connected flag; first onReady synchronously backfills candidates from the retained 64KB window per original chunk boundary (lazy safety-net fallback). ~28.5us/chunk (~99.8%) saved on the desktop-only hot path; mobile parity preserved (Tier-1 raw-window read unchanged + backfill before any file RPC). 5-round review converged 2-consecutive-clean; independently verified tsc+902 tests.

Co-authored-by: Orca <help@stably.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant