@smthrs/platform-node 1.0.0-rc.3 → 1.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/bin/darwin-arm64/smithers-jj-export +0 -0
  2. package/bin/darwin-x64/smithers-jj-export +0 -0
  3. package/bin/linux-arm64/smithers-jj-export +0 -0
  4. package/bin/linux-x64/smithers-jj-export +2 -2
  5. package/bin/win32-x64/smithers-jj-export.exe +0 -0
  6. package/dist/cjs/ProcessConfinement.d.ts.map +1 -1
  7. package/dist/cjs/ProcessConfinement.js +6 -1
  8. package/dist/cjs/ProcessConfinement.js.map +2 -2
  9. package/dist/cjs/ProcessSandbox.d.ts +16 -2
  10. package/dist/cjs/ProcessSandbox.d.ts.map +1 -1
  11. package/dist/cjs/ProcessSandbox.js +17 -2
  12. package/dist/cjs/ProcessSandbox.js.map +2 -2
  13. package/dist/cjs/ScopedProcess.d.ts +2 -1
  14. package/dist/cjs/ScopedProcess.d.ts.map +1 -1
  15. package/dist/cjs/ScopedProcess.js.map +2 -2
  16. package/dist/cjs/internal/ProcessSupervisor.d.ts +2 -0
  17. package/dist/cjs/internal/ProcessSupervisor.d.ts.map +1 -1
  18. package/dist/cjs/internal/ProcessSupervisor.js +5 -2
  19. package/dist/cjs/internal/ProcessSupervisor.js.map +2 -2
  20. package/dist/cjs/internal/SupervisorProgram.d.ts.map +1 -1
  21. package/dist/cjs/internal/SupervisorProgram.js +23 -3
  22. package/dist/cjs/internal/SupervisorProgram.js.map +2 -2
  23. package/dist/esm/ProcessConfinement.d.ts.map +1 -1
  24. package/dist/esm/ProcessConfinement.js.map +1 -1
  25. package/dist/esm/ProcessSandbox.d.ts +16 -2
  26. package/dist/esm/ProcessSandbox.d.ts.map +1 -1
  27. package/dist/esm/ProcessSandbox.js +33 -4
  28. package/dist/esm/ProcessSandbox.js.map +1 -1
  29. package/dist/esm/ScopedProcess.d.ts +2 -1
  30. package/dist/esm/ScopedProcess.d.ts.map +1 -1
  31. package/dist/esm/ScopedProcess.js +2 -1
  32. package/dist/esm/ScopedProcess.js.map +1 -1
  33. package/dist/esm/internal/ProcessSupervisor.d.ts +2 -0
  34. package/dist/esm/internal/ProcessSupervisor.d.ts.map +1 -1
  35. package/dist/esm/internal/ProcessSupervisor.js +9 -2
  36. package/dist/esm/internal/ProcessSupervisor.js.map +1 -1
  37. package/dist/esm/internal/SupervisorProgram.d.ts.map +1 -1
  38. package/dist/esm/internal/SupervisorProgram.js +23 -3
  39. package/dist/esm/internal/SupervisorProgram.js.map +1 -1
  40. package/docs/api.md +2 -1
  41. package/docs/concepts/process-containment.md +8 -0
  42. package/package.json +4 -4
  43. package/src/ProcessConfinement.ts +10 -3
  44. package/src/ProcessSandbox.ts +38 -4
  45. package/src/ScopedProcess.ts +2 -1
  46. package/src/internal/ProcessSupervisor.ts +8 -2
  47. package/src/internal/SupervisorProgram.ts +23 -3
@@ -1 +1 @@
1
- {"version":3,"file":"ScopedProcess.js","sourceRoot":"","sources":["../../src/ScopedProcess.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Scoped transient commands with the host's process-tree cleanup policy.\n * @since 1.0.0\n */\n\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport type * as PlatformError from \"effect/PlatformError\"\nimport * as Scope from \"effect/Scope\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport type { ChildProcessHandle } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as PipedProcess from \"./internal/PipedProcess.ts\"\nimport { targetPidOf } from \"./internal/ProcessSupervisor.ts\"\nimport * as ProcessReaper from \"./ProcessReaper.ts\"\n\n/**\n * One command's literal argv, environment, pipes and termination policy.\n * @category models\n * @since 1.0.0\n */\nexport interface Options extends ChildProcess.KillOptions {\n readonly command: string\n readonly args?: ReadonlyArray<string> | undefined\n readonly cwd?: string | undefined\n readonly env?: Readonly<Record<string, string | undefined>> | undefined\n readonly stdin?: \"ignore\" | \"pipe\" | undefined\n readonly windowsVerbatimArguments?: boolean | undefined\n readonly windowsHide?: boolean | undefined\n}\n\n/**\n * The managed owner identity and the actual target identity are distinct.\n * @category models\n * @since 1.0.0\n */\nexport interface Handle extends ChildProcessHandle {\n /** The native target's pid, for diagnostics and service liveness. */\n readonly targetPid: number\n}\n\n/**\n * Starts a pipe-based command and contains its lifetime inside the caller's\n * scope. The returned pid names the live supervisor; exitCode reports\n * the actual target. The private parent connection stops the tree on host loss.\n * Transient commands have no durable ledger; durable hosts use NodeHost instead.\n *\n * Unconsumed output stays in bounded native buffers until it is read or the\n * scope closes. Consume stdout and stderr alongside exitCode: a command can\n * block when an unread pipe is full.\n *\n * Failed startup closes its child scope before returning an error, even when\n * the caller catches that error and retains the surrounding scope.\n * @category constructors\n * @since 1.0.0\n */\nexport const spawn = (\n options: Options\n): Effect.Effect<Handle, PlatformError.PlatformError, Scope.Scope> =>\n Effect.uninterruptibleMask((restore) =>\n Effect.gen(function*() {\n const scope = yield* Scope.fork(yield* Scope.Scope)\n const command = ChildProcess.make(options.command, [...options.args ?? []], {\n cwd: options.cwd,\n env: options.env,\n extendEnv: false,\n stdin: options.stdin ?? \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n detached: process.platform !== \"win32\",\n killSignal: options.killSignal ?? \"SIGTERM\",\n forceKillAfter: options.forceKillAfter ?? 2000,\n windowsHide: options.windowsHide ?? true,\n // Preserve the target's native option through the private protocol.\n ...{ windowsVerbatimArguments: options.windowsVerbatimArguments }\n })\n return yield* restore(\n Effect.gen(function*() {\n const prepared = yield* ProcessReaper.processLifecycle(\n command,\n (command) => PipedProcess.spawn(command, false, true)\n )\n yield* prepared.activate\n const targetPid = targetPidOf(prepared.handle)\n if (targetPid === undefined) {\n return yield* Effect.fail(\n PipedProcess.failure(\"spawn\", new Error(\"The supervisor did not identify its target\"))\n )\n }\n return Object.defineProperty(prepared.handle, \"targetPid\", { value: targetPid, enumerable: true }) as Handle\n }).pipe(Scope.provide(scope))\n ).pipe(\n Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause)))\n )\n })\n )\n\n/**\n * The native command's result, preserving a signal instead of inventing a code.\n * @category models\n * @since 1.0.0\n */\nexport interface Status {\n readonly code: number | null\n readonly signal: ChildProcess.Signal | null\n}\n\n/**\n * Reads the target's result. Failures without an actual target signal remain\n * platform failures, including loss of the supervisor before a result arrives.\n * @category execution\n * @since 1.0.0\n */\nexport const status = (handle: ChildProcessHandle): Effect.Effect<Status, PlatformError.PlatformError> =>\n handle.exitCode.pipe(\n Effect.map((code): Status => ({ code, signal: null })),\n Effect.catch((error) => {\n const cause = \"cause\" in error.reason ? error.reason.cause : undefined\n const signal = typeof cause === \"object\" && cause !== null && \"signal\" in cause ? cause.signal : undefined\n return typeof signal === \"string\" && /^SIG[A-Z0-9]+$/.test(signal)\n ? Effect.succeed({ code: null, signal: signal as ChildProcess.Signal })\n : Effect.fail(error)\n })\n )\n"]}
1
+ {"version":3,"file":"ScopedProcess.js","sourceRoot":"","sources":["../../src/ScopedProcess.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Scoped transient commands with the host's process-tree cleanup policy.\n * @since 1.0.0\n */\n\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport type * as PlatformError from \"effect/PlatformError\"\nimport * as Scope from \"effect/Scope\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport type { ChildProcessHandle } from \"effect/unstable/process/ChildProcessSpawner\"\nimport * as PipedProcess from \"./internal/PipedProcess.ts\"\nimport { targetPidOf } from \"./internal/ProcessSupervisor.ts\"\nimport * as ProcessReaper from \"./ProcessReaper.ts\"\n\n/**\n * One command's literal argv, environment, pipes and termination policy.\n * @category models\n * @since 1.0.0\n */\nexport interface Options extends ChildProcess.KillOptions {\n readonly command: string\n readonly args?: ReadonlyArray<string> | undefined\n readonly cwd?: string | undefined\n readonly env?: Readonly<Record<string, string | undefined>> | undefined\n readonly stdin?: \"ignore\" | \"pipe\" | undefined\n readonly windowsVerbatimArguments?: boolean | undefined\n readonly windowsHide?: boolean | undefined\n}\n\n/**\n * The managed owner identity and the actual target identity are distinct.\n * @category models\n * @since 1.0.0\n */\nexport interface Handle extends ChildProcessHandle {\n /** The native target's pid, for diagnostics and service liveness. */\n readonly targetPid: number\n}\n\n/**\n * Starts a pipe-based command and contains its lifetime inside the caller's\n * scope. The returned pid names the live supervisor; exitCode reports\n * the actual target. The private parent connection stops the tree on host loss,\n * and the supervisor's group guardian stops the group on supervisor loss.\n * Transient commands have no durable ledger; durable hosts use NodeHost instead.\n *\n * Unconsumed output stays in bounded native buffers until it is read or the\n * scope closes. Consume stdout and stderr alongside exitCode: a command can\n * block when an unread pipe is full.\n *\n * Failed startup closes its child scope before returning an error, even when\n * the caller catches that error and retains the surrounding scope.\n * @category constructors\n * @since 1.0.0\n */\nexport const spawn = (\n options: Options\n): Effect.Effect<Handle, PlatformError.PlatformError, Scope.Scope> =>\n Effect.uninterruptibleMask((restore) =>\n Effect.gen(function*() {\n const scope = yield* Scope.fork(yield* Scope.Scope)\n const command = ChildProcess.make(options.command, [...options.args ?? []], {\n cwd: options.cwd,\n env: options.env,\n extendEnv: false,\n stdin: options.stdin ?? \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n detached: process.platform !== \"win32\",\n killSignal: options.killSignal ?? \"SIGTERM\",\n forceKillAfter: options.forceKillAfter ?? 2000,\n windowsHide: options.windowsHide ?? true,\n // Preserve the target's native option through the private protocol.\n ...{ windowsVerbatimArguments: options.windowsVerbatimArguments }\n })\n return yield* restore(\n Effect.gen(function*() {\n const prepared = yield* ProcessReaper.processLifecycle(\n command,\n (command) => PipedProcess.spawn(command, false, true)\n )\n yield* prepared.activate\n const targetPid = targetPidOf(prepared.handle)\n if (targetPid === undefined) {\n return yield* Effect.fail(\n PipedProcess.failure(\"spawn\", new Error(\"The supervisor did not identify its target\"))\n )\n }\n return Object.defineProperty(prepared.handle, \"targetPid\", { value: targetPid, enumerable: true }) as Handle\n }).pipe(Scope.provide(scope))\n ).pipe(\n Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause)))\n )\n })\n )\n\n/**\n * The native command's result, preserving a signal instead of inventing a code.\n * @category models\n * @since 1.0.0\n */\nexport interface Status {\n readonly code: number | null\n readonly signal: ChildProcess.Signal | null\n}\n\n/**\n * Reads the target's result. Failures without an actual target signal remain\n * platform failures, including loss of the supervisor before a result arrives.\n * @category execution\n * @since 1.0.0\n */\nexport const status = (handle: ChildProcessHandle): Effect.Effect<Status, PlatformError.PlatformError> =>\n handle.exitCode.pipe(\n Effect.map((code): Status => ({ code, signal: null })),\n Effect.catch((error) => {\n const cause = \"cause\" in error.reason ? error.reason.cause : undefined\n const signal = typeof cause === \"object\" && cause !== null && \"signal\" in cause ? cause.signal : undefined\n return typeof signal === \"string\" && /^SIG[A-Z0-9]+$/.test(signal)\n ? Effect.succeed({ code: null, signal: signal as ChildProcess.Signal })\n : Effect.fail(error)\n })\n )\n"]}
@@ -102,6 +102,8 @@ export declare class Control {
102
102
  targetDone: boolean;
103
103
  ownerCreation: unknown;
104
104
  targetPid: number | undefined;
105
+ /** The owner's group guardian: a member that is neither target nor owner. */
106
+ guardianPid: number | undefined;
105
107
  ownerDone: boolean;
106
108
  spawnFailed: boolean;
107
109
  cleanupFailed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"ProcessSupervisor.d.ts","sourceRoot":"","sources":["../../../src/internal/ProcessSupervisor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ProcessSupervisor.d.ts","sourceRoot":"","sources":["../../../src/internal/ProcessSupervisor.ts"],"names":[],"mappings":"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"}
@@ -176,6 +176,8 @@ export class Control {
176
176
  targetDone = false;
177
177
  ownerCreation;
178
178
  targetPid;
179
+ /** The owner's group guardian: a member that is neither target nor owner. */
180
+ guardianPid;
179
181
  ownerDone = false;
180
182
  spawnFailed = false;
181
183
  cleanupFailed = false;
@@ -379,11 +381,15 @@ export class Control {
379
381
  this.ready.resolve(Number(message.pid));
380
382
  return;
381
383
  case "spawned":
382
- if (!this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1) {
384
+ if (!this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) ||
385
+ Number(message.pid) <= 1 ||
386
+ message.guardian !== undefined && (!Number.isSafeInteger(message.guardian) || Number(message.guardian) <= 1)) {
383
387
  throw processFault("status_invalid", "Invalid target startup");
384
388
  }
385
389
  this.receivedStarted = true;
386
390
  this.targetPid = Number(message.pid);
391
+ if (message.guardian !== undefined)
392
+ this.guardianPid = Number(message.guardian);
387
393
  this.started.resolve();
388
394
  return;
389
395
  case "spawn_error":
@@ -494,7 +500,8 @@ export const prepare = (system, policy, transport = "native") => (command, spawn
494
500
  const observed = snapshot();
495
501
  if (observed === undefined || observed.ownGroup === raw.pid)
496
502
  return false;
497
- const running = observed.members.filter((member) => !member.zombie);
503
+ // The guardian leaves with the owner's final group SIGKILL.
504
+ const running = observed.members.filter((member) => !member.zombie && member.pid !== control.guardianPid);
498
505
  return running.length === 1 && running[0].pid === raw.pid;
499
506
  };
500
507
  // This observation only shortens the owner's deadline. The live owner makes
@@ -1 +1 @@
1
- {"version":3,"file":"ProcessSupervisor.js","sourceRoot":"","sources":["../../../src/internal/ProcessSupervisor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Private parent connection for a POSIX process owner. Effect retains ownership\n * of the caller's streams; separate sockets carry requests and lifetime status.\n * @since 1.0.0\n */\n\nimport type { Lifecycle } from \"@smthrs/kernel/ContainedSpawner\"\nimport * as Channel from \"effect/Channel\"\nimport * as Clock from \"effect/Clock\"\nimport * as Effect from \"effect/Effect\"\nimport * as PlatformError from \"effect/PlatformError\"\nimport * as Sink from \"effect/Sink\"\nimport * as Stream from \"effect/Stream\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport { type ChildProcessHandle, ExitCode, makeHandle } from \"effect/unstable/process/ChildProcessSpawner\"\nimport { randomBytes } from \"node:crypto\"\nimport { chmodSync, mkdtempSync, rmdirSync, rmSync } from \"node:fs\"\nimport { createConnection, createServer, type Socket } from \"node:net\"\nimport { tmpdir } from \"node:os\"\nimport { join, parse, resolve } from \"node:path\"\nimport * as Tls from \"node:tls\"\nimport { standardFdsOf } from \"./PipedProcess.ts\"\nimport type { Policy, Snapshot, System } from \"./ProcessCleanup.ts\"\nimport { NativeProcessError, processFault } from \"./ProcessFault.ts\"\nimport { source } from \"./SupervisorProgram.ts\"\nimport { resolveJobExecutable, WindowsProcessJob } from \"./WindowsProcessJob.ts\"\n\nconst startupMs = 5000\nconst deliveryMs = 500\nconst exitAllowanceMs = 2500\n// Host-wide process observations can exceed a socket-delivery deadline on a\n// loaded machine. Keep verification bounded without mistaking that delay for\n// an unclean exit; an unknown observation still never counts as success.\nconst verificationMs = 2500\nconst targets = new WeakMap<ChildProcessHandle, Control>()\n// Native owners and sockets keep running when the caller freezes its Clock.\n// Their delivery bounds and cleanup retries must keep running with them.\nconst processClock = Clock.Clock.defaultValue()\n\n/**\n * Actual service pid, distinct from the owner recorded by the host.\n * @private\n * @since 1.0.0\n */\nexport const targetPidOf = (handle: ChildProcessHandle): number | undefined => targets.get(handle)?.targetPid\n\n/** Native error fields remain data on the public PlatformError cause. */\nconst nativeError = (cause: unknown): Error & { code?: string | undefined; syscall?: string | undefined } => {\n if (cause instanceof Error) return cause\n const value = (cause ?? {}) as Record<string, unknown>\n const text = (field: string): string | undefined => typeof value[field] === \"string\" ? value[field] : undefined\n return new NativeProcessError({\n message: text(\"message\") ?? \"The process supervisor failed\",\n code: text(\"code\"),\n errno: typeof value.errno === \"number\" ? value.errno : undefined,\n reason: text(\"reason\"),\n syscall: text(\"syscall\"),\n path: text(\"path\"),\n signal: text(\"signal\")\n })\n}\n\n/**\n * Preserve the platform's errno and signal vocabulary across the private wire.\n * @private\n * @since 1.0.0\n */\nexport const failure = (method: string, command: string, cause: unknown): PlatformError.PlatformError => {\n const error = nativeError(cause)\n const tags: Readonly<Record<string, PlatformError.SystemErrorTag>> = {\n ENOENT: \"NotFound\",\n EACCES: \"PermissionDenied\",\n EEXIST: \"AlreadyExists\",\n EISDIR: \"BadResource\",\n ENOTDIR: \"BadResource\",\n ELOOP: \"BadResource\",\n EBUSY: \"Busy\"\n }\n return PlatformError.systemError({\n _tag: tags[error.code ?? \"\"] ?? \"Unknown\",\n module: \"ChildProcess\",\n method,\n pathOrDescriptor: command,\n syscall: error.syscall,\n description: error.message,\n cause: error\n })\n}\n\n/**\n * The observation behind an unverified cleanup, in the message itself: a\n * failure report usually shows only the message, and whether the receipt, the\n * kernel or the snapshot was missing decides host load versus a live survivor.\n * @private\n * @since 1.0.0\n */\nexport const unverifiedCleanup = (\n control: {\n readonly fault: unknown\n readonly cleanupFailed: boolean\n readonly cleanupAcknowledged: boolean\n readonly targetDone: boolean\n },\n cleanupRequired: boolean,\n vacant: boolean,\n observed: Snapshot | undefined\n): string =>\n [\n `target exited: ${control.targetDone}`,\n `cleanup receipt: ${\n control.cleanupFailed\n ? \"failed\"\n : !cleanupRequired\n ? \"not required\"\n : control.cleanupAcknowledged\n ? \"acknowledged\"\n : \"missing\"\n }`,\n `group vacant: ${vacant}`,\n observed === undefined\n ? \"group snapshot: unavailable\"\n : `group members: ${\n observed.members.length === 0\n ? \"none\"\n : observed.members.map((member) => `${member.pid} ${member.zombie ? \"zombie\" : \"live\"}`).join(\", \")\n }; host group ${observed.ownGroup}`,\n ...(control.fault === undefined\n ? []\n : [`fault: ${String((control.fault as { message?: unknown })?.message ?? control.fault)}`])\n ].join(\"; \")\n\nconst promise = <A>() => {\n let resolve!: (value: A) => void\n let reject!: (cause: unknown) => void\n const promise = new Promise<A>((yes, no) => {\n resolve = yes\n reject = no\n })\n // A status may arrive before its Effect consumer starts waiting.\n void promise.catch(() => {})\n return { promise, resolve, reject }\n}\n\nconst wait = <A>(value: Promise<A>, method: string, command: string) =>\n Effect.tryPromise({ try: () => value, catch: (cause) => failure(method, command, cause) })\n\nconst bounded = <A, E, R>(effect: Effect.Effect<A, E, R>, millis: number, method: string, command: string) =>\n effect.pipe(\n Effect.timeoutOrElse({\n duration: millis,\n orElse: () =>\n Effect.fail(\n failure(method, command, processFault(\"supervisor_timeout\", `Process supervisor ${method} timed out`))\n )\n }),\n Effect.provideService(Clock.Clock, processClock)\n )\n\n/**\n * Standalone application executables do not implement the runtime's eval CLI.\n * Refuse them before spawning rather than recursively launching the application.\n * @private\n * @since 1.0.0\n */\nexport const bootstrapArguments = (runtime: { readonly bun: boolean; readonly main: string; readonly sea: boolean }) =>\n runtime.sea || runtime.main.startsWith(\"/$bunfs/\")\n ? Effect.fail(\n failure(\n \"spawn\",\n process.execPath,\n processFault(\n \"runtime_unsupported\",\n \"Process supervision requires a Node or Bun runtime executable, not a compiled application\"\n )\n )\n )\n : Effect.succeed(runtime.bun ? [\"--no-env-file\", \"--config=/dev/null\"] : [])\n\nconst channelEnvironment = \"SMITHERS_PROCESS_CHANNEL\"\nconst tlsOptions = { minVersion: \"TLSv1.3\", maxVersion: \"TLSv1.3\", ciphers: \"TLS_AES_128_GCM_SHA256\" } as const\n\n/**\n * Connect an owner to its authenticated private channel.\n * @private\n * @since 1.0.0\n */\nexport const connectOwner = (path: string, environment: Readonly<Record<string, string | undefined>>): Socket => {\n const encoded = environment[channelEnvironment]\n if (encoded === undefined) return createConnection(path)\n const channel = JSON.parse(encoded) as { key: string; status: number; requests: number }\n return Tls.connect({\n ...tlsOptions,\n host: \"127.0.0.1\",\n port: path.endsWith(\"/r\") ? channel.requests : channel.status,\n pskCallback: () => ({ identity: \"smithers-owner\", psk: Buffer.from(channel.key, \"hex\") })\n })\n}\n\n/**\n * Kept separate from Effect scopes so native socket callbacks only settle\n * promises; none can start an unowned fiber or signal an observed process id.\n * @private\n * @since 1.0.0\n */\nexport class Control {\n readonly ready = promise<number>()\n readonly started = promise<void>()\n readonly exited = promise<ExitCode>()\n readonly lost = promise<never>()\n readonly ended = promise<void>()\n readonly requestsReady = promise<void>()\n readonly directory: string\n readonly path: string\n readonly requestPath: string\n readonly server\n readonly requestServer\n readonly listening: Promise<void>\n private readonly key: Buffer | undefined\n private readonly connections = new Set<Socket>()\n socket: Socket | undefined\n requestSocket: Socket | undefined\n targetDone = false\n ownerCreation: unknown\n targetPid: number | undefined\n ownerDone = false\n spawnFailed = false\n cleanupFailed = false\n cleanupAcknowledged = false\n activationSent = false\n closeSent = false\n fault: unknown\n onTargetExit: () => void = () => {}\n onCleanup: () => void = () => {}\n private receivedReady = false\n private receivedStarted = false\n private withdrawn = false\n\n constructor(transport: \"native\" | \"tls\" = \"native\") {\n this.key = transport === \"tls\" || process.platform === \"win32\" ? randomBytes(32) : undefined\n this.directory = mkdtempSync(this.key === undefined ? \"/tmp/sm-p-\" : join(tmpdir(), \"sm-p-\"))\n this.path = `${this.directory}/s`\n this.requestPath = `${this.directory}/r`\n const servers: Array<ReturnType<typeof createServer>> = []\n try {\n chmodSync(this.directory, 0o700)\n this.server = this.makeServer((socket) => this.accept(socket))\n servers.push(this.server)\n this.requestServer = this.makeServer((socket) => this.acceptRequests(socket))\n servers.push(this.requestServer)\n this.listening = Promise.all([\n new Promise<void>((resolve, reject) => {\n this.server.once(\"error\", reject)\n if (this.key === undefined) this.server.listen(this.path, resolve)\n else this.server.listen(0, \"127.0.0.1\", resolve)\n }),\n new Promise<void>((resolve, reject) => {\n this.requestServer.once(\"error\", reject)\n if (this.key === undefined) this.requestServer.listen(this.requestPath, resolve)\n else this.requestServer.listen(0, \"127.0.0.1\", resolve)\n })\n ]).then(() => {})\n } catch (cause) {\n for (const server of servers) server.close()\n rmSync(this.directory, { recursive: true, force: true })\n throw cause\n }\n }\n\n private makeServer(accept: (socket: Socket) => void): ReturnType<typeof createServer> {\n if (this.key === undefined) return createServer(accept)\n const server = Tls.createServer({\n ...tlsOptions,\n handshakeTimeout: startupMs,\n pskCallback: (_socket, identity) => identity === \"smithers-owner\" ? this.key! : null\n }, accept)\n server.on(\"connection\", (socket) => {\n this.connections.add(socket)\n socket.once(\"close\", () => this.connections.delete(socket))\n })\n server.on(\"tlsClientError\", (_error, socket) => socket.destroy())\n return server\n }\n\n /** Only the trusted owner receives this environment; target configuration replaces it. */\n environment(): Readonly<Record<string, string>> {\n if (this.key === undefined) return {}\n const status = this.server.address() as { port: number }\n const requests = this.requestServer.address() as { port: number }\n return {\n [channelEnvironment]: JSON.stringify({\n key: this.key.toString(\"hex\"),\n status: status.port,\n requests: requests.port\n })\n }\n }\n\n /** The test peer uses the same authenticated transport as the isolated owner. */\n connect(requests = false): Socket {\n return connectOwner(requests ? this.requestPath : this.path, this.environment())\n }\n\n /** Validate the stored READY after the raw spawn effect has returned its pid. */\n withdraw(pid: number, actual: number): void {\n if (pid !== actual) throw processFault(\"identity_mismatch\", \"Wrong supervisor identity\")\n this.server.close()\n this.server.unref()\n this.requestServer.close()\n this.requestServer.unref()\n // Node may unlink the owned socket synchronously inside server.close().\n rmSync(this.path, { force: true })\n rmSync(this.requestPath, { force: true })\n rmdirSync(this.directory)\n this.withdrawn = true\n }\n\n /** Request EOF asks for cleanup; leave its independent status reader intact. */\n disconnect(): void {\n this.requestSocket?.destroy()\n }\n\n dispose(): void {\n for (const socket of this.connections) socket.destroy()\n this.disconnect()\n this.socket?.destroy()\n this.server.close()\n this.requestServer.close()\n if (!this.withdrawn) rmSync(this.directory, { recursive: true, force: true })\n }\n\n rawEnded(): void {\n this.ownerDone = true\n // An accepted socket may still have buffered status frames. Its close event\n // rejects missing outcomes only after Node has delivered those frames.\n if (this.socket === undefined) this.closed()\n }\n\n write(message: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this.requestSocket\n if (socket === undefined || socket.destroyed || !socket.writable) {\n reject(processFault(\"control_channel_closed\", \"Private process control channel closed\"))\n return\n }\n const data = `${JSON.stringify(message)}\\n`\n if (Buffer.byteLength(data) > 4 * 1024 * 1024) {\n reject(processFault(\"configuration_too_large\", \"Process configuration exceeds the private frame limit\"))\n return\n }\n socket.write(data, (error) => error ? reject(error) : resolve())\n })\n }\n\n private closed(): void {\n this.disconnect()\n const cause = this.fault ??\n processFault(\"outcome_missing\", \"Process supervisor closed before reporting its outcome\")\n if (this.activationSent && !this.targetDone && !this.spawnFailed) this.lost.reject(cause)\n this.ready.reject(cause)\n this.requestsReady.reject(cause)\n this.started.reject(cause)\n this.exited.reject(cause)\n this.ended.resolve()\n }\n\n private acceptRequests(socket: Socket): void {\n if (this.requestSocket !== undefined) {\n socket.destroy()\n return\n }\n this.requestSocket = socket\n // A late write may fail after the owner has sent its last status frames.\n // Destroying this socket must never discard those frames on the reader.\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n this.requestsReady.resolve()\n }\n\n private accept(socket: Socket): void {\n if (this.socket !== undefined) {\n socket.destroy()\n return\n }\n this.socket = socket\n let buffer = \"\"\n socket.setEncoding(\"utf8\")\n socket.on(\"data\", (data: string) => {\n try {\n buffer += data\n if (Buffer.byteLength(buffer) > 16 * 1024) {\n throw processFault(\"status_too_large\", \"Process status frame exceeds its limit\")\n }\n for (;;) {\n const end = buffer.indexOf(\"\\n\")\n if (end < 0) break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + 1)\n this.receive(JSON.parse(line))\n }\n } catch (cause) {\n this.fault = cause\n socket.destroy()\n }\n })\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n socket.once(\"close\", () => this.closed())\n }\n\n private receive(value: unknown): void {\n if (typeof value !== \"object\" || value === null) throw processFault(\"status_invalid\", \"Invalid process status\")\n const message = value as Record<string, unknown>\n switch (message.type) {\n case \"ready\":\n if (\n this.receivedReady || message.version !== 1 || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1\n ) {\n throw processFault(\"status_invalid\", \"Invalid process readiness\")\n }\n this.receivedReady = true\n this.ownerCreation = message.created\n this.ready.resolve(Number(message.pid))\n return\n case \"spawned\":\n if (\n !this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1\n ) {\n throw processFault(\"status_invalid\", \"Invalid target startup\")\n }\n this.receivedStarted = true\n this.targetPid = Number(message.pid)\n this.started.resolve()\n return\n case \"spawn_error\":\n if (!this.activationSent || this.receivedStarted) {\n throw processFault(\"status_invalid\", \"Invalid target spawn failure\")\n }\n this.spawnFailed = true\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"fault\":\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"exit\":\n if (\n !this.receivedStarted || this.targetDone ||\n !(Number.isInteger(message.code) && Number(message.code) >= 0 && message.signal === null ||\n message.code === null && typeof message.signal === \"string\" && /^SIG[A-Z0-9]+$/.test(message.signal))\n ) {\n throw processFault(\"status_invalid\", \"Invalid target exit status\")\n }\n this.targetDone = true\n if (message.code === null) {\n this.exited.reject({\n message: `Process interrupted due to receipt of signal: '${message.signal}'`,\n signal: message.signal\n })\n } else this.exited.resolve(ExitCode(Number(message.code)))\n this.onTargetExit()\n return\n case \"cleanup_error\":\n this.cleanupFailed = true\n this.fault = message\n return\n case \"cleanup\":\n this.cleanupAcknowledged = true\n this.onCleanup()\n return\n default:\n throw processFault(\"status_unknown\", \"Unknown process status\")\n }\n }\n}\n\n/**\n * Prepare a private, independently bounded process owner before target launch.\n * @private\n * @since 1.0.0\n */\nexport const prepare = (\n system: System,\n policy: (\n options: ChildProcess.KillOptions,\n defaults?: ChildProcess.KillOptions\n ) => Effect.Effect<Policy, PlatformError.PlatformError>,\n transport: \"native\" | \"tls\" = \"native\"\n): Lifecycle =>\n(command, spawn) =>\n Effect.gen(function*() {\n const initial = yield* policy(command.options)\n const bun = process.versions.bun !== undefined\n const sea = bun ? false : (yield* Effect.tryPromise({\n try: () => import(\"node:sea\"),\n catch: (cause) => failure(\"spawn\", process.execPath, cause)\n })).isSea()\n const bootstrap = yield* bootstrapArguments({\n bun,\n sea,\n main: (globalThis as { readonly Bun?: { readonly main?: string } }).Bun?.main ?? \"\"\n })\n const windows = system.platform === \"win32\"\n const grouped = !windows && (command.options.detached ?? true)\n const jobExecutable = windows ?\n yield* Effect.try({\n try: resolveJobExecutable,\n catch: (cause) => failure(\"spawn\", command.command, cause)\n }) :\n undefined\n const control = yield* Effect.acquireRelease(\n Effect.try({ try: () => new Control(transport), catch: (cause) => failure(\"spawn\", command.command, cause) }),\n (control) => Effect.sync(() => control.dispose())\n )\n yield* bounded(wait(control.listening, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n const raw = yield* spawn(ChildProcess.make(process.execPath, [\n ...bootstrap,\n \"-e\",\n source,\n control.path,\n grouped ? \"group\" : \"direct\"\n ], {\n ...command.options,\n cwd: parse(process.execPath).root,\n env: {\n PATH: \"/usr/bin:/bin\",\n HOME: \"/\",\n XDG_CONFIG_HOME: \"/\",\n BUN_RUNTIME_TRANSPILER_CACHE_PATH: \"0\",\n ...control.environment(),\n ...(jobExecutable === undefined ? {} : { SMITHERS_PROCESS_JOB_HELPER: jobExecutable })\n },\n extendEnv: false,\n shell: false,\n detached: grouped,\n killSignal: \"SIGTERM\",\n forceKillAfter: initial.graceMs\n }))\n yield* Effect.exit(raw.exitCode).pipe(Effect.andThen(Effect.sync(() => control.rawEnded())), Effect.forkScoped)\n let job: WindowsProcessJob | undefined\n let settled = false\n let referenced = true\n let reref: Effect.Effect<void, PlatformError.PlatformError> = Effect.void\n let selected = initial\n let requireCleanupReceipt = false\n const snapshot = () => system.snapshot(raw.pid)\n const alone = () => {\n if (!grouped) return control.targetDone\n const observed = snapshot()\n if (observed === undefined || observed.ownGroup === raw.pid) return false\n const running = observed.members.filter((member) => !member.zombie)\n return running.length === 1 && running[0]!.pid === raw.pid\n }\n // This observation only shortens the owner's deadline. The live owner makes\n // the signal, so neither a stale observation nor a reused pid grants a kill.\n control.onTargetExit = () => {\n // An explicit stop already owns its deadline and escaped-child sweep.\n // Natural exit must not replace that policy with a second fast stop.\n if (control.closeSent) return\n if (!alone()) return\n control.closeSent = true\n void control.write({ type: \"stop\", killSignal: \"SIGKILL\", fast: true }).catch(() => control.disconnect())\n }\n const finish = yield* Effect.cached(Effect.gen(function*() {\n yield* bounded(Effect.exit(raw.exitCode), selected.graceMs + exitAllowanceMs, \"kill\", command.command).pipe(\n Effect.catch((cause) =>\n job === undefined ? Effect.fail(cause) : Effect.gen(function*() {\n // The native guardian can terminate a stalled owner independently.\n job!.stop()\n yield* bounded(Effect.exit(raw.exitCode), exitAllowanceMs, \"kill\", command.command)\n })\n )\n )\n if (job !== undefined) {\n yield* bounded(wait(job.settled.promise, \"kill\", command.command), 5500, \"kill\", command.command)\n settled = true\n return\n }\n yield* bounded(wait(control.ended.promise, \"kill\", command.command), deliveryMs, \"kill\", command.command).pipe(\n Effect.ignore\n )\n const deadline = Date.now() + verificationMs\n for (;;) {\n // The kernel's ESRCH proves the group empty with no fork. A `ps`\n // snapshot can go unanswered on a loaded host, so it only decides what\n // the kernel cannot: a group still holding zombies, or an unknown one.\n // A live member keeps both answers false. This host is alive, so a\n // vacant group is never this host's own group.\n const vacant = grouped && system.vacant(raw.pid)\n const observed = grouped && !vacant ? snapshot() : undefined\n settled = !control.cleanupFailed && (!requireCleanupReceipt || control.cleanupAcknowledged) && (grouped\n ? vacant ||\n observed !== undefined && observed.ownGroup !== raw.pid && observed.members.every((member) => member.zombie)\n : control.targetDone || control.spawnFailed || !control.activationSent)\n if (settled) return\n if (Date.now() >= deadline) {\n return yield* Effect.fail(\n failure(\n \"kill\",\n command.command,\n processFault(\n \"cleanup_unverified\",\n \"Process cleanup could not be verified; its ledger record is retained \" +\n `(${unverifiedCleanup(control, requireCleanupReceipt, vacant, observed)})`,\n {\n cause: {\n fault: control.fault,\n cleanupFailed: control.cleanupFailed,\n cleanupRequired: requireCleanupReceipt,\n cleanupAcknowledged: control.cleanupAcknowledged,\n targetDone: control.targetDone,\n groupVacant: vacant,\n ownerObserved: observed !== undefined,\n members: observed?.members\n }\n }\n )\n )\n )\n }\n yield* Effect.sleep(10).pipe(Effect.provideService(Clock.Clock, processClock))\n }\n }))\n const kill = (options: ChildProcess.KillOptions = {}) =>\n Effect.gen(function*() {\n const requested = yield* policy(options, command.options)\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n if (!control.closeSent) {\n control.closeSent = true\n selected = requested\n // An empty original group cannot prove an explicit escaped-descendant\n // sweep succeeded if its status frames were lost. Startup and natural\n // completion have no such additional contract.\n requireCleanupReceipt = grouped && control.activationSent && !control.spawnFailed && !control.targetDone\n yield* bounded(\n wait(\n control.write({\n type: \"stop\",\n explicit: true,\n ...requested,\n // A live target can move out of this group with setsid().\n // Only an owner whose target was never activated can replace\n // the requested signal; natural exit has its own fast path.\n killSignal: !control.activationSent && alone() ? \"SIGKILL\" : requested.killSignal\n }),\n \"kill\",\n command.command\n ),\n deliveryMs,\n \"kill\",\n command.command\n )\n .pipe(Effect.catch(() => Effect.sync(() => control.disconnect())))\n }\n yield* finish\n }).pipe(Effect.uninterruptible)\n yield* Effect.addFinalizer(() =>\n kill().pipe(\n // A stuck owner keeps its ledger entry. Disable the underlying spawner's\n // unconditional group-kill finalizer rather than signal a stale identity.\n Effect.ensuring(\n Effect.suspend(() =>\n settled ? Effect.void : Effect.andThen(\n raw.unref,\n Effect.sync(() => {\n job?.stop()\n job?.reference(false)\n control.disconnect()\n })\n )\n ).pipe(Effect.orDie)\n ),\n Effect.orDie\n )\n )\n const ready = yield* bounded(\n wait(control.ready.promise, \"spawn\", command.command),\n startupMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.requestsReady.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n yield* Effect.try({\n try: () => control.withdraw(ready, raw.pid),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n if (windows) {\n job = yield* Effect.try({\n try: () => new WindowsProcessJob(raw.pid, control.ownerCreation, jobExecutable!),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n yield* bounded(wait(job.ready.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }\n const acknowledgeCleanup = windows || transport === \"tls\"\n if (acknowledgeCleanup) {\n control.onCleanup = () => {\n if (!control.ownerDone) {\n void control.write({ type: \"cleanup_ack\" }).catch(() => control.disconnect())\n }\n }\n }\n const options = command.options\n // Match Effect/Node's undefined-vs-empty environment semantics in the host,\n // before replacing the helper's environment with its isolated bootstrap.\n const env = options.extendEnv ? { ...process.env, ...options.env } : options.env ?? { ...process.env }\n yield* bounded(\n wait(\n control.write({\n type: \"configure\",\n acknowledgeCleanup,\n command: command.command,\n args: command.args,\n cwd: resolve(options.cwd ?? process.cwd()),\n env,\n shell: options.shell,\n windowsHide: options.windowsHide ?? true,\n windowsVerbatimArguments:\n (options as ChildProcess.CommandOptions & { readonly windowsVerbatimArguments?: boolean })\n .windowsVerbatimArguments,\n standardFds: standardFdsOf(raw),\n userFds: [\n ...new Set(\n Object.keys(options.additionalFds ?? {}).map(ChildProcess.parseFdName)\n .filter((fd): fd is number => fd !== undefined)\n )\n ],\n ...initial\n }),\n \"spawn\",\n command.command\n ),\n deliveryMs,\n \"spawn\",\n command.command\n )\n const activate = yield* Effect.cached(Effect.gen(function*() {\n control.activationSent = true\n yield* bounded(\n wait(control.write({ type: \"start\" }), \"spawn\", command.command),\n deliveryMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.started.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }))\n const unref = Effect.gen(function*() {\n if (referenced) {\n reref = yield* raw.unref\n job?.reference(false)\n control.socket?.unref()\n control.requestSocket?.unref()\n referenced = false\n }\n return Effect.gen(function*() {\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n })\n })\n const output = <A>(stream: Stream.Stream<A, PlatformError.PlatformError>) =>\n stream.pipe(\n Stream.interruptWhen(wait(control.lost.promise, \"read\", command.command))\n )\n const input = <A>(sink: Sink.Sink<A, Uint8Array, never, PlatformError.PlatformError>) =>\n Sink.fromChannel(\n Sink.toChannel(sink).pipe(Channel.interruptWhen(wait(control.lost.promise, \"write\", command.command)))\n )\n const handle = makeHandle({\n ...raw,\n exitCode: wait(control.exited.promise, \"exitCode\", command.command),\n isRunning: Effect.sync(() => !control.targetDone && !control.ownerDone),\n stdin: input(raw.stdin),\n getInputFd: (fd) => input(raw.getInputFd(fd)),\n stdout: output(raw.stdout),\n stderr: output(raw.stderr),\n all: output(raw.all),\n getOutputFd: (fd) => output(raw.getOutputFd(fd)),\n kill,\n unref\n })\n targets.set(handle, control)\n return {\n handle,\n activate,\n settled: Effect.sync(() => settled)\n }\n })\n"]}
1
+ {"version":3,"file":"ProcessSupervisor.js","sourceRoot":"","sources":["../../../src/internal/ProcessSupervisor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Private parent connection for a POSIX process owner. Effect retains ownership\n * of the caller's streams; separate sockets carry requests and lifetime status.\n * @since 1.0.0\n */\n\nimport type { Lifecycle } from \"@smthrs/kernel/ContainedSpawner\"\nimport * as Channel from \"effect/Channel\"\nimport * as Clock from \"effect/Clock\"\nimport * as Effect from \"effect/Effect\"\nimport * as PlatformError from \"effect/PlatformError\"\nimport * as Sink from \"effect/Sink\"\nimport * as Stream from \"effect/Stream\"\nimport * as ChildProcess from \"effect/unstable/process/ChildProcess\"\nimport { type ChildProcessHandle, ExitCode, makeHandle } from \"effect/unstable/process/ChildProcessSpawner\"\nimport { randomBytes } from \"node:crypto\"\nimport { chmodSync, mkdtempSync, rmdirSync, rmSync } from \"node:fs\"\nimport { createConnection, createServer, type Socket } from \"node:net\"\nimport { tmpdir } from \"node:os\"\nimport { join, parse, resolve } from \"node:path\"\nimport * as Tls from \"node:tls\"\nimport { standardFdsOf } from \"./PipedProcess.ts\"\nimport type { Policy, Snapshot, System } from \"./ProcessCleanup.ts\"\nimport { NativeProcessError, processFault } from \"./ProcessFault.ts\"\nimport { source } from \"./SupervisorProgram.ts\"\nimport { resolveJobExecutable, WindowsProcessJob } from \"./WindowsProcessJob.ts\"\n\nconst startupMs = 5000\nconst deliveryMs = 500\nconst exitAllowanceMs = 2500\n// Host-wide process observations can exceed a socket-delivery deadline on a\n// loaded machine. Keep verification bounded without mistaking that delay for\n// an unclean exit; an unknown observation still never counts as success.\nconst verificationMs = 2500\nconst targets = new WeakMap<ChildProcessHandle, Control>()\n// Native owners and sockets keep running when the caller freezes its Clock.\n// Their delivery bounds and cleanup retries must keep running with them.\nconst processClock = Clock.Clock.defaultValue()\n\n/**\n * Actual service pid, distinct from the owner recorded by the host.\n * @private\n * @since 1.0.0\n */\nexport const targetPidOf = (handle: ChildProcessHandle): number | undefined => targets.get(handle)?.targetPid\n\n/** Native error fields remain data on the public PlatformError cause. */\nconst nativeError = (cause: unknown): Error & { code?: string | undefined; syscall?: string | undefined } => {\n if (cause instanceof Error) return cause\n const value = (cause ?? {}) as Record<string, unknown>\n const text = (field: string): string | undefined => typeof value[field] === \"string\" ? value[field] : undefined\n return new NativeProcessError({\n message: text(\"message\") ?? \"The process supervisor failed\",\n code: text(\"code\"),\n errno: typeof value.errno === \"number\" ? value.errno : undefined,\n reason: text(\"reason\"),\n syscall: text(\"syscall\"),\n path: text(\"path\"),\n signal: text(\"signal\")\n })\n}\n\n/**\n * Preserve the platform's errno and signal vocabulary across the private wire.\n * @private\n * @since 1.0.0\n */\nexport const failure = (method: string, command: string, cause: unknown): PlatformError.PlatformError => {\n const error = nativeError(cause)\n const tags: Readonly<Record<string, PlatformError.SystemErrorTag>> = {\n ENOENT: \"NotFound\",\n EACCES: \"PermissionDenied\",\n EEXIST: \"AlreadyExists\",\n EISDIR: \"BadResource\",\n ENOTDIR: \"BadResource\",\n ELOOP: \"BadResource\",\n EBUSY: \"Busy\"\n }\n return PlatformError.systemError({\n _tag: tags[error.code ?? \"\"] ?? \"Unknown\",\n module: \"ChildProcess\",\n method,\n pathOrDescriptor: command,\n syscall: error.syscall,\n description: error.message,\n cause: error\n })\n}\n\n/**\n * The observation behind an unverified cleanup, in the message itself: a\n * failure report usually shows only the message, and whether the receipt, the\n * kernel or the snapshot was missing decides host load versus a live survivor.\n * @private\n * @since 1.0.0\n */\nexport const unverifiedCleanup = (\n control: {\n readonly fault: unknown\n readonly cleanupFailed: boolean\n readonly cleanupAcknowledged: boolean\n readonly targetDone: boolean\n },\n cleanupRequired: boolean,\n vacant: boolean,\n observed: Snapshot | undefined\n): string =>\n [\n `target exited: ${control.targetDone}`,\n `cleanup receipt: ${\n control.cleanupFailed\n ? \"failed\"\n : !cleanupRequired\n ? \"not required\"\n : control.cleanupAcknowledged\n ? \"acknowledged\"\n : \"missing\"\n }`,\n `group vacant: ${vacant}`,\n observed === undefined\n ? \"group snapshot: unavailable\"\n : `group members: ${\n observed.members.length === 0\n ? \"none\"\n : observed.members.map((member) => `${member.pid} ${member.zombie ? \"zombie\" : \"live\"}`).join(\", \")\n }; host group ${observed.ownGroup}`,\n ...(control.fault === undefined\n ? []\n : [`fault: ${String((control.fault as { message?: unknown })?.message ?? control.fault)}`])\n ].join(\"; \")\n\nconst promise = <A>() => {\n let resolve!: (value: A) => void\n let reject!: (cause: unknown) => void\n const promise = new Promise<A>((yes, no) => {\n resolve = yes\n reject = no\n })\n // A status may arrive before its Effect consumer starts waiting.\n void promise.catch(() => {})\n return { promise, resolve, reject }\n}\n\nconst wait = <A>(value: Promise<A>, method: string, command: string) =>\n Effect.tryPromise({ try: () => value, catch: (cause) => failure(method, command, cause) })\n\nconst bounded = <A, E, R>(effect: Effect.Effect<A, E, R>, millis: number, method: string, command: string) =>\n effect.pipe(\n Effect.timeoutOrElse({\n duration: millis,\n orElse: () =>\n Effect.fail(\n failure(method, command, processFault(\"supervisor_timeout\", `Process supervisor ${method} timed out`))\n )\n }),\n Effect.provideService(Clock.Clock, processClock)\n )\n\n/**\n * Standalone application executables do not implement the runtime's eval CLI.\n * Refuse them before spawning rather than recursively launching the application.\n * @private\n * @since 1.0.0\n */\nexport const bootstrapArguments = (runtime: { readonly bun: boolean; readonly main: string; readonly sea: boolean }) =>\n runtime.sea || runtime.main.startsWith(\"/$bunfs/\")\n ? Effect.fail(\n failure(\n \"spawn\",\n process.execPath,\n processFault(\n \"runtime_unsupported\",\n \"Process supervision requires a Node or Bun runtime executable, not a compiled application\"\n )\n )\n )\n : Effect.succeed(runtime.bun ? [\"--no-env-file\", \"--config=/dev/null\"] : [])\n\nconst channelEnvironment = \"SMITHERS_PROCESS_CHANNEL\"\nconst tlsOptions = { minVersion: \"TLSv1.3\", maxVersion: \"TLSv1.3\", ciphers: \"TLS_AES_128_GCM_SHA256\" } as const\n\n/**\n * Connect an owner to its authenticated private channel.\n * @private\n * @since 1.0.0\n */\nexport const connectOwner = (path: string, environment: Readonly<Record<string, string | undefined>>): Socket => {\n const encoded = environment[channelEnvironment]\n if (encoded === undefined) return createConnection(path)\n const channel = JSON.parse(encoded) as { key: string; status: number; requests: number }\n return Tls.connect({\n ...tlsOptions,\n host: \"127.0.0.1\",\n port: path.endsWith(\"/r\") ? channel.requests : channel.status,\n pskCallback: () => ({ identity: \"smithers-owner\", psk: Buffer.from(channel.key, \"hex\") })\n })\n}\n\n/**\n * Kept separate from Effect scopes so native socket callbacks only settle\n * promises; none can start an unowned fiber or signal an observed process id.\n * @private\n * @since 1.0.0\n */\nexport class Control {\n readonly ready = promise<number>()\n readonly started = promise<void>()\n readonly exited = promise<ExitCode>()\n readonly lost = promise<never>()\n readonly ended = promise<void>()\n readonly requestsReady = promise<void>()\n readonly directory: string\n readonly path: string\n readonly requestPath: string\n readonly server\n readonly requestServer\n readonly listening: Promise<void>\n private readonly key: Buffer | undefined\n private readonly connections = new Set<Socket>()\n socket: Socket | undefined\n requestSocket: Socket | undefined\n targetDone = false\n ownerCreation: unknown\n targetPid: number | undefined\n /** The owner's group guardian: a member that is neither target nor owner. */\n guardianPid: number | undefined\n ownerDone = false\n spawnFailed = false\n cleanupFailed = false\n cleanupAcknowledged = false\n activationSent = false\n closeSent = false\n fault: unknown\n onTargetExit: () => void = () => {}\n onCleanup: () => void = () => {}\n private receivedReady = false\n private receivedStarted = false\n private withdrawn = false\n\n constructor(transport: \"native\" | \"tls\" = \"native\") {\n this.key = transport === \"tls\" || process.platform === \"win32\" ? randomBytes(32) : undefined\n this.directory = mkdtempSync(this.key === undefined ? \"/tmp/sm-p-\" : join(tmpdir(), \"sm-p-\"))\n this.path = `${this.directory}/s`\n this.requestPath = `${this.directory}/r`\n const servers: Array<ReturnType<typeof createServer>> = []\n try {\n chmodSync(this.directory, 0o700)\n this.server = this.makeServer((socket) => this.accept(socket))\n servers.push(this.server)\n this.requestServer = this.makeServer((socket) => this.acceptRequests(socket))\n servers.push(this.requestServer)\n this.listening = Promise.all([\n new Promise<void>((resolve, reject) => {\n this.server.once(\"error\", reject)\n if (this.key === undefined) this.server.listen(this.path, resolve)\n else this.server.listen(0, \"127.0.0.1\", resolve)\n }),\n new Promise<void>((resolve, reject) => {\n this.requestServer.once(\"error\", reject)\n if (this.key === undefined) this.requestServer.listen(this.requestPath, resolve)\n else this.requestServer.listen(0, \"127.0.0.1\", resolve)\n })\n ]).then(() => {})\n } catch (cause) {\n for (const server of servers) server.close()\n rmSync(this.directory, { recursive: true, force: true })\n throw cause\n }\n }\n\n private makeServer(accept: (socket: Socket) => void): ReturnType<typeof createServer> {\n if (this.key === undefined) return createServer(accept)\n const server = Tls.createServer({\n ...tlsOptions,\n handshakeTimeout: startupMs,\n pskCallback: (_socket, identity) => identity === \"smithers-owner\" ? this.key! : null\n }, accept)\n server.on(\"connection\", (socket) => {\n this.connections.add(socket)\n socket.once(\"close\", () => this.connections.delete(socket))\n })\n server.on(\"tlsClientError\", (_error, socket) => socket.destroy())\n return server\n }\n\n /** Only the trusted owner receives this environment; target configuration replaces it. */\n environment(): Readonly<Record<string, string>> {\n if (this.key === undefined) return {}\n const status = this.server.address() as { port: number }\n const requests = this.requestServer.address() as { port: number }\n return {\n [channelEnvironment]: JSON.stringify({\n key: this.key.toString(\"hex\"),\n status: status.port,\n requests: requests.port\n })\n }\n }\n\n /** The test peer uses the same authenticated transport as the isolated owner. */\n connect(requests = false): Socket {\n return connectOwner(requests ? this.requestPath : this.path, this.environment())\n }\n\n /** Validate the stored READY after the raw spawn effect has returned its pid. */\n withdraw(pid: number, actual: number): void {\n if (pid !== actual) throw processFault(\"identity_mismatch\", \"Wrong supervisor identity\")\n this.server.close()\n this.server.unref()\n this.requestServer.close()\n this.requestServer.unref()\n // Node may unlink the owned socket synchronously inside server.close().\n rmSync(this.path, { force: true })\n rmSync(this.requestPath, { force: true })\n rmdirSync(this.directory)\n this.withdrawn = true\n }\n\n /** Request EOF asks for cleanup; leave its independent status reader intact. */\n disconnect(): void {\n this.requestSocket?.destroy()\n }\n\n dispose(): void {\n for (const socket of this.connections) socket.destroy()\n this.disconnect()\n this.socket?.destroy()\n this.server.close()\n this.requestServer.close()\n if (!this.withdrawn) rmSync(this.directory, { recursive: true, force: true })\n }\n\n rawEnded(): void {\n this.ownerDone = true\n // An accepted socket may still have buffered status frames. Its close event\n // rejects missing outcomes only after Node has delivered those frames.\n if (this.socket === undefined) this.closed()\n }\n\n write(message: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const socket = this.requestSocket\n if (socket === undefined || socket.destroyed || !socket.writable) {\n reject(processFault(\"control_channel_closed\", \"Private process control channel closed\"))\n return\n }\n const data = `${JSON.stringify(message)}\\n`\n if (Buffer.byteLength(data) > 4 * 1024 * 1024) {\n reject(processFault(\"configuration_too_large\", \"Process configuration exceeds the private frame limit\"))\n return\n }\n socket.write(data, (error) => error ? reject(error) : resolve())\n })\n }\n\n private closed(): void {\n this.disconnect()\n const cause = this.fault ??\n processFault(\"outcome_missing\", \"Process supervisor closed before reporting its outcome\")\n if (this.activationSent && !this.targetDone && !this.spawnFailed) this.lost.reject(cause)\n this.ready.reject(cause)\n this.requestsReady.reject(cause)\n this.started.reject(cause)\n this.exited.reject(cause)\n this.ended.resolve()\n }\n\n private acceptRequests(socket: Socket): void {\n if (this.requestSocket !== undefined) {\n socket.destroy()\n return\n }\n this.requestSocket = socket\n // A late write may fail after the owner has sent its last status frames.\n // Destroying this socket must never discard those frames on the reader.\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n this.requestsReady.resolve()\n }\n\n private accept(socket: Socket): void {\n if (this.socket !== undefined) {\n socket.destroy()\n return\n }\n this.socket = socket\n let buffer = \"\"\n socket.setEncoding(\"utf8\")\n socket.on(\"data\", (data: string) => {\n try {\n buffer += data\n if (Buffer.byteLength(buffer) > 16 * 1024) {\n throw processFault(\"status_too_large\", \"Process status frame exceeds its limit\")\n }\n for (;;) {\n const end = buffer.indexOf(\"\\n\")\n if (end < 0) break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + 1)\n this.receive(JSON.parse(line))\n }\n } catch (cause) {\n this.fault = cause\n socket.destroy()\n }\n })\n socket.on(\"error\", (cause) => {\n this.fault = cause\n })\n socket.once(\"close\", () => this.closed())\n }\n\n private receive(value: unknown): void {\n if (typeof value !== \"object\" || value === null) throw processFault(\"status_invalid\", \"Invalid process status\")\n const message = value as Record<string, unknown>\n switch (message.type) {\n case \"ready\":\n if (\n this.receivedReady || message.version !== 1 || !Number.isSafeInteger(message.pid) || Number(message.pid) <= 1\n ) {\n throw processFault(\"status_invalid\", \"Invalid process readiness\")\n }\n this.receivedReady = true\n this.ownerCreation = message.created\n this.ready.resolve(Number(message.pid))\n return\n case \"spawned\":\n if (\n !this.activationSent || this.receivedStarted || !Number.isSafeInteger(message.pid) ||\n Number(message.pid) <= 1 ||\n message.guardian !== undefined && (!Number.isSafeInteger(message.guardian) || Number(message.guardian) <= 1)\n ) {\n throw processFault(\"status_invalid\", \"Invalid target startup\")\n }\n this.receivedStarted = true\n this.targetPid = Number(message.pid)\n if (message.guardian !== undefined) this.guardianPid = Number(message.guardian)\n this.started.resolve()\n return\n case \"spawn_error\":\n if (!this.activationSent || this.receivedStarted) {\n throw processFault(\"status_invalid\", \"Invalid target spawn failure\")\n }\n this.spawnFailed = true\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"fault\":\n this.fault = message\n this.started.reject(message)\n this.exited.reject(message)\n return\n case \"exit\":\n if (\n !this.receivedStarted || this.targetDone ||\n !(Number.isInteger(message.code) && Number(message.code) >= 0 && message.signal === null ||\n message.code === null && typeof message.signal === \"string\" && /^SIG[A-Z0-9]+$/.test(message.signal))\n ) {\n throw processFault(\"status_invalid\", \"Invalid target exit status\")\n }\n this.targetDone = true\n if (message.code === null) {\n this.exited.reject({\n message: `Process interrupted due to receipt of signal: '${message.signal}'`,\n signal: message.signal\n })\n } else this.exited.resolve(ExitCode(Number(message.code)))\n this.onTargetExit()\n return\n case \"cleanup_error\":\n this.cleanupFailed = true\n this.fault = message\n return\n case \"cleanup\":\n this.cleanupAcknowledged = true\n this.onCleanup()\n return\n default:\n throw processFault(\"status_unknown\", \"Unknown process status\")\n }\n }\n}\n\n/**\n * Prepare a private, independently bounded process owner before target launch.\n * @private\n * @since 1.0.0\n */\nexport const prepare = (\n system: System,\n policy: (\n options: ChildProcess.KillOptions,\n defaults?: ChildProcess.KillOptions\n ) => Effect.Effect<Policy, PlatformError.PlatformError>,\n transport: \"native\" | \"tls\" = \"native\"\n): Lifecycle =>\n(command, spawn) =>\n Effect.gen(function*() {\n const initial = yield* policy(command.options)\n const bun = process.versions.bun !== undefined\n const sea = bun ? false : (yield* Effect.tryPromise({\n try: () => import(\"node:sea\"),\n catch: (cause) => failure(\"spawn\", process.execPath, cause)\n })).isSea()\n const bootstrap = yield* bootstrapArguments({\n bun,\n sea,\n main: (globalThis as { readonly Bun?: { readonly main?: string } }).Bun?.main ?? \"\"\n })\n const windows = system.platform === \"win32\"\n const grouped = !windows && (command.options.detached ?? true)\n const jobExecutable = windows ?\n yield* Effect.try({\n try: resolveJobExecutable,\n catch: (cause) => failure(\"spawn\", command.command, cause)\n }) :\n undefined\n const control = yield* Effect.acquireRelease(\n Effect.try({ try: () => new Control(transport), catch: (cause) => failure(\"spawn\", command.command, cause) }),\n (control) => Effect.sync(() => control.dispose())\n )\n yield* bounded(wait(control.listening, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n const raw = yield* spawn(ChildProcess.make(process.execPath, [\n ...bootstrap,\n \"-e\",\n source,\n control.path,\n grouped ? \"group\" : \"direct\"\n ], {\n ...command.options,\n cwd: parse(process.execPath).root,\n env: {\n PATH: \"/usr/bin:/bin\",\n HOME: \"/\",\n XDG_CONFIG_HOME: \"/\",\n BUN_RUNTIME_TRANSPILER_CACHE_PATH: \"0\",\n ...control.environment(),\n ...(jobExecutable === undefined ? {} : { SMITHERS_PROCESS_JOB_HELPER: jobExecutable })\n },\n extendEnv: false,\n shell: false,\n detached: grouped,\n killSignal: \"SIGTERM\",\n forceKillAfter: initial.graceMs\n }))\n yield* Effect.exit(raw.exitCode).pipe(Effect.andThen(Effect.sync(() => control.rawEnded())), Effect.forkScoped)\n let job: WindowsProcessJob | undefined\n let settled = false\n let referenced = true\n let reref: Effect.Effect<void, PlatformError.PlatformError> = Effect.void\n let selected = initial\n let requireCleanupReceipt = false\n const snapshot = () => system.snapshot(raw.pid)\n const alone = () => {\n if (!grouped) return control.targetDone\n const observed = snapshot()\n if (observed === undefined || observed.ownGroup === raw.pid) return false\n // The guardian leaves with the owner's final group SIGKILL.\n const running = observed.members.filter((member) => !member.zombie && member.pid !== control.guardianPid)\n return running.length === 1 && running[0]!.pid === raw.pid\n }\n // This observation only shortens the owner's deadline. The live owner makes\n // the signal, so neither a stale observation nor a reused pid grants a kill.\n control.onTargetExit = () => {\n // An explicit stop already owns its deadline and escaped-child sweep.\n // Natural exit must not replace that policy with a second fast stop.\n if (control.closeSent) return\n if (!alone()) return\n control.closeSent = true\n void control.write({ type: \"stop\", killSignal: \"SIGKILL\", fast: true }).catch(() => control.disconnect())\n }\n const finish = yield* Effect.cached(Effect.gen(function*() {\n yield* bounded(Effect.exit(raw.exitCode), selected.graceMs + exitAllowanceMs, \"kill\", command.command).pipe(\n Effect.catch((cause) =>\n job === undefined ? Effect.fail(cause) : Effect.gen(function*() {\n // The native guardian can terminate a stalled owner independently.\n job!.stop()\n yield* bounded(Effect.exit(raw.exitCode), exitAllowanceMs, \"kill\", command.command)\n })\n )\n )\n if (job !== undefined) {\n yield* bounded(wait(job.settled.promise, \"kill\", command.command), 5500, \"kill\", command.command)\n settled = true\n return\n }\n yield* bounded(wait(control.ended.promise, \"kill\", command.command), deliveryMs, \"kill\", command.command).pipe(\n Effect.ignore\n )\n const deadline = Date.now() + verificationMs\n for (;;) {\n // The kernel's ESRCH proves the group empty with no fork. A `ps`\n // snapshot can go unanswered on a loaded host, so it only decides what\n // the kernel cannot: a group still holding zombies, or an unknown one.\n // A live member keeps both answers false. This host is alive, so a\n // vacant group is never this host's own group.\n const vacant = grouped && system.vacant(raw.pid)\n const observed = grouped && !vacant ? snapshot() : undefined\n settled = !control.cleanupFailed && (!requireCleanupReceipt || control.cleanupAcknowledged) && (grouped\n ? vacant ||\n observed !== undefined && observed.ownGroup !== raw.pid && observed.members.every((member) => member.zombie)\n : control.targetDone || control.spawnFailed || !control.activationSent)\n if (settled) return\n if (Date.now() >= deadline) {\n return yield* Effect.fail(\n failure(\n \"kill\",\n command.command,\n processFault(\n \"cleanup_unverified\",\n \"Process cleanup could not be verified; its ledger record is retained \" +\n `(${unverifiedCleanup(control, requireCleanupReceipt, vacant, observed)})`,\n {\n cause: {\n fault: control.fault,\n cleanupFailed: control.cleanupFailed,\n cleanupRequired: requireCleanupReceipt,\n cleanupAcknowledged: control.cleanupAcknowledged,\n targetDone: control.targetDone,\n groupVacant: vacant,\n ownerObserved: observed !== undefined,\n members: observed?.members\n }\n }\n )\n )\n )\n }\n yield* Effect.sleep(10).pipe(Effect.provideService(Clock.Clock, processClock))\n }\n }))\n const kill = (options: ChildProcess.KillOptions = {}) =>\n Effect.gen(function*() {\n const requested = yield* policy(options, command.options)\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n if (!control.closeSent) {\n control.closeSent = true\n selected = requested\n // An empty original group cannot prove an explicit escaped-descendant\n // sweep succeeded if its status frames were lost. Startup and natural\n // completion have no such additional contract.\n requireCleanupReceipt = grouped && control.activationSent && !control.spawnFailed && !control.targetDone\n yield* bounded(\n wait(\n control.write({\n type: \"stop\",\n explicit: true,\n ...requested,\n // A live target can move out of this group with setsid().\n // Only an owner whose target was never activated can replace\n // the requested signal; natural exit has its own fast path.\n killSignal: !control.activationSent && alone() ? \"SIGKILL\" : requested.killSignal\n }),\n \"kill\",\n command.command\n ),\n deliveryMs,\n \"kill\",\n command.command\n )\n .pipe(Effect.catch(() => Effect.sync(() => control.disconnect())))\n }\n yield* finish\n }).pipe(Effect.uninterruptible)\n yield* Effect.addFinalizer(() =>\n kill().pipe(\n // A stuck owner keeps its ledger entry. Disable the underlying spawner's\n // unconditional group-kill finalizer rather than signal a stale identity.\n Effect.ensuring(\n Effect.suspend(() =>\n settled ? Effect.void : Effect.andThen(\n raw.unref,\n Effect.sync(() => {\n job?.stop()\n job?.reference(false)\n control.disconnect()\n })\n )\n ).pipe(Effect.orDie)\n ),\n Effect.orDie\n )\n )\n const ready = yield* bounded(\n wait(control.ready.promise, \"spawn\", command.command),\n startupMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.requestsReady.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n yield* Effect.try({\n try: () => control.withdraw(ready, raw.pid),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n if (windows) {\n job = yield* Effect.try({\n try: () => new WindowsProcessJob(raw.pid, control.ownerCreation, jobExecutable!),\n catch: (cause) => failure(\"spawn\", command.command, cause)\n })\n yield* bounded(wait(job.ready.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }\n const acknowledgeCleanup = windows || transport === \"tls\"\n if (acknowledgeCleanup) {\n control.onCleanup = () => {\n if (!control.ownerDone) {\n void control.write({ type: \"cleanup_ack\" }).catch(() => control.disconnect())\n }\n }\n }\n const options = command.options\n // Match Effect/Node's undefined-vs-empty environment semantics in the host,\n // before replacing the helper's environment with its isolated bootstrap.\n const env = options.extendEnv ? { ...process.env, ...options.env } : options.env ?? { ...process.env }\n yield* bounded(\n wait(\n control.write({\n type: \"configure\",\n acknowledgeCleanup,\n command: command.command,\n args: command.args,\n cwd: resolve(options.cwd ?? process.cwd()),\n env,\n shell: options.shell,\n windowsHide: options.windowsHide ?? true,\n windowsVerbatimArguments:\n (options as ChildProcess.CommandOptions & { readonly windowsVerbatimArguments?: boolean })\n .windowsVerbatimArguments,\n standardFds: standardFdsOf(raw),\n userFds: [\n ...new Set(\n Object.keys(options.additionalFds ?? {}).map(ChildProcess.parseFdName)\n .filter((fd): fd is number => fd !== undefined)\n )\n ],\n ...initial\n }),\n \"spawn\",\n command.command\n ),\n deliveryMs,\n \"spawn\",\n command.command\n )\n const activate = yield* Effect.cached(Effect.gen(function*() {\n control.activationSent = true\n yield* bounded(\n wait(control.write({ type: \"start\" }), \"spawn\", command.command),\n deliveryMs,\n \"spawn\",\n command.command\n )\n yield* bounded(wait(control.started.promise, \"spawn\", command.command), startupMs, \"spawn\", command.command)\n }))\n const unref = Effect.gen(function*() {\n if (referenced) {\n reref = yield* raw.unref\n job?.reference(false)\n control.socket?.unref()\n control.requestSocket?.unref()\n referenced = false\n }\n return Effect.gen(function*() {\n if (!referenced) {\n job?.reference(true)\n control.socket?.ref()\n control.requestSocket?.ref()\n yield* reref\n referenced = true\n }\n })\n })\n const output = <A>(stream: Stream.Stream<A, PlatformError.PlatformError>) =>\n stream.pipe(\n Stream.interruptWhen(wait(control.lost.promise, \"read\", command.command))\n )\n const input = <A>(sink: Sink.Sink<A, Uint8Array, never, PlatformError.PlatformError>) =>\n Sink.fromChannel(\n Sink.toChannel(sink).pipe(Channel.interruptWhen(wait(control.lost.promise, \"write\", command.command)))\n )\n const handle = makeHandle({\n ...raw,\n exitCode: wait(control.exited.promise, \"exitCode\", command.command),\n isRunning: Effect.sync(() => !control.targetDone && !control.ownerDone),\n stdin: input(raw.stdin),\n getInputFd: (fd) => input(raw.getInputFd(fd)),\n stdout: output(raw.stdout),\n stderr: output(raw.stderr),\n all: output(raw.all),\n getOutputFd: (fd) => output(raw.getOutputFd(fd)),\n kill,\n unref\n })\n targets.set(handle, control)\n return {\n handle,\n activate,\n settled: Effect.sync(() => settled)\n }\n })\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SupervisorProgram.d.ts","sourceRoot":"","sources":["../../../src/internal/SupervisorProgram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,QAyRlB,CAAA"}
1
+ {"version":3,"file":"SupervisorProgram.d.ts","sourceRoot":"","sources":["../../../src/internal/SupervisorProgram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,QA6SlB,CAAA"}
@@ -44,6 +44,13 @@ const control = connect(socketPath);
44
44
  const requests = connect(socketPath.replace(/\/s$/, '/r'));
45
45
  let config;
46
46
  let target;
47
+ // An owner killed outright (SIGKILL, the OOM killer) runs no handler, so it
48
+ // cannot stop its group. Its guardian is a member of that group that waits on
49
+ // a pipe only the owner holds. At EOF it kills its own group: kill 0 names the
50
+ // caller's group, never a number that could be stale. It ignores the catchable
51
+ // signals a stop sends the group and dies in the owner's final SIGKILL.
52
+ let guardian;
53
+ const guardianScript = "command trap '' HUP INT QUIT ABRT ALRM TERM USR1 USR2 PIPE TSTP TTIN TTOU; read -r line; kill -s KILL 0";
47
54
  let targetDone = false;
48
55
  let stopping = false;
49
56
  let explicitStop = false;
@@ -204,8 +211,9 @@ const settleVacantGroup = () => {
204
211
  let rows;
205
212
  try { rows = snapshot(); } catch { return; }
206
213
  for (const row of rows.values()) {
207
- // The owner's only other child is the ps answering this snapshot; the
208
- // exited target is already reaped and its orphans have another parent.
214
+ // The owner's other children are its guardian and the ps answering this
215
+ // snapshot; the exited target is already reaped and its orphans have
216
+ // another parent.
209
217
  if (row.group === process.pid && row.pid !== process.pid && row.parent !== process.pid && !row.zombie) return;
210
218
  }
211
219
  clearTimeout(timer);
@@ -251,6 +259,18 @@ requests.on('data', (data) => {
251
259
  if (config.standardFds !== undefined) {
252
260
  for (const fd of [0, 1, 2]) descriptors[fd] = config.standardFds[fd];
253
261
  }
262
+ if (grouped) {
263
+ // Started before the target, so no target outlives an owner unguarded.
264
+ // Every caller descriptor slot is replaced: a guardian holding a copy
265
+ // of the caller's output would keep that pipe from reaching EOF.
266
+ const guarded = descriptors.map(() => 'ignore');
267
+ guarded[0] = 'pipe';
268
+ guardian = cp.spawn('/bin/sh', ['-c', guardianScript], { cwd: '/', env: {}, detached: false, stdio: guarded });
269
+ // A failed launch has no pid; its later error event is the same fault.
270
+ guardian.once('error', () => {});
271
+ if (guardian.pid === undefined) throw new SupervisorFault('guardian_unavailable', 'Process group guardian unavailable');
272
+ guardian.stdin.on('error', () => {});
273
+ }
254
274
  try {
255
275
  target = cp.spawn(config.command, config.args, {
256
276
  cwd: config.cwd, env: config.env, shell: config.shell,
@@ -273,7 +293,7 @@ requests.on('data', (data) => {
273
293
  }
274
294
  }
275
295
  for (const fd of config.userFds) fs.closeSync(fd);
276
- send({ type: 'spawned', pid: target.pid });
296
+ send({ type: 'spawned', pid: target.pid, ...(guardian === undefined ? {} : { guardian: guardian.pid }) });
277
297
  });
278
298
  target.once('error', spawnError);
279
299
  target.once('exit', (code, signal) => {
@@ -1 +1 @@
1
- {"version":3,"file":"SupervisorProgram.js","sourceRoot":"","sources":["../../../src/internal/SupervisorProgram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyR/B,CAAA","sourcesContent":["/**\n * The isolated POSIX group owner. Kept as source because the same fixed program\n * runs in Node and Bun without loading the caller's modules or configuration.\n * Its behavior is exercised through the real prepared lifecycle tests.\n * @private\n * @since 1.0.0\n */\nexport const source = String.raw`\n// A fault of the owner itself: reason is its stable code on the status wire.\nclass SupervisorFault extends Error {\n constructor(reason, message) { super(message); this.name = 'SupervisorFault'; this.reason = reason; }\n}\nconst fs = require('node:fs');\nconst net = require('node:net');\nconst cp = require('node:child_process');\nconst [socketPath, mode] = process.argv.slice(-2);\nconst grouped = mode === 'group';\nconst jobHelper = process.env.SMITHERS_PROCESS_JOB_HELPER;\ndelete process.env.SMITHERS_PROCESS_JOB_HELPER;\nlet created;\nif (jobHelper !== undefined) {\n // The still-live owner observes itself. A later PID reuse cannot replace this\n // identity with a different process before the guardian attaches its job.\n const result = cp.spawnSync(jobHelper, ['--process-identity', String(process.pid)], {\n encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL', maxBuffer: 4096, env: {}\n });\n if (result.error || result.signal !== null || result.status !== 0) throw new SupervisorFault('owner_identity_unavailable', 'Owner identity unavailable');\n const identity = JSON.parse(result.stdout);\n if (identity?.status !== 'started' || typeof identity.created !== 'string' || !/^[1-9][0-9]{0,19}$/.test(identity.created)) {\n throw new SupervisorFault('owner_identity_unavailable', 'Owner creation identity unavailable');\n }\n created = identity.created;\n}\nconst channel = process.env.SMITHERS_PROCESS_CHANNEL ? JSON.parse(process.env.SMITHERS_PROCESS_CHANNEL) : undefined;\ndelete process.env.SMITHERS_PROCESS_CHANNEL;\nconst connect = path => channel === undefined ? net.connect(path) : require('node:tls').connect({\n minVersion: 'TLSv1.3', maxVersion: 'TLSv1.3', ciphers: 'TLS_AES_128_GCM_SHA256',\n host: '127.0.0.1', port: path.endsWith('/r') ? channel.requests : channel.status,\n pskCallback: () => ({ identity: 'smithers-owner', psk: Buffer.from(channel.key, 'hex') })\n});\nconst control = connect(socketPath);\n// A request write racing our exit may get EPIPE. Keep status on its own\n// connection so the host still receives the exit and cleanup already sent.\nconst requests = connect(socketPath.replace(/\\/s$/, '/r'));\nlet config;\nlet target;\nlet targetDone = false;\nlet stopping = false;\nlet explicitStop = false;\nlet killing = false;\nlet buffer = '';\nlet timer;\nlet escaped = new Map();\n\n// DirectorySandbox's trusted local explicit-stop contract also covers children\n// that deliberately create another session. This is best-effort positive-pid\n// signalling with identity revalidation, not the atomic own-group guarantee.\n// Linux reads its kernel table because slim images ship no procps (and BusyBox\n// ps lacks these columns); other POSIX hosts ask their system ps.\nconst procSnapshot = () => {\n let names;\n try { names = fs.readdirSync('/proc'); }\n catch { throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable'); }\n const rows = new Map();\n for (const name of names) {\n if (!/^[0-9]+$/.test(name)) continue;\n let text;\n try { text = fs.readFileSync('/proc/' + name + '/stat', 'utf8'); }\n catch (error) {\n // A process that ended after the listing is not an unreadable table.\n if (error.code === 'ENOENT' || error.code === 'ESRCH') continue;\n throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable');\n }\n // comm may contain spaces and parentheses; fields follow its last paren.\n const close = text.lastIndexOf(')');\n const head = text.slice(0, text.indexOf('(')).trim();\n const fields = text.slice(close + 1).trim().split(/[ \\t]+/);\n if (close < 0 || head !== name || fields.length < 20) throw new SupervisorFault('descendant_observation_invalid', 'Invalid descendant observation');\n // Fields 4, 5 and 22: parent, group and start time in clock ticks since boot.\n const [pid, parent, group, start] = [head, fields[1], fields[2], fields[19]].map(Number);\n if (![pid, parent, group, start].every(Number.isSafeInteger)) throw new SupervisorFault('descendant_identity_invalid', 'Invalid descendant identity');\n rows.set(pid, { pid, parent, group, start, zombie: fields[0] === 'Z' });\n }\n return rows;\n};\nconst psSnapshot = () => {\n const result = cp.spawnSync('/bin/ps', ['-A', '-o', 'pid=,ppid=,pgid=,stat=,lstart='], {\n encoding: 'utf8', timeout: 500, killSignal: 'SIGKILL', maxBuffer: 4 * 1024 * 1024,\n env: { PATH: '/usr/bin:/bin', LC_ALL: 'C' }\n });\n if (result.error || result.status !== 0) throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable');\n const rows = new Map();\n for (const line of result.stdout.trim().split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\S+)\\s+(.+)$/.exec(line);\n if (!match) throw new SupervisorFault('descendant_observation_invalid', 'Invalid descendant observation');\n const [pid, parent, group] = match.slice(1, 4).map(Number);\n const start = Date.parse(match[5]);\n if (![pid, parent, group, start].every(Number.isSafeInteger)) throw new SupervisorFault('descendant_identity_invalid', 'Invalid descendant identity');\n rows.set(pid, { pid, parent, group, start, zombie: match[4].startsWith('Z') });\n }\n return rows;\n};\nconst snapshot = process.platform === 'linux' ? procSnapshot : psSnapshot;\nconst captureEscaped = () => {\n const rows = snapshot();\n const descendants = new Set([target.pid]);\n for (;;) {\n const previous = descendants.size;\n for (const row of rows.values()) if (descendants.has(row.parent)) descendants.add(row.pid);\n if (descendants.size === previous) break;\n }\n for (const pid of descendants) {\n const row = rows.get(pid);\n if (row && !row.zombie && row.group !== process.pid && pid !== process.pid && pid > 1) escaped.set(pid, row);\n }\n};\nconst signalEscaped = (signal) => {\n if (escaped.size === 0) return;\n const rows = snapshot();\n for (const [pid, recorded] of escaped) {\n const row = rows.get(pid);\n if (!row || row.zombie) { escaped.delete(pid); continue; }\n if (row.start !== recorded.start || row.group !== recorded.group) {\n throw new SupervisorFault('descendant_identity_changed', 'Escaped descendant identity changed before signalling');\n }\n try { process.kill(pid, signal); }\n catch (error) { if (error.code === 'ESRCH') escaped.delete(pid); else throw error; }\n }\n};\nconst cleanupError = (error) => send({ type: 'cleanup_error', reason: error.reason, message: String(error.message).slice(0, 2048) });\nconst escapedSettled = () => {\n if (escaped.size === 0) return true;\n const rows = snapshot();\n for (const [pid, recorded] of escaped) {\n const row = rows.get(pid);\n if (!row || row.zombie) { escaped.delete(pid); continue; }\n if (row.start !== recorded.start || row.group !== recorded.group) {\n throw new SupervisorFault('descendant_identity_changed', 'Escaped descendant identity changed before cleanup verification');\n }\n }\n return escaped.size === 0;\n};\n\nconst send = (message, done = () => {}) => {\n if (control.destroyed || !control.writable) return done();\n control.write(JSON.stringify(message) + '\\n', done);\n};\nconst selfKill = () => process.kill(grouped ? -process.pid : process.pid, 'SIGKILL');\nconst force = () => {\n if (killing) return;\n killing = true;\n if (!grouped && target?.pid !== undefined && !targetDone) {\n target.kill('SIGKILL');\n return;\n }\n try { signalEscaped('SIGKILL'); } catch (error) { cleanupError(error); }\n const deadline = Date.now() + 500;\n const complete = () => {\n try {\n if (!escapedSettled()) {\n if (Date.now() < deadline) { setTimeout(complete, 10); return; }\n throw new SupervisorFault('descendants_unsettled', 'Escaped descendants did not settle before the cleanup bound');\n }\n } catch (error) { cleanupError(error); }\n // TLS write completion does not prove the peer received terminal status.\n // Keep the owner alive for its receipt; an unresponsive host still cannot\n // delay cleanup beyond the existing delivery bound.\n setTimeout(selfKill, 100);\n send({ type: 'cleanup' }, config?.acknowledgeCleanup ? () => {} : selfKill);\n };\n complete();\n};\nconst stop = (options = {}) => {\n // The first explicit stop owns its signal and deadline, including after EOF\n // or target exit. Only natural cleanup can accept the host's fast shortcut.\n if (stopping && (explicitStop || !options.fast)) return;\n const signal = options.killSignal ?? config?.killSignal ?? 'SIGTERM';\n // A target's exit cannot shorten a captured escaped child's grace period.\n if (options.fast && escaped.size !== 0) return;\n // A grouped owner reaches its members with one group signal and captures\n // only children that left the group. A direct target shares the host's\n // group, so every descendant is captured and signalled by pid.\n if (options.explicit && !targetDone && target?.pid !== undefined) {\n try { captureEscaped(); } catch (error) { cleanupError(error); }\n }\n stopping = true;\n explicitStop = options.explicit === true;\n if (signal === 'SIGKILL' || target?.pid === undefined || (!grouped && targetDone)) return force();\n if (signal === 'SIGSTOP') return force();\n // Keep the group owner alive to enforce escalation, including when the caller\n // chooses a catchable signal other than TERM/INT. SIGSTOP is refused by host.\n process.on(signal, () => {});\n try { signalEscaped(signal); } catch (error) { cleanupError(error); }\n if (grouped) process.kill(-process.pid, signal);\n else target.kill(signal);\n timer = setTimeout(force, options.graceMs ?? config?.graceMs ?? 2000);\n};\n// The grace window exists for the group's remaining members. Once the target\n// has exited and a snapshot shows no other live member and no escaped child,\n// nobody is left to wait for: finish now instead of sleeping out the grace.\n// An unreadable table keeps the deadline.\nconst settleVacantGroup = () => {\n if (!stopping || killing || escaped.size !== 0) return;\n let rows;\n try { rows = snapshot(); } catch { return; }\n for (const row of rows.values()) {\n // The owner's only other child is the ps answering this snapshot; the\n // exited target is already reaped and its orphans have another parent.\n if (row.group === process.pid && row.pid !== process.pid && row.parent !== process.pid && !row.zombie) return;\n }\n clearTimeout(timer);\n force();\n};\nconst spawnError = (error) => {\n send({ type: 'spawn_error', code: error.code, errno: error.errno,\n syscall: error.syscall, path: error.path, message: String(error.message).slice(0, 2048) });\n stop();\n};\nprocess.on('SIGTERM', () => { if (!stopping) stop(); });\nprocess.on('SIGINT', () => { if (!stopping) stop(); });\nprocess.on('uncaughtException', (error) => {\n try { send({ type: 'fault', reason: error.reason, message: String(error.message).slice(0, 2048) }, force); }\n finally { force(); }\n});\nprocess.on('unhandledRejection', (error) => { throw error; });\ncontrol.on('end', () => stop({ explicit: true }));\ncontrol.on('error', () => stop({ explicit: true }));\nrequests.on('end', () => stop({ explicit: true }));\nrequests.on('error', () => stop({ explicit: true }));\nrequests.setEncoding('utf8');\nrequests.on('data', (data) => {\n buffer += data;\n if (Buffer.byteLength(buffer) > 4 * 1024 * 1024) throw new SupervisorFault('control_frame_too_large', 'Control frame too large');\n for (;;) {\n const end = buffer.indexOf('\\n');\n if (end < 0) break;\n const line = buffer.slice(0, end);\n buffer = buffer.slice(end + 1);\n const message = JSON.parse(line);\n if (message.type === 'configure') {\n if (config !== undefined || stopping) throw new SupervisorFault('configuration_invalid', 'Duplicate or late configuration');\n config = message;\n } else if (message.type === 'cleanup_ack') {\n if (!config?.acknowledgeCleanup || !killing) throw new SupervisorFault('cleanup_acknowledgment_unexpected', 'Unexpected cleanup acknowledgment');\n selfKill();\n } else if (message.type === 'stop') stop(message);\n else if (message.type === 'start') {\n if (config === undefined || target !== undefined || stopping) throw new SupervisorFault('activation_invalid', 'Invalid activation');\n const descriptors = Array.from({ length: Math.max(2, ...config.userFds) + 1 }, () => 'ignore');\n for (const fd of [0, 1, 2, ...config.userFds]) descriptors[fd] = fd;\n if (config.standardFds !== undefined) {\n for (const fd of [0, 1, 2]) descriptors[fd] = config.standardFds[fd];\n }\n try {\n target = cp.spawn(config.command, config.args, {\n cwd: config.cwd, env: config.env, shell: config.shell,\n windowsHide: config.windowsHide, windowsVerbatimArguments: config.windowsVerbatimArguments,\n detached: false, stdio: descriptors\n });\n } catch (error) { spawnError(error); continue; }\n target.once('spawn', () => {\n // Release every caller pipe copy. Keep the runtime's standard slots\n // valid so a later internal allocation cannot reuse a closed 0/1/2.\n if (config.standardFds !== undefined) {\n // libuv intentionally does not close Windows CRT descriptors 0..2.\n // Caller pipes arrive in separate slots; the reserved slots are NUL.\n for (const fd of config.standardFds) if (fd !== 'ignore') fs.closeSync(fd);\n } else {\n for (const fd of [0, 1, 2]) {\n fs.closeSync(fd);\n const replacement = fs.openSync(require('node:os').devNull, fd === 0 ? 'r' : 'w');\n if (replacement !== fd) throw new SupervisorFault('stream_detach_failed', 'Could not detach supervisor standard streams');\n }\n }\n for (const fd of config.userFds) fs.closeSync(fd);\n send({ type: 'spawned', pid: target.pid });\n });\n target.once('error', spawnError);\n target.once('exit', (code, signal) => {\n targetDone = true;\n send({ type: 'exit', code, signal });\n if (grouped) { stop(); settleVacantGroup(); }\n else { killing = false; clearTimeout(timer); force(); }\n });\n } else throw new SupervisorFault('control_message_invalid', 'Invalid control message');\n }\n});\ncontrol.once('connect', () => send({ type: 'ready', version: 1, pid: process.pid, created }));\n`\n"]}
1
+ {"version":3,"file":"SupervisorProgram.js","sourceRoot":"","sources":["../../../src/internal/SupervisorProgram.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6S/B,CAAA","sourcesContent":["/**\n * The isolated POSIX group owner. Kept as source because the same fixed program\n * runs in Node and Bun without loading the caller's modules or configuration.\n * Its behavior is exercised through the real prepared lifecycle tests.\n * @private\n * @since 1.0.0\n */\nexport const source = String.raw`\n// A fault of the owner itself: reason is its stable code on the status wire.\nclass SupervisorFault extends Error {\n constructor(reason, message) { super(message); this.name = 'SupervisorFault'; this.reason = reason; }\n}\nconst fs = require('node:fs');\nconst net = require('node:net');\nconst cp = require('node:child_process');\nconst [socketPath, mode] = process.argv.slice(-2);\nconst grouped = mode === 'group';\nconst jobHelper = process.env.SMITHERS_PROCESS_JOB_HELPER;\ndelete process.env.SMITHERS_PROCESS_JOB_HELPER;\nlet created;\nif (jobHelper !== undefined) {\n // The still-live owner observes itself. A later PID reuse cannot replace this\n // identity with a different process before the guardian attaches its job.\n const result = cp.spawnSync(jobHelper, ['--process-identity', String(process.pid)], {\n encoding: 'utf8', timeout: 5000, killSignal: 'SIGKILL', maxBuffer: 4096, env: {}\n });\n if (result.error || result.signal !== null || result.status !== 0) throw new SupervisorFault('owner_identity_unavailable', 'Owner identity unavailable');\n const identity = JSON.parse(result.stdout);\n if (identity?.status !== 'started' || typeof identity.created !== 'string' || !/^[1-9][0-9]{0,19}$/.test(identity.created)) {\n throw new SupervisorFault('owner_identity_unavailable', 'Owner creation identity unavailable');\n }\n created = identity.created;\n}\nconst channel = process.env.SMITHERS_PROCESS_CHANNEL ? JSON.parse(process.env.SMITHERS_PROCESS_CHANNEL) : undefined;\ndelete process.env.SMITHERS_PROCESS_CHANNEL;\nconst connect = path => channel === undefined ? net.connect(path) : require('node:tls').connect({\n minVersion: 'TLSv1.3', maxVersion: 'TLSv1.3', ciphers: 'TLS_AES_128_GCM_SHA256',\n host: '127.0.0.1', port: path.endsWith('/r') ? channel.requests : channel.status,\n pskCallback: () => ({ identity: 'smithers-owner', psk: Buffer.from(channel.key, 'hex') })\n});\nconst control = connect(socketPath);\n// A request write racing our exit may get EPIPE. Keep status on its own\n// connection so the host still receives the exit and cleanup already sent.\nconst requests = connect(socketPath.replace(/\\/s$/, '/r'));\nlet config;\nlet target;\n// An owner killed outright (SIGKILL, the OOM killer) runs no handler, so it\n// cannot stop its group. Its guardian is a member of that group that waits on\n// a pipe only the owner holds. At EOF it kills its own group: kill 0 names the\n// caller's group, never a number that could be stale. It ignores the catchable\n// signals a stop sends the group and dies in the owner's final SIGKILL.\nlet guardian;\nconst guardianScript = \"command trap '' HUP INT QUIT ABRT ALRM TERM USR1 USR2 PIPE TSTP TTIN TTOU; read -r line; kill -s KILL 0\";\nlet targetDone = false;\nlet stopping = false;\nlet explicitStop = false;\nlet killing = false;\nlet buffer = '';\nlet timer;\nlet escaped = new Map();\n\n// DirectorySandbox's trusted local explicit-stop contract also covers children\n// that deliberately create another session. This is best-effort positive-pid\n// signalling with identity revalidation, not the atomic own-group guarantee.\n// Linux reads its kernel table because slim images ship no procps (and BusyBox\n// ps lacks these columns); other POSIX hosts ask their system ps.\nconst procSnapshot = () => {\n let names;\n try { names = fs.readdirSync('/proc'); }\n catch { throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable'); }\n const rows = new Map();\n for (const name of names) {\n if (!/^[0-9]+$/.test(name)) continue;\n let text;\n try { text = fs.readFileSync('/proc/' + name + '/stat', 'utf8'); }\n catch (error) {\n // A process that ended after the listing is not an unreadable table.\n if (error.code === 'ENOENT' || error.code === 'ESRCH') continue;\n throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable');\n }\n // comm may contain spaces and parentheses; fields follow its last paren.\n const close = text.lastIndexOf(')');\n const head = text.slice(0, text.indexOf('(')).trim();\n const fields = text.slice(close + 1).trim().split(/[ \\t]+/);\n if (close < 0 || head !== name || fields.length < 20) throw new SupervisorFault('descendant_observation_invalid', 'Invalid descendant observation');\n // Fields 4, 5 and 22: parent, group and start time in clock ticks since boot.\n const [pid, parent, group, start] = [head, fields[1], fields[2], fields[19]].map(Number);\n if (![pid, parent, group, start].every(Number.isSafeInteger)) throw new SupervisorFault('descendant_identity_invalid', 'Invalid descendant identity');\n rows.set(pid, { pid, parent, group, start, zombie: fields[0] === 'Z' });\n }\n return rows;\n};\nconst psSnapshot = () => {\n const result = cp.spawnSync('/bin/ps', ['-A', '-o', 'pid=,ppid=,pgid=,stat=,lstart='], {\n encoding: 'utf8', timeout: 500, killSignal: 'SIGKILL', maxBuffer: 4 * 1024 * 1024,\n env: { PATH: '/usr/bin:/bin', LC_ALL: 'C' }\n });\n if (result.error || result.status !== 0) throw new SupervisorFault('descendant_observation_unavailable', 'Descendant observation unavailable');\n const rows = new Map();\n for (const line of result.stdout.trim().split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\S+)\\s+(.+)$/.exec(line);\n if (!match) throw new SupervisorFault('descendant_observation_invalid', 'Invalid descendant observation');\n const [pid, parent, group] = match.slice(1, 4).map(Number);\n const start = Date.parse(match[5]);\n if (![pid, parent, group, start].every(Number.isSafeInteger)) throw new SupervisorFault('descendant_identity_invalid', 'Invalid descendant identity');\n rows.set(pid, { pid, parent, group, start, zombie: match[4].startsWith('Z') });\n }\n return rows;\n};\nconst snapshot = process.platform === 'linux' ? procSnapshot : psSnapshot;\nconst captureEscaped = () => {\n const rows = snapshot();\n const descendants = new Set([target.pid]);\n for (;;) {\n const previous = descendants.size;\n for (const row of rows.values()) if (descendants.has(row.parent)) descendants.add(row.pid);\n if (descendants.size === previous) break;\n }\n for (const pid of descendants) {\n const row = rows.get(pid);\n if (row && !row.zombie && row.group !== process.pid && pid !== process.pid && pid > 1) escaped.set(pid, row);\n }\n};\nconst signalEscaped = (signal) => {\n if (escaped.size === 0) return;\n const rows = snapshot();\n for (const [pid, recorded] of escaped) {\n const row = rows.get(pid);\n if (!row || row.zombie) { escaped.delete(pid); continue; }\n if (row.start !== recorded.start || row.group !== recorded.group) {\n throw new SupervisorFault('descendant_identity_changed', 'Escaped descendant identity changed before signalling');\n }\n try { process.kill(pid, signal); }\n catch (error) { if (error.code === 'ESRCH') escaped.delete(pid); else throw error; }\n }\n};\nconst cleanupError = (error) => send({ type: 'cleanup_error', reason: error.reason, message: String(error.message).slice(0, 2048) });\nconst escapedSettled = () => {\n if (escaped.size === 0) return true;\n const rows = snapshot();\n for (const [pid, recorded] of escaped) {\n const row = rows.get(pid);\n if (!row || row.zombie) { escaped.delete(pid); continue; }\n if (row.start !== recorded.start || row.group !== recorded.group) {\n throw new SupervisorFault('descendant_identity_changed', 'Escaped descendant identity changed before cleanup verification');\n }\n }\n return escaped.size === 0;\n};\n\nconst send = (message, done = () => {}) => {\n if (control.destroyed || !control.writable) return done();\n control.write(JSON.stringify(message) + '\\n', done);\n};\nconst selfKill = () => process.kill(grouped ? -process.pid : process.pid, 'SIGKILL');\nconst force = () => {\n if (killing) return;\n killing = true;\n if (!grouped && target?.pid !== undefined && !targetDone) {\n target.kill('SIGKILL');\n return;\n }\n try { signalEscaped('SIGKILL'); } catch (error) { cleanupError(error); }\n const deadline = Date.now() + 500;\n const complete = () => {\n try {\n if (!escapedSettled()) {\n if (Date.now() < deadline) { setTimeout(complete, 10); return; }\n throw new SupervisorFault('descendants_unsettled', 'Escaped descendants did not settle before the cleanup bound');\n }\n } catch (error) { cleanupError(error); }\n // TLS write completion does not prove the peer received terminal status.\n // Keep the owner alive for its receipt; an unresponsive host still cannot\n // delay cleanup beyond the existing delivery bound.\n setTimeout(selfKill, 100);\n send({ type: 'cleanup' }, config?.acknowledgeCleanup ? () => {} : selfKill);\n };\n complete();\n};\nconst stop = (options = {}) => {\n // The first explicit stop owns its signal and deadline, including after EOF\n // or target exit. Only natural cleanup can accept the host's fast shortcut.\n if (stopping && (explicitStop || !options.fast)) return;\n const signal = options.killSignal ?? config?.killSignal ?? 'SIGTERM';\n // A target's exit cannot shorten a captured escaped child's grace period.\n if (options.fast && escaped.size !== 0) return;\n // A grouped owner reaches its members with one group signal and captures\n // only children that left the group. A direct target shares the host's\n // group, so every descendant is captured and signalled by pid.\n if (options.explicit && !targetDone && target?.pid !== undefined) {\n try { captureEscaped(); } catch (error) { cleanupError(error); }\n }\n stopping = true;\n explicitStop = options.explicit === true;\n if (signal === 'SIGKILL' || target?.pid === undefined || (!grouped && targetDone)) return force();\n if (signal === 'SIGSTOP') return force();\n // Keep the group owner alive to enforce escalation, including when the caller\n // chooses a catchable signal other than TERM/INT. SIGSTOP is refused by host.\n process.on(signal, () => {});\n try { signalEscaped(signal); } catch (error) { cleanupError(error); }\n if (grouped) process.kill(-process.pid, signal);\n else target.kill(signal);\n timer = setTimeout(force, options.graceMs ?? config?.graceMs ?? 2000);\n};\n// The grace window exists for the group's remaining members. Once the target\n// has exited and a snapshot shows no other live member and no escaped child,\n// nobody is left to wait for: finish now instead of sleeping out the grace.\n// An unreadable table keeps the deadline.\nconst settleVacantGroup = () => {\n if (!stopping || killing || escaped.size !== 0) return;\n let rows;\n try { rows = snapshot(); } catch { return; }\n for (const row of rows.values()) {\n // The owner's other children are its guardian and the ps answering this\n // snapshot; the exited target is already reaped and its orphans have\n // another parent.\n if (row.group === process.pid && row.pid !== process.pid && row.parent !== process.pid && !row.zombie) return;\n }\n clearTimeout(timer);\n force();\n};\nconst spawnError = (error) => {\n send({ type: 'spawn_error', code: error.code, errno: error.errno,\n syscall: error.syscall, path: error.path, message: String(error.message).slice(0, 2048) });\n stop();\n};\nprocess.on('SIGTERM', () => { if (!stopping) stop(); });\nprocess.on('SIGINT', () => { if (!stopping) stop(); });\nprocess.on('uncaughtException', (error) => {\n try { send({ type: 'fault', reason: error.reason, message: String(error.message).slice(0, 2048) }, force); }\n finally { force(); }\n});\nprocess.on('unhandledRejection', (error) => { throw error; });\ncontrol.on('end', () => stop({ explicit: true }));\ncontrol.on('error', () => stop({ explicit: true }));\nrequests.on('end', () => stop({ explicit: true }));\nrequests.on('error', () => stop({ explicit: true }));\nrequests.setEncoding('utf8');\nrequests.on('data', (data) => {\n buffer += data;\n if (Buffer.byteLength(buffer) > 4 * 1024 * 1024) throw new SupervisorFault('control_frame_too_large', 'Control frame too large');\n for (;;) {\n const end = buffer.indexOf('\\n');\n if (end < 0) break;\n const line = buffer.slice(0, end);\n buffer = buffer.slice(end + 1);\n const message = JSON.parse(line);\n if (message.type === 'configure') {\n if (config !== undefined || stopping) throw new SupervisorFault('configuration_invalid', 'Duplicate or late configuration');\n config = message;\n } else if (message.type === 'cleanup_ack') {\n if (!config?.acknowledgeCleanup || !killing) throw new SupervisorFault('cleanup_acknowledgment_unexpected', 'Unexpected cleanup acknowledgment');\n selfKill();\n } else if (message.type === 'stop') stop(message);\n else if (message.type === 'start') {\n if (config === undefined || target !== undefined || stopping) throw new SupervisorFault('activation_invalid', 'Invalid activation');\n const descriptors = Array.from({ length: Math.max(2, ...config.userFds) + 1 }, () => 'ignore');\n for (const fd of [0, 1, 2, ...config.userFds]) descriptors[fd] = fd;\n if (config.standardFds !== undefined) {\n for (const fd of [0, 1, 2]) descriptors[fd] = config.standardFds[fd];\n }\n if (grouped) {\n // Started before the target, so no target outlives an owner unguarded.\n // Every caller descriptor slot is replaced: a guardian holding a copy\n // of the caller's output would keep that pipe from reaching EOF.\n const guarded = descriptors.map(() => 'ignore');\n guarded[0] = 'pipe';\n guardian = cp.spawn('/bin/sh', ['-c', guardianScript], { cwd: '/', env: {}, detached: false, stdio: guarded });\n // A failed launch has no pid; its later error event is the same fault.\n guardian.once('error', () => {});\n if (guardian.pid === undefined) throw new SupervisorFault('guardian_unavailable', 'Process group guardian unavailable');\n guardian.stdin.on('error', () => {});\n }\n try {\n target = cp.spawn(config.command, config.args, {\n cwd: config.cwd, env: config.env, shell: config.shell,\n windowsHide: config.windowsHide, windowsVerbatimArguments: config.windowsVerbatimArguments,\n detached: false, stdio: descriptors\n });\n } catch (error) { spawnError(error); continue; }\n target.once('spawn', () => {\n // Release every caller pipe copy. Keep the runtime's standard slots\n // valid so a later internal allocation cannot reuse a closed 0/1/2.\n if (config.standardFds !== undefined) {\n // libuv intentionally does not close Windows CRT descriptors 0..2.\n // Caller pipes arrive in separate slots; the reserved slots are NUL.\n for (const fd of config.standardFds) if (fd !== 'ignore') fs.closeSync(fd);\n } else {\n for (const fd of [0, 1, 2]) {\n fs.closeSync(fd);\n const replacement = fs.openSync(require('node:os').devNull, fd === 0 ? 'r' : 'w');\n if (replacement !== fd) throw new SupervisorFault('stream_detach_failed', 'Could not detach supervisor standard streams');\n }\n }\n for (const fd of config.userFds) fs.closeSync(fd);\n send({ type: 'spawned', pid: target.pid, ...(guardian === undefined ? {} : { guardian: guardian.pid }) });\n });\n target.once('error', spawnError);\n target.once('exit', (code, signal) => {\n targetDone = true;\n send({ type: 'exit', code, signal });\n if (grouped) { stop(); settleVacantGroup(); }\n else { killing = false; clearTimeout(timer); force(); }\n });\n } else throw new SupervisorFault('control_message_invalid', 'Invalid control message');\n }\n});\ncontrol.once('connect', () => send({ type: 'ready', version: 1, pid: process.pid, created }));\n`\n"]}
package/docs/api.md CHANGED
@@ -169,7 +169,8 @@ A missing or invalid target result remains a platform failure. Use the handle's
169
169
  Drain stdout, stderr, stdin and status concurrently when using pipes. Keep the
170
170
  whole operation inside `Effect.scoped`; a target's natural exit also triggers
171
171
  cleanup of children holding those pipes open. The private parent connection
172
- requests cleanup on host loss. This API has no durable ledger; use
172
+ requests cleanup on host loss, and the supervisor's group guardian kills the
173
+ group on supervisor loss. This API has no durable ledger; use
173
174
  `NodeHost.layerContained` when a later host must reconcile retained records.
174
175
 
175
176
  ## ProcessReaper.layerSpawner
@@ -39,6 +39,14 @@ adapter and `ProcessReaper.processLifecycle`:
39
39
  - The grace period is an upper bound. Once the target has exited and the group
40
40
  holds no other live member and no captured escaped descendant, cleanup
41
41
  finishes at once.
42
+ - A grouped supervisor starts a guardian in its group before the target: a
43
+ `/bin/sh` that waits on a pipe only the supervisor holds. A supervisor killed
44
+ outright (`SIGKILL`, the OOM killer) runs no handler, so at that pipe's EOF
45
+ the guardian kills its own group with `kill 0`, which names the caller's
46
+ group rather than a number that could be stale. It ignores the catchable
47
+ signals a stop sends the group and dies in the supervisor's final `SIGKILL`.
48
+ A host without `/bin/sh` refuses to start a grouped target. A lost
49
+ supervisor sends no cleanup receipt, so its release stays unverified.
42
50
 
43
51
  Confined children use private directories for `HOME` and XDG config, cache, data, and state.
44
52
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@smthrs/platform-node",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.3",
4
+ "version": "1.0.0-rc.4",
5
5
  "license": "MIT",
6
6
  "smthrs": {
7
7
  "group": "engine",
@@ -161,8 +161,8 @@
161
161
  "tag": "next"
162
162
  },
163
163
  "dependencies": {
164
- "@smthrs/jj": "1.0.0-rc.3",
165
- "@smthrs/kernel": "1.0.0-rc.3",
164
+ "@smthrs/jj": "1.0.0-rc.4",
165
+ "@smthrs/kernel": "1.0.0-rc.4",
166
166
  "undici": "8.10.2",
167
167
  "redis": "6.2.1",
168
168
  "@types/ws": "8.18.1",
@@ -177,7 +177,7 @@
177
177
  "@effect/platform-node-shared": "4.0.0-rc.115",
178
178
  "@effect/vitest": "4.0.0-rc.115",
179
179
  "@eslint/js": "9.39.5",
180
- "@smthrs/journal": "1.0.0-rc.3",
180
+ "@smthrs/journal": "1.0.0-rc.4",
181
181
  "@types/node": "26.4.1",
182
182
  "@vitest/coverage-v8": "5.0.0",
183
183
  "dprint": "0.57.1",