orca/src/preload
Jinwoo Hong 05603a2e78
fix(resource-manager): never destroy a session Orca cannot prove is idle (#8459) (#10893)
* fix(resource-manager): never destroy a session Orca cannot prove is idle (#8459)

Resource Manager decided a session was an "orphan" from the absence of a
renderer binding, then force-killed it with no prompt. Absence of a binding is
not evidence a session is idle — during restore the binding map is legitimately
empty, and deferred SSH sessions never appear in it at all. Live agent sessions
were destroyed this way, losing unrecoverable work.

Three gaps, one rule: only positive evidence authorizes destruction.

- `pty:listSessions` dropped `agentSessionOwners` at the IPC boundary, so the
  renderer could not see the one fact that proves work is running. It now
  reports `hasAgentOwner`, typed once in `shared/pty-listed-session.ts` so the
  main handler, both preload surfaces, and the renderer cannot drift.
- The binding index ignored `deferredSshSessionIdsByTabId` — sessions restore
  knows are live on an SSH host but has not reattached. No other binding source
  can see them.
- The bulk-kill handler filtered sessions separately from the button's count,
  so the set killed could differ from the set advertised. Both now call
  `selectUnboundDaemonSessions`.

The single-row kill path had the same defect: it skipped confirmation whenever
`bound` was false. `requiresKillConfirmation` now also holds for agent-owned
sessions, and snapshot-derived rows carry ownership across from the daemon list
rather than reporting `false`.

* fix(resource-manager): distinguish unprovable ownership from proven absence

Adversarial review of the previous commit found it committed the same class of
error it was fixing: it collapsed "no agent owns this" and "this provider cannot
tell me" into one boolean `false`, and both destructive paths read that as proof.

A daemon generation below the claim protocol, an older SSH relay, or the
in-process local fallback all list no owners for a session that may well have
one. `pty.ts` already encodes the rule at :613 — "only providers that serialize
claims may make listing absence authoritative" — and the new IPC row ignored it.
So after upgrading with a legacy daemon still holding a live agent terminal,
bulk cleanup would have destroyed it: exactly #8459, one layer down.

`hasAgentOwner: boolean` is now `agentOwnership: 'present' | 'absent' | 'unknown'`,
derived via `providesAgentSessionOwnerListings`. Only `absent` authorizes
destruction, so `unknown` protects and confirms.

Second defect, found independently by four review lenses: the deferred-SSH
bindings reached the bulk selector but not `mergeSnapshotAndSessions`, because
the merge call site re-listed the binding fields instead of reusing the object.
A deferred SSH session therefore rendered `bound: false`, and its single-row kill
skipped confirmation while bulk cleanup correctly spared it. The call site now
spreads `resourceSessionBindings`, and a parity test fails if any binding field
is re-listed inline — the drift itself is now impossible to reintroduce quietly.

The e2e ownership assertion was also weak: it checked only that a boolean
arrived. It now asserts the exact arm, and that the live local provider reports
`absent` rather than `unknown`, so a degenerate all-unknown implementation fails.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-07-27 11:52:55 -07:00
..
api-types.ts fix(resource-manager): never destroy a session Orca cannot prove is idle (#8459) (#10893) 2026-07-27 11:52:55 -07:00
e2e-config.ts Terminal performance initiative: pipeline fixes + term-speed-2 revival + PTY flow control (integration branch) (#7214) 2026-07-10 17:27:47 -07:00
gitlab.ts fix(gitlab): thread MR search query and surface MR base failures (#6263) (#6591) 2026-06-28 18:05:29 -07:00
index.ts fix(resource-manager): never destroy a session Orca cannot prove is idle (#8459) (#10893) 2026-07-27 11:52:55 -07:00
renderer-heap-statistics-reader.test.ts fix(crash-reporting): record exact V8 heap sizes, not Blink's quantized ones (#10683) 2026-07-25 22:54:20 -07:00
renderer-heap-statistics-reader.ts fix(crash-reporting): record exact V8 heap sizes, not Blink's quantized ones (#10683) 2026-07-25 22:54:20 -07:00
renderer-restart-preparation.test.ts perf(renderer): stop full durable-state save on every top-level view switch (#9002) (#9393) 2026-07-20 01:14:17 -07:00
renderer-restart-preparation.ts perf(renderer): stop full durable-state save on every top-level view switch (#9002) (#9393) 2026-07-20 01:14:17 -07:00
runtime-environment-subscriptions.test.ts fix: bound preload runtime subscription IPC listeners to O(1) 2026-06-28 16:53:03 -07:00
runtime-environment-subscriptions.ts fix: bound preload runtime subscription IPC listeners to O(1) 2026-06-28 16:53:03 -07:00