{"record":{"id":"ebf60b12781dc562","repo":"stablyai/orca","slug":"expected-baseline-helper-to-remain-after-abrupt-ow","errorCode":null,"errorMessage":"Expected baseline helper to remain after abrupt owner loss","messagePattern":"Expected baseline helper to remain after abrupt owner loss","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/macos-computer-helper-owner-loss-benchmark.mjs","lineNumber":358,"sourceCode":"    const connected = await sampleProcess(helper.pid)\n    const invalidSocketPath = socketPathFromCommand(helper.command)\n    invalidPeer = await connectInvalidPeer(invalidSocketPath)\n    invalidPeerRejected = true\n    const survivedClaimDeadline =\n      performance.now() - authenticatedAt >= OWNER_HOLD_MS && isProcessAlive(helper.pid)\n\n    sidecar.child.kill('SIGKILL')\n    await waitForChildExit(sidecar.child, PROCESS_EXIT_TIMEOUT_MS)\n    const abruptExitMs = await waitForProcessExit(\n      helper,\n      expectation === 'reaped' ? PROCESS_EXIT_TIMEOUT_MS : RETAIN_PROOF_MS\n    )\n    const helperExitedAfterAbruptLoss = abruptExitMs !== null\n    if (expectation === 'reaped' && !helperExitedAfterAbruptLoss) {\n      throw new Error('Expected helper to exit after abrupt authenticated owner loss')\n    }\n    if (expectation === 'retained' && helperExitedAfterAbruptLoss) {\n      throw new Error('Expected baseline helper to remain after abrupt owner loss')\n    }\n    const postLossRssBytes = helperExitedAfterAbruptLoss ? 0 : processSnapshot(helper.pid).rssBytes\n    await stopProcess(helper)\n    helper = null\n    invalidPeer.destroy()\n    invalidPeer = null\n\n    const gracefulExitMs = await verifyGracefulClose()\n    return {\n      authenticated: session.authenticated,\n      survivedClaimDeadline,\n      invalidPeerRejectedAndDidNotRetain: invalidPeerRejected && helperExitedAfterAbruptLoss,\n      connectedRssBytes: connected.rssBytes,\n      connectedCpuMilliseconds: Math.max(\n        0,\n        Math.round((connected.cpuTimeSeconds - initial.cpuTimeSeconds) * 1_000)\n      ),\n      activeRequests,","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/macos-computer-helper-owner-loss-benchmark.mjs#L340-L376","documentation":"Thrown when running with --expect retained (baseline mode). After SIGKILL-ing the sidecar, the benchmark expects the baseline helper to survive for at least RETAIN_PROOF_MS (3s). If the helper exits within that window, the baseline is incorrectly coupled to the owner's lifecycle — a baseline helper should be independent of the authenticated owner.","triggerScenarios":"Called from runInternalTrial('retained') at line 357. waitForProcessExit(helper, 3000) returns a non-null elapsed time because the helper exited within 3s. helperExitedAfterAbruptLoss is true, so the assertion fires.","commonSituations":"The baseline helper was spawned in the same process group as the sidecar and received the cascading SIGKILL via kill(-pgid); the baseline build inadvertently includes owner-loss detection that should only exist in the reaped build; a signal handler terminates the helper on parent exit.","solutions":["Ensure the baseline helper is spawned detached (setsid / new process group) so it does not receive the sidecar's process-group SIGKILL","Verify no owner-loss watchdog runs in the baseline build configuration","Check that RETAIN_PROOF_MS (3s) is shorter than the baseline's natural lifetime — if the baseline crashes on its own, investigate startup failures"],"exampleFix":"// before: helper inherits the sidecar's process group, dies on cascading SIGKILL\nspawn(helperPath, args, { stdio: 'ignore' })\n\n// after: detach into its own session/group so it survives owner loss\nconst child = spawn(helperPath, args, { detached: true, stdio: 'ignore' })\nchild.unref()","handlingStrategy":"try-catch","validationCode":"// Before running the retained benchmark, verify the baseline helper is detached\nconst helper = await waitForHelper(sidecarPid)\n// pgid === pid confirms the helper is its own session leader\nif (helper.pgid !== helper.pid) {\n  throw new Error('Baseline helper is not a session leader — it will die with the sidecar')\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await runInternalTrial('retained')\n} catch (error) {\n  if (error.message.includes('Expected baseline helper to remain')) {\n    // baseline helper died with owner — check process group configuration\n    console.error('Baseline helper is coupled to owner lifecycle:', error)\n  }\n  throw error\n}","preventionTips":["Spawn the baseline helper with detached:true and unref() so it survives owner loss","Ensure the baseline build does not include owner-loss detection code","Verify the baseline helper's pgid differs from the sidecar's pgid"],"tags":["macos","process-lifecycle","owner-loss","benchmark"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}