mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 16:02:50 +00:00
Round-3 review found the guard was not the choke point its own comments claimed: six pid-addressed `taskkill /pid <pid> /t /f` families in main were ungated and uninstrumented, so the stale-pid shape stayed producible and a `selfInitiatedTreeKillCount: 0` could read as exculpatory when it was not. - Gate the remaining main-process families: the git command-runner abort, the notebook-cell and automation-precheck timeouts. - Turn the `src/shared` seam into the gate itself (`process-tree-kill-gate`), so the runProcess choke point, the codex app-server deadline kill and the ephemeral-VM recipe kill ask the same decision. Those three are compiled into the CLI/relay too and cannot import main; main installs the guard at preflight. - Ratchet (`main-process-tree-kill-gate.test.ts`): a new pid-addressed taskkill in main that skips the gate fails, and the allowlist entries must still exist. - Give pid-addressed kills eviction priority in the 32-entry ring: 32 routine `win-pty-job` teardowns from a window-close burst no longer evict the one entry that discriminates a self-kill from an external one. - Correct the coverage doc, which described the uninstrumented Windows sites as POSIX `process.kill(-pid)` group kills and omitted the git and codex paths.
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
/**
|
|
* Seam that lets the main process decide, and record, the tree-kills issued
|
|
* from code it does not own.
|
|
*
|
|
* Why a seam and not a direct call: `signalProcessTree` is the choke point every
|
|
* `runProcess` termination funnels through, and the codex app-server and
|
|
* ephemeral-VM kills are shared with the CLI — all of them live outside
|
|
* `src/main` and cannot import the own-Chromium guard or the crash breadcrumb
|
|
* store. Main registers the guard at startup; everywhere else this admits every
|
|
* kill and records nothing.
|
|
*/
|
|
|
|
/** Blast radius, not mechanism: `win-taskkill-tree` is addressed by pid and walks
|
|
* whatever tree that pid has *now*, so it can land on a recycled pid that is
|
|
* since one of Orca's own Chromium processes. A process group can only contain
|
|
* processes Orca itself put there. */
|
|
export type ProcessTreeKillScope = 'win-taskkill-tree' | 'posix-process-group'
|
|
|
|
export type ProcessTreeKill = {
|
|
pid: number
|
|
site: string
|
|
scope: ProcessTreeKillScope
|
|
}
|
|
|
|
/** False means the caller must not kill: main is currently accounting for that pid. */
|
|
type ProcessTreeKillGate = (kill: ProcessTreeKill) => boolean
|
|
|
|
let gate: ProcessTreeKillGate | null = null
|
|
|
|
export function setProcessTreeKillGate(next: ProcessTreeKillGate | null): void {
|
|
gate = next
|
|
}
|
|
|
|
export function admitProcessTreeKill(kill: ProcessTreeKill): boolean {
|
|
try {
|
|
return gate?.(kill) ?? true
|
|
} catch {
|
|
// Diagnostics must never turn a successful termination into a failed one.
|
|
return true
|
|
}
|
|
}
|