@ponythewhite/base-context 1.0.2 → 1.0.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 (44) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/src/rlm/mcp.py +39 -17
  4. package/dist/base-context-runtime/test/test_mcp.py +87 -1
  5. package/dist/base-context-runtime/uv.lock +1 -1
  6. package/dist/build-info.json +1 -1
  7. package/dist/bundle/{bundled-modules-PWOGKUQQ.js → bundled-modules-R5EAJ62K.js} +2 -2
  8. package/dist/bundle/{chunk-44PEHPOG.js → chunk-BV25CVRM.js} +322 -171
  9. package/dist/bundle/{chunk-IADCPVEI.js → chunk-XDJ56NJA.js} +26 -11
  10. package/dist/bundle/{cli-main-4DS7Y3PI.js → cli-main-OUKN743U.js} +2 -2
  11. package/dist/bundle/cli.js +1 -1
  12. package/dist/bundle/{main-SV7JLVEB.js → main-QPCXSW6X.js} +2 -2
  13. package/dist/cli/daemon-ps.d.ts.map +1 -1
  14. package/dist/cli/daemon-ps.js +1 -0
  15. package/dist/cli/daemon-ps.js.map +1 -1
  16. package/dist/core/auth-storage.d.ts +4 -0
  17. package/dist/core/auth-storage.d.ts.map +1 -1
  18. package/dist/core/auth-storage.js +77 -19
  19. package/dist/core/auth-storage.js.map +1 -1
  20. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  21. package/dist/core/kernel/bootstrap.js +5 -2
  22. package/dist/core/kernel/bootstrap.js.map +1 -1
  23. package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
  24. package/dist/core/mcp/mcp-manager.js +2 -2
  25. package/dist/core/mcp/mcp-manager.js.map +1 -1
  26. package/dist/installer.mjs +5 -2
  27. package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
  28. package/dist/modes/daemon/daemon-supervisor-ownership.js +16 -16
  29. package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
  30. package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
  31. package/dist/modes/interactive/auth-flows.js +7 -6
  32. package/dist/modes/interactive/auth-flows.js.map +1 -1
  33. package/dist/modes/interactive/components/login-dialog.d.ts +3 -1
  34. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  35. package/dist/modes/interactive/components/login-dialog.js +3 -1
  36. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  37. package/dist/modes/interactive/components/menu-panel.d.ts +1 -0
  38. package/dist/modes/interactive/components/menu-panel.d.ts.map +1 -1
  39. package/dist/modes/interactive/components/menu-panel.js +3 -0
  40. package/dist/modes/interactive/components/menu-panel.js.map +1 -1
  41. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  42. package/dist/modes/interactive/interactive-mode.js +7 -5
  43. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  44. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-supervisor-ownership.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-supervisor-ownership.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { getProcessStartId } from \"../../core/session-lease.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport { normalizeSocketPath } from \"./daemon-socket.js\";\n\nconst DAEMON_SUPERVISOR_REGISTRY_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_REGISTRY_DIR\";\n\nconst OWNER_VERSION = 1;\nconst REGISTRY_LOCK_STALE_MS = 5000;\nconst REGISTRY_LOCK_UPDATE_MS = 1000;\nconst REGISTRY_LOCK_RETRIES = 500;\nconst REGISTRY_LOCK_RETRY_MS = 10;\nconst STARTUP_FENCE_POLL_MS = 250;\nconst SHUTDOWN_ADMISSION_FILE_NAME = \"shutdown-admission.json\";\nconst SHUTDOWN_ADMISSION_LEASE_MS = 5000;\nconst SHUTDOWN_ADMISSION_REFRESH_MS = 1000;\nconst SHUTDOWN_ADMISSION_WAIT_MS = 50;\n\ntype DaemonSupervisorOwnerPhase = \"starting\" | \"owner\" | \"stopping\";\n\ninterface ProcessIdentity {\n\tpid: number;\n\tprocessStartId?: string;\n}\n\ninterface DaemonSupervisorOwnerRecord extends ProcessIdentity {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tappVersion: string;\n\tphase: DaemonSupervisorOwnerPhase;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\ninterface DaemonShutdownAdmissionRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\texpiresAt: string;\n}\n\ninterface DaemonSupervisorOwnerScope {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir?: string;\n\tjournalPath?: string;\n}\n\ninterface DaemonStartupFenceRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\townerToken: string;\n\tsocketPath: string;\n\tsupervisorGeneration: string;\n\tcreatedAt: string;\n}\n\ninterface DaemonSupervisorHelloIdentity {\n\tsupervisorGeneration?: string;\n\tsupervisorOwnerToken?: string;\n\tsupervisorPid?: number;\n\tsupervisorProcessStartId?: string;\n\tsupervisorSocketPath?: string;\n}\n\ninterface AcquireDaemonSupervisorOwnershipOptions {\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tgeneration: string;\n\tappVersion: string;\n\tregistryDir?: string;\n}\n\nclass DaemonSupervisorAlreadyRunningError extends Error {\n\treadonly code = \"daemon_supervisor_already_running\" as const;\n\n\tconstructor(readonly owner: DaemonSupervisorOwnerRecord) {\n\t\tsuper(`Daemon supervisor ${owner.generation} already owns ${owner.socketPath}`);\n\t\tthis.name = \"DaemonSupervisorAlreadyRunningError\";\n\t}\n}\n\nclass DaemonSupervisorOwnershipLostError extends Error {\n\treadonly code = \"supervisor_generation_stale\" as const;\n\n\tconstructor(generation: string, details: { socketPath?: string; registryDir?: string } = {}) {\n\t\tconst context = [\n\t\t\tdetails.socketPath ? `socket: ${details.socketPath}` : undefined,\n\t\t\tdetails.registryDir ? `registry: ${details.registryDir}` : undefined,\n\t\t].filter((part) => part !== undefined);\n\t\tsuper(\n\t\t\t`Daemon supervisor generation ${generation} no longer owns its registry entry ` +\n\t\t\t\t`(record on disk is missing or was replaced)${context.length > 0 ? `; ${context.join(\"; \")}` : \"\"}; ` +\n\t\t\t\t\"restart the daemon to recover — sessions are preserved\",\n\t\t);\n\t\tthis.name = \"DaemonSupervisorOwnershipLostError\";\n\t}\n}\n\nclass DaemonShutdownAdmissionError extends Error {\n\treadonly code = \"daemon_shutdown_in_progress\" as const;\n\n\tconstructor(message = \"Daemon shutdown is in progress\") {\n\t\tsuper(message);\n\t\tthis.name = \"DaemonShutdownAdmissionError\";\n\t}\n}\n\n/**\n * Owns a lease-renew loop safely: the unref()'d interval, single-flight\n * refresh dedup shared by timer-fired and direct calls, and lost-state fencing.\n */\nclass RenewableRegistryRecord {\n\tprivate stopped = false;\n\tprivate lost = false;\n\tprivate refreshPromise?: Promise<void>;\n\tprivate readonly refreshTimer: ReturnType<typeof setInterval>;\n\n\tconstructor(\n\t\tprivate readonly registryDir: string,\n\t\trefreshMs: number,\n\t\tprivate readonly renewUnderGuard: () => void,\n\t\tprivate readonly createLostError: () => Error,\n\t) {\n\t\tthis.refreshTimer = setInterval(() => {\n\t\t\tvoid this.assertOrRenew().catch(() => undefined);\n\t\t}, refreshMs);\n\t\tthis.refreshTimer.unref();\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.stopped || this.lost) {\n\t\t\tthrow this.createLostError();\n\t\t}\n\t\tthis.refreshPromise ??= this.performRenew().finally(() => {\n\t\t\tthis.refreshPromise = undefined;\n\t\t});\n\t\tawait this.refreshPromise;\n\t}\n\n\tprivate async performRenew(): Promise<void> {\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\t// stop() may have completed while this call waited on the guard;\n\t\t\t\t// a stopped record must never be rewritten to disk.\n\t\t\t\tif (this.stopped || this.lost) {\n\t\t\t\t\tthrow this.createLostError();\n\t\t\t\t}\n\t\t\t\tthis.renewUnderGuard();\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.lost = true;\n\t\t\tclearInterval(this.refreshTimer);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.stopped = true;\n\t\tclearInterval(this.refreshTimer);\n\t\tawait this.refreshPromise?.catch(() => undefined);\n\t}\n}\n\nclass DaemonSupervisorOwnership {\n\tprivate released = false;\n\n\tconstructor(\n\t\treadonly record: DaemonSupervisorOwnerRecord,\n\t\tprivate readonly registryDir: string,\n\t\tprivate readonly ownerDirectory: string,\n\t) {}\n\n\tasync assertCurrent(): Promise<void> {\n\t\tthis.assertCurrentSync();\n\t}\n\n\tassertJournalCurrent(journalPath: string): void {\n\t\tif (this.record.journalPath !== canonicalizeFilesystemPath(assertProductStatePath(journalPath))) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tthis.assertCurrentSync();\n\t}\n\n\tprivate assertCurrentSync(): void {\n\t\tif (this.released) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\tif (!current || !sameOwnerRecord(current, this.record)) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t}\n\n\tprivate ownershipLostError(): DaemonSupervisorOwnershipLostError {\n\t\treturn new DaemonSupervisorOwnershipLostError(this.record.generation, {\n\t\t\tsocketPath: this.record.socketPath,\n\t\t\tregistryDir: this.registryDir,\n\t\t});\n\t}\n\n\tasync updatePhase(phase: DaemonSupervisorOwnerPhase): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tconst updated = await mutateDaemonSupervisorOwner(\n\t\t\tthis.record.generation,\n\t\t\tthis.record.token,\n\t\t\t(owner) => {\n\t\t\t\towner.phase = phase;\n\t\t\t},\n\t\t\tthis.registryDir,\n\t\t);\n\t\tif (!updated) {\n\t\t\tthrow new Error(`Daemon supervisor ownership was lost for ${this.record.socketPath}`);\n\t\t}\n\t\tthis.record.phase = phase;\n\t\tthis.record.updatedAt = updated.updatedAt;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tlet releasedDirectory: string | undefined;\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\t\t\tif (!current || current.token !== this.record.token) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treleasedDirectory = `${this.ownerDirectory}.released-${randomUUID()}`;\n\t\t\t\trenameSync(this.ownerDirectory, releasedDirectory);\n\t\t\t});\n\t\t\tthis.released = true;\n\t\t} finally {\n\t\t\tif (releasedDirectory) {\n\t\t\t\trmSync(releasedDirectory, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass DaemonShutdownAdmission {\n\tprivate released = false;\n\tprivate readonly renewal: RenewableRegistryRecord;\n\n\tconstructor(\n\t\tprivate readonly record: DaemonShutdownAdmissionRecord,\n\t\tprivate readonly registryDir: string,\n\t) {\n\t\tthis.renewal = new RenewableRegistryRecord(\n\t\t\tregistryDir,\n\t\t\tSHUTDOWN_ADMISSION_REFRESH_MS,\n\t\t\t() => this.renewUnderGuard(),\n\t\t\t() => new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\"),\n\t\t);\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.released) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tawait this.renewal.assertOrRenew();\n\t}\n\n\tprivate renewUnderGuard(): void {\n\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\tconst current = readShutdownAdmission(path);\n\t\tif (\n\t\t\t!current ||\n\t\t\tcurrent.token !== this.record.token ||\n\t\t\tcurrent.pid !== this.record.pid ||\n\t\t\tcurrent.processStartId !== this.record.processStartId ||\n\t\t\tDate.parse(current.expiresAt) <= Date.now() ||\n\t\t\t!matchesExactProcessIdentity(this.record)\n\t\t) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tconst now = Date.now();\n\t\tthis.record.updatedAt = new Date(now).toISOString();\n\t\tthis.record.expiresAt = new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString();\n\t\twriteJsonAtomically(path, this.record);\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tthis.released = true;\n\t\tawait this.renewal.stop();\n\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\t\tconst current = readShutdownAdmission(path);\n\t\t\tif (current?.token === this.record.token) {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t}\n\t\t});\n\t}\n}\n\n/** Durable supervisor authority is scoped to one product home, never an upstream registry. */\nfunction defaultDaemonSupervisorRegistryDir(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst override = readAbsolutePathEnv(DAEMON_SUPERVISOR_REGISTRY_DIR_ENV, environment);\n\treturn assertProductStatePath(override ?? resolveRuntimePaths(environment).daemonRegistry);\n}\n\n/**\n * Non-mutating legacy scan: never reclaims abandoned directories (old-build\n * daemons own that location's lifecycle) and runs without the legacy guard —\n * best-effort is acceptable because records are written rename-atomically.\n */\nfunction readLegacyOwnersForSocket(\n\tlegacyRegistryDir: string,\n\tnormalizedSocketPath: string,\n): DaemonSupervisorOwnerRecord[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(legacyRegistryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn entries\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.flatMap((name) => {\n\t\t\tconst owner = readOwnerRecord(resolve(legacyRegistryDir, name));\n\t\t\treturn owner && owner.socketPath === normalizedSocketPath ? [owner] : [];\n\t\t});\n}\n\nasync function withDaemonSupervisorRegistryGuard<T>(registryDir: string, action: () => T | Promise<T>): Promise<T> {\n\tassertProductStatePath(registryDir);\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst guardPath = resolve(registryDir, \".guard\");\n\tlet compromisedError: Error | undefined;\n\tconst release = await lockfile.lock(registryDir, {\n\t\trealpath: false,\n\t\tlockfilePath: guardPath,\n\t\tstale: REGISTRY_LOCK_STALE_MS,\n\t\tupdate: REGISTRY_LOCK_UPDATE_MS,\n\t\tonCompromised: (error) => {\n\t\t\tcompromisedError ??= error;\n\t\t},\n\t\tretries: {\n\t\t\tretries: REGISTRY_LOCK_RETRIES,\n\t\t\tfactor: 1,\n\t\t\tminTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t\tmaxTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t},\n\t});\n\t// Compromise detection is timer-driven and cannot preempt a synchronous stall: a stalled action's\n\t// writes may already be on disk when a successor reclaims the stale guard. The guard directory's\n\t// inode is the ownership identity (a steal is rmdir+mkdir), checked synchronously where the timer\n\t// cannot run; when the inode is unobservable, only timer-driven detection applies.\n\tconst guardIno = (() => {\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t})();\n\tconst guardStolen = () => {\n\t\tif (guardIno === undefined) return false;\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino !== guardIno;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t};\n\tconst assertGuardHeld = () => {\n\t\tif (compromisedError)\n\t\t\tthrow new Error(`Daemon supervisor registry guard was compromised: ${compromisedError.message}`);\n\t\tif (guardStolen())\n\t\t\tthrow new Error(\"Daemon supervisor registry guard was compromised: the guard lock changed hands\");\n\t};\n\ttry {\n\t\tassertGuardHeld();\n\t\tconst result = await action();\n\t\tassertGuardHeld();\n\t\treturn result;\n\t} finally {\n\t\tif (compromisedError) {\n\t\t\tawait release().catch(() => undefined);\n\t\t} else if (!guardStolen()) {\n\t\t\tawait release();\n\t\t}\n\t\t// A stolen-but-undetected guard is never released: that would delete the successor's lock.\n\t\t// The abandoned updater notices the foreign mtime on its next tick and cleans itself up.\n\t}\n}\n\nasync function mutateDaemonSupervisorOwner(\n\tgeneration: string,\n\texpectedToken: string,\n\tmutation: (owner: DaemonSupervisorOwnerRecord) => void,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<DaemonSupervisorOwnerRecord | undefined> {\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst directory = ownerDirectoryPath(registryDir, generation);\n\t\tif (!existsSync(directory)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst current = requireOwnerRecord(directory);\n\t\tif (current.token !== expectedToken) {\n\t\t\treturn undefined;\n\t\t}\n\t\tmutation(current);\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tif (\n\t\t\t!isDaemonSupervisorOwnerRecord(current) ||\n\t\t\tcurrent.generation !== generation ||\n\t\t\tcurrent.token !== expectedToken\n\t\t) {\n\t\t\tthrow new Error(`Invalid mutation for daemon supervisor owner ${generation}`);\n\t\t}\n\t\twriteOwnerRecord(directory, current);\n\t\treturn current;\n\t});\n}\n\nexport async function acquireDaemonSupervisorOwnership(\n\toptions: AcquireDaemonSupervisorOwnershipOptions,\n): Promise<DaemonSupervisorOwnership> {\n\tconst registryDir = options.registryDir ?? defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst token = randomUUID();\n\tconst processStartId = getProcessStartId(process.pid);\n\tconst now = new Date().toISOString();\n\tconst record: DaemonSupervisorOwnerRecord = {\n\t\tversion: OWNER_VERSION,\n\t\trole: \"supervisor\",\n\t\ttoken,\n\t\tgeneration: options.generation,\n\t\tpid: process.pid,\n\t\t...(processStartId ? { processStartId } : {}),\n\t\tsocketPath: normalizeSocketPath(options.socketPath),\n\t\tdescriptorDir: canonicalizeFilesystemPath(options.descriptorDir),\n\t\tagentDir: canonicalizeFilesystemPath(options.agentDir),\n\t\t...(options.journalPath\n\t\t\t? { journalPath: canonicalizeFilesystemPath(assertProductStatePath(options.journalPath)) }\n\t\t\t: {}),\n\t\tappVersion: options.appVersion,\n\t\tphase: \"starting\",\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t};\n\tconst candidateDirectory = resolve(registryDir, `.candidate-${process.pid}-${token}`);\n\tconst ownerDirectory = ownerDirectoryPath(registryDir, options.generation);\n\tmkdirSync(candidateDirectory, { mode: 0o700 });\n\tconst staleDirectories: string[] = [];\n\ttry {\n\t\twriteOwnerScope(candidateDirectory, record);\n\t\twriteOwnerRecord(candidateDirectory, record);\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\tthrow new DaemonShutdownAdmissionError();\n\t\t\t}\n\t\t\tfor (const directory of listOwnerDirectories(registryDir)) {\n\t\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => ownerConflicts(scope, record));\n\t\t\t\tif (!owner) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!ownerConflicts(owner, record)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (isProcessIdentityAlive(owner)) {\n\t\t\t\t\tthrow new DaemonSupervisorAlreadyRunningError(owner);\n\t\t\t\t}\n\t\t\t\tconst staleDirectory = `${directory}.stale-${randomUUID()}`;\n\t\t\t\trenameSync(directory, staleDirectory);\n\t\t\t\tstaleDirectories.push(staleDirectory);\n\t\t\t}\n\t\t\trenameSync(candidateDirectory, ownerDirectory);\n\t\t});\n\t} catch (error) {\n\t\trmSync(candidateDirectory, { recursive: true, force: true });\n\t\tthrow error;\n\t} finally {\n\t\tfor (const directory of staleDirectories) {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t}\n\t}\n\treturn new DaemonSupervisorOwnership(record, registryDir, ownerDirectory);\n}\n\n/** Read only: discovery must not acquire ownership or reclaim registry directories. */\nexport function listDaemonSupervisorSocketPathsForAgentDir(\n\tagentDir: string,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): string[] {\n\tlet canonicalAgentDir: string;\n\tlet directories: string[];\n\ttry {\n\t\tcanonicalAgentDir = canonicalizeFilesystemPath(agentDir);\n\t\tdirectories = listOwnerDirectories(registryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst socketPaths: string[] = [];\n\tfor (const directory of directories) {\n\t\tconst owner = readOwnerRecord(directory);\n\t\tif (!owner) continue;\n\t\ttry {\n\t\t\tif (canonicalizeFilesystemPath(owner.agentDir) === canonicalAgentDir) {\n\t\t\t\tsocketPaths.push(normalizeSocketPath(owner.socketPath));\n\t\t\t}\n\t\t} catch {\n\t\t\t// A stale or inaccessible record must not hide the other supervisors.\n\t\t}\n\t}\n\treturn socketPaths;\n}\n\nexport async function assertDaemonSupervisorOwnerCurrent(\n\towner: {\n\t\tgeneration: string;\n\t\tpid: number;\n\t\tprocessStartId?: string;\n\t\tsocketPath: string;\n\t},\n\tvalidatedFingerprint?: string,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<string> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tconst current =\n\t\treadOwnerRecord(ownerDirectoryPath(registryDir, owner.generation)) ??\n\t\t(legacyRegistryDir ? readOwnerRecord(ownerDirectoryPath(legacyRegistryDir, owner.generation)) : undefined);\n\tif (\n\t\t!current ||\n\t\tcurrent.pid !== owner.pid ||\n\t\tcurrent.processStartId !== owner.processStartId ||\n\t\tcurrent.socketPath !== normalizeSocketPath(owner.socketPath) ||\n\t\t!isProcessAlive(current.pid)\n\t) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\tconst fingerprint = ownerRecordFingerprint(current);\n\tif (fingerprint !== validatedFingerprint && !isProcessIdentityAlive(current)) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\treturn fingerprint;\n}\n\nexport async function acquireDaemonShutdownAdmission(): Promise<DaemonShutdownAdmission> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\tconst processStartId = getProcessStartId(process.pid);\n\twhile (true) {\n\t\tlet acquired: DaemonShutdownAdmissionRecord | undefined;\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst now = Date.now();\n\t\t\tacquired = {\n\t\t\t\tversion: OWNER_VERSION,\n\t\t\t\ttoken: randomUUID(),\n\t\t\t\tpid: process.pid,\n\t\t\t\t...(processStartId ? { processStartId } : {}),\n\t\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t\t\tupdatedAt: new Date(now).toISOString(),\n\t\t\t\texpiresAt: new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString(),\n\t\t\t};\n\t\t\twriteJsonAtomically(shutdownAdmissionPath(registryDir), acquired);\n\t\t});\n\t\tif (acquired) {\n\t\t\treturn new DaemonShutdownAdmission(acquired, registryDir);\n\t\t}\n\t\tawait delay(SHUTDOWN_ADMISSION_WAIT_MS);\n\t}\n}\n\nexport async function isDaemonShutdownAdmissionActive(): Promise<boolean> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => readActiveShutdownAdmission(registryDir) !== undefined);\n}\n\nexport async function persistDaemonStartupFenceFromOwner(\n\tsocketPath: string,\n\thello: DaemonSupervisorHelloIdentity,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<void> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst fenceDirectory = resolve(registryDir, \"startup-fences\");\n\tmkdirSync(fenceDirectory, { recursive: true, mode: 0o700 });\n\tconst path = startupFencePath(fenceDirectory, socketPath);\n\tconst normalizedSocketPath = normalizeSocketPath(socketPath);\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst owners = listOwnerDirectories(registryDir).flatMap((directory) => {\n\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => scope.socketPath === normalizedSocketPath);\n\t\t\treturn owner ? [owner] : [];\n\t\t});\n\t\tlet matchingOwners = owners.filter((owner) => owner.socketPath === normalizedSocketPath);\n\t\tif (matchingOwners.length === 0 && legacyRegistryDir) {\n\t\t\t// Stale legacy leftovers are expected; keep only records matching the\n\t\t\t// identity the caller already holds.\n\t\t\tmatchingOwners = readLegacyOwnersForSocket(legacyRegistryDir, normalizedSocketPath).filter(\n\t\t\t\t(owner) => owner.token === hello.supervisorOwnerToken && owner.pid === hello.supervisorPid,\n\t\t\t);\n\t\t}\n\t\tif (matchingOwners.length === 0) {\n\t\t\tthrow new Error(`Daemon supervisor owner does not match ${socketPath}`);\n\t\t}\n\t\tif (matchingOwners.length > 1) {\n\t\t\tthrow new Error(`Multiple daemon supervisor owners match ${socketPath}`);\n\t\t}\n\t\tconst owner = matchingOwners[0];\n\t\tif (!owner) {\n\t\t\tthrow new Error(`Daemon supervisor owner disappeared for ${socketPath}`);\n\t\t}\n\t\tconst helloSocketPath = hello.supervisorSocketPath;\n\t\tif (\n\t\t\t!Number.isInteger(hello.supervisorPid) ||\n\t\t\thello.supervisorPid !== owner.pid ||\n\t\t\thello.supervisorGeneration !== owner.generation ||\n\t\t\thello.supervisorOwnerToken !== owner.token ||\n\t\t\ttypeof helloSocketPath !== \"string\" ||\n\t\t\tnormalizeSocketPath(helloSocketPath) !== owner.socketPath ||\n\t\t\ttypeof owner.processStartId !== \"string\" ||\n\t\t\thello.supervisorProcessStartId !== owner.processStartId\n\t\t) {\n\t\t\tthrow new Error(`Daemon supervisor hello does not match its durable owner for ${socketPath}`);\n\t\t}\n\t\tconst observedProcessStartId = getProcessStartId(owner.pid);\n\t\tif (observedProcessStartId !== owner.processStartId) {\n\t\t\tthrow new Error(`Daemon supervisor process identity changed for ${socketPath}`);\n\t\t}\n\t\tconst record: DaemonStartupFenceRecord = {\n\t\t\tversion: OWNER_VERSION,\n\t\t\ttoken: randomUUID(),\n\t\t\townerToken: owner.token,\n\t\t\tpid: owner.pid,\n\t\t\tprocessStartId: owner.processStartId,\n\t\t\tsocketPath: owner.socketPath,\n\t\t\tsupervisorGeneration: owner.generation,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\t\twriteJsonAtomically(path, record);\n\t});\n}\n\nexport async function waitForDaemonStartupFence(\n\tsocketPath: string,\n\ttimeoutMs = 10_000,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<void> {\n\tconst path = startupFencePath(resolve(registryDir, \"startup-fences\"), socketPath);\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (true) {\n\t\tconst fence = readStartupFence(path);\n\t\tif (!fence) {\n\t\t\treturn;\n\t\t}\n\t\tif (fence.socketPath !== normalizeSocketPath(socketPath)) {\n\t\t\tthrow new Error(`Daemon startup fence does not match ${socketPath}`);\n\t\t}\n\t\tif (!isProcessIdentityAlive(fence)) {\n\t\t\tconst cleared = await withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\t\tconst current = readStartupFence(path);\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (current?.token === fence.token) {\n\t\t\t\t\trmSync(path, { force: true });\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (cleared) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (Date.now() >= deadline) {\n\t\t\tthrow new Error(`Timed out waiting for predecessor daemon process ${fence.pid} to exit`);\n\t\t}\n\t\tawait delay(STARTUP_FENCE_POLL_MS);\n\t}\n}\n\nfunction isProcessIdentityAlive(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\tif (!identity.processStartId) {\n\t\treturn true;\n\t}\n\tconst observed = getProcessStartId(identity.pid);\n\treturn observed === undefined || observed === identity.processStartId;\n}\n\nfunction matchesExactProcessIdentity(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\treturn identity.processStartId === undefined || getProcessStartId(identity.pid) === identity.processStartId;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t} catch (error) {\n\t\treturn (error as NodeJS.ErrnoException).code !== \"ESRCH\";\n\t}\n\treturn true;\n}\n\nfunction canonicalizeFilesystemPath(path: string): string {\n\tlet existingAncestor = resolve(path);\n\tconst missingSuffix: string[] = [];\n\twhile (true) {\n\t\ttry {\n\t\t\tconst physicalAncestor = realpathSync.native(existingAncestor);\n\t\t\tconst canonical = join(physicalAncestor, ...missingSuffix);\n\t\t\treturn process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst parent = dirname(existingAncestor);\n\t\t\tif (parent === existingAncestor) {\n\t\t\t\tconst unresolved = resolve(path);\n\t\t\t\treturn process.platform === \"win32\" ? unresolved.toLowerCase() : unresolved;\n\t\t\t}\n\t\t\tmissingSuffix.unshift(basename(existingAncestor));\n\t\t\texistingAncestor = parent;\n\t\t}\n\t}\n}\n\nfunction ownerConflicts(left: DaemonSupervisorOwnerScope, right: DaemonSupervisorOwnerScope): boolean {\n\tif (left.socketPath === right.socketPath || left.descriptorDir === right.descriptorDir) return true;\n\tif (left.journalPath && right.journalPath) return left.journalPath === right.journalPath;\n\t// Older records do not identify their family journal. An unknown footprint cannot grant a writer.\n\treturn Boolean(\n\t\t(left.journalPath || right.journalPath) &&\n\t\t\t(!left.agentDir || !right.agentDir || left.agentDir === right.agentDir),\n\t);\n}\n\nfunction sameOwnerRecord(left: DaemonSupervisorOwnerRecord, right: DaemonSupervisorOwnerRecord): boolean {\n\treturn (\n\t\tleft.token === right.token &&\n\t\tleft.generation === right.generation &&\n\t\tleft.pid === right.pid &&\n\t\tleft.processStartId === right.processStartId &&\n\t\tleft.socketPath === right.socketPath &&\n\t\tleft.descriptorDir === right.descriptorDir &&\n\t\tleft.agentDir === right.agentDir &&\n\t\tleft.journalPath === right.journalPath\n\t);\n}\n\nfunction ownerRecordFingerprint(record: DaemonSupervisorOwnerRecord): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(record)).digest(\"hex\");\n}\n\nfunction listOwnerDirectories(registryDir: string): string[] {\n\treturn readdirSync(registryDir)\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.map((name) => resolve(registryDir, name));\n}\n\nfunction ownerDirectoryPath(registryDir: string, generation: string): string {\n\tif (!/^[A-Za-z0-9._-]+$/.test(generation)) {\n\t\tthrow new Error(`Invalid daemon supervisor generation: ${generation}`);\n\t}\n\treturn resolve(registryDir, `${generation}.owner`);\n}\n\nfunction requireOwnerRecord(directory: string): DaemonSupervisorOwnerRecord {\n\tconst owner = readOwnerRecord(directory);\n\tif (!owner) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn owner;\n}\n\nfunction readOwnerRecordForScope(\n\tdirectory: string,\n\tisRelevant: (scope: DaemonSupervisorOwnerScope) => boolean,\n): DaemonSupervisorOwnerRecord | undefined {\n\tconst owner = readOwnerRecord(directory);\n\tif (owner) {\n\t\treturn owner;\n\t}\n\tconst scope = readOwnerScope(directory);\n\tconst entries = !scope ? readdirSync(directory) : [];\n\tif (!scope && !entries.includes(\"owner.json\") && !entries.includes(\"scope.json\")) {\n\t\tconst abandonedDirectory = `${directory}.abandoned-${randomUUID()}`;\n\t\trenameSync(directory, abandonedDirectory);\n\t\trmSync(abandonedDirectory, { recursive: true, force: true });\n\t\treturn undefined;\n\t}\n\tif (!scope || isRelevant(scope)) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn undefined;\n}\n\nfunction readOwnerRecord(directory: string): DaemonSupervisorOwnerRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"owner.json\"), \"utf8\")) as unknown;\n\t\treturn isDaemonSupervisorOwnerRecord(value) ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerRecord(value: unknown): value is DaemonSupervisorOwnerRecord {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst record = value as Partial<DaemonSupervisorOwnerRecord>;\n\treturn (\n\t\trecord.version === OWNER_VERSION &&\n\t\trecord.role === \"supervisor\" &&\n\t\ttypeof record.token === \"string\" &&\n\t\ttypeof record.generation === \"string\" &&\n\t\tNumber.isInteger(record.pid) &&\n\t\t(record.pid ?? 0) > 0 &&\n\t\t(record.processStartId === undefined || typeof record.processStartId === \"string\") &&\n\t\ttypeof record.socketPath === \"string\" &&\n\t\ttypeof record.descriptorDir === \"string\" &&\n\t\ttypeof record.agentDir === \"string\" &&\n\t\t(record.journalPath === undefined || typeof record.journalPath === \"string\") &&\n\t\ttypeof record.appVersion === \"string\" &&\n\t\t(record.phase === \"starting\" || record.phase === \"owner\" || record.phase === \"stopping\") &&\n\t\ttypeof record.createdAt === \"string\" &&\n\t\ttypeof record.updatedAt === \"string\"\n\t);\n}\n\nfunction readOwnerScope(directory: string): DaemonSupervisorOwnerScope | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"scope.json\"), \"utf8\")) as unknown;\n\t\tif (!isDaemonSupervisorOwnerScope(value)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn ownerDirectoryPath(dirname(directory), value.generation) === directory ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerScope(value: unknown): value is DaemonSupervisorOwnerScope {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst scope = value as Partial<DaemonSupervisorOwnerScope>;\n\treturn (\n\t\tscope.version === OWNER_VERSION &&\n\t\tscope.role === \"supervisor\" &&\n\t\ttypeof scope.token === \"string\" &&\n\t\ttypeof scope.generation === \"string\" &&\n\t\ttypeof scope.socketPath === \"string\" &&\n\t\ttypeof scope.descriptorDir === \"string\" &&\n\t\t(scope.agentDir === undefined || typeof scope.agentDir === \"string\") &&\n\t\t(scope.journalPath === undefined || typeof scope.journalPath === \"string\")\n\t);\n}\n\nfunction writeOwnerScope(directory: string, owner: DaemonSupervisorOwnerRecord): void {\n\tconst scope: DaemonSupervisorOwnerScope = {\n\t\tversion: owner.version,\n\t\trole: owner.role,\n\t\ttoken: owner.token,\n\t\tgeneration: owner.generation,\n\t\tsocketPath: owner.socketPath,\n\t\tdescriptorDir: owner.descriptorDir,\n\t\tagentDir: owner.agentDir,\n\t\t...(owner.journalPath ? { journalPath: owner.journalPath } : {}),\n\t};\n\twriteJsonAtomically(resolve(directory, \"scope.json\"), scope);\n}\n\nfunction writeOwnerRecord(directory: string, record: DaemonSupervisorOwnerRecord): void {\n\twriteJsonAtomically(resolve(directory, \"owner.json\"), record);\n}\n\nfunction readStartupFence(path: string): DaemonStartupFenceRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\tconst fence = value as Partial<DaemonStartupFenceRecord>;\n\t\tif (\n\t\t\tfence.version !== OWNER_VERSION ||\n\t\t\ttypeof fence.token !== \"string\" ||\n\t\t\ttypeof fence.ownerToken !== \"string\" ||\n\t\t\t!Number.isInteger(fence.pid) ||\n\t\t\t(fence.pid ?? 0) <= 0 ||\n\t\t\ttypeof fence.processStartId !== \"string\" ||\n\t\t\ttypeof fence.socketPath !== \"string\" ||\n\t\t\ttypeof fence.supervisorGeneration !== \"string\" ||\n\t\t\ttypeof fence.createdAt !== \"string\"\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\treturn fence as DaemonStartupFenceRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction readActiveShutdownAdmission(registryDir: string): DaemonShutdownAdmissionRecord | undefined {\n\tconst path = shutdownAdmissionPath(registryDir);\n\tconst admission = readShutdownAdmission(path);\n\tif (!admission) {\n\t\treturn undefined;\n\t}\n\tif (Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission)) {\n\t\treturn admission;\n\t}\n\trmSync(path, { force: true });\n\treturn undefined;\n}\n\nfunction readShutdownAdmission(path: string): DaemonShutdownAdmissionRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\tconst admission = value as Partial<DaemonShutdownAdmissionRecord>;\n\t\tif (\n\t\t\tadmission.version !== OWNER_VERSION ||\n\t\t\ttypeof admission.token !== \"string\" ||\n\t\t\t!Number.isInteger(admission.pid) ||\n\t\t\t(admission.pid ?? 0) <= 0 ||\n\t\t\t(admission.processStartId !== undefined && typeof admission.processStartId !== \"string\") ||\n\t\t\ttypeof admission.createdAt !== \"string\" ||\n\t\t\ttypeof admission.updatedAt !== \"string\" ||\n\t\t\ttypeof admission.expiresAt !== \"string\" ||\n\t\t\t!Number.isFinite(Date.parse(admission.expiresAt))\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\treturn admission as DaemonShutdownAdmissionRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction writeJsonAtomically(path: string, value: unknown): void {\n\tconst tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\twriteFileSync(tempPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction startupFencePath(directory: string, socketPath: string): string {\n\tconst key = createHash(\"sha256\").update(normalizeSocketPath(socketPath)).digest(\"hex\");\n\treturn resolve(directory, `${key}.json`);\n}\n\nfunction shutdownAdmissionPath(registryDir: string): string {\n\treturn resolve(registryDir, SHUTDOWN_ADMISSION_FILE_NAME);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n"]}
1
+ {"version":3,"file":"daemon-supervisor-ownership.d.ts","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-supervisor-ownership.ts"],"names":[],"mappings":"AA+BA,KAAK,0BAA0B,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpE,UAAU,eAAe;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,2BAA4B,SAAQ,eAAe;IAC5D,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,0BAA0B,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,6BAA8B,SAAQ,eAAe;IAC9D,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAsBD,UAAU,6BAA6B;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,uCAAuC;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AA0FD,cAAM,yBAAyB;IAI7B,QAAQ,CAAC,MAAM,EAAE,2BAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IALhC,OAAO,CAAC,QAAQ,CAAS;IAEzB,YACU,MAAM,EAAE,2BAA2B,EAC3B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACpC;IAEE,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnC;IAED,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAK9C;IAED,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,kBAAkB;IAOpB,WAAW,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAoB7B;CACD;AAED,cAAM,uBAAuB;IAK3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAL7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD,YACkB,MAAM,EAAE,6BAA6B,EACrC,WAAW,EAAE,MAAM,EAQpC;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAKnC;IAED,OAAO,CAAC,eAAe;IAmBjB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAa7B;CACD;AAyHD,wBAAsB,gCAAgC,CACrD,OAAO,EAAE,uCAAuC,GAC9C,OAAO,CAAC,yBAAyB,CAAC,CA6DpC;AAED,uFAAuF;AACvF,wBAAgB,0CAA0C,CACzD,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAA6C,GACxD,MAAM,EAAE,CAsBV;AAED,wBAAsB,kCAAkC,CACvD,KAAK,EAAE;IACN,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACnB,EACD,oBAAoB,CAAC,EAAE,MAAM,EAC7B,WAAW,CAAC,EAAE,MAAM,EACpB,iBAAiB,GAAE,MAAM,GAAG,SAAqB,GAC/C,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,uBAAuB,CAAC,CA0BvF;AAED,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,OAAO,CAAC,CAKxE;AAED,wBAAsB,kCAAkC,CACvD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,6BAA6B,EACpC,WAAW,CAAC,EAAE,MAAM,EACpB,iBAAiB,GAAE,MAAM,GAAG,SAAqB,GAC/C,OAAO,CAAC,IAAI,CAAC,CA2Df;AAED,wBAAsB,yBAAyB,CAC9C,UAAU,EAAE,MAAM,EAClB,SAAS,SAAS,EAClB,WAAW,GAAE,MAA6C,GACxD,OAAO,CAAC,IAAI,CAAC,CAiCf","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { getProcessStartId } from \"../../core/session-lease.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport { normalizeSocketPath } from \"./daemon-socket.js\";\n\nconst DAEMON_SUPERVISOR_REGISTRY_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_REGISTRY_DIR\";\n\nconst OWNER_VERSION = 1;\nconst REGISTRY_LOCK_STALE_MS = 5000;\nconst REGISTRY_LOCK_UPDATE_MS = 1000;\nconst REGISTRY_LOCK_RETRIES = 500;\nconst REGISTRY_LOCK_RETRY_MS = 10;\nconst STARTUP_FENCE_POLL_MS = 250;\nconst SHUTDOWN_ADMISSION_FILE_NAME = \"shutdown-admission.json\";\nconst SHUTDOWN_ADMISSION_LEASE_MS = 5000;\nconst SHUTDOWN_ADMISSION_REFRESH_MS = 1000;\nconst SHUTDOWN_ADMISSION_WAIT_MS = 50;\n\ntype DaemonSupervisorOwnerPhase = \"starting\" | \"owner\" | \"stopping\";\n\ninterface ProcessIdentity {\n\tpid: number;\n\tprocessStartId?: string;\n}\n\ninterface DaemonSupervisorOwnerRecord extends ProcessIdentity {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tappVersion: string;\n\tphase: DaemonSupervisorOwnerPhase;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\ninterface DaemonShutdownAdmissionRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\texpiresAt: string;\n}\n\ninterface DaemonSupervisorOwnerScope {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir?: string;\n\tjournalPath?: string;\n}\n\ninterface DaemonStartupFenceRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\townerToken: string;\n\tsocketPath: string;\n\tsupervisorGeneration: string;\n\tcreatedAt: string;\n}\n\ninterface DaemonSupervisorHelloIdentity {\n\tsupervisorGeneration?: string;\n\tsupervisorOwnerToken?: string;\n\tsupervisorPid?: number;\n\tsupervisorProcessStartId?: string;\n\tsupervisorSocketPath?: string;\n}\n\ninterface AcquireDaemonSupervisorOwnershipOptions {\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tgeneration: string;\n\tappVersion: string;\n\tregistryDir?: string;\n}\n\nclass DaemonSupervisorAlreadyRunningError extends Error {\n\treadonly code = \"daemon_supervisor_already_running\" as const;\n\n\tconstructor(readonly owner: DaemonSupervisorOwnerRecord) {\n\t\tsuper(`Daemon supervisor ${owner.generation} already owns ${owner.socketPath}`);\n\t\tthis.name = \"DaemonSupervisorAlreadyRunningError\";\n\t}\n}\n\nclass DaemonSupervisorOwnershipLostError extends Error {\n\treadonly code = \"supervisor_generation_stale\" as const;\n\n\tconstructor(generation: string, details: { socketPath?: string; registryDir?: string } = {}) {\n\t\tconst context = [\n\t\t\tdetails.socketPath ? `socket: ${details.socketPath}` : undefined,\n\t\t\tdetails.registryDir ? `registry: ${details.registryDir}` : undefined,\n\t\t].filter((part) => part !== undefined);\n\t\tsuper(\n\t\t\t`Daemon supervisor generation ${generation} no longer owns its registry entry ` +\n\t\t\t\t`(record on disk is missing or was replaced)${context.length > 0 ? `; ${context.join(\"; \")}` : \"\"}; ` +\n\t\t\t\t\"restart the daemon to recover — sessions are preserved\",\n\t\t);\n\t\tthis.name = \"DaemonSupervisorOwnershipLostError\";\n\t}\n}\n\nclass DaemonShutdownAdmissionError extends Error {\n\treadonly code = \"daemon_shutdown_in_progress\" as const;\n\n\tconstructor(message = \"Daemon shutdown is in progress\") {\n\t\tsuper(message);\n\t\tthis.name = \"DaemonShutdownAdmissionError\";\n\t}\n}\n\n/**\n * Owns a lease-renew loop safely: the unref()'d interval, single-flight\n * refresh dedup shared by timer-fired and direct calls, and lost-state fencing.\n */\nclass RenewableRegistryRecord {\n\tprivate stopped = false;\n\tprivate lost = false;\n\tprivate refreshPromise?: Promise<void>;\n\tprivate readonly refreshTimer: ReturnType<typeof setInterval>;\n\n\tconstructor(\n\t\tprivate readonly registryDir: string,\n\t\trefreshMs: number,\n\t\tprivate readonly renewUnderGuard: () => boolean,\n\t\tprivate readonly createLostError: () => Error,\n\t) {\n\t\tthis.refreshTimer = setInterval(() => {\n\t\t\tvoid this.assertOrRenew().catch(() => undefined);\n\t\t}, refreshMs);\n\t\tthis.refreshTimer.unref();\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.stopped || this.lost) {\n\t\t\tthrow this.createLostError();\n\t\t}\n\t\tthis.refreshPromise ??= this.performRenew().finally(() => {\n\t\t\tthis.refreshPromise = undefined;\n\t\t});\n\t\tawait this.refreshPromise;\n\t}\n\n\tprivate async performRenew(): Promise<void> {\n\t\tconst held = await withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t// stop() may have completed while this call waited on the guard;\n\t\t\t// a stopped record must never be rewritten to disk.\n\t\t\tif (this.stopped || this.lost) return false;\n\t\t\treturn this.renewUnderGuard();\n\t\t});\n\t\tif (!held) {\n\t\t\tthis.lost = true;\n\t\t\tclearInterval(this.refreshTimer);\n\t\t\tthrow this.createLostError();\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.stopped = true;\n\t\tclearInterval(this.refreshTimer);\n\t\tawait this.refreshPromise?.catch(() => undefined);\n\t}\n}\n\nclass DaemonSupervisorOwnership {\n\tprivate released = false;\n\n\tconstructor(\n\t\treadonly record: DaemonSupervisorOwnerRecord,\n\t\tprivate readonly registryDir: string,\n\t\tprivate readonly ownerDirectory: string,\n\t) {}\n\n\tasync assertCurrent(): Promise<void> {\n\t\tthis.assertCurrentSync();\n\t}\n\n\tassertJournalCurrent(journalPath: string): void {\n\t\tif (this.record.journalPath !== canonicalizeFilesystemPath(assertProductStatePath(journalPath))) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tthis.assertCurrentSync();\n\t}\n\n\tprivate assertCurrentSync(): void {\n\t\tif (this.released) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\tif (!current || !sameOwnerRecord(current, this.record)) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t}\n\n\tprivate ownershipLostError(): DaemonSupervisorOwnershipLostError {\n\t\treturn new DaemonSupervisorOwnershipLostError(this.record.generation, {\n\t\t\tsocketPath: this.record.socketPath,\n\t\t\tregistryDir: this.registryDir,\n\t\t});\n\t}\n\n\tasync updatePhase(phase: DaemonSupervisorOwnerPhase): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tconst updated = await mutateDaemonSupervisorOwner(\n\t\t\tthis.record.generation,\n\t\t\tthis.record.token,\n\t\t\t(owner) => {\n\t\t\t\towner.phase = phase;\n\t\t\t},\n\t\t\tthis.registryDir,\n\t\t);\n\t\tif (!updated) {\n\t\t\tthrow new Error(`Daemon supervisor ownership was lost for ${this.record.socketPath}`);\n\t\t}\n\t\tthis.record.phase = phase;\n\t\tthis.record.updatedAt = updated.updatedAt;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tlet releasedDirectory: string | undefined;\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\t\t\tif (!current || current.token !== this.record.token) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treleasedDirectory = `${this.ownerDirectory}.released-${randomUUID()}`;\n\t\t\t\trenameSync(this.ownerDirectory, releasedDirectory);\n\t\t\t});\n\t\t\tthis.released = true;\n\t\t} finally {\n\t\t\tif (releasedDirectory) {\n\t\t\t\trmSync(releasedDirectory, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass DaemonShutdownAdmission {\n\tprivate released = false;\n\tprivate readonly renewal: RenewableRegistryRecord;\n\n\tconstructor(\n\t\tprivate readonly record: DaemonShutdownAdmissionRecord,\n\t\tprivate readonly registryDir: string,\n\t) {\n\t\tthis.renewal = new RenewableRegistryRecord(\n\t\t\tregistryDir,\n\t\t\tSHUTDOWN_ADMISSION_REFRESH_MS,\n\t\t\t() => this.renewUnderGuard(),\n\t\t\t() => new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\"),\n\t\t);\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.released) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tawait this.renewal.assertOrRenew();\n\t}\n\n\tprivate renewUnderGuard(): boolean {\n\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\tconst current = readShutdownAdmission(path);\n\t\tif (\n\t\t\t!current ||\n\t\t\tcurrent.token !== this.record.token ||\n\t\t\tcurrent.pid !== this.record.pid ||\n\t\t\tcurrent.processStartId !== this.record.processStartId ||\n\t\t\t!matchesExactProcessIdentity(this.record)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tconst now = Date.now();\n\t\tthis.record.updatedAt = new Date(now).toISOString();\n\t\tthis.record.expiresAt = new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString();\n\t\twriteJsonAtomically(path, this.record);\n\t\treturn true;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tthis.released = true;\n\t\tawait this.renewal.stop();\n\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\t\tconst current = readShutdownAdmission(path);\n\t\t\tif (current?.token === this.record.token) {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t}\n\t\t});\n\t}\n}\n\n/** Durable supervisor authority is scoped to one product home, never an upstream registry. */\nfunction defaultDaemonSupervisorRegistryDir(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst override = readAbsolutePathEnv(DAEMON_SUPERVISOR_REGISTRY_DIR_ENV, environment);\n\treturn assertProductStatePath(override ?? resolveRuntimePaths(environment).daemonRegistry);\n}\n\n/**\n * Non-mutating legacy scan: never reclaims abandoned directories (old-build\n * daemons own that location's lifecycle) and runs without the legacy guard —\n * best-effort is acceptable because records are written rename-atomically.\n */\nfunction readLegacyOwnersForSocket(\n\tlegacyRegistryDir: string,\n\tnormalizedSocketPath: string,\n): DaemonSupervisorOwnerRecord[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(legacyRegistryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn entries\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.flatMap((name) => {\n\t\t\tconst owner = readOwnerRecord(resolve(legacyRegistryDir, name));\n\t\t\treturn owner && owner.socketPath === normalizedSocketPath ? [owner] : [];\n\t\t});\n}\n\nasync function withDaemonSupervisorRegistryGuard<T>(registryDir: string, action: () => T | Promise<T>): Promise<T> {\n\tassertProductStatePath(registryDir);\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst guardPath = resolve(registryDir, \".guard\");\n\tlet compromisedError: Error | undefined;\n\tconst release = await lockfile.lock(registryDir, {\n\t\trealpath: false,\n\t\tlockfilePath: guardPath,\n\t\tstale: REGISTRY_LOCK_STALE_MS,\n\t\tupdate: REGISTRY_LOCK_UPDATE_MS,\n\t\tonCompromised: (error) => {\n\t\t\tcompromisedError ??= error;\n\t\t},\n\t\tretries: {\n\t\t\tretries: REGISTRY_LOCK_RETRIES,\n\t\t\tfactor: 1,\n\t\t\tminTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t\tmaxTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t},\n\t});\n\t// Compromise detection is timer-driven and cannot preempt a synchronous stall: a stalled action's\n\t// writes may already be on disk when a successor reclaims the stale guard. The guard directory's\n\t// inode is the ownership identity (a steal is rmdir+mkdir), checked synchronously where the timer\n\t// cannot run; when the inode is unobservable, only timer-driven detection applies.\n\tconst guardIno = (() => {\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t})();\n\tconst guardStolen = () => {\n\t\tif (guardIno === undefined) return false;\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino !== guardIno;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t};\n\tconst assertGuardHeld = () => {\n\t\tif (compromisedError)\n\t\t\tthrow new Error(`Daemon supervisor registry guard was compromised: ${compromisedError.message}`);\n\t\tif (guardStolen())\n\t\t\tthrow new Error(\"Daemon supervisor registry guard was compromised: the guard lock changed hands\");\n\t};\n\ttry {\n\t\tassertGuardHeld();\n\t\tconst result = await action();\n\t\tassertGuardHeld();\n\t\treturn result;\n\t} finally {\n\t\tif (compromisedError) {\n\t\t\tawait release().catch(() => undefined);\n\t\t} else if (!guardStolen()) {\n\t\t\tawait release();\n\t\t}\n\t\t// A stolen-but-undetected guard is never released: that would delete the successor's lock.\n\t\t// The abandoned updater notices the foreign mtime on its next tick and cleans itself up.\n\t}\n}\n\nasync function mutateDaemonSupervisorOwner(\n\tgeneration: string,\n\texpectedToken: string,\n\tmutation: (owner: DaemonSupervisorOwnerRecord) => void,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<DaemonSupervisorOwnerRecord | undefined> {\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst directory = ownerDirectoryPath(registryDir, generation);\n\t\tif (!existsSync(directory)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst current = requireOwnerRecord(directory);\n\t\tif (current.token !== expectedToken) {\n\t\t\treturn undefined;\n\t\t}\n\t\tmutation(current);\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tif (\n\t\t\t!isDaemonSupervisorOwnerRecord(current) ||\n\t\t\tcurrent.generation !== generation ||\n\t\t\tcurrent.token !== expectedToken\n\t\t) {\n\t\t\tthrow new Error(`Invalid mutation for daemon supervisor owner ${generation}`);\n\t\t}\n\t\twriteOwnerRecord(directory, current);\n\t\treturn current;\n\t});\n}\n\nexport async function acquireDaemonSupervisorOwnership(\n\toptions: AcquireDaemonSupervisorOwnershipOptions,\n): Promise<DaemonSupervisorOwnership> {\n\tconst registryDir = options.registryDir ?? defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst token = randomUUID();\n\tconst processStartId = getProcessStartId(process.pid);\n\tconst now = new Date().toISOString();\n\tconst record: DaemonSupervisorOwnerRecord = {\n\t\tversion: OWNER_VERSION,\n\t\trole: \"supervisor\",\n\t\ttoken,\n\t\tgeneration: options.generation,\n\t\tpid: process.pid,\n\t\t...(processStartId ? { processStartId } : {}),\n\t\tsocketPath: normalizeSocketPath(options.socketPath),\n\t\tdescriptorDir: canonicalizeFilesystemPath(options.descriptorDir),\n\t\tagentDir: canonicalizeFilesystemPath(options.agentDir),\n\t\t...(options.journalPath\n\t\t\t? { journalPath: canonicalizeFilesystemPath(assertProductStatePath(options.journalPath)) }\n\t\t\t: {}),\n\t\tappVersion: options.appVersion,\n\t\tphase: \"starting\",\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t};\n\tconst candidateDirectory = resolve(registryDir, `.candidate-${process.pid}-${token}`);\n\tconst ownerDirectory = ownerDirectoryPath(registryDir, options.generation);\n\tmkdirSync(candidateDirectory, { mode: 0o700 });\n\tconst staleDirectories: string[] = [];\n\ttry {\n\t\twriteOwnerScope(candidateDirectory, record);\n\t\twriteOwnerRecord(candidateDirectory, record);\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\tthrow new DaemonShutdownAdmissionError();\n\t\t\t}\n\t\t\tfor (const directory of listOwnerDirectories(registryDir)) {\n\t\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => ownerConflicts(scope, record));\n\t\t\t\tif (!owner) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!ownerConflicts(owner, record)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (isProcessIdentityAlive(owner)) {\n\t\t\t\t\tthrow new DaemonSupervisorAlreadyRunningError(owner);\n\t\t\t\t}\n\t\t\t\tconst staleDirectory = `${directory}.stale-${randomUUID()}`;\n\t\t\t\trenameSync(directory, staleDirectory);\n\t\t\t\tstaleDirectories.push(staleDirectory);\n\t\t\t}\n\t\t\trenameSync(candidateDirectory, ownerDirectory);\n\t\t});\n\t} catch (error) {\n\t\trmSync(candidateDirectory, { recursive: true, force: true });\n\t\tthrow error;\n\t} finally {\n\t\tfor (const directory of staleDirectories) {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t}\n\t}\n\treturn new DaemonSupervisorOwnership(record, registryDir, ownerDirectory);\n}\n\n/** Read only: discovery must not acquire ownership or reclaim registry directories. */\nexport function listDaemonSupervisorSocketPathsForAgentDir(\n\tagentDir: string,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): string[] {\n\tlet canonicalAgentDir: string;\n\tlet directories: string[];\n\ttry {\n\t\tcanonicalAgentDir = canonicalizeFilesystemPath(agentDir);\n\t\tdirectories = listOwnerDirectories(registryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst socketPaths: string[] = [];\n\tfor (const directory of directories) {\n\t\tconst owner = readOwnerRecord(directory);\n\t\tif (!owner) continue;\n\t\ttry {\n\t\t\tif (canonicalizeFilesystemPath(owner.agentDir) === canonicalAgentDir) {\n\t\t\t\tsocketPaths.push(normalizeSocketPath(owner.socketPath));\n\t\t\t}\n\t\t} catch {\n\t\t\t// A stale or inaccessible record must not hide the other supervisors.\n\t\t}\n\t}\n\treturn socketPaths;\n}\n\nexport async function assertDaemonSupervisorOwnerCurrent(\n\towner: {\n\t\tgeneration: string;\n\t\tpid: number;\n\t\tprocessStartId?: string;\n\t\tsocketPath: string;\n\t},\n\tvalidatedFingerprint?: string,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<string> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tconst current =\n\t\treadOwnerRecord(ownerDirectoryPath(registryDir, owner.generation)) ??\n\t\t(legacyRegistryDir ? readOwnerRecord(ownerDirectoryPath(legacyRegistryDir, owner.generation)) : undefined);\n\tif (\n\t\t!current ||\n\t\tcurrent.pid !== owner.pid ||\n\t\tcurrent.processStartId !== owner.processStartId ||\n\t\tcurrent.socketPath !== normalizeSocketPath(owner.socketPath) ||\n\t\t!isProcessAlive(current.pid)\n\t) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\tconst fingerprint = ownerRecordFingerprint(current);\n\tif (fingerprint !== validatedFingerprint && !isProcessIdentityAlive(current)) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\treturn fingerprint;\n}\n\nexport async function acquireDaemonShutdownAdmission(): Promise<DaemonShutdownAdmission> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\tconst processStartId = getProcessStartId(process.pid);\n\twhile (true) {\n\t\tlet acquired: DaemonShutdownAdmissionRecord | undefined;\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst now = Date.now();\n\t\t\tacquired = {\n\t\t\t\tversion: OWNER_VERSION,\n\t\t\t\ttoken: randomUUID(),\n\t\t\t\tpid: process.pid,\n\t\t\t\t...(processStartId ? { processStartId } : {}),\n\t\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t\t\tupdatedAt: new Date(now).toISOString(),\n\t\t\t\texpiresAt: new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString(),\n\t\t\t};\n\t\t\twriteJsonAtomically(shutdownAdmissionPath(registryDir), acquired);\n\t\t});\n\t\tif (acquired) {\n\t\t\treturn new DaemonShutdownAdmission(acquired, registryDir);\n\t\t}\n\t\tawait delay(SHUTDOWN_ADMISSION_WAIT_MS);\n\t}\n}\n\nexport async function isDaemonShutdownAdmissionActive(): Promise<boolean> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () =>\n\t\tshutdownAdmissionIsActive(readShutdownAdmission(shutdownAdmissionPath(registryDir))),\n\t);\n}\n\nexport async function persistDaemonStartupFenceFromOwner(\n\tsocketPath: string,\n\thello: DaemonSupervisorHelloIdentity,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<void> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst fenceDirectory = resolve(registryDir, \"startup-fences\");\n\tmkdirSync(fenceDirectory, { recursive: true, mode: 0o700 });\n\tconst path = startupFencePath(fenceDirectory, socketPath);\n\tconst normalizedSocketPath = normalizeSocketPath(socketPath);\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst owners = listOwnerDirectories(registryDir).flatMap((directory) => {\n\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => scope.socketPath === normalizedSocketPath);\n\t\t\treturn owner ? [owner] : [];\n\t\t});\n\t\tlet matchingOwners = owners.filter((owner) => owner.socketPath === normalizedSocketPath);\n\t\tif (matchingOwners.length === 0 && legacyRegistryDir) {\n\t\t\t// Stale legacy leftovers are expected; keep only records matching the\n\t\t\t// identity the caller already holds.\n\t\t\tmatchingOwners = readLegacyOwnersForSocket(legacyRegistryDir, normalizedSocketPath).filter(\n\t\t\t\t(owner) => owner.token === hello.supervisorOwnerToken && owner.pid === hello.supervisorPid,\n\t\t\t);\n\t\t}\n\t\tif (matchingOwners.length === 0) {\n\t\t\tthrow new Error(`Daemon supervisor owner does not match ${socketPath}`);\n\t\t}\n\t\tif (matchingOwners.length > 1) {\n\t\t\tthrow new Error(`Multiple daemon supervisor owners match ${socketPath}`);\n\t\t}\n\t\tconst owner = matchingOwners[0];\n\t\tif (!owner) {\n\t\t\tthrow new Error(`Daemon supervisor owner disappeared for ${socketPath}`);\n\t\t}\n\t\tconst helloSocketPath = hello.supervisorSocketPath;\n\t\tif (\n\t\t\t!Number.isInteger(hello.supervisorPid) ||\n\t\t\thello.supervisorPid !== owner.pid ||\n\t\t\thello.supervisorGeneration !== owner.generation ||\n\t\t\thello.supervisorOwnerToken !== owner.token ||\n\t\t\ttypeof helloSocketPath !== \"string\" ||\n\t\t\tnormalizeSocketPath(helloSocketPath) !== owner.socketPath ||\n\t\t\ttypeof owner.processStartId !== \"string\" ||\n\t\t\thello.supervisorProcessStartId !== owner.processStartId\n\t\t) {\n\t\t\tthrow new Error(`Daemon supervisor hello does not match its durable owner for ${socketPath}`);\n\t\t}\n\t\tconst observedProcessStartId = getProcessStartId(owner.pid);\n\t\tif (observedProcessStartId !== owner.processStartId) {\n\t\t\tthrow new Error(`Daemon supervisor process identity changed for ${socketPath}`);\n\t\t}\n\t\tconst record: DaemonStartupFenceRecord = {\n\t\t\tversion: OWNER_VERSION,\n\t\t\ttoken: randomUUID(),\n\t\t\townerToken: owner.token,\n\t\t\tpid: owner.pid,\n\t\t\tprocessStartId: owner.processStartId,\n\t\t\tsocketPath: owner.socketPath,\n\t\t\tsupervisorGeneration: owner.generation,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\t\twriteJsonAtomically(path, record);\n\t});\n}\n\nexport async function waitForDaemonStartupFence(\n\tsocketPath: string,\n\ttimeoutMs = 10_000,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<void> {\n\tconst path = startupFencePath(resolve(registryDir, \"startup-fences\"), socketPath);\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (true) {\n\t\tconst fence = readStartupFence(path);\n\t\tif (!fence) {\n\t\t\treturn;\n\t\t}\n\t\tif (fence.socketPath !== normalizeSocketPath(socketPath)) {\n\t\t\tthrow new Error(`Daemon startup fence does not match ${socketPath}`);\n\t\t}\n\t\tif (!isProcessIdentityAlive(fence)) {\n\t\t\tconst cleared = await withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\t\tconst current = readStartupFence(path);\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (current?.token === fence.token) {\n\t\t\t\t\trmSync(path, { force: true });\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (cleared) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (Date.now() >= deadline) {\n\t\t\tthrow new Error(`Timed out waiting for predecessor daemon process ${fence.pid} to exit`);\n\t\t}\n\t\tawait delay(STARTUP_FENCE_POLL_MS);\n\t}\n}\n\nfunction isProcessIdentityAlive(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\tif (!identity.processStartId) {\n\t\treturn true;\n\t}\n\tconst observed = getProcessStartId(identity.pid);\n\treturn observed === undefined || observed === identity.processStartId;\n}\n\nfunction matchesExactProcessIdentity(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\treturn identity.processStartId === undefined || getProcessStartId(identity.pid) === identity.processStartId;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t} catch (error) {\n\t\treturn (error as NodeJS.ErrnoException).code !== \"ESRCH\";\n\t}\n\treturn true;\n}\n\nfunction canonicalizeFilesystemPath(path: string): string {\n\tlet existingAncestor = resolve(path);\n\tconst missingSuffix: string[] = [];\n\twhile (true) {\n\t\ttry {\n\t\t\tconst physicalAncestor = realpathSync.native(existingAncestor);\n\t\t\tconst canonical = join(physicalAncestor, ...missingSuffix);\n\t\t\treturn process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst parent = dirname(existingAncestor);\n\t\t\tif (parent === existingAncestor) {\n\t\t\t\tconst unresolved = resolve(path);\n\t\t\t\treturn process.platform === \"win32\" ? unresolved.toLowerCase() : unresolved;\n\t\t\t}\n\t\t\tmissingSuffix.unshift(basename(existingAncestor));\n\t\t\texistingAncestor = parent;\n\t\t}\n\t}\n}\n\nfunction ownerConflicts(left: DaemonSupervisorOwnerScope, right: DaemonSupervisorOwnerScope): boolean {\n\tif (left.socketPath === right.socketPath || left.descriptorDir === right.descriptorDir) return true;\n\tif (left.journalPath && right.journalPath) return left.journalPath === right.journalPath;\n\t// Older records do not identify their family journal. An unknown footprint cannot grant a writer.\n\treturn Boolean(\n\t\t(left.journalPath || right.journalPath) &&\n\t\t\t(!left.agentDir || !right.agentDir || left.agentDir === right.agentDir),\n\t);\n}\n\nfunction sameOwnerRecord(left: DaemonSupervisorOwnerRecord, right: DaemonSupervisorOwnerRecord): boolean {\n\treturn (\n\t\tleft.token === right.token &&\n\t\tleft.generation === right.generation &&\n\t\tleft.pid === right.pid &&\n\t\tleft.processStartId === right.processStartId &&\n\t\tleft.socketPath === right.socketPath &&\n\t\tleft.descriptorDir === right.descriptorDir &&\n\t\tleft.agentDir === right.agentDir &&\n\t\tleft.journalPath === right.journalPath\n\t);\n}\n\nfunction ownerRecordFingerprint(record: DaemonSupervisorOwnerRecord): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(record)).digest(\"hex\");\n}\n\nfunction listOwnerDirectories(registryDir: string): string[] {\n\treturn readdirSync(registryDir)\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.map((name) => resolve(registryDir, name));\n}\n\nfunction ownerDirectoryPath(registryDir: string, generation: string): string {\n\tif (!/^[A-Za-z0-9._-]+$/.test(generation)) {\n\t\tthrow new Error(`Invalid daemon supervisor generation: ${generation}`);\n\t}\n\treturn resolve(registryDir, `${generation}.owner`);\n}\n\nfunction requireOwnerRecord(directory: string): DaemonSupervisorOwnerRecord {\n\tconst owner = readOwnerRecord(directory);\n\tif (!owner) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn owner;\n}\n\nfunction readOwnerRecordForScope(\n\tdirectory: string,\n\tisRelevant: (scope: DaemonSupervisorOwnerScope) => boolean,\n): DaemonSupervisorOwnerRecord | undefined {\n\tconst owner = readOwnerRecord(directory);\n\tif (owner) {\n\t\treturn owner;\n\t}\n\tconst scope = readOwnerScope(directory);\n\tconst entries = !scope ? readdirSync(directory) : [];\n\tif (!scope && !entries.includes(\"owner.json\") && !entries.includes(\"scope.json\")) {\n\t\tconst abandonedDirectory = `${directory}.abandoned-${randomUUID()}`;\n\t\trenameSync(directory, abandonedDirectory);\n\t\trmSync(abandonedDirectory, { recursive: true, force: true });\n\t\treturn undefined;\n\t}\n\tif (!scope || isRelevant(scope)) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn undefined;\n}\n\nfunction readOwnerRecord(directory: string): DaemonSupervisorOwnerRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"owner.json\"), \"utf8\")) as unknown;\n\t\treturn isDaemonSupervisorOwnerRecord(value) ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerRecord(value: unknown): value is DaemonSupervisorOwnerRecord {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst record = value as Partial<DaemonSupervisorOwnerRecord>;\n\treturn (\n\t\trecord.version === OWNER_VERSION &&\n\t\trecord.role === \"supervisor\" &&\n\t\ttypeof record.token === \"string\" &&\n\t\ttypeof record.generation === \"string\" &&\n\t\tNumber.isInteger(record.pid) &&\n\t\t(record.pid ?? 0) > 0 &&\n\t\t(record.processStartId === undefined || typeof record.processStartId === \"string\") &&\n\t\ttypeof record.socketPath === \"string\" &&\n\t\ttypeof record.descriptorDir === \"string\" &&\n\t\ttypeof record.agentDir === \"string\" &&\n\t\t(record.journalPath === undefined || typeof record.journalPath === \"string\") &&\n\t\ttypeof record.appVersion === \"string\" &&\n\t\t(record.phase === \"starting\" || record.phase === \"owner\" || record.phase === \"stopping\") &&\n\t\ttypeof record.createdAt === \"string\" &&\n\t\ttypeof record.updatedAt === \"string\"\n\t);\n}\n\nfunction readOwnerScope(directory: string): DaemonSupervisorOwnerScope | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"scope.json\"), \"utf8\")) as unknown;\n\t\tif (!isDaemonSupervisorOwnerScope(value)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn ownerDirectoryPath(dirname(directory), value.generation) === directory ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerScope(value: unknown): value is DaemonSupervisorOwnerScope {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst scope = value as Partial<DaemonSupervisorOwnerScope>;\n\treturn (\n\t\tscope.version === OWNER_VERSION &&\n\t\tscope.role === \"supervisor\" &&\n\t\ttypeof scope.token === \"string\" &&\n\t\ttypeof scope.generation === \"string\" &&\n\t\ttypeof scope.socketPath === \"string\" &&\n\t\ttypeof scope.descriptorDir === \"string\" &&\n\t\t(scope.agentDir === undefined || typeof scope.agentDir === \"string\") &&\n\t\t(scope.journalPath === undefined || typeof scope.journalPath === \"string\")\n\t);\n}\n\nfunction writeOwnerScope(directory: string, owner: DaemonSupervisorOwnerRecord): void {\n\tconst scope: DaemonSupervisorOwnerScope = {\n\t\tversion: owner.version,\n\t\trole: owner.role,\n\t\ttoken: owner.token,\n\t\tgeneration: owner.generation,\n\t\tsocketPath: owner.socketPath,\n\t\tdescriptorDir: owner.descriptorDir,\n\t\tagentDir: owner.agentDir,\n\t\t...(owner.journalPath ? { journalPath: owner.journalPath } : {}),\n\t};\n\twriteJsonAtomically(resolve(directory, \"scope.json\"), scope);\n}\n\nfunction writeOwnerRecord(directory: string, record: DaemonSupervisorOwnerRecord): void {\n\twriteJsonAtomically(resolve(directory, \"owner.json\"), record);\n}\n\nfunction readStartupFence(path: string): DaemonStartupFenceRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\tconst fence = value as Partial<DaemonStartupFenceRecord>;\n\t\tif (\n\t\t\tfence.version !== OWNER_VERSION ||\n\t\t\ttypeof fence.token !== \"string\" ||\n\t\t\ttypeof fence.ownerToken !== \"string\" ||\n\t\t\t!Number.isInteger(fence.pid) ||\n\t\t\t(fence.pid ?? 0) <= 0 ||\n\t\t\ttypeof fence.processStartId !== \"string\" ||\n\t\t\ttypeof fence.socketPath !== \"string\" ||\n\t\t\ttypeof fence.supervisorGeneration !== \"string\" ||\n\t\t\ttypeof fence.createdAt !== \"string\"\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\treturn fence as DaemonStartupFenceRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction shutdownAdmissionIsActive(admission: DaemonShutdownAdmissionRecord | undefined): boolean {\n\treturn admission !== undefined && Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission);\n}\n\nfunction readActiveShutdownAdmission(registryDir: string): DaemonShutdownAdmissionRecord | undefined {\n\tconst path = shutdownAdmissionPath(registryDir);\n\tconst admission = readShutdownAdmission(path);\n\tif (!admission) {\n\t\treturn undefined;\n\t}\n\tif (shutdownAdmissionIsActive(admission)) {\n\t\treturn admission;\n\t}\n\trmSync(path, { force: true });\n\treturn undefined;\n}\n\nfunction readShutdownAdmission(path: string): DaemonShutdownAdmissionRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\tconst admission = value as Partial<DaemonShutdownAdmissionRecord>;\n\t\tif (\n\t\t\tadmission.version !== OWNER_VERSION ||\n\t\t\ttypeof admission.token !== \"string\" ||\n\t\t\t!Number.isInteger(admission.pid) ||\n\t\t\t(admission.pid ?? 0) <= 0 ||\n\t\t\t(admission.processStartId !== undefined && typeof admission.processStartId !== \"string\") ||\n\t\t\ttypeof admission.createdAt !== \"string\" ||\n\t\t\ttypeof admission.updatedAt !== \"string\" ||\n\t\t\ttypeof admission.expiresAt !== \"string\" ||\n\t\t\t!Number.isFinite(Date.parse(admission.expiresAt))\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\treturn admission as DaemonShutdownAdmissionRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction writeJsonAtomically(path: string, value: unknown): void {\n\tconst tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\twriteFileSync(tempPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction startupFencePath(directory: string, socketPath: string): string {\n\tconst key = createHash(\"sha256\").update(normalizeSocketPath(socketPath)).digest(\"hex\");\n\treturn resolve(directory, `${key}.json`);\n}\n\nfunction shutdownAdmissionPath(registryDir: string): string {\n\treturn resolve(registryDir, SHUTDOWN_ADMISSION_FILE_NAME);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n"]}
@@ -76,20 +76,17 @@ class RenewableRegistryRecord {
76
76
  await this.refreshPromise;
77
77
  }
78
78
  async performRenew() {
79
- try {
80
- await withDaemonSupervisorRegistryGuard(this.registryDir, () => {
81
- // stop() may have completed while this call waited on the guard;
82
- // a stopped record must never be rewritten to disk.
83
- if (this.stopped || this.lost) {
84
- throw this.createLostError();
85
- }
86
- this.renewUnderGuard();
87
- });
88
- }
89
- catch (error) {
79
+ const held = await withDaemonSupervisorRegistryGuard(this.registryDir, () => {
80
+ // stop() may have completed while this call waited on the guard;
81
+ // a stopped record must never be rewritten to disk.
82
+ if (this.stopped || this.lost)
83
+ return false;
84
+ return this.renewUnderGuard();
85
+ });
86
+ if (!held) {
90
87
  this.lost = true;
91
88
  clearInterval(this.refreshTimer);
92
- throw error;
89
+ throw this.createLostError();
93
90
  }
94
91
  }
95
92
  async stop() {
@@ -191,14 +188,14 @@ class DaemonShutdownAdmission {
191
188
  current.token !== this.record.token ||
192
189
  current.pid !== this.record.pid ||
193
190
  current.processStartId !== this.record.processStartId ||
194
- Date.parse(current.expiresAt) <= Date.now() ||
195
191
  !matchesExactProcessIdentity(this.record)) {
196
- throw new DaemonShutdownAdmissionError("Daemon shutdown admission was lost");
192
+ return false;
197
193
  }
198
194
  const now = Date.now();
199
195
  this.record.updatedAt = new Date(now).toISOString();
200
196
  this.record.expiresAt = new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString();
201
197
  writeJsonAtomically(path, this.record);
198
+ return true;
202
199
  }
203
200
  async release() {
204
201
  if (this.released) {
@@ -463,7 +460,7 @@ export async function acquireDaemonShutdownAdmission() {
463
460
  }
464
461
  export async function isDaemonShutdownAdmissionActive() {
465
462
  const registryDir = defaultDaemonSupervisorRegistryDir();
466
- return withDaemonSupervisorRegistryGuard(registryDir, () => readActiveShutdownAdmission(registryDir) !== undefined);
463
+ return withDaemonSupervisorRegistryGuard(registryDir, () => shutdownAdmissionIsActive(readShutdownAdmission(shutdownAdmissionPath(registryDir))));
467
464
  }
468
465
  export async function persistDaemonStartupFenceFromOwner(socketPath, hello, registryDir, legacyRegistryDir = undefined) {
469
466
  registryDir ??= defaultDaemonSupervisorRegistryDir();
@@ -760,13 +757,16 @@ function readStartupFence(path) {
760
757
  throw error;
761
758
  }
762
759
  }
760
+ function shutdownAdmissionIsActive(admission) {
761
+ return admission !== undefined && Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission);
762
+ }
763
763
  function readActiveShutdownAdmission(registryDir) {
764
764
  const path = shutdownAdmissionPath(registryDir);
765
765
  const admission = readShutdownAdmission(path);
766
766
  if (!admission) {
767
767
  return undefined;
768
768
  }
769
- if (Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission)) {
769
+ if (shutdownAdmissionIsActive(admission)) {
770
770
  return admission;
771
771
  }
772
772
  rmSync(path, { force: true });
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-supervisor-ownership.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-supervisor-ownership.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { getProcessStartId } from \"../../core/session-lease.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport { normalizeSocketPath } from \"./daemon-socket.js\";\n\nconst DAEMON_SUPERVISOR_REGISTRY_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_REGISTRY_DIR\";\n\nconst OWNER_VERSION = 1;\nconst REGISTRY_LOCK_STALE_MS = 5000;\nconst REGISTRY_LOCK_UPDATE_MS = 1000;\nconst REGISTRY_LOCK_RETRIES = 500;\nconst REGISTRY_LOCK_RETRY_MS = 10;\nconst STARTUP_FENCE_POLL_MS = 250;\nconst SHUTDOWN_ADMISSION_FILE_NAME = \"shutdown-admission.json\";\nconst SHUTDOWN_ADMISSION_LEASE_MS = 5000;\nconst SHUTDOWN_ADMISSION_REFRESH_MS = 1000;\nconst SHUTDOWN_ADMISSION_WAIT_MS = 50;\n\ntype DaemonSupervisorOwnerPhase = \"starting\" | \"owner\" | \"stopping\";\n\ninterface ProcessIdentity {\n\tpid: number;\n\tprocessStartId?: string;\n}\n\ninterface DaemonSupervisorOwnerRecord extends ProcessIdentity {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tappVersion: string;\n\tphase: DaemonSupervisorOwnerPhase;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\ninterface DaemonShutdownAdmissionRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\texpiresAt: string;\n}\n\ninterface DaemonSupervisorOwnerScope {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir?: string;\n\tjournalPath?: string;\n}\n\ninterface DaemonStartupFenceRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\townerToken: string;\n\tsocketPath: string;\n\tsupervisorGeneration: string;\n\tcreatedAt: string;\n}\n\ninterface DaemonSupervisorHelloIdentity {\n\tsupervisorGeneration?: string;\n\tsupervisorOwnerToken?: string;\n\tsupervisorPid?: number;\n\tsupervisorProcessStartId?: string;\n\tsupervisorSocketPath?: string;\n}\n\ninterface AcquireDaemonSupervisorOwnershipOptions {\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tgeneration: string;\n\tappVersion: string;\n\tregistryDir?: string;\n}\n\nclass DaemonSupervisorAlreadyRunningError extends Error {\n\treadonly code = \"daemon_supervisor_already_running\" as const;\n\n\tconstructor(readonly owner: DaemonSupervisorOwnerRecord) {\n\t\tsuper(`Daemon supervisor ${owner.generation} already owns ${owner.socketPath}`);\n\t\tthis.name = \"DaemonSupervisorAlreadyRunningError\";\n\t}\n}\n\nclass DaemonSupervisorOwnershipLostError extends Error {\n\treadonly code = \"supervisor_generation_stale\" as const;\n\n\tconstructor(generation: string, details: { socketPath?: string; registryDir?: string } = {}) {\n\t\tconst context = [\n\t\t\tdetails.socketPath ? `socket: ${details.socketPath}` : undefined,\n\t\t\tdetails.registryDir ? `registry: ${details.registryDir}` : undefined,\n\t\t].filter((part) => part !== undefined);\n\t\tsuper(\n\t\t\t`Daemon supervisor generation ${generation} no longer owns its registry entry ` +\n\t\t\t\t`(record on disk is missing or was replaced)${context.length > 0 ? `; ${context.join(\"; \")}` : \"\"}; ` +\n\t\t\t\t\"restart the daemon to recover — sessions are preserved\",\n\t\t);\n\t\tthis.name = \"DaemonSupervisorOwnershipLostError\";\n\t}\n}\n\nclass DaemonShutdownAdmissionError extends Error {\n\treadonly code = \"daemon_shutdown_in_progress\" as const;\n\n\tconstructor(message = \"Daemon shutdown is in progress\") {\n\t\tsuper(message);\n\t\tthis.name = \"DaemonShutdownAdmissionError\";\n\t}\n}\n\n/**\n * Owns a lease-renew loop safely: the unref()'d interval, single-flight\n * refresh dedup shared by timer-fired and direct calls, and lost-state fencing.\n */\nclass RenewableRegistryRecord {\n\tprivate stopped = false;\n\tprivate lost = false;\n\tprivate refreshPromise?: Promise<void>;\n\tprivate readonly refreshTimer: ReturnType<typeof setInterval>;\n\n\tconstructor(\n\t\tprivate readonly registryDir: string,\n\t\trefreshMs: number,\n\t\tprivate readonly renewUnderGuard: () => void,\n\t\tprivate readonly createLostError: () => Error,\n\t) {\n\t\tthis.refreshTimer = setInterval(() => {\n\t\t\tvoid this.assertOrRenew().catch(() => undefined);\n\t\t}, refreshMs);\n\t\tthis.refreshTimer.unref();\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.stopped || this.lost) {\n\t\t\tthrow this.createLostError();\n\t\t}\n\t\tthis.refreshPromise ??= this.performRenew().finally(() => {\n\t\t\tthis.refreshPromise = undefined;\n\t\t});\n\t\tawait this.refreshPromise;\n\t}\n\n\tprivate async performRenew(): Promise<void> {\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\t// stop() may have completed while this call waited on the guard;\n\t\t\t\t// a stopped record must never be rewritten to disk.\n\t\t\t\tif (this.stopped || this.lost) {\n\t\t\t\t\tthrow this.createLostError();\n\t\t\t\t}\n\t\t\t\tthis.renewUnderGuard();\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis.lost = true;\n\t\t\tclearInterval(this.refreshTimer);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.stopped = true;\n\t\tclearInterval(this.refreshTimer);\n\t\tawait this.refreshPromise?.catch(() => undefined);\n\t}\n}\n\nclass DaemonSupervisorOwnership {\n\tprivate released = false;\n\n\tconstructor(\n\t\treadonly record: DaemonSupervisorOwnerRecord,\n\t\tprivate readonly registryDir: string,\n\t\tprivate readonly ownerDirectory: string,\n\t) {}\n\n\tasync assertCurrent(): Promise<void> {\n\t\tthis.assertCurrentSync();\n\t}\n\n\tassertJournalCurrent(journalPath: string): void {\n\t\tif (this.record.journalPath !== canonicalizeFilesystemPath(assertProductStatePath(journalPath))) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tthis.assertCurrentSync();\n\t}\n\n\tprivate assertCurrentSync(): void {\n\t\tif (this.released) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\tif (!current || !sameOwnerRecord(current, this.record)) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t}\n\n\tprivate ownershipLostError(): DaemonSupervisorOwnershipLostError {\n\t\treturn new DaemonSupervisorOwnershipLostError(this.record.generation, {\n\t\t\tsocketPath: this.record.socketPath,\n\t\t\tregistryDir: this.registryDir,\n\t\t});\n\t}\n\n\tasync updatePhase(phase: DaemonSupervisorOwnerPhase): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tconst updated = await mutateDaemonSupervisorOwner(\n\t\t\tthis.record.generation,\n\t\t\tthis.record.token,\n\t\t\t(owner) => {\n\t\t\t\towner.phase = phase;\n\t\t\t},\n\t\t\tthis.registryDir,\n\t\t);\n\t\tif (!updated) {\n\t\t\tthrow new Error(`Daemon supervisor ownership was lost for ${this.record.socketPath}`);\n\t\t}\n\t\tthis.record.phase = phase;\n\t\tthis.record.updatedAt = updated.updatedAt;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tlet releasedDirectory: string | undefined;\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\t\t\tif (!current || current.token !== this.record.token) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treleasedDirectory = `${this.ownerDirectory}.released-${randomUUID()}`;\n\t\t\t\trenameSync(this.ownerDirectory, releasedDirectory);\n\t\t\t});\n\t\t\tthis.released = true;\n\t\t} finally {\n\t\t\tif (releasedDirectory) {\n\t\t\t\trmSync(releasedDirectory, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass DaemonShutdownAdmission {\n\tprivate released = false;\n\tprivate readonly renewal: RenewableRegistryRecord;\n\n\tconstructor(\n\t\tprivate readonly record: DaemonShutdownAdmissionRecord,\n\t\tprivate readonly registryDir: string,\n\t) {\n\t\tthis.renewal = new RenewableRegistryRecord(\n\t\t\tregistryDir,\n\t\t\tSHUTDOWN_ADMISSION_REFRESH_MS,\n\t\t\t() => this.renewUnderGuard(),\n\t\t\t() => new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\"),\n\t\t);\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.released) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tawait this.renewal.assertOrRenew();\n\t}\n\n\tprivate renewUnderGuard(): void {\n\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\tconst current = readShutdownAdmission(path);\n\t\tif (\n\t\t\t!current ||\n\t\t\tcurrent.token !== this.record.token ||\n\t\t\tcurrent.pid !== this.record.pid ||\n\t\t\tcurrent.processStartId !== this.record.processStartId ||\n\t\t\tDate.parse(current.expiresAt) <= Date.now() ||\n\t\t\t!matchesExactProcessIdentity(this.record)\n\t\t) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tconst now = Date.now();\n\t\tthis.record.updatedAt = new Date(now).toISOString();\n\t\tthis.record.expiresAt = new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString();\n\t\twriteJsonAtomically(path, this.record);\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tthis.released = true;\n\t\tawait this.renewal.stop();\n\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\t\tconst current = readShutdownAdmission(path);\n\t\t\tif (current?.token === this.record.token) {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t}\n\t\t});\n\t}\n}\n\n/** Durable supervisor authority is scoped to one product home, never an upstream registry. */\nfunction defaultDaemonSupervisorRegistryDir(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst override = readAbsolutePathEnv(DAEMON_SUPERVISOR_REGISTRY_DIR_ENV, environment);\n\treturn assertProductStatePath(override ?? resolveRuntimePaths(environment).daemonRegistry);\n}\n\n/**\n * Non-mutating legacy scan: never reclaims abandoned directories (old-build\n * daemons own that location's lifecycle) and runs without the legacy guard —\n * best-effort is acceptable because records are written rename-atomically.\n */\nfunction readLegacyOwnersForSocket(\n\tlegacyRegistryDir: string,\n\tnormalizedSocketPath: string,\n): DaemonSupervisorOwnerRecord[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(legacyRegistryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn entries\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.flatMap((name) => {\n\t\t\tconst owner = readOwnerRecord(resolve(legacyRegistryDir, name));\n\t\t\treturn owner && owner.socketPath === normalizedSocketPath ? [owner] : [];\n\t\t});\n}\n\nasync function withDaemonSupervisorRegistryGuard<T>(registryDir: string, action: () => T | Promise<T>): Promise<T> {\n\tassertProductStatePath(registryDir);\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst guardPath = resolve(registryDir, \".guard\");\n\tlet compromisedError: Error | undefined;\n\tconst release = await lockfile.lock(registryDir, {\n\t\trealpath: false,\n\t\tlockfilePath: guardPath,\n\t\tstale: REGISTRY_LOCK_STALE_MS,\n\t\tupdate: REGISTRY_LOCK_UPDATE_MS,\n\t\tonCompromised: (error) => {\n\t\t\tcompromisedError ??= error;\n\t\t},\n\t\tretries: {\n\t\t\tretries: REGISTRY_LOCK_RETRIES,\n\t\t\tfactor: 1,\n\t\t\tminTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t\tmaxTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t},\n\t});\n\t// Compromise detection is timer-driven and cannot preempt a synchronous stall: a stalled action's\n\t// writes may already be on disk when a successor reclaims the stale guard. The guard directory's\n\t// inode is the ownership identity (a steal is rmdir+mkdir), checked synchronously where the timer\n\t// cannot run; when the inode is unobservable, only timer-driven detection applies.\n\tconst guardIno = (() => {\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t})();\n\tconst guardStolen = () => {\n\t\tif (guardIno === undefined) return false;\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino !== guardIno;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t};\n\tconst assertGuardHeld = () => {\n\t\tif (compromisedError)\n\t\t\tthrow new Error(`Daemon supervisor registry guard was compromised: ${compromisedError.message}`);\n\t\tif (guardStolen())\n\t\t\tthrow new Error(\"Daemon supervisor registry guard was compromised: the guard lock changed hands\");\n\t};\n\ttry {\n\t\tassertGuardHeld();\n\t\tconst result = await action();\n\t\tassertGuardHeld();\n\t\treturn result;\n\t} finally {\n\t\tif (compromisedError) {\n\t\t\tawait release().catch(() => undefined);\n\t\t} else if (!guardStolen()) {\n\t\t\tawait release();\n\t\t}\n\t\t// A stolen-but-undetected guard is never released: that would delete the successor's lock.\n\t\t// The abandoned updater notices the foreign mtime on its next tick and cleans itself up.\n\t}\n}\n\nasync function mutateDaemonSupervisorOwner(\n\tgeneration: string,\n\texpectedToken: string,\n\tmutation: (owner: DaemonSupervisorOwnerRecord) => void,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<DaemonSupervisorOwnerRecord | undefined> {\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst directory = ownerDirectoryPath(registryDir, generation);\n\t\tif (!existsSync(directory)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst current = requireOwnerRecord(directory);\n\t\tif (current.token !== expectedToken) {\n\t\t\treturn undefined;\n\t\t}\n\t\tmutation(current);\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tif (\n\t\t\t!isDaemonSupervisorOwnerRecord(current) ||\n\t\t\tcurrent.generation !== generation ||\n\t\t\tcurrent.token !== expectedToken\n\t\t) {\n\t\t\tthrow new Error(`Invalid mutation for daemon supervisor owner ${generation}`);\n\t\t}\n\t\twriteOwnerRecord(directory, current);\n\t\treturn current;\n\t});\n}\n\nexport async function acquireDaemonSupervisorOwnership(\n\toptions: AcquireDaemonSupervisorOwnershipOptions,\n): Promise<DaemonSupervisorOwnership> {\n\tconst registryDir = options.registryDir ?? defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst token = randomUUID();\n\tconst processStartId = getProcessStartId(process.pid);\n\tconst now = new Date().toISOString();\n\tconst record: DaemonSupervisorOwnerRecord = {\n\t\tversion: OWNER_VERSION,\n\t\trole: \"supervisor\",\n\t\ttoken,\n\t\tgeneration: options.generation,\n\t\tpid: process.pid,\n\t\t...(processStartId ? { processStartId } : {}),\n\t\tsocketPath: normalizeSocketPath(options.socketPath),\n\t\tdescriptorDir: canonicalizeFilesystemPath(options.descriptorDir),\n\t\tagentDir: canonicalizeFilesystemPath(options.agentDir),\n\t\t...(options.journalPath\n\t\t\t? { journalPath: canonicalizeFilesystemPath(assertProductStatePath(options.journalPath)) }\n\t\t\t: {}),\n\t\tappVersion: options.appVersion,\n\t\tphase: \"starting\",\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t};\n\tconst candidateDirectory = resolve(registryDir, `.candidate-${process.pid}-${token}`);\n\tconst ownerDirectory = ownerDirectoryPath(registryDir, options.generation);\n\tmkdirSync(candidateDirectory, { mode: 0o700 });\n\tconst staleDirectories: string[] = [];\n\ttry {\n\t\twriteOwnerScope(candidateDirectory, record);\n\t\twriteOwnerRecord(candidateDirectory, record);\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\tthrow new DaemonShutdownAdmissionError();\n\t\t\t}\n\t\t\tfor (const directory of listOwnerDirectories(registryDir)) {\n\t\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => ownerConflicts(scope, record));\n\t\t\t\tif (!owner) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!ownerConflicts(owner, record)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (isProcessIdentityAlive(owner)) {\n\t\t\t\t\tthrow new DaemonSupervisorAlreadyRunningError(owner);\n\t\t\t\t}\n\t\t\t\tconst staleDirectory = `${directory}.stale-${randomUUID()}`;\n\t\t\t\trenameSync(directory, staleDirectory);\n\t\t\t\tstaleDirectories.push(staleDirectory);\n\t\t\t}\n\t\t\trenameSync(candidateDirectory, ownerDirectory);\n\t\t});\n\t} catch (error) {\n\t\trmSync(candidateDirectory, { recursive: true, force: true });\n\t\tthrow error;\n\t} finally {\n\t\tfor (const directory of staleDirectories) {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t}\n\t}\n\treturn new DaemonSupervisorOwnership(record, registryDir, ownerDirectory);\n}\n\n/** Read only: discovery must not acquire ownership or reclaim registry directories. */\nexport function listDaemonSupervisorSocketPathsForAgentDir(\n\tagentDir: string,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): string[] {\n\tlet canonicalAgentDir: string;\n\tlet directories: string[];\n\ttry {\n\t\tcanonicalAgentDir = canonicalizeFilesystemPath(agentDir);\n\t\tdirectories = listOwnerDirectories(registryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst socketPaths: string[] = [];\n\tfor (const directory of directories) {\n\t\tconst owner = readOwnerRecord(directory);\n\t\tif (!owner) continue;\n\t\ttry {\n\t\t\tif (canonicalizeFilesystemPath(owner.agentDir) === canonicalAgentDir) {\n\t\t\t\tsocketPaths.push(normalizeSocketPath(owner.socketPath));\n\t\t\t}\n\t\t} catch {\n\t\t\t// A stale or inaccessible record must not hide the other supervisors.\n\t\t}\n\t}\n\treturn socketPaths;\n}\n\nexport async function assertDaemonSupervisorOwnerCurrent(\n\towner: {\n\t\tgeneration: string;\n\t\tpid: number;\n\t\tprocessStartId?: string;\n\t\tsocketPath: string;\n\t},\n\tvalidatedFingerprint?: string,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<string> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tconst current =\n\t\treadOwnerRecord(ownerDirectoryPath(registryDir, owner.generation)) ??\n\t\t(legacyRegistryDir ? readOwnerRecord(ownerDirectoryPath(legacyRegistryDir, owner.generation)) : undefined);\n\tif (\n\t\t!current ||\n\t\tcurrent.pid !== owner.pid ||\n\t\tcurrent.processStartId !== owner.processStartId ||\n\t\tcurrent.socketPath !== normalizeSocketPath(owner.socketPath) ||\n\t\t!isProcessAlive(current.pid)\n\t) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\tconst fingerprint = ownerRecordFingerprint(current);\n\tif (fingerprint !== validatedFingerprint && !isProcessIdentityAlive(current)) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\treturn fingerprint;\n}\n\nexport async function acquireDaemonShutdownAdmission(): Promise<DaemonShutdownAdmission> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\tconst processStartId = getProcessStartId(process.pid);\n\twhile (true) {\n\t\tlet acquired: DaemonShutdownAdmissionRecord | undefined;\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst now = Date.now();\n\t\t\tacquired = {\n\t\t\t\tversion: OWNER_VERSION,\n\t\t\t\ttoken: randomUUID(),\n\t\t\t\tpid: process.pid,\n\t\t\t\t...(processStartId ? { processStartId } : {}),\n\t\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t\t\tupdatedAt: new Date(now).toISOString(),\n\t\t\t\texpiresAt: new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString(),\n\t\t\t};\n\t\t\twriteJsonAtomically(shutdownAdmissionPath(registryDir), acquired);\n\t\t});\n\t\tif (acquired) {\n\t\t\treturn new DaemonShutdownAdmission(acquired, registryDir);\n\t\t}\n\t\tawait delay(SHUTDOWN_ADMISSION_WAIT_MS);\n\t}\n}\n\nexport async function isDaemonShutdownAdmissionActive(): Promise<boolean> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => readActiveShutdownAdmission(registryDir) !== undefined);\n}\n\nexport async function persistDaemonStartupFenceFromOwner(\n\tsocketPath: string,\n\thello: DaemonSupervisorHelloIdentity,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<void> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst fenceDirectory = resolve(registryDir, \"startup-fences\");\n\tmkdirSync(fenceDirectory, { recursive: true, mode: 0o700 });\n\tconst path = startupFencePath(fenceDirectory, socketPath);\n\tconst normalizedSocketPath = normalizeSocketPath(socketPath);\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst owners = listOwnerDirectories(registryDir).flatMap((directory) => {\n\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => scope.socketPath === normalizedSocketPath);\n\t\t\treturn owner ? [owner] : [];\n\t\t});\n\t\tlet matchingOwners = owners.filter((owner) => owner.socketPath === normalizedSocketPath);\n\t\tif (matchingOwners.length === 0 && legacyRegistryDir) {\n\t\t\t// Stale legacy leftovers are expected; keep only records matching the\n\t\t\t// identity the caller already holds.\n\t\t\tmatchingOwners = readLegacyOwnersForSocket(legacyRegistryDir, normalizedSocketPath).filter(\n\t\t\t\t(owner) => owner.token === hello.supervisorOwnerToken && owner.pid === hello.supervisorPid,\n\t\t\t);\n\t\t}\n\t\tif (matchingOwners.length === 0) {\n\t\t\tthrow new Error(`Daemon supervisor owner does not match ${socketPath}`);\n\t\t}\n\t\tif (matchingOwners.length > 1) {\n\t\t\tthrow new Error(`Multiple daemon supervisor owners match ${socketPath}`);\n\t\t}\n\t\tconst owner = matchingOwners[0];\n\t\tif (!owner) {\n\t\t\tthrow new Error(`Daemon supervisor owner disappeared for ${socketPath}`);\n\t\t}\n\t\tconst helloSocketPath = hello.supervisorSocketPath;\n\t\tif (\n\t\t\t!Number.isInteger(hello.supervisorPid) ||\n\t\t\thello.supervisorPid !== owner.pid ||\n\t\t\thello.supervisorGeneration !== owner.generation ||\n\t\t\thello.supervisorOwnerToken !== owner.token ||\n\t\t\ttypeof helloSocketPath !== \"string\" ||\n\t\t\tnormalizeSocketPath(helloSocketPath) !== owner.socketPath ||\n\t\t\ttypeof owner.processStartId !== \"string\" ||\n\t\t\thello.supervisorProcessStartId !== owner.processStartId\n\t\t) {\n\t\t\tthrow new Error(`Daemon supervisor hello does not match its durable owner for ${socketPath}`);\n\t\t}\n\t\tconst observedProcessStartId = getProcessStartId(owner.pid);\n\t\tif (observedProcessStartId !== owner.processStartId) {\n\t\t\tthrow new Error(`Daemon supervisor process identity changed for ${socketPath}`);\n\t\t}\n\t\tconst record: DaemonStartupFenceRecord = {\n\t\t\tversion: OWNER_VERSION,\n\t\t\ttoken: randomUUID(),\n\t\t\townerToken: owner.token,\n\t\t\tpid: owner.pid,\n\t\t\tprocessStartId: owner.processStartId,\n\t\t\tsocketPath: owner.socketPath,\n\t\t\tsupervisorGeneration: owner.generation,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\t\twriteJsonAtomically(path, record);\n\t});\n}\n\nexport async function waitForDaemonStartupFence(\n\tsocketPath: string,\n\ttimeoutMs = 10_000,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<void> {\n\tconst path = startupFencePath(resolve(registryDir, \"startup-fences\"), socketPath);\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (true) {\n\t\tconst fence = readStartupFence(path);\n\t\tif (!fence) {\n\t\t\treturn;\n\t\t}\n\t\tif (fence.socketPath !== normalizeSocketPath(socketPath)) {\n\t\t\tthrow new Error(`Daemon startup fence does not match ${socketPath}`);\n\t\t}\n\t\tif (!isProcessIdentityAlive(fence)) {\n\t\t\tconst cleared = await withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\t\tconst current = readStartupFence(path);\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (current?.token === fence.token) {\n\t\t\t\t\trmSync(path, { force: true });\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (cleared) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (Date.now() >= deadline) {\n\t\t\tthrow new Error(`Timed out waiting for predecessor daemon process ${fence.pid} to exit`);\n\t\t}\n\t\tawait delay(STARTUP_FENCE_POLL_MS);\n\t}\n}\n\nfunction isProcessIdentityAlive(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\tif (!identity.processStartId) {\n\t\treturn true;\n\t}\n\tconst observed = getProcessStartId(identity.pid);\n\treturn observed === undefined || observed === identity.processStartId;\n}\n\nfunction matchesExactProcessIdentity(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\treturn identity.processStartId === undefined || getProcessStartId(identity.pid) === identity.processStartId;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t} catch (error) {\n\t\treturn (error as NodeJS.ErrnoException).code !== \"ESRCH\";\n\t}\n\treturn true;\n}\n\nfunction canonicalizeFilesystemPath(path: string): string {\n\tlet existingAncestor = resolve(path);\n\tconst missingSuffix: string[] = [];\n\twhile (true) {\n\t\ttry {\n\t\t\tconst physicalAncestor = realpathSync.native(existingAncestor);\n\t\t\tconst canonical = join(physicalAncestor, ...missingSuffix);\n\t\t\treturn process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst parent = dirname(existingAncestor);\n\t\t\tif (parent === existingAncestor) {\n\t\t\t\tconst unresolved = resolve(path);\n\t\t\t\treturn process.platform === \"win32\" ? unresolved.toLowerCase() : unresolved;\n\t\t\t}\n\t\t\tmissingSuffix.unshift(basename(existingAncestor));\n\t\t\texistingAncestor = parent;\n\t\t}\n\t}\n}\n\nfunction ownerConflicts(left: DaemonSupervisorOwnerScope, right: DaemonSupervisorOwnerScope): boolean {\n\tif (left.socketPath === right.socketPath || left.descriptorDir === right.descriptorDir) return true;\n\tif (left.journalPath && right.journalPath) return left.journalPath === right.journalPath;\n\t// Older records do not identify their family journal. An unknown footprint cannot grant a writer.\n\treturn Boolean(\n\t\t(left.journalPath || right.journalPath) &&\n\t\t\t(!left.agentDir || !right.agentDir || left.agentDir === right.agentDir),\n\t);\n}\n\nfunction sameOwnerRecord(left: DaemonSupervisorOwnerRecord, right: DaemonSupervisorOwnerRecord): boolean {\n\treturn (\n\t\tleft.token === right.token &&\n\t\tleft.generation === right.generation &&\n\t\tleft.pid === right.pid &&\n\t\tleft.processStartId === right.processStartId &&\n\t\tleft.socketPath === right.socketPath &&\n\t\tleft.descriptorDir === right.descriptorDir &&\n\t\tleft.agentDir === right.agentDir &&\n\t\tleft.journalPath === right.journalPath\n\t);\n}\n\nfunction ownerRecordFingerprint(record: DaemonSupervisorOwnerRecord): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(record)).digest(\"hex\");\n}\n\nfunction listOwnerDirectories(registryDir: string): string[] {\n\treturn readdirSync(registryDir)\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.map((name) => resolve(registryDir, name));\n}\n\nfunction ownerDirectoryPath(registryDir: string, generation: string): string {\n\tif (!/^[A-Za-z0-9._-]+$/.test(generation)) {\n\t\tthrow new Error(`Invalid daemon supervisor generation: ${generation}`);\n\t}\n\treturn resolve(registryDir, `${generation}.owner`);\n}\n\nfunction requireOwnerRecord(directory: string): DaemonSupervisorOwnerRecord {\n\tconst owner = readOwnerRecord(directory);\n\tif (!owner) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn owner;\n}\n\nfunction readOwnerRecordForScope(\n\tdirectory: string,\n\tisRelevant: (scope: DaemonSupervisorOwnerScope) => boolean,\n): DaemonSupervisorOwnerRecord | undefined {\n\tconst owner = readOwnerRecord(directory);\n\tif (owner) {\n\t\treturn owner;\n\t}\n\tconst scope = readOwnerScope(directory);\n\tconst entries = !scope ? readdirSync(directory) : [];\n\tif (!scope && !entries.includes(\"owner.json\") && !entries.includes(\"scope.json\")) {\n\t\tconst abandonedDirectory = `${directory}.abandoned-${randomUUID()}`;\n\t\trenameSync(directory, abandonedDirectory);\n\t\trmSync(abandonedDirectory, { recursive: true, force: true });\n\t\treturn undefined;\n\t}\n\tif (!scope || isRelevant(scope)) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn undefined;\n}\n\nfunction readOwnerRecord(directory: string): DaemonSupervisorOwnerRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"owner.json\"), \"utf8\")) as unknown;\n\t\treturn isDaemonSupervisorOwnerRecord(value) ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerRecord(value: unknown): value is DaemonSupervisorOwnerRecord {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst record = value as Partial<DaemonSupervisorOwnerRecord>;\n\treturn (\n\t\trecord.version === OWNER_VERSION &&\n\t\trecord.role === \"supervisor\" &&\n\t\ttypeof record.token === \"string\" &&\n\t\ttypeof record.generation === \"string\" &&\n\t\tNumber.isInteger(record.pid) &&\n\t\t(record.pid ?? 0) > 0 &&\n\t\t(record.processStartId === undefined || typeof record.processStartId === \"string\") &&\n\t\ttypeof record.socketPath === \"string\" &&\n\t\ttypeof record.descriptorDir === \"string\" &&\n\t\ttypeof record.agentDir === \"string\" &&\n\t\t(record.journalPath === undefined || typeof record.journalPath === \"string\") &&\n\t\ttypeof record.appVersion === \"string\" &&\n\t\t(record.phase === \"starting\" || record.phase === \"owner\" || record.phase === \"stopping\") &&\n\t\ttypeof record.createdAt === \"string\" &&\n\t\ttypeof record.updatedAt === \"string\"\n\t);\n}\n\nfunction readOwnerScope(directory: string): DaemonSupervisorOwnerScope | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"scope.json\"), \"utf8\")) as unknown;\n\t\tif (!isDaemonSupervisorOwnerScope(value)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn ownerDirectoryPath(dirname(directory), value.generation) === directory ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerScope(value: unknown): value is DaemonSupervisorOwnerScope {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst scope = value as Partial<DaemonSupervisorOwnerScope>;\n\treturn (\n\t\tscope.version === OWNER_VERSION &&\n\t\tscope.role === \"supervisor\" &&\n\t\ttypeof scope.token === \"string\" &&\n\t\ttypeof scope.generation === \"string\" &&\n\t\ttypeof scope.socketPath === \"string\" &&\n\t\ttypeof scope.descriptorDir === \"string\" &&\n\t\t(scope.agentDir === undefined || typeof scope.agentDir === \"string\") &&\n\t\t(scope.journalPath === undefined || typeof scope.journalPath === \"string\")\n\t);\n}\n\nfunction writeOwnerScope(directory: string, owner: DaemonSupervisorOwnerRecord): void {\n\tconst scope: DaemonSupervisorOwnerScope = {\n\t\tversion: owner.version,\n\t\trole: owner.role,\n\t\ttoken: owner.token,\n\t\tgeneration: owner.generation,\n\t\tsocketPath: owner.socketPath,\n\t\tdescriptorDir: owner.descriptorDir,\n\t\tagentDir: owner.agentDir,\n\t\t...(owner.journalPath ? { journalPath: owner.journalPath } : {}),\n\t};\n\twriteJsonAtomically(resolve(directory, \"scope.json\"), scope);\n}\n\nfunction writeOwnerRecord(directory: string, record: DaemonSupervisorOwnerRecord): void {\n\twriteJsonAtomically(resolve(directory, \"owner.json\"), record);\n}\n\nfunction readStartupFence(path: string): DaemonStartupFenceRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\tconst fence = value as Partial<DaemonStartupFenceRecord>;\n\t\tif (\n\t\t\tfence.version !== OWNER_VERSION ||\n\t\t\ttypeof fence.token !== \"string\" ||\n\t\t\ttypeof fence.ownerToken !== \"string\" ||\n\t\t\t!Number.isInteger(fence.pid) ||\n\t\t\t(fence.pid ?? 0) <= 0 ||\n\t\t\ttypeof fence.processStartId !== \"string\" ||\n\t\t\ttypeof fence.socketPath !== \"string\" ||\n\t\t\ttypeof fence.supervisorGeneration !== \"string\" ||\n\t\t\ttypeof fence.createdAt !== \"string\"\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\treturn fence as DaemonStartupFenceRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction readActiveShutdownAdmission(registryDir: string): DaemonShutdownAdmissionRecord | undefined {\n\tconst path = shutdownAdmissionPath(registryDir);\n\tconst admission = readShutdownAdmission(path);\n\tif (!admission) {\n\t\treturn undefined;\n\t}\n\tif (Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission)) {\n\t\treturn admission;\n\t}\n\trmSync(path, { force: true });\n\treturn undefined;\n}\n\nfunction readShutdownAdmission(path: string): DaemonShutdownAdmissionRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\tconst admission = value as Partial<DaemonShutdownAdmissionRecord>;\n\t\tif (\n\t\t\tadmission.version !== OWNER_VERSION ||\n\t\t\ttypeof admission.token !== \"string\" ||\n\t\t\t!Number.isInteger(admission.pid) ||\n\t\t\t(admission.pid ?? 0) <= 0 ||\n\t\t\t(admission.processStartId !== undefined && typeof admission.processStartId !== \"string\") ||\n\t\t\ttypeof admission.createdAt !== \"string\" ||\n\t\t\ttypeof admission.updatedAt !== \"string\" ||\n\t\t\ttypeof admission.expiresAt !== \"string\" ||\n\t\t\t!Number.isFinite(Date.parse(admission.expiresAt))\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\treturn admission as DaemonShutdownAdmissionRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction writeJsonAtomically(path: string, value: unknown): void {\n\tconst tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\twriteFileSync(tempPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction startupFencePath(directory: string, socketPath: string): string {\n\tconst key = createHash(\"sha256\").update(normalizeSocketPath(socketPath)).digest(\"hex\");\n\treturn resolve(directory, `${key}.json`);\n}\n\nfunction shutdownAdmissionPath(registryDir: string): string {\n\treturn resolve(registryDir, SHUTDOWN_ADMISSION_FILE_NAME);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n"]}
1
+ {"version":3,"file":"daemon-supervisor-ownership.js","sourceRoot":"","sources":["../../../src/modes/daemon/daemon-supervisor-ownership.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport {\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trealpathSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { getProcessStartId } from \"../../core/session-lease.js\";\nimport { assertProductStatePath, readAbsolutePathEnv, resolveRuntimePaths } from \"../../runtime-paths.js\";\nimport { normalizeSocketPath } from \"./daemon-socket.js\";\n\nconst DAEMON_SUPERVISOR_REGISTRY_DIR_ENV = \"BASE_CONTEXT_INTERNAL_DAEMON_SUPERVISOR_REGISTRY_DIR\";\n\nconst OWNER_VERSION = 1;\nconst REGISTRY_LOCK_STALE_MS = 5000;\nconst REGISTRY_LOCK_UPDATE_MS = 1000;\nconst REGISTRY_LOCK_RETRIES = 500;\nconst REGISTRY_LOCK_RETRY_MS = 10;\nconst STARTUP_FENCE_POLL_MS = 250;\nconst SHUTDOWN_ADMISSION_FILE_NAME = \"shutdown-admission.json\";\nconst SHUTDOWN_ADMISSION_LEASE_MS = 5000;\nconst SHUTDOWN_ADMISSION_REFRESH_MS = 1000;\nconst SHUTDOWN_ADMISSION_WAIT_MS = 50;\n\ntype DaemonSupervisorOwnerPhase = \"starting\" | \"owner\" | \"stopping\";\n\ninterface ProcessIdentity {\n\tpid: number;\n\tprocessStartId?: string;\n}\n\ninterface DaemonSupervisorOwnerRecord extends ProcessIdentity {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tappVersion: string;\n\tphase: DaemonSupervisorOwnerPhase;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\ninterface DaemonShutdownAdmissionRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\texpiresAt: string;\n}\n\ninterface DaemonSupervisorOwnerScope {\n\tversion: 1;\n\trole: \"supervisor\";\n\ttoken: string;\n\tgeneration: string;\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir?: string;\n\tjournalPath?: string;\n}\n\ninterface DaemonStartupFenceRecord extends ProcessIdentity {\n\tversion: 1;\n\ttoken: string;\n\townerToken: string;\n\tsocketPath: string;\n\tsupervisorGeneration: string;\n\tcreatedAt: string;\n}\n\ninterface DaemonSupervisorHelloIdentity {\n\tsupervisorGeneration?: string;\n\tsupervisorOwnerToken?: string;\n\tsupervisorPid?: number;\n\tsupervisorProcessStartId?: string;\n\tsupervisorSocketPath?: string;\n}\n\ninterface AcquireDaemonSupervisorOwnershipOptions {\n\tsocketPath: string;\n\tdescriptorDir: string;\n\tagentDir: string;\n\tjournalPath?: string;\n\tgeneration: string;\n\tappVersion: string;\n\tregistryDir?: string;\n}\n\nclass DaemonSupervisorAlreadyRunningError extends Error {\n\treadonly code = \"daemon_supervisor_already_running\" as const;\n\n\tconstructor(readonly owner: DaemonSupervisorOwnerRecord) {\n\t\tsuper(`Daemon supervisor ${owner.generation} already owns ${owner.socketPath}`);\n\t\tthis.name = \"DaemonSupervisorAlreadyRunningError\";\n\t}\n}\n\nclass DaemonSupervisorOwnershipLostError extends Error {\n\treadonly code = \"supervisor_generation_stale\" as const;\n\n\tconstructor(generation: string, details: { socketPath?: string; registryDir?: string } = {}) {\n\t\tconst context = [\n\t\t\tdetails.socketPath ? `socket: ${details.socketPath}` : undefined,\n\t\t\tdetails.registryDir ? `registry: ${details.registryDir}` : undefined,\n\t\t].filter((part) => part !== undefined);\n\t\tsuper(\n\t\t\t`Daemon supervisor generation ${generation} no longer owns its registry entry ` +\n\t\t\t\t`(record on disk is missing or was replaced)${context.length > 0 ? `; ${context.join(\"; \")}` : \"\"}; ` +\n\t\t\t\t\"restart the daemon to recover — sessions are preserved\",\n\t\t);\n\t\tthis.name = \"DaemonSupervisorOwnershipLostError\";\n\t}\n}\n\nclass DaemonShutdownAdmissionError extends Error {\n\treadonly code = \"daemon_shutdown_in_progress\" as const;\n\n\tconstructor(message = \"Daemon shutdown is in progress\") {\n\t\tsuper(message);\n\t\tthis.name = \"DaemonShutdownAdmissionError\";\n\t}\n}\n\n/**\n * Owns a lease-renew loop safely: the unref()'d interval, single-flight\n * refresh dedup shared by timer-fired and direct calls, and lost-state fencing.\n */\nclass RenewableRegistryRecord {\n\tprivate stopped = false;\n\tprivate lost = false;\n\tprivate refreshPromise?: Promise<void>;\n\tprivate readonly refreshTimer: ReturnType<typeof setInterval>;\n\n\tconstructor(\n\t\tprivate readonly registryDir: string,\n\t\trefreshMs: number,\n\t\tprivate readonly renewUnderGuard: () => boolean,\n\t\tprivate readonly createLostError: () => Error,\n\t) {\n\t\tthis.refreshTimer = setInterval(() => {\n\t\t\tvoid this.assertOrRenew().catch(() => undefined);\n\t\t}, refreshMs);\n\t\tthis.refreshTimer.unref();\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.stopped || this.lost) {\n\t\t\tthrow this.createLostError();\n\t\t}\n\t\tthis.refreshPromise ??= this.performRenew().finally(() => {\n\t\t\tthis.refreshPromise = undefined;\n\t\t});\n\t\tawait this.refreshPromise;\n\t}\n\n\tprivate async performRenew(): Promise<void> {\n\t\tconst held = await withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t// stop() may have completed while this call waited on the guard;\n\t\t\t// a stopped record must never be rewritten to disk.\n\t\t\tif (this.stopped || this.lost) return false;\n\t\t\treturn this.renewUnderGuard();\n\t\t});\n\t\tif (!held) {\n\t\t\tthis.lost = true;\n\t\t\tclearInterval(this.refreshTimer);\n\t\t\tthrow this.createLostError();\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tthis.stopped = true;\n\t\tclearInterval(this.refreshTimer);\n\t\tawait this.refreshPromise?.catch(() => undefined);\n\t}\n}\n\nclass DaemonSupervisorOwnership {\n\tprivate released = false;\n\n\tconstructor(\n\t\treadonly record: DaemonSupervisorOwnerRecord,\n\t\tprivate readonly registryDir: string,\n\t\tprivate readonly ownerDirectory: string,\n\t) {}\n\n\tasync assertCurrent(): Promise<void> {\n\t\tthis.assertCurrentSync();\n\t}\n\n\tassertJournalCurrent(journalPath: string): void {\n\t\tif (this.record.journalPath !== canonicalizeFilesystemPath(assertProductStatePath(journalPath))) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tthis.assertCurrentSync();\n\t}\n\n\tprivate assertCurrentSync(): void {\n\t\tif (this.released) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\tif (!current || !sameOwnerRecord(current, this.record)) {\n\t\t\tthrow this.ownershipLostError();\n\t\t}\n\t}\n\n\tprivate ownershipLostError(): DaemonSupervisorOwnershipLostError {\n\t\treturn new DaemonSupervisorOwnershipLostError(this.record.generation, {\n\t\t\tsocketPath: this.record.socketPath,\n\t\t\tregistryDir: this.registryDir,\n\t\t});\n\t}\n\n\tasync updatePhase(phase: DaemonSupervisorOwnerPhase): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tconst updated = await mutateDaemonSupervisorOwner(\n\t\t\tthis.record.generation,\n\t\t\tthis.record.token,\n\t\t\t(owner) => {\n\t\t\t\towner.phase = phase;\n\t\t\t},\n\t\t\tthis.registryDir,\n\t\t);\n\t\tif (!updated) {\n\t\t\tthrow new Error(`Daemon supervisor ownership was lost for ${this.record.socketPath}`);\n\t\t}\n\t\tthis.record.phase = phase;\n\t\tthis.record.updatedAt = updated.updatedAt;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tlet releasedDirectory: string | undefined;\n\t\ttry {\n\t\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\t\tconst current = readOwnerRecord(this.ownerDirectory);\n\t\t\t\tif (!current || current.token !== this.record.token) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treleasedDirectory = `${this.ownerDirectory}.released-${randomUUID()}`;\n\t\t\t\trenameSync(this.ownerDirectory, releasedDirectory);\n\t\t\t});\n\t\t\tthis.released = true;\n\t\t} finally {\n\t\t\tif (releasedDirectory) {\n\t\t\t\trmSync(releasedDirectory, { recursive: true, force: true });\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass DaemonShutdownAdmission {\n\tprivate released = false;\n\tprivate readonly renewal: RenewableRegistryRecord;\n\n\tconstructor(\n\t\tprivate readonly record: DaemonShutdownAdmissionRecord,\n\t\tprivate readonly registryDir: string,\n\t) {\n\t\tthis.renewal = new RenewableRegistryRecord(\n\t\t\tregistryDir,\n\t\t\tSHUTDOWN_ADMISSION_REFRESH_MS,\n\t\t\t() => this.renewUnderGuard(),\n\t\t\t() => new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\"),\n\t\t);\n\t}\n\n\tasync assertOrRenew(): Promise<void> {\n\t\tif (this.released) {\n\t\t\tthrow new DaemonShutdownAdmissionError(\"Daemon shutdown admission was lost\");\n\t\t}\n\t\tawait this.renewal.assertOrRenew();\n\t}\n\n\tprivate renewUnderGuard(): boolean {\n\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\tconst current = readShutdownAdmission(path);\n\t\tif (\n\t\t\t!current ||\n\t\t\tcurrent.token !== this.record.token ||\n\t\t\tcurrent.pid !== this.record.pid ||\n\t\t\tcurrent.processStartId !== this.record.processStartId ||\n\t\t\t!matchesExactProcessIdentity(this.record)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tconst now = Date.now();\n\t\tthis.record.updatedAt = new Date(now).toISOString();\n\t\tthis.record.expiresAt = new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString();\n\t\twriteJsonAtomically(path, this.record);\n\t\treturn true;\n\t}\n\n\tasync release(): Promise<void> {\n\t\tif (this.released) {\n\t\t\treturn;\n\t\t}\n\t\tthis.released = true;\n\t\tawait this.renewal.stop();\n\t\tawait withDaemonSupervisorRegistryGuard(this.registryDir, () => {\n\t\t\tconst path = shutdownAdmissionPath(this.registryDir);\n\t\t\tconst current = readShutdownAdmission(path);\n\t\t\tif (current?.token === this.record.token) {\n\t\t\t\trmSync(path, { force: true });\n\t\t\t}\n\t\t});\n\t}\n}\n\n/** Durable supervisor authority is scoped to one product home, never an upstream registry. */\nfunction defaultDaemonSupervisorRegistryDir(environment: NodeJS.ProcessEnv = process.env): string {\n\tconst override = readAbsolutePathEnv(DAEMON_SUPERVISOR_REGISTRY_DIR_ENV, environment);\n\treturn assertProductStatePath(override ?? resolveRuntimePaths(environment).daemonRegistry);\n}\n\n/**\n * Non-mutating legacy scan: never reclaims abandoned directories (old-build\n * daemons own that location's lifecycle) and runs without the legacy guard —\n * best-effort is acceptable because records are written rename-atomically.\n */\nfunction readLegacyOwnersForSocket(\n\tlegacyRegistryDir: string,\n\tnormalizedSocketPath: string,\n): DaemonSupervisorOwnerRecord[] {\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(legacyRegistryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn entries\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.flatMap((name) => {\n\t\t\tconst owner = readOwnerRecord(resolve(legacyRegistryDir, name));\n\t\t\treturn owner && owner.socketPath === normalizedSocketPath ? [owner] : [];\n\t\t});\n}\n\nasync function withDaemonSupervisorRegistryGuard<T>(registryDir: string, action: () => T | Promise<T>): Promise<T> {\n\tassertProductStatePath(registryDir);\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst guardPath = resolve(registryDir, \".guard\");\n\tlet compromisedError: Error | undefined;\n\tconst release = await lockfile.lock(registryDir, {\n\t\trealpath: false,\n\t\tlockfilePath: guardPath,\n\t\tstale: REGISTRY_LOCK_STALE_MS,\n\t\tupdate: REGISTRY_LOCK_UPDATE_MS,\n\t\tonCompromised: (error) => {\n\t\t\tcompromisedError ??= error;\n\t\t},\n\t\tretries: {\n\t\t\tretries: REGISTRY_LOCK_RETRIES,\n\t\t\tfactor: 1,\n\t\t\tminTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t\tmaxTimeout: REGISTRY_LOCK_RETRY_MS,\n\t\t},\n\t});\n\t// Compromise detection is timer-driven and cannot preempt a synchronous stall: a stalled action's\n\t// writes may already be on disk when a successor reclaims the stale guard. The guard directory's\n\t// inode is the ownership identity (a steal is rmdir+mkdir), checked synchronously where the timer\n\t// cannot run; when the inode is unobservable, only timer-driven detection applies.\n\tconst guardIno = (() => {\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t})();\n\tconst guardStolen = () => {\n\t\tif (guardIno === undefined) return false;\n\t\ttry {\n\t\t\treturn statSync(guardPath, { bigint: true }).ino !== guardIno;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t};\n\tconst assertGuardHeld = () => {\n\t\tif (compromisedError)\n\t\t\tthrow new Error(`Daemon supervisor registry guard was compromised: ${compromisedError.message}`);\n\t\tif (guardStolen())\n\t\t\tthrow new Error(\"Daemon supervisor registry guard was compromised: the guard lock changed hands\");\n\t};\n\ttry {\n\t\tassertGuardHeld();\n\t\tconst result = await action();\n\t\tassertGuardHeld();\n\t\treturn result;\n\t} finally {\n\t\tif (compromisedError) {\n\t\t\tawait release().catch(() => undefined);\n\t\t} else if (!guardStolen()) {\n\t\t\tawait release();\n\t\t}\n\t\t// A stolen-but-undetected guard is never released: that would delete the successor's lock.\n\t\t// The abandoned updater notices the foreign mtime on its next tick and cleans itself up.\n\t}\n}\n\nasync function mutateDaemonSupervisorOwner(\n\tgeneration: string,\n\texpectedToken: string,\n\tmutation: (owner: DaemonSupervisorOwnerRecord) => void,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<DaemonSupervisorOwnerRecord | undefined> {\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst directory = ownerDirectoryPath(registryDir, generation);\n\t\tif (!existsSync(directory)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst current = requireOwnerRecord(directory);\n\t\tif (current.token !== expectedToken) {\n\t\t\treturn undefined;\n\t\t}\n\t\tmutation(current);\n\t\tcurrent.updatedAt = new Date().toISOString();\n\t\tif (\n\t\t\t!isDaemonSupervisorOwnerRecord(current) ||\n\t\t\tcurrent.generation !== generation ||\n\t\t\tcurrent.token !== expectedToken\n\t\t) {\n\t\t\tthrow new Error(`Invalid mutation for daemon supervisor owner ${generation}`);\n\t\t}\n\t\twriteOwnerRecord(directory, current);\n\t\treturn current;\n\t});\n}\n\nexport async function acquireDaemonSupervisorOwnership(\n\toptions: AcquireDaemonSupervisorOwnershipOptions,\n): Promise<DaemonSupervisorOwnership> {\n\tconst registryDir = options.registryDir ?? defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst token = randomUUID();\n\tconst processStartId = getProcessStartId(process.pid);\n\tconst now = new Date().toISOString();\n\tconst record: DaemonSupervisorOwnerRecord = {\n\t\tversion: OWNER_VERSION,\n\t\trole: \"supervisor\",\n\t\ttoken,\n\t\tgeneration: options.generation,\n\t\tpid: process.pid,\n\t\t...(processStartId ? { processStartId } : {}),\n\t\tsocketPath: normalizeSocketPath(options.socketPath),\n\t\tdescriptorDir: canonicalizeFilesystemPath(options.descriptorDir),\n\t\tagentDir: canonicalizeFilesystemPath(options.agentDir),\n\t\t...(options.journalPath\n\t\t\t? { journalPath: canonicalizeFilesystemPath(assertProductStatePath(options.journalPath)) }\n\t\t\t: {}),\n\t\tappVersion: options.appVersion,\n\t\tphase: \"starting\",\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t};\n\tconst candidateDirectory = resolve(registryDir, `.candidate-${process.pid}-${token}`);\n\tconst ownerDirectory = ownerDirectoryPath(registryDir, options.generation);\n\tmkdirSync(candidateDirectory, { mode: 0o700 });\n\tconst staleDirectories: string[] = [];\n\ttry {\n\t\twriteOwnerScope(candidateDirectory, record);\n\t\twriteOwnerRecord(candidateDirectory, record);\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\tthrow new DaemonShutdownAdmissionError();\n\t\t\t}\n\t\t\tfor (const directory of listOwnerDirectories(registryDir)) {\n\t\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => ownerConflicts(scope, record));\n\t\t\t\tif (!owner) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!ownerConflicts(owner, record)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (isProcessIdentityAlive(owner)) {\n\t\t\t\t\tthrow new DaemonSupervisorAlreadyRunningError(owner);\n\t\t\t\t}\n\t\t\t\tconst staleDirectory = `${directory}.stale-${randomUUID()}`;\n\t\t\t\trenameSync(directory, staleDirectory);\n\t\t\t\tstaleDirectories.push(staleDirectory);\n\t\t\t}\n\t\t\trenameSync(candidateDirectory, ownerDirectory);\n\t\t});\n\t} catch (error) {\n\t\trmSync(candidateDirectory, { recursive: true, force: true });\n\t\tthrow error;\n\t} finally {\n\t\tfor (const directory of staleDirectories) {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t}\n\t}\n\treturn new DaemonSupervisorOwnership(record, registryDir, ownerDirectory);\n}\n\n/** Read only: discovery must not acquire ownership or reclaim registry directories. */\nexport function listDaemonSupervisorSocketPathsForAgentDir(\n\tagentDir: string,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): string[] {\n\tlet canonicalAgentDir: string;\n\tlet directories: string[];\n\ttry {\n\t\tcanonicalAgentDir = canonicalizeFilesystemPath(agentDir);\n\t\tdirectories = listOwnerDirectories(registryDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst socketPaths: string[] = [];\n\tfor (const directory of directories) {\n\t\tconst owner = readOwnerRecord(directory);\n\t\tif (!owner) continue;\n\t\ttry {\n\t\t\tif (canonicalizeFilesystemPath(owner.agentDir) === canonicalAgentDir) {\n\t\t\t\tsocketPaths.push(normalizeSocketPath(owner.socketPath));\n\t\t\t}\n\t\t} catch {\n\t\t\t// A stale or inaccessible record must not hide the other supervisors.\n\t\t}\n\t}\n\treturn socketPaths;\n}\n\nexport async function assertDaemonSupervisorOwnerCurrent(\n\towner: {\n\t\tgeneration: string;\n\t\tpid: number;\n\t\tprocessStartId?: string;\n\t\tsocketPath: string;\n\t},\n\tvalidatedFingerprint?: string,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<string> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tconst current =\n\t\treadOwnerRecord(ownerDirectoryPath(registryDir, owner.generation)) ??\n\t\t(legacyRegistryDir ? readOwnerRecord(ownerDirectoryPath(legacyRegistryDir, owner.generation)) : undefined);\n\tif (\n\t\t!current ||\n\t\tcurrent.pid !== owner.pid ||\n\t\tcurrent.processStartId !== owner.processStartId ||\n\t\tcurrent.socketPath !== normalizeSocketPath(owner.socketPath) ||\n\t\t!isProcessAlive(current.pid)\n\t) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\tconst fingerprint = ownerRecordFingerprint(current);\n\tif (fingerprint !== validatedFingerprint && !isProcessIdentityAlive(current)) {\n\t\tthrow new DaemonSupervisorOwnershipLostError(owner.generation, { socketPath: owner.socketPath, registryDir });\n\t}\n\treturn fingerprint;\n}\n\nexport async function acquireDaemonShutdownAdmission(): Promise<DaemonShutdownAdmission> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\tconst processStartId = getProcessStartId(process.pid);\n\twhile (true) {\n\t\tlet acquired: DaemonShutdownAdmissionRecord | undefined;\n\t\tawait withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\tif (readActiveShutdownAdmission(registryDir)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst now = Date.now();\n\t\t\tacquired = {\n\t\t\t\tversion: OWNER_VERSION,\n\t\t\t\ttoken: randomUUID(),\n\t\t\t\tpid: process.pid,\n\t\t\t\t...(processStartId ? { processStartId } : {}),\n\t\t\t\tcreatedAt: new Date(now).toISOString(),\n\t\t\t\tupdatedAt: new Date(now).toISOString(),\n\t\t\t\texpiresAt: new Date(now + SHUTDOWN_ADMISSION_LEASE_MS).toISOString(),\n\t\t\t};\n\t\t\twriteJsonAtomically(shutdownAdmissionPath(registryDir), acquired);\n\t\t});\n\t\tif (acquired) {\n\t\t\treturn new DaemonShutdownAdmission(acquired, registryDir);\n\t\t}\n\t\tawait delay(SHUTDOWN_ADMISSION_WAIT_MS);\n\t}\n}\n\nexport async function isDaemonShutdownAdmissionActive(): Promise<boolean> {\n\tconst registryDir = defaultDaemonSupervisorRegistryDir();\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () =>\n\t\tshutdownAdmissionIsActive(readShutdownAdmission(shutdownAdmissionPath(registryDir))),\n\t);\n}\n\nexport async function persistDaemonStartupFenceFromOwner(\n\tsocketPath: string,\n\thello: DaemonSupervisorHelloIdentity,\n\tregistryDir?: string,\n\tlegacyRegistryDir: string | undefined = undefined,\n): Promise<void> {\n\tregistryDir ??= defaultDaemonSupervisorRegistryDir();\n\tmkdirSync(registryDir, { recursive: true, mode: 0o700 });\n\tconst fenceDirectory = resolve(registryDir, \"startup-fences\");\n\tmkdirSync(fenceDirectory, { recursive: true, mode: 0o700 });\n\tconst path = startupFencePath(fenceDirectory, socketPath);\n\tconst normalizedSocketPath = normalizeSocketPath(socketPath);\n\treturn withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\tconst owners = listOwnerDirectories(registryDir).flatMap((directory) => {\n\t\t\tconst owner = readOwnerRecordForScope(directory, (scope) => scope.socketPath === normalizedSocketPath);\n\t\t\treturn owner ? [owner] : [];\n\t\t});\n\t\tlet matchingOwners = owners.filter((owner) => owner.socketPath === normalizedSocketPath);\n\t\tif (matchingOwners.length === 0 && legacyRegistryDir) {\n\t\t\t// Stale legacy leftovers are expected; keep only records matching the\n\t\t\t// identity the caller already holds.\n\t\t\tmatchingOwners = readLegacyOwnersForSocket(legacyRegistryDir, normalizedSocketPath).filter(\n\t\t\t\t(owner) => owner.token === hello.supervisorOwnerToken && owner.pid === hello.supervisorPid,\n\t\t\t);\n\t\t}\n\t\tif (matchingOwners.length === 0) {\n\t\t\tthrow new Error(`Daemon supervisor owner does not match ${socketPath}`);\n\t\t}\n\t\tif (matchingOwners.length > 1) {\n\t\t\tthrow new Error(`Multiple daemon supervisor owners match ${socketPath}`);\n\t\t}\n\t\tconst owner = matchingOwners[0];\n\t\tif (!owner) {\n\t\t\tthrow new Error(`Daemon supervisor owner disappeared for ${socketPath}`);\n\t\t}\n\t\tconst helloSocketPath = hello.supervisorSocketPath;\n\t\tif (\n\t\t\t!Number.isInteger(hello.supervisorPid) ||\n\t\t\thello.supervisorPid !== owner.pid ||\n\t\t\thello.supervisorGeneration !== owner.generation ||\n\t\t\thello.supervisorOwnerToken !== owner.token ||\n\t\t\ttypeof helloSocketPath !== \"string\" ||\n\t\t\tnormalizeSocketPath(helloSocketPath) !== owner.socketPath ||\n\t\t\ttypeof owner.processStartId !== \"string\" ||\n\t\t\thello.supervisorProcessStartId !== owner.processStartId\n\t\t) {\n\t\t\tthrow new Error(`Daemon supervisor hello does not match its durable owner for ${socketPath}`);\n\t\t}\n\t\tconst observedProcessStartId = getProcessStartId(owner.pid);\n\t\tif (observedProcessStartId !== owner.processStartId) {\n\t\t\tthrow new Error(`Daemon supervisor process identity changed for ${socketPath}`);\n\t\t}\n\t\tconst record: DaemonStartupFenceRecord = {\n\t\t\tversion: OWNER_VERSION,\n\t\t\ttoken: randomUUID(),\n\t\t\townerToken: owner.token,\n\t\t\tpid: owner.pid,\n\t\t\tprocessStartId: owner.processStartId,\n\t\t\tsocketPath: owner.socketPath,\n\t\t\tsupervisorGeneration: owner.generation,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\t\twriteJsonAtomically(path, record);\n\t});\n}\n\nexport async function waitForDaemonStartupFence(\n\tsocketPath: string,\n\ttimeoutMs = 10_000,\n\tregistryDir: string = defaultDaemonSupervisorRegistryDir(),\n): Promise<void> {\n\tconst path = startupFencePath(resolve(registryDir, \"startup-fences\"), socketPath);\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (true) {\n\t\tconst fence = readStartupFence(path);\n\t\tif (!fence) {\n\t\t\treturn;\n\t\t}\n\t\tif (fence.socketPath !== normalizeSocketPath(socketPath)) {\n\t\t\tthrow new Error(`Daemon startup fence does not match ${socketPath}`);\n\t\t}\n\t\tif (!isProcessIdentityAlive(fence)) {\n\t\t\tconst cleared = await withDaemonSupervisorRegistryGuard(registryDir, () => {\n\t\t\t\tconst current = readStartupFence(path);\n\t\t\t\tif (!current) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (current?.token === fence.token) {\n\t\t\t\t\trmSync(path, { force: true });\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\tif (cleared) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (Date.now() >= deadline) {\n\t\t\tthrow new Error(`Timed out waiting for predecessor daemon process ${fence.pid} to exit`);\n\t\t}\n\t\tawait delay(STARTUP_FENCE_POLL_MS);\n\t}\n}\n\nfunction isProcessIdentityAlive(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\tif (!identity.processStartId) {\n\t\treturn true;\n\t}\n\tconst observed = getProcessStartId(identity.pid);\n\treturn observed === undefined || observed === identity.processStartId;\n}\n\nfunction matchesExactProcessIdentity(identity: ProcessIdentity): boolean {\n\tif (!isProcessAlive(identity.pid)) {\n\t\treturn false;\n\t}\n\treturn identity.processStartId === undefined || getProcessStartId(identity.pid) === identity.processStartId;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t} catch (error) {\n\t\treturn (error as NodeJS.ErrnoException).code !== \"ESRCH\";\n\t}\n\treturn true;\n}\n\nfunction canonicalizeFilesystemPath(path: string): string {\n\tlet existingAncestor = resolve(path);\n\tconst missingSuffix: string[] = [];\n\twhile (true) {\n\t\ttry {\n\t\t\tconst physicalAncestor = realpathSync.native(existingAncestor);\n\t\t\tconst canonical = join(physicalAncestor, ...missingSuffix);\n\t\t\treturn process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst parent = dirname(existingAncestor);\n\t\t\tif (parent === existingAncestor) {\n\t\t\t\tconst unresolved = resolve(path);\n\t\t\t\treturn process.platform === \"win32\" ? unresolved.toLowerCase() : unresolved;\n\t\t\t}\n\t\t\tmissingSuffix.unshift(basename(existingAncestor));\n\t\t\texistingAncestor = parent;\n\t\t}\n\t}\n}\n\nfunction ownerConflicts(left: DaemonSupervisorOwnerScope, right: DaemonSupervisorOwnerScope): boolean {\n\tif (left.socketPath === right.socketPath || left.descriptorDir === right.descriptorDir) return true;\n\tif (left.journalPath && right.journalPath) return left.journalPath === right.journalPath;\n\t// Older records do not identify their family journal. An unknown footprint cannot grant a writer.\n\treturn Boolean(\n\t\t(left.journalPath || right.journalPath) &&\n\t\t\t(!left.agentDir || !right.agentDir || left.agentDir === right.agentDir),\n\t);\n}\n\nfunction sameOwnerRecord(left: DaemonSupervisorOwnerRecord, right: DaemonSupervisorOwnerRecord): boolean {\n\treturn (\n\t\tleft.token === right.token &&\n\t\tleft.generation === right.generation &&\n\t\tleft.pid === right.pid &&\n\t\tleft.processStartId === right.processStartId &&\n\t\tleft.socketPath === right.socketPath &&\n\t\tleft.descriptorDir === right.descriptorDir &&\n\t\tleft.agentDir === right.agentDir &&\n\t\tleft.journalPath === right.journalPath\n\t);\n}\n\nfunction ownerRecordFingerprint(record: DaemonSupervisorOwnerRecord): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(record)).digest(\"hex\");\n}\n\nfunction listOwnerDirectories(registryDir: string): string[] {\n\treturn readdirSync(registryDir)\n\t\t.filter((name) => name.endsWith(\".owner\"))\n\t\t.map((name) => resolve(registryDir, name));\n}\n\nfunction ownerDirectoryPath(registryDir: string, generation: string): string {\n\tif (!/^[A-Za-z0-9._-]+$/.test(generation)) {\n\t\tthrow new Error(`Invalid daemon supervisor generation: ${generation}`);\n\t}\n\treturn resolve(registryDir, `${generation}.owner`);\n}\n\nfunction requireOwnerRecord(directory: string): DaemonSupervisorOwnerRecord {\n\tconst owner = readOwnerRecord(directory);\n\tif (!owner) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn owner;\n}\n\nfunction readOwnerRecordForScope(\n\tdirectory: string,\n\tisRelevant: (scope: DaemonSupervisorOwnerScope) => boolean,\n): DaemonSupervisorOwnerRecord | undefined {\n\tconst owner = readOwnerRecord(directory);\n\tif (owner) {\n\t\treturn owner;\n\t}\n\tconst scope = readOwnerScope(directory);\n\tconst entries = !scope ? readdirSync(directory) : [];\n\tif (!scope && !entries.includes(\"owner.json\") && !entries.includes(\"scope.json\")) {\n\t\tconst abandonedDirectory = `${directory}.abandoned-${randomUUID()}`;\n\t\trenameSync(directory, abandonedDirectory);\n\t\trmSync(abandonedDirectory, { recursive: true, force: true });\n\t\treturn undefined;\n\t}\n\tif (!scope || isRelevant(scope)) {\n\t\tthrow new Error(`Invalid daemon supervisor owner record: ${directory}`);\n\t}\n\treturn undefined;\n}\n\nfunction readOwnerRecord(directory: string): DaemonSupervisorOwnerRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"owner.json\"), \"utf8\")) as unknown;\n\t\treturn isDaemonSupervisorOwnerRecord(value) ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerRecord(value: unknown): value is DaemonSupervisorOwnerRecord {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst record = value as Partial<DaemonSupervisorOwnerRecord>;\n\treturn (\n\t\trecord.version === OWNER_VERSION &&\n\t\trecord.role === \"supervisor\" &&\n\t\ttypeof record.token === \"string\" &&\n\t\ttypeof record.generation === \"string\" &&\n\t\tNumber.isInteger(record.pid) &&\n\t\t(record.pid ?? 0) > 0 &&\n\t\t(record.processStartId === undefined || typeof record.processStartId === \"string\") &&\n\t\ttypeof record.socketPath === \"string\" &&\n\t\ttypeof record.descriptorDir === \"string\" &&\n\t\ttypeof record.agentDir === \"string\" &&\n\t\t(record.journalPath === undefined || typeof record.journalPath === \"string\") &&\n\t\ttypeof record.appVersion === \"string\" &&\n\t\t(record.phase === \"starting\" || record.phase === \"owner\" || record.phase === \"stopping\") &&\n\t\ttypeof record.createdAt === \"string\" &&\n\t\ttypeof record.updatedAt === \"string\"\n\t);\n}\n\nfunction readOwnerScope(directory: string): DaemonSupervisorOwnerScope | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(resolve(directory, \"scope.json\"), \"utf8\")) as unknown;\n\t\tif (!isDaemonSupervisorOwnerScope(value)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn ownerDirectoryPath(dirname(directory), value.generation) === directory ? value : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isDaemonSupervisorOwnerScope(value: unknown): value is DaemonSupervisorOwnerScope {\n\tif (!value || typeof value !== \"object\") {\n\t\treturn false;\n\t}\n\tconst scope = value as Partial<DaemonSupervisorOwnerScope>;\n\treturn (\n\t\tscope.version === OWNER_VERSION &&\n\t\tscope.role === \"supervisor\" &&\n\t\ttypeof scope.token === \"string\" &&\n\t\ttypeof scope.generation === \"string\" &&\n\t\ttypeof scope.socketPath === \"string\" &&\n\t\ttypeof scope.descriptorDir === \"string\" &&\n\t\t(scope.agentDir === undefined || typeof scope.agentDir === \"string\") &&\n\t\t(scope.journalPath === undefined || typeof scope.journalPath === \"string\")\n\t);\n}\n\nfunction writeOwnerScope(directory: string, owner: DaemonSupervisorOwnerRecord): void {\n\tconst scope: DaemonSupervisorOwnerScope = {\n\t\tversion: owner.version,\n\t\trole: owner.role,\n\t\ttoken: owner.token,\n\t\tgeneration: owner.generation,\n\t\tsocketPath: owner.socketPath,\n\t\tdescriptorDir: owner.descriptorDir,\n\t\tagentDir: owner.agentDir,\n\t\t...(owner.journalPath ? { journalPath: owner.journalPath } : {}),\n\t};\n\twriteJsonAtomically(resolve(directory, \"scope.json\"), scope);\n}\n\nfunction writeOwnerRecord(directory: string, record: DaemonSupervisorOwnerRecord): void {\n\twriteJsonAtomically(resolve(directory, \"owner.json\"), record);\n}\n\nfunction readStartupFence(path: string): DaemonStartupFenceRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\tconst fence = value as Partial<DaemonStartupFenceRecord>;\n\t\tif (\n\t\t\tfence.version !== OWNER_VERSION ||\n\t\t\ttypeof fence.token !== \"string\" ||\n\t\t\ttypeof fence.ownerToken !== \"string\" ||\n\t\t\t!Number.isInteger(fence.pid) ||\n\t\t\t(fence.pid ?? 0) <= 0 ||\n\t\t\ttypeof fence.processStartId !== \"string\" ||\n\t\t\ttypeof fence.socketPath !== \"string\" ||\n\t\t\ttypeof fence.supervisorGeneration !== \"string\" ||\n\t\t\ttypeof fence.createdAt !== \"string\"\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon startup fence: ${path}`);\n\t\t}\n\t\treturn fence as DaemonStartupFenceRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction shutdownAdmissionIsActive(admission: DaemonShutdownAdmissionRecord | undefined): boolean {\n\treturn admission !== undefined && Date.parse(admission.expiresAt) > Date.now() && isProcessIdentityAlive(admission);\n}\n\nfunction readActiveShutdownAdmission(registryDir: string): DaemonShutdownAdmissionRecord | undefined {\n\tconst path = shutdownAdmissionPath(registryDir);\n\tconst admission = readShutdownAdmission(path);\n\tif (!admission) {\n\t\treturn undefined;\n\t}\n\tif (shutdownAdmissionIsActive(admission)) {\n\t\treturn admission;\n\t}\n\trmSync(path, { force: true });\n\treturn undefined;\n}\n\nfunction readShutdownAdmission(path: string): DaemonShutdownAdmissionRecord | undefined {\n\ttry {\n\t\tconst value = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n\t\tif (!value || typeof value !== \"object\") {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\tconst admission = value as Partial<DaemonShutdownAdmissionRecord>;\n\t\tif (\n\t\t\tadmission.version !== OWNER_VERSION ||\n\t\t\ttypeof admission.token !== \"string\" ||\n\t\t\t!Number.isInteger(admission.pid) ||\n\t\t\t(admission.pid ?? 0) <= 0 ||\n\t\t\t(admission.processStartId !== undefined && typeof admission.processStartId !== \"string\") ||\n\t\t\ttypeof admission.createdAt !== \"string\" ||\n\t\t\ttypeof admission.updatedAt !== \"string\" ||\n\t\t\ttypeof admission.expiresAt !== \"string\" ||\n\t\t\t!Number.isFinite(Date.parse(admission.expiresAt))\n\t\t) {\n\t\t\tthrow new Error(`Invalid daemon shutdown admission: ${path}`);\n\t\t}\n\t\treturn admission as DaemonShutdownAdmissionRecord;\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\treturn undefined;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction writeJsonAtomically(path: string, value: unknown): void {\n\tconst tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n\ttry {\n\t\twriteFileSync(tempPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n\t\trenameSync(tempPath, path);\n\t} catch (error) {\n\t\trmSync(tempPath, { force: true });\n\t\tthrow error;\n\t}\n}\n\nfunction startupFencePath(directory: string, socketPath: string): string {\n\tconst key = createHash(\"sha256\").update(normalizeSocketPath(socketPath)).digest(\"hex\");\n\treturn resolve(directory, `${key}.json`);\n}\n\nfunction shutdownAdmissionPath(registryDir: string): string {\n\treturn resolve(registryDir, SHUTDOWN_ADMISSION_FILE_NAME);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n"]}