cohorte 3.0.0-dev.1 → 3.0.0-dev.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"src-CId6kMsY.mjs","names":["fsConstants","oneOf","count","strict","strict","count","delivery","strict","strict","count","strict","count"],"sources":["../../../../packages/security/src/exec/capabilities.ts","../../../../packages/security/src/exec/identity.ts","../../../../packages/security/src/exec/ulimit.ts","../../../../packages/security/src/exec/executor.ts","../../../../packages/security/src/exec/index.ts","../../../../packages/security/src/redact/seal.ts","../../../../packages/security/src/redact/index.ts","../../../../packages/security/src/contract/builtin.ts","../../../../packages/security/src/contract/decisions.ts","../../../../packages/security/src/contract/exec.ts","../../../../packages/runtime-contract/src/capabilities.ts","../../../../packages/runtime-contract/src/session.ts","../../../../packages/runtime-contract/src/tools.ts","../../../../packages/runtime-contract/src/events.ts","../../../../packages/runtime-contract/src/pin.ts","../../../../packages/runtime-contract/src/spawn.ts"],"sourcesContent":["// What the L0 executor honestly guarantees, and detection of the L1 binaries this unit does not yet wrap\n// (DESIGN 2.6.6, ADR-0003: \"L1 backends are U4.07\"). `computeCapabilities` is the ONE function behind both\n// `Executor.run()`'s `ExecResult.guarantees` and the top-level `probeSandbox()`, so the two can never disagree.\nimport { accessSync, constants as fsConstants } from 'node:fs';\nimport { delimiter, join } from 'node:path';\nimport { type ErrorInfo, errorOf } from '@cohorte/base';\nimport type { SandboxBackend, SandboxCapabilities } from '../contract/index.ts';\n\n/**\n * The fixed L0-process report (every OS, the built-in `none` backend). `memory` stays `unavailable`: the ulimit\n * wrapper never attempts `-v` (toolchain.md §8: it fails outright on macOS, and this unit applies only `-t/-f/-n/-u`\n * on every platform alike, per DESIGN 2.6.6's own list of flags). `missing`/`notes` report what `probeSandbox`\n * observed about L1 binaries on this machine; the level stays `L0-process` regardless, since no backend besides\n * `none` is implemented here.\n *\n * `cpuTime` and `processes` say `enforced` because the wrapper FAILS CLOSED (ulimit.ts): a limit the kernel\n * refuses aborts the run instead of letting the program start without it, so the word is never a claim about a\n * limit that was silently dropped.\n */\nexport function l0Capabilities(missing: readonly string[] = [], notes: readonly string[] = []): SandboxCapabilities {\n return {\n level: 'L0-process',\n backend: 'none',\n filesystem: 'advisory',\n network: 'unenforced',\n processEscape: 'possible',\n envFiltering: 'enforced',\n timeout: 'enforced',\n outputCap: 'enforced',\n cpuTime: 'enforced',\n memory: 'unavailable',\n processes: 'enforced',\n killTree: 'process-group-with-sweep',\n missing: [...missing],\n notes: [...notes],\n };\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n accessSync(path, fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Is `name` an executable on the host's PATH? Scanned directly rather than through `which`, which is not part of\n * coreutils and is simply absent from many minimal Linux images and containers: there, a spawned `which` fails,\n * `bwrap` is reported missing although it is installed, and `doctor` — the report ADR-0003 makes load-bearing for\n * the `native` / `best-effort` decision — states a false negative. A `stat` per PATH entry also costs no fork.\n *\n * This is the one place the executor reads `process.env`, and it reads the HOST's PATH to answer a question about\n * the host. Nothing here ever reaches a child: the environment of a spawned command is built from `ExecRequest.env`\n * alone (S-20, executor.ts).\n */\nfunction isOnPath(name: string): boolean {\n for (const dir of (process.env.PATH ?? '').split(delimiter)) {\n if (dir !== '' && isExecutable(join(dir, name))) return true;\n }\n return false;\n}\n\nconst settledDetection = new Map<string, readonly string[]>();\n\n/**\n * Informational only (DESIGN 2.6.6 `missing` example: `[\"bwrap\"]`): this unit never wraps a command in Seatbelt or\n * bubblewrap (that is U4.07's job), so detecting them changes nothing about the reported `level`/`backend` — it\n * only tells `doctor` what is absent.\n *\n * SYNCHRONOUS, because `Executor.capabilities()` is: DESIGN 2.6.6 marks `SandboxCapabilities` `[S]` and\n * `capabilities()` returns it without awaiting anything. Priming an asynchronous detection at construction was not\n * enough — a `capabilities()` called in the same tick still read an unsettled memo and answered `missing: []` while\n * `probeSandbox()` answered `['bwrap']`, i.e. `doctor` contradicted itself depending on when it was called. A\n * handful of `stat`s is all the answer needs.\n *\n * MEMOISED per platform: DESIGN 2.6.6 says `probe()` is \"cached per Cohorte version + OS build\", and the answer is\n * a property of the machine, not of the command; without the memo it would be recomputed on every `run()`.\n */\nexport function detectMissingL1Binaries(platform: string): readonly string[] {\n const settled = settledDetection.get(platform);\n if (settled !== undefined) return settled;\n const missing: string[] = [];\n if (platform === 'darwin' && !isExecutable('/usr/bin/sandbox-exec')) missing.push('sandbox-exec');\n if (platform === 'linux' && !isOnPath('bwrap')) missing.push('bwrap');\n settledDetection.set(platform, missing);\n return missing;\n}\n\n/** The backend that produced `capabilities`, if any — `undefined` means \"nothing usable: the honest L0 report\". */\nexport interface ResolvedSandbox {\n backend?: SandboxBackend;\n capabilities: SandboxCapabilities;\n}\n\n/**\n * Tries every non-`none` backend in order and returns the FIRST one whose probe reports `L1-os`, together with its\n * report; falls back to the honest L0 report (with L1-binary detection folded into `missing`) when none is usable —\n * which, until U4.07 lands, is always, since no L1 `SandboxBackend` is constructed by this unit.\n *\n * Returning the backend and its report together is what keeps `ExecResult.guarantees` honest: the executor wraps\n * the command with exactly the backend that earned the report, so it can never claim an isolation that the argv it\n * spawned does not carry.\n */\nexport async function resolveSandbox(backends: readonly SandboxBackend[], platform: string): Promise<ResolvedSandbox> {\n for (const backend of backends) {\n if (backend.id === 'none') continue;\n try {\n const probed = await backend.probe();\n if (probed.level === 'L1-os') return { backend, capabilities: probed };\n } catch {\n // Not implemented yet, or failed to probe: fall through to the honest L0 report.\n }\n }\n return { capabilities: l0Capabilities(detectMissingL1Binaries(platform)) };\n}\n\n/** The escape self-test that gates the word `enforced` on this platform (DESIGN 2.6.6, ADR-0003 §2b). */\nfunction escapeSelfTest(platform: string): string {\n if (platform === 'darwin') return 'escape self-test S-28';\n if (platform === 'linux') return 'escape self-test S-29';\n return 'the platform escape self-test';\n}\n\n/**\n * One sentence per axis on which `guarantees` falls short of `require: 'native'`; empty exactly when it satisfies\n * it. DESIGN 2.6.6 requires the refusal to NAME the failing self-test rather than hand the caller a bare enum, so\n * these strings are what the executor appends to `guarantees.notes` on a `sandbox-denied` result and what\n * `sandboxUnavailable()` (exec/index.ts) turns into the catalogued error's message.\n *\n * `level: 'L1-os'` alone is never enough: a backend whose escape self-test has not passed here reports `partial` on\n * the axes that matter, and `native` is satisfied only by `enforced` (ADR-0003 §2b).\n */\nexport function nativeShortfalls(\n guarantees: SandboxCapabilities,\n platform: string = process.platform,\n): readonly string[] {\n if (guarantees.level !== 'L1-os') {\n const missing = guarantees.missing.length > 0 ? ` (missing: ${guarantees.missing.join(', ')})` : '';\n return [\n `sandbox: no OS sandbox backend is active${missing} — level is '${guarantees.level}', backend '${guarantees.backend}', ` +\n `so filesystem isolation is '${guarantees.filesystem}' and network '${guarantees.network}'`,\n ];\n }\n const test = escapeSelfTest(platform);\n const shortfalls: string[] = [];\n if (guarantees.filesystem !== 'enforced') {\n shortfalls.push(`sandbox: filesystem is '${guarantees.filesystem}' (${test} has not passed on this machine)`);\n }\n if (guarantees.network !== 'enforced-off') {\n shortfalls.push(`sandbox: network is '${guarantees.network}' (${test} has not passed on this machine)`);\n }\n if (guarantees.processEscape !== 'denied') {\n shortfalls.push(`sandbox: processEscape is '${guarantees.processEscape}' (${test} has not passed on this machine)`);\n }\n return shortfalls;\n}\n\n/** `resolveSandbox`'s report alone, for callers that only want to know what is guaranteed (`probeSandbox`). */\nexport async function computeCapabilities(\n backends: readonly SandboxBackend[],\n platform: string,\n): Promise<SandboxCapabilities> {\n return (await resolveSandbox(backends, platform)).capabilities;\n}\n\n/**\n * DESIGN 2.6.6: \"`require: 'native'` with no usable backend => `security/sandbox-unavailable` with the `doctor`\n * remediation.\" Minted HERE, once, from the same `nativeShortfalls` the executor already put in `guarantees.notes`\n * on the `sandbox-denied` result, so the catalogued error and the reported notes can never say different things.\n */\nexport function sandboxUnavailable(guarantees: SandboxCapabilities, platform: string = process.platform): ErrorInfo {\n const shortfalls = nativeShortfalls(guarantees, platform);\n const message = shortfalls.length > 0 ? shortfalls.join(' ') : 'no OS sandbox backend is active';\n return errorOf('security/sandbox-unavailable', message, { details: { guarantees: { ...guarantees } } });\n}\n","// Kill-tree, orphan sweep and cross-restart identity verification (DESIGN 2.6.6, 4.4 step 5). Two mechanisms, and\n// NEITHER of them ever signals a bare pid:\n//\n// - an in-run TRACKER (`trackDescendants` + `sweepTracked`): while the leader is alive, its process tree is\n// polled by PPID, because a `setsid()` escapee keeps its PPID even after it leaves the process GROUP (S-22).\n// Every descendant ever seen is remembered — a later reparent to pid 1 (the leader exits before we look again)\n// cannot make an escapee invisible — and it is remembered WITH the start time it had when first seen. Over a\n// command of minutes (`pnpm test`, a build) most of that set is long dead by the end, and the OS is free to\n// hand those numbers to unrelated processes of the same user; the sweep therefore re-reads each pid's current\n// start time and touches only the ones that are still the very process that was tracked.\n// - a STATELESS, cross-restart entry point (`sweepGroupByToken`, DESIGN 4.4 step 5, \"callable on demand by the\n// Resumer\"): after a host restart there is no in-memory tracker left, so a bare pgid is never enough — the OS\n// may have recycled it for an unrelated process. Identity is verified against the process's own START TIME\n// (`processStartToken`), the same technique `pids/*.json` files are meant to support (I1, I4: \"never kills on\n// a bare pid\").\nimport { execFile } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport { sha256Hex } from '@cohorte/base';\n\nconst execFileAsync = promisify(execFile);\n\ninterface ProcRow {\n pid: number;\n ppid: number;\n pgid: number;\n /** when this pid started, as the process table reports it — what tells a recycled number from the real process */\n start: string;\n}\n\n/**\n * One `ps` fork, four columns. `lstart=` is the last one on purpose: it is the only field with embedded spaces\n * (`Tue Sep 15 09:09:30 2026`), so everything after the third column is its value. A row that cannot produce all\n * four is DROPPED rather than tracked without an identity — a pid with no start time is a bare pid, and this file\n * does not kill those.\n */\nasync function processTable(): Promise<ProcRow[]> {\n const { stdout } = await execFileAsync('ps', ['-Ao', 'pid=,ppid=,pgid=,lstart=']);\n const rows: ProcRow[] = [];\n for (const line of stdout.split('\\n')) {\n const fields = line.trim().split(/\\s+/);\n if (fields.length < 4) continue;\n const [pidText, ppidText, pgidText] = fields;\n const pid = Number(pidText);\n const ppid = Number(ppidText);\n const pgid = Number(pgidText);\n const start = fields.slice(3).join(' ');\n if (Number.isInteger(pid) && Number.isInteger(ppid) && Number.isInteger(pgid) && start !== '') {\n rows.push({ pid, ppid, pgid, start });\n }\n }\n return rows;\n}\n\n/** Every row transitively parented by `rootPid`, whatever its CURRENT pgid (so a `setsid()` escapee still shows). */\nfunction descendantsOf(rootPid: number, table: readonly ProcRow[]): ProcRow[] {\n const byParent = new Map<number, ProcRow[]>();\n for (const row of table) {\n const siblings = byParent.get(row.ppid);\n if (siblings) siblings.push(row);\n else byParent.set(row.ppid, [row]);\n }\n const found: ProcRow[] = [];\n const queue = [...(byParent.get(rootPid) ?? [])];\n for (let next = queue.pop(); next !== undefined; next = queue.pop()) {\n found.push(next);\n queue.push(...(byParent.get(next.pid) ?? []));\n }\n return found;\n}\n\n/**\n * Is `pgid` a real process group we may address? On POSIX `kill(-0, …)` signals the CALLER's own process group —\n * the run host itself — and `kill(-1, …)` every process the user may signal. `ExecResult.pgid` is `0` on every\n * early return (nothing was spawned), so a dependant that feeds a result back into a sweep must find a closed door\n * here rather than one missing guard between it and a TERM of the run host.\n */\nfunction isAddressableGroup(pgid: number): boolean {\n return Number.isInteger(pgid) && pgid > 1;\n}\n\nexport function isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/** `true` when the signal was actually delivered; `false` when the target was gone or refused us. */\nfunction trySignal(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch {\n // Already gone, or never existed: sweeping is always best-effort.\n return false;\n }\n}\n\n/** TERM the pids that are still alive, wait `graceMs`, KILL the survivors. Returns how many were signalled. */\nasync function terminatePids(\n pids: readonly number[],\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n const alive = pids.filter((pid) => isAlive(pid));\n if (alive.length === 0) return 0;\n for (const pid of alive) trySignal(pid, 'SIGTERM');\n await wait(graceMs);\n for (const pid of alive) if (isAlive(pid)) trySignal(pid, 'SIGKILL');\n return alive.length;\n}\n\n/**\n * How often the tracker forks `ps`. Every poll is a fork plus a full process-table scan, and this executor is the\n * path that runs `pnpm test` / `pnpm build`, where a run of minutes is ordinary — a fixed fast period would cost\n * tens of thousands of forks for one check command. The period is therefore fast only while it buys something: an\n * escapee that `setsid()`s immediately must be seen before the leader is reaped, which is a matter of milliseconds,\n * whereas after the first second the tracker is merely keeping an already-known set fresh. The final snapshot at\n * exit (below) is taken at full resolution whatever the period has grown to, so the last moment is never sampled\n * coarsely.\n */\nexport interface TrackInterval {\n /** the period during the fast window */\n initialMs: number;\n /** the period never grows past this */\n maxMs: number;\n /** total polled time after which the period starts doubling */\n rampAfterMs: number;\n}\n\n/** What the tracker remembers about a descendant: the pid, and the start time it had the first time it was seen. */\nexport type TrackedDescendants = Map<number, string>;\n\n/**\n * Polls the process table until `until` settles, folding every descendant ever seen under `rootPid` into `sink`\n * AS `pid -> start time`. The start time is what makes the record an identity instead of a number: by the end of a\n * long command most of these pids are gone, and the sweep must be able to tell the process it tracked from whatever\n * the OS has since given that number to. It is kept as FIRST SEEN and never overwritten — a differing later reading\n * means the number was recycled, which is exactly what the sweep needs to notice.\n *\n * Run concurrently with the leader's own lifetime (DESIGN 2.6.6 \"post-run SWEEP ... also callable on demand by the\n * Resumer\"); its own errors (no `ps` on the machine, a transient failure) are swallowed — sweeping is advisory,\n * never a reason to fail the call it is watching.\n */\nexport async function trackDescendants(\n rootPid: number,\n sink: TrackedDescendants,\n until: Promise<unknown>,\n wait: (ms: number) => Promise<void>,\n interval: TrackInterval,\n): Promise<void> {\n let settled = false;\n const stop = (): void => {\n settled = true;\n };\n void until.then(stop, stop);\n const poll = async (): Promise<void> => {\n try {\n for (const row of descendantsOf(rootPid, await processTable())) {\n if (!sink.has(row.pid)) sink.set(row.pid, row.start);\n }\n } catch {\n // best-effort\n }\n };\n let period = interval.initialMs;\n let polledMs = 0;\n for (;;) {\n await poll();\n if (settled) return;\n try {\n await wait(period);\n } catch {\n return;\n }\n polledMs += period;\n if (polledMs >= interval.rampAfterMs) period = Math.min(interval.maxMs, period * 2);\n if (settled) {\n // One last snapshot, taken as close as possible to the moment the leader actually exited.\n await poll();\n return;\n }\n }\n}\n\n/**\n * TERM every tracked descendant that is STILL THAT DESCENDANT, wait `graceMs`, then KILL the survivors (`leaderPid`\n * itself is excluded: the caller already handled the group leader through its own `-pgid` kill).\n *\n * Identity first, always. One process-table snapshot is taken before anything is signalled, and a tracked pid takes\n * part only when its CURRENT start time still equals the one recorded when it was first seen. A `pnpm test` that\n * forks hundreds of short-lived children leaves a set whose pids are mostly dead by the end; without this check the\n * sweep would TERM+KILL whatever unrelated process of the same user the OS had meanwhile given one of those numbers\n * to — a bare-pid kill, which DESIGN 4.4 step 5 forbids here exactly as it does across a restart — and would count\n * it as an escapee on top. A pid that is gone, or whose start time has moved, is neither signalled nor counted.\n *\n * Of the survivors that ARE ours, the KILL is total — every tracked descendant, whatever its group. The COUNT is\n * not: DESIGN 2.6.6 defines `ExecResult.escapees` as \"processes that LEFT the group\". A tracked pid whose current\n * pgid still equals `leaderPid` is an ordinary grandchild outliving its parent — routine, and counting it would\n * raise a false escapee on DESIGN 4.4's resume diagnostics and on any `escapees > 0` alerting; a pid that\n * `setsid()`ed away has its own pgid and IS one (S-22). When the snapshot cannot be taken at all, nothing is\n * signalled and nothing is claimed: an unverifiable pid is not a target.\n */\nexport async function sweepTracked(\n seen: ReadonlyMap<number, string>,\n leaderPid: number,\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n if (seen.size === 0) return 0;\n let table: ProcRow[];\n try {\n table = await processTable();\n } catch {\n // No snapshot, no identity, no kill: best-effort never means \"signal a number and hope\".\n return 0;\n }\n const current = new Map(table.map((row) => [row.pid, row]));\n let escapees = 0;\n const targets: number[] = [];\n for (const [pid, start] of seen) {\n if (pid === leaderPid) continue;\n const row = current.get(pid);\n // Gone (the common case at the end of a run), or the number has been recycled since: not ours to touch.\n if (row === undefined || row.start !== start) continue;\n targets.push(pid);\n if (row.pgid !== leaderPid) escapees += 1;\n }\n await terminatePids(targets, wait, graceMs);\n return escapees;\n}\n\n/**\n * The post-exit safety net, and a BEST-EFFORT net, not an identity-verified kill — be precise about what it is:\n * once the leader has been reaped (Node emits `'exit'` AFTER `waitpid`) its pid is free for reuse, and this\n * function keys on that same bare pgid NUMBER. It is narrower than `kill(-pgid)` in one respect only — it signals\n * members one pid at a time, sparing a recycled leader (`row.pid !== pgid`) — and it does NOT verify a start token,\n * so a group that has taken over the recycled number would be signalled with its members. The window is the few\n * milliseconds between the leader's reap and this call, and pids are allocated sequentially, so a recycle inside it\n * is not realistic. The identity-verified path is `sweepGroupByToken`, which is what the Resumer (DESIGN 4.4\n * step 5, \"never kills on a bare pid\") uses across restarts, where the window is unbounded and the guarantee must\n * be real. Returns how many were signalled.\n */\nexport async function killGroupMembers(\n pgid: number,\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n if (!isAddressableGroup(pgid)) return 0;\n let members: number[];\n try {\n members = (await processTable()).filter((row) => row.pgid === pgid && row.pid !== pgid).map((row) => row.pid);\n } catch {\n return 0;\n }\n return terminatePids(members, wait, graceMs);\n}\n\n/**\n * A string that identifies WHEN `pid` started, not just its number — the \"start token\" of DESIGN 4.4 step 5.\n * `undefined` when the pid is gone or the platform's process table cannot be read.\n *\n * The token must be EXEC-STABLE: it is minted at the `'spawn'` event, while the leader's process image is still\n * `/bin/sh -c '<ulimit script>'`, and every later reading of it — which is all the Resumer ever has — sees the image\n * the wrapper `exec`ed into. Anything image-dependent in the hash (a command line, an argv) therefore cannot round\n * trip, and `sweepGroupByToken` would never verify a group this executor recorded. Only start TIME qualifies.\n *\n * Resolution differs per platform, and it decides how narrow the pid-reuse window is. Linux reads `starttime` from\n * `/proc/<pid>/stat`, in clock ticks since boot: two processes can share a pid only if one started long after the\n * other died, so the token is effectively unique. macOS has no such counter; `ps -o lstart=` has ONE-SECOND\n * resolution, so the residual risk there is a pid recycled by a process that started in the SAME SECOND. That is\n * why nothing but a kill-tree cleanup is ever driven from this token, and why the program's identity is carried\n * separately, by `PidRegistry.record({ label: req.file })` (contract/exec.ts).\n */\nexport async function processStartToken(pid: number, platform: string = process.platform): Promise<string | undefined> {\n try {\n if (platform === 'linux') {\n const stat = await readFile(`/proc/${pid}/stat`, 'utf8');\n // `(comm)` may itself contain spaces or parentheses: skip to the LAST ')', then count fields from `state`.\n const afterComm = stat.slice(stat.lastIndexOf(')') + 2).split(' ');\n // state(3) ppid(4) pgrp(5) session(6) tty_nr(7) tpgid(8) flags(9) minflt..cstime(10-17) priority nice(18-19)\n // num_threads(20) itrealvalue(21) starttime(22) -> index 19 (0-based, starting at field 3) of `afterComm`.\n const starttime = afterComm[19];\n return starttime === undefined || starttime === '' ? undefined : `linux:${starttime}`;\n }\n const { stdout } = await execFileAsync('ps', ['-o', 'lstart=', '-p', String(pid)]);\n const identity = stdout.trim();\n return identity === '' ? undefined : `lstart:${sha256Hex(identity)}`;\n } catch {\n return undefined;\n }\n}\n\nexport interface SweepByTokenOptions {\n wait: (ms: number) => Promise<void>;\n graceMs: number;\n platform?: string;\n}\n\nexport interface SweepByTokenResult {\n /** `false` when `pgid` is dead, or alive but its start token does not match: nothing was signalled. */\n verified: boolean;\n /** `true` only when a signal was actually DELIVERED to the group — never merely \"we tried\". */\n killed: boolean;\n}\n\n/**\n * The Resumer's stateless, on-demand entry point (DESIGN 4.4 step 5): kills the process group `pgid` ONLY when its\n * CURRENT start token still equals `startToken`. After a host restart the in-memory tracker above is gone and the\n * OS may have reused `pgid` for an unrelated process since this run's host died (I1, I4) — a bare pid is never\n * enough. No match ⇒ nothing is signalled.\n */\nexport async function sweepGroupByToken(\n pgid: number,\n startToken: string,\n options: SweepByTokenOptions,\n): Promise<SweepByTokenResult> {\n if (!isAddressableGroup(pgid) || !isAlive(pgid)) return { verified: false, killed: false };\n const platform = options.platform ?? process.platform;\n const current = await processStartToken(pgid, platform);\n if (current === undefined || current !== startToken) return { verified: false, killed: false };\n const termed = trySignal(-pgid, 'SIGTERM');\n await options.wait(options.graceMs);\n const killed = isAlive(pgid) ? trySignal(-pgid, 'SIGKILL') : false;\n // `verified` says the group we found is this run's; `killed` says a signal really landed. A group that had\n // already exited between `isAlive` and here, or one every `kill` refused, reports `killed: false` — so the\n // Resumer can tell \"I stopped it\" from \"there was nothing left to stop\".\n return { verified: true, killed: termed || killed };\n}\n\n/**\n * Best-effort TERM -> grace -> KILL of the whole process group, addressed as `-pgid`. Never throws: a dead group\n * is not an error. Only ever called while the group LEADER is known alive (an escalation during the run): once the\n * leader has been reaped its pid can be recycled, and the post-exit cleanup uses `killGroupMembers` instead.\n */\nexport async function killGroup(pgid: number, wait: (ms: number) => Promise<void>, graceMs: number): Promise<void> {\n if (!isAddressableGroup(pgid)) return;\n trySignal(-pgid, 'SIGTERM');\n await wait(graceMs);\n trySignal(-pgid, 'SIGKILL');\n}\n","// The ONE shell in the product (DESIGN 2.6.6, I3, ADR-0003). `ULIMIT_WRAPPER_SCRIPT` is a compile-time constant:\n// request data is NEVER interpolated into it as text. Every limit value and every real argv element reaches the\n// program as a literal POSITIONAL PARAMETER, consumed by `shift` before `exec` replaces the shell's own process\n// image — so `; && | $()` and newlines inside an argument are never re-parsed by anything (EV-01..EV-15).\n//\n// The final `exec` goes through `/usr/bin/env -u PWD -u SHLVL` rather than straight to `\"$0\" \"$@\"`: macOS's\n// `/bin/sh` (bash) re-exports `PWD` and `SHLVL` into the process environ on every `exec`, `unset` notwithstanding\n// (verified on this machine: `unset SHLVL` is undone before the next `exec`) — two names that belong to neither\n// `ExecRequest.env` nor `OS_INJECTED_ENV`. `env` is not a shell (no word-splitting, no metacharacter handling: its\n// own arguments are plain argv), so this changes nothing about I3; it only strips the two stowaway names before the\n// real program's image ever exists. `env`'s own rlimits are inherited unchanged from `sh` (rlimits are a property\n// of the process, not reset by `execve`).\n//\n// The ONE thing `env` does parse is its operands: any operand containing `=` is a variable assignment, and the\n// first operand WITHOUT one is the utility to exec. The program path is that operand, so a path containing `=` is\n// swallowed as an assignment and `env` execs the NEXT argv element — a model-influenced argument (I3) — as the\n// program. `--` does not protect it on either BSD or GNU (assignments are operands, not options), and there is no\n// escaping form. `isWrappableProgramPath` therefore REFUSES such a path and the executor fails the run closed (I2)\n// rather than run something nobody approved. Arguments are unaffected (`env` stops scanning at the program).\n// The refusal costs exactly what it must and no more: the executor reaches for this wrapper only when a request\n// actually asks for a rlimit, so a request with empty `limits` spawns the program directly and never meets `env`.\n//\n// The script FAILS CLOSED. A `ulimit` the kernel refuses (a value above the hard limit, a limit this OS does not\n// support) must never let the program start anyway: that would run it with no limit while `SandboxCapabilities`\n// still says `cpuTime: 'enforced'` / `processes: 'enforced'` — the \"silently skipped\" case S-24 forbids. Each\n// `ulimit` is therefore guarded by `|| exit <ULIMIT_REFUSED_EXIT>`, and its own diagnostic is sent to `/dev/null`\n// rather than to the child's stderr pipe, where it would be counted as the PROGRAM's output (folded into\n// `outputSha256`, pushed to the model through `onChunk`, and put at the head of `tail`).\nconst ULIMIT_REFUSED_EXIT = 126;\nconst ULIMIT_WRAPPER_SCRIPT =\n `[ -n \"$1\" ] && { ulimit -t \"$1\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$2\" ] && { ulimit -f \"$2\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$3\" ] && { ulimit -n \"$3\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$4\" ] && { ulimit -u \"$4\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n 'shift 4; exec /usr/bin/env -u PWD -u SHLVL \"$0\" \"$@\"';\n\n/**\n * How the wrapper reports \"the kernel refused a limit you asked for\". The executor maps it to `outcome: 'error'`\n * when it comes with NO output at all — the shell's own `exec` failure (program not executable, ENOENT) uses the\n * same code but writes a diagnostic to stderr first, and a program is free to exit 126 by itself.\n */\nexport const ULIMIT_REFUSED_EXIT_CODE = ULIMIT_REFUSED_EXIT;\n\n/** Absolute, not resolved through PATH: the wrapper never depends on what an agent-controlled PATH would find. */\nexport const ULIMIT_SHELL = '/bin/sh';\n\n/**\n * Can the wrapper carry this program at all? `false` for a path `/usr/bin/env` would read as a variable assignment\n * (see the header): the executor turns that into `outcome: 'error'` and nothing is spawned. The check is on the\n * path the wrapper's `env` actually receives as its first operand — that is `SandboxBackend.wrap()`'s output, not\n * necessarily `ExecRequest.file`: when a backend prepends its own helper, the original program has become an\n * ARGUMENT of that helper, which `env` never inspects.\n */\nexport function isWrappableProgramPath(file: string): boolean {\n return !file.includes('=');\n}\n\n/** Why a run was refused before any spawn, in the words the result carries in `guarantees.notes`. */\nexport function unwrappableProgramNote(file: string): string {\n return (\n `exec: refused to run '${file}' under the requested rlimits: a program path containing '=' cannot be carried ` +\n `through the rlimit wrapper — '/usr/bin/env' would read it as a variable assignment and exec the next argument ` +\n 'instead. Nothing was spawned. (The same program runs when no rlimit is requested: there is no wrapper then.)'\n );\n}\n\nexport interface UlimitLimits {\n cpuSeconds?: number;\n fileSizeBytes?: number;\n openFiles?: number;\n processes?: number;\n}\n\nexport interface WrappedCommand {\n file: string;\n args: string[];\n}\n\nconst toIntArg = (value: number | undefined): string =>\n value === undefined ? '' : String(Math.max(0, Math.trunc(value)));\n\n/**\n * `ulimit -f` uses 1 KiB blocks on macOS and 512-byte blocks on Linux (the POSIX shells expose different units).\n * At least one block once a POSITIVE byte limit was asked for —\n * but `fileSizeBytes: 0` is a request in its own right (\"this command may create no file at all\"), and rounding it\n * up to one block would hand the caller 1024 writable bytes while `guarantees` still claims the limit applied.\n */\nconst toBlockArg = (bytes: number | undefined): string => {\n if (bytes === undefined) return '';\n if (bytes <= 0) return '0';\n const blockSize = process.platform === 'linux' ? 512 : 1024;\n return String(Math.max(1, Math.ceil(bytes / blockSize)));\n};\n\n/**\n * Wraps `file`/`args` so the process starts under `ulimit -t/-f/-n/-u` before `exec` hands control to it. `limits`\n * become POSITIONAL ARGUMENTS of the constant script (never text baked into it); an omitted limit is passed as an\n * empty string and the script's own `[ -n \"$k\" ]` guard skips it. A limit that IS asked for and that the kernel\n * refuses aborts with `ULIMIT_REFUSED_EXIT_CODE` instead of running unlimited. `ulimit -v` (address space) is not\n * attempted: toolchain.md §8 measured it failing outright on macOS (\"cannot modify limit: Invalid argument\"), so\n * `memoryBytes` is not enforced by this wrapper on any platform (SandboxCapabilities.memory stays `unavailable`).\n */\nexport function requestsAnyRlimit(limits: UlimitLimits): boolean {\n return (\n limits.cpuSeconds !== undefined ||\n limits.fileSizeBytes !== undefined ||\n limits.openFiles !== undefined ||\n limits.processes !== undefined\n );\n}\n\nexport function wrapWithUlimit(file: string, args: readonly string[], limits: UlimitLimits): WrappedCommand {\n return {\n file: ULIMIT_SHELL,\n args: [\n '-c',\n ULIMIT_WRAPPER_SCRIPT,\n file,\n toIntArg(limits.cpuSeconds),\n toBlockArg(limits.fileSizeBytes),\n toIntArg(limits.openFiles),\n toIntArg(limits.processes),\n ...args,\n ],\n };\n}\n","// The L0 isolated executor (DESIGN 2.6.6, ADR-0003). Every OS, pure Node: a verified cwd, an env built ONLY from\n// `ExecRequest.env`, a detached process-group kill tree with a post-run sweep, wall-clock and output-cap kills, and\n// the constant `ulimit` wrapper (I3). `fs`/`network` are recorded but not enforced here — that is L1 (U4.07); L0\n// is advisory filesystem isolation and no network isolation (DESIGN 0.3), which is exactly what `l0Capabilities`\n// reports.\n//\n// `ExecResult.outcome` describes how the EXECUTOR ended the process, never how the program judged itself: a\n// program that ran to completion is `'ok'` whatever its exit code (a non-zero exit is the caller's\n// `tool-terminal/nonzero-exit`, not this layer's business), and `'error'` is reserved for a run that produced no\n// usable process at all — an unverifiable cwd, a spawn failure, a rlimit the kernel refused.\nimport { spawn } from 'node:child_process';\nimport { realpathSync } from 'node:fs';\nimport { StringDecoder } from 'node:string_decoder';\nimport { type Clock, type Redactor, sha256Hex } from '@cohorte/base';\nimport type {\n ExecRequest,\n ExecResult,\n Executor,\n PidRegistry,\n SandboxBackend,\n SandboxCapabilities,\n} from '../contract/index.ts';\nimport { detectMissingL1Binaries, l0Capabilities, nativeShortfalls, resolveSandbox } from './capabilities.ts';\nimport {\n killGroup,\n killGroupMembers,\n processStartToken,\n sweepTracked,\n type TrackedDescendants,\n type TrackInterval,\n trackDescendants,\n} from './identity.ts';\nimport {\n isWrappableProgramPath,\n requestsAnyRlimit,\n ULIMIT_REFUSED_EXIT_CODE,\n unwrappableProgramNote,\n wrapWithUlimit,\n} from './ulimit.ts';\n\n/** Verified (toolchain.md §8: \"detached: true + negative-pid kill... put a timeout on stream draining as well\"). */\nconst GRACE_MS = 300;\nconst STREAM_DRAIN_TIMEOUT_MS = 500;\n/** 40 ms while the leader is young (an escapee must be seen before it is reaped), backing off after one second. */\nconst TRACK_INTERVAL: TrackInterval = { initialMs: 40, maxMs: 500, rampAfterMs: 1_000 };\nconst TAIL_MAX_CHARS = 64 * 1024;\n\nexport interface ExecutorOptions {\n /** chunks and the tail are sealed before they leave the executor (I7) */\n redactor: Redactor;\n pids: PidRegistry;\n clock: Clock;\n /** default: the `none` backend (L0). The L1 backends are injected by the composition root (U4.07). */\n backend?: SandboxBackend;\n}\n\n/** The built-in `none` `SandboxBackend`: wraps nothing, always reports the honest L0 level. */\nexport function createNoneBackend(): SandboxBackend {\n return {\n id: 'none',\n probe: () => Promise.resolve(l0Capabilities()),\n wrap: (file, args) => ({ file, args: [...args] }),\n };\n}\n\n/** The identity wrapper used whenever no L1 backend earned the reported guarantees. */\nconst NONE_BACKEND = createNoneBackend();\n\nfunction backendsFor(backend: SandboxBackend): readonly SandboxBackend[] {\n return backend.id === 'none' ? [] : [backend];\n}\n\n/**\n * DESIGN 2.6.6 / ADR-0003 §2b: \"`sandbox.require: native` is satisfied only by `enforced`: with a `partial`\n * backend the run refuses to start\". `level: 'L1-os'` alone is not enough — a backend whose escape self-test\n * (S-28 on macOS, S-29 on Linux) has not passed here reports `partial` on the axes that matter.\n */\nfunction satisfiesNative(guarantees: SandboxCapabilities): boolean {\n return (\n guarantees.level === 'L1-os' &&\n guarantees.filesystem === 'enforced' &&\n guarantees.network === 'enforced-off' &&\n guarantees.processEscape === 'denied'\n );\n}\n\n/**\n * DESIGN 2.6.6 L0 row: \"Filesystem and network isolation are advisory.\" The plan makes that explicit for the roots\n * a caller asked to be protected — `fs.readOnly` (the slot's dependency directories, DESIGN 5.7) and `fs.denyRead`\n * — by RECORDING them on the result rather than silently ignoring them: at L0 nothing enforces them, and U4.07 is\n * where these same roots become real. A request that asks for neither adds no note, so `ExecResult.guarantees`\n * still equals `probeSandbox()` for it.\n */\nfunction advisoryFsNotes(req: ExecRequest, guarantees: SandboxCapabilities): readonly string[] {\n if (guarantees.filesystem === 'enforced') return [];\n const parts: string[] = [];\n if (req.fs.readOnly.length > 0) parts.push(`readOnly: ${req.fs.readOnly.join(', ')}`);\n if (req.fs.denyRead.length > 0) parts.push(`denyRead: ${req.fs.denyRead.join(', ')}`);\n if (parts.length === 0) return [];\n return [\n `filesystem is '${guarantees.filesystem}' at this level: the requested roots are recorded but NOT enforced ` +\n `(${parts.join('; ')}) — an OS sandbox backend is what enforces them`,\n ];\n}\n\n/** `guarantees` plus the notes that describe THIS request; never the report cached for `capabilities()`. */\nfunction withNotes(guarantees: SandboxCapabilities, notes: readonly string[]): SandboxCapabilities {\n return notes.length === 0 ? guarantees : { ...guarantees, notes: [...guarantees.notes, ...notes] };\n}\n\n/** `req.cwd` must still refer to exactly what it claims to (defence against a TOCTOU swap between resolve and spawn). */\nfunction cwdVerifies(cwd: string): boolean {\n try {\n return realpathSync.native(cwd) === cwd;\n } catch {\n return false;\n }\n}\n\ntype EarlyOutcome = Extract<ExecResult['outcome'], 'sandbox-denied' | 'error' | 'killed'>;\n\nexport function createExecutor(options: ExecutorOptions): Executor {\n const backend = options.backend ?? NONE_BACKEND;\n const platform = process.platform;\n // What the last run observed about THIS MACHINE — `resolveSandbox`'s own report, never the per-request copy the\n // result carries (a `sandbox-denied` refusal or an advisory-filesystem record describes one call, not the\n // machine, and `capabilities()` is what `cohorte doctor --json` prints under \"sandbox\", DESIGN 2.6.6 [S]).\n let lastGuarantees: SandboxCapabilities | undefined;\n\n return {\n capabilities(): SandboxCapabilities {\n // Detection is synchronous and memoised (capabilities.ts), so a COLD `capabilities()` — called before any\n // `run()` or `probeSandbox()` — already reports the same `missing` as the probe, in the same tick.\n return lastGuarantees ?? l0Capabilities(detectMissingL1Binaries(platform));\n },\n run: async (req: ExecRequest, signal: AbortSignal): Promise<ExecResult> => {\n const run = await runOnce(options, backend, req, signal);\n lastGuarantees = run.observed;\n return run.result;\n },\n };\n}\n\n/**\n * `pgid: 0` is the \"nothing was spawned\" sentinel of every early return, NOT a process group: on POSIX `kill(-0)`\n * addresses the caller's own group, so `sweepGroupByToken`, `killGroup` and `killGroupMembers` all refuse a pgid\n * of 0 or 1 outright (identity.ts). A dependant must read it as \"no group\", never as one to sweep.\n */\nfunction emptyResult(\n outcome: EarlyOutcome,\n guarantees: SandboxCapabilities,\n redactor: Redactor,\n startedMonoMs: number,\n clock: Clock,\n): ExecResult {\n return {\n exitCode: null,\n outcome,\n tail: redactor.sealText('').text,\n outputSha256: sha256Hex(''),\n outputBytes: 0,\n truncated: false,\n durationMs: clock.monotonicMs() - startedMonoMs,\n pgid: 0,\n startToken: '',\n escapees: 0,\n guarantees,\n };\n}\n\n/** What one call produced: the result handed to the caller, and what it OBSERVED about the machine (`capabilities()`). */\ninterface RunOutput {\n result: ExecResult;\n observed: SandboxCapabilities;\n}\n\nasync function runOnce(\n options: ExecutorOptions,\n backend: SandboxBackend,\n req: ExecRequest,\n signal: AbortSignal,\n): Promise<RunOutput> {\n const platform = process.platform;\n const startedMonoMs = options.clock.monotonicMs();\n const resolved = await resolveSandbox(backendsFor(backend), platform);\n const observed = resolved.capabilities;\n // Everything below reports on THIS REQUEST; `observed` stays the untouched machine report.\n const guarantees = withNotes(observed, advisoryFsNotes(req, observed));\n const early = (outcome: EarlyOutcome, notes: readonly string[] = []): RunOutput => ({\n result: emptyResult(outcome, withNotes(guarantees, notes), options.redactor, startedMonoMs, options.clock),\n observed,\n });\n\n if (req.require === 'native' && !satisfiesNative(observed)) {\n // DESIGN 2.6.6: the refusal NAMES the failing axes rather than handing the caller a bare enum; minted from the\n // same `nativeShortfalls` that `sandboxUnavailable()` (exec/index.ts) turns into the catalogued error's message.\n return early('sandbox-denied', nativeShortfalls(observed, platform));\n }\n // A signal aborted BEFORE the spawn is a cancellation ('killed'), never `error` — `error` is reserved for a run\n // that could not produce a usable process (an unverifiable cwd, a spawn failure, a refused rlimit; R3).\n if (signal.aborted) return early('killed');\n if (!cwdVerifies(req.cwd)) return early('error');\n\n // The sandbox seam, applied by the backend that ACTUALLY earned `guarantees` (a backend whose probe failed is\n // used for neither). The `ulimit` wrapper goes OUTSIDE it, so the rlimits also cover the sandbox helper process\n // itself — a `sandbox-exec`/`bwrap` that forked without bound would otherwise escape `processes` before the real\n // program ever starts. DESIGN 2.6.6 does not fix the order; this is the choice, and `wrap()` is pure, so it is\n // free to be composed either way.\n const outer = (resolved.backend ?? NONE_BACKEND).wrap(req.file, req.args, req);\n // The `ulimit` wrapper exists to APPLY rlimits; a request that asks for none has nothing for it to do, and going\n // through it anyway would buy a shell process and its `/usr/bin/env` operand hazard for no guarantee at all. A\n // direct spawn is not a weaker path: there is still no shell, so I3 holds by construction, and with no shell\n // there is nothing to re-export `PWD`/`SHLVL` either, so S-20 holds trivially instead of by countermeasure.\n const wrapping = requestsAnyRlimit(req.limits);\n // Fail closed (I2) on the one program path the wrapper cannot carry: `/usr/bin/env` would read a path containing\n // `=` as a variable assignment and exec the next argv element — model-influenced text (I3) — in its place. The\n // refusal is scoped to the requests that actually need the wrapper: without it there is no `env` to be fooled,\n // and a worktree whose path contains `=` is not a reason to refuse every command (U1.04 request R4).\n if (wrapping && !isWrappableProgramPath(outer.file)) return early('error', [unwrappableProgramNote(outer.file)]);\n const launch = wrapping\n ? wrapWithUlimit(outer.file, outer.args, req.limits)\n : { file: outer.file, args: [...outer.args] };\n const child = spawn(launch.file, launch.args, {\n cwd: req.cwd,\n // Built ONLY from `req.env`: `process.env` is never read, never merged (S-20).\n env: { ...req.env },\n detached: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n // `child.pid` is set synchronously when the spawn succeeded, and `undefined` when it did not.\n const leaderPid = child.pid;\n\n // ---------------------------------------------------------------------------------------------------------\n // Everything the child can emit is wired HERE, before the first `await`. That is not style, it is correctness:\n // Node delivers `'exit'` once, to whoever is listening when the child is reaped, and a `stdout` that was never\n // resumed is thrown away when the process ends. A program faster than the `ps` fork of `processStartToken` below\n // — `/usr/bin/env`, `true`, anything tiny — is already gone by the time a listener added after an `await` exists:\n // measured on this machine, wiring the streams after that fork loses ALL of a fast program's output, and wiring\n // `'exit'` after it makes `await exited` wait for something that has already happened (the run then ends at its\n // own wall-clock timeout, or never, if the injected Clock ignores the timer's abort).\n // ---------------------------------------------------------------------------------------------------------\n let outcome: ExecResult['outcome'] = 'ok';\n let truncated = false;\n let totalBytes = 0;\n let rawTail = '';\n const chunks: Buffer[] = [];\n\n // One decoder per stream, kept across reads: a multi-byte UTF-8 sequence that straddles a pipe-read boundary\n // would otherwise be destroyed (U+FFFD) in both the text handed to the model and the accumulated tail. `chunks`\n // and `outputSha256` stay byte-based and are unaffected. A read that ends mid-sequence decodes to '' and is\n // still reported, so `bytes` stays an exact account of what was read.\n const decoders: Record<'stdout' | 'stderr', StringDecoder> = {\n stdout: new StringDecoder('utf8'),\n stderr: new StringDecoder('utf8'),\n };\n\n const sealChunk = (stream: 'stdout' | 'stderr', bytes: Buffer): void => {\n const text = decoders[stream].write(bytes);\n rawTail = (rawTail + text).slice(-TAIL_MAX_CHARS);\n req.onChunk?.({ stream, bytes: bytes.length, text: options.redactor.sealText(text).text });\n };\n\n let escalation: Promise<void> | undefined;\n const escalate = (why: ExecResult['outcome']): void => {\n // No pid means the spawn failed; the early return below is that call's whole story.\n if (escalation !== undefined || leaderPid === undefined) return;\n outcome = why;\n escalation = killGroup(leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n };\n\n const onData =\n (stream: 'stdout' | 'stderr') =>\n (chunk: Buffer): void => {\n if (truncated) return;\n let bytes = chunk;\n if (totalBytes + bytes.length > req.maxOutputBytes) {\n const room = Math.max(0, req.maxOutputBytes - totalBytes);\n bytes = bytes.subarray(0, room);\n truncated = true;\n }\n if (bytes.length > 0) {\n totalBytes += bytes.length;\n chunks.push(Buffer.from(bytes));\n sealChunk(stream, bytes);\n }\n if (truncated) escalate('output-capped');\n };\n child.stdout?.on('data', onData('stdout'));\n child.stderr?.on('data', onData('stderr'));\n\n let exitCode: number | null = null;\n let exitSignal: string | undefined;\n const exited = new Promise<void>((resolve) => {\n child.once('exit', (code, sig) => {\n exitCode = code;\n exitSignal = sig ?? undefined;\n resolve();\n });\n });\n\n const spawnOutcome = await new Promise<'spawned' | 'error'>((resolve) => {\n child.once('spawn', () => resolve('spawned'));\n child.once('error', () => resolve('error'));\n });\n if (spawnOutcome === 'error' || leaderPid === undefined) return early('error');\n // A later 'error' (e.g. an EPIPE after the child is gone) would otherwise throw, unhandled, once the `once`\n // listener above has fired and been removed.\n child.on('error', () => {});\n // Computed and recorded NOW, while the leader is still alive: `ps -o lstart=` (or /proc/.../stat) needs a live\n // pid, and a crash between here and exit must still leave a recoverable (pgid, startToken) trace (DESIGN 4.4).\n // A program that beat this fork to its own exit simply has no token: `unknown:<pid>` says so rather than\n // inventing one, and `sweepGroupByToken` verifies nothing against it (identity.ts).\n const startToken = (await processStartToken(leaderPid, platform)) ?? `unknown:${leaderPid}`;\n options.pids.record({ pgid: leaderPid, startToken, label: req.file });\n\n // `pid -> start time as first seen`: the sweep signals a tracked pid only while it is still that same process.\n const escapeesSeen: TrackedDescendants = new Map<number, string>();\n const trackingTask = trackDescendants(\n leaderPid,\n escapeesSeen,\n exited,\n (ms) => options.clock.sleep(ms),\n TRACK_INTERVAL,\n );\n\n // `outcome` may never depend on a Clock honouring an OPTIONAL argument: `Clock.sleep(ms, signal?)` (@cohorte/base\n // ports.ts) leaves the signal optional, so a perfectly conforming clock that ignores it would otherwise make every\n // run report `timed-out` for a program that exited in milliseconds. `finished` is the correctness condition; the\n // abort below stays what it always was — the optimisation that stops the timer early.\n let finished = false;\n const timeoutAbort = new AbortController();\n const timeoutTask = options.clock\n .sleep(req.timeoutMs, timeoutAbort.signal)\n .then(() => {\n if (!finished) escalate('timed-out');\n })\n .catch(() => {\n // Aborted because the process already ended, or the caller cancelled: nothing to do.\n });\n\n const onExternalAbort = (): void => escalate('killed');\n if (!signal.aborted) signal.addEventListener('abort', onExternalAbort, { once: true });\n\n await exited;\n finished = true;\n timeoutAbort.abort();\n signal.removeEventListener('abort', onExternalAbort);\n await timeoutTask;\n await trackingTask;\n if (escalation) await escalation;\n // Safety net: whatever ended the wait, make sure nothing of the group is left running. The leader has been\n // reaped by now, so `kill(-leaderPid)` is no longer addressable to a group we can prove is ours — this walks\n // the process table and signals only the pids still IN the group (DESIGN 4.4 step 5). `GRACE_MS`, like every\n // other kill path here: DESIGN 2.6.6 says TERM -> grace -> KILL, and a leftover grandchild of a command that\n // ended NORMALLY is the case that most deserves its chance to flush and exit on the TERM. It costs nothing when\n // the group is already empty — the grace is only waited when something was actually signalled (identity.ts).\n await killGroupMembers(leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n\n await drainStreams(child, (ms) => options.clock.sleep(ms).catch(() => {}));\n // Flush whatever incomplete sequence the decoders still hold; only the tail can still take it.\n const flushed = decoders.stdout.end() + decoders.stderr.end();\n if (flushed !== '') rawTail = (rawTail + flushed).slice(-TAIL_MAX_CHARS);\n\n const escapees = await sweepTracked(escapeesSeen, leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n options.pids.remove(leaderPid);\n\n // A rlimit the kernel refused: the wrapper aborted before `exec`, so no program ever ran. It is the ONE exit\n // code the wrapper mints itself, and it always comes with no output at all (the shell's own diagnostics are\n // discarded, and its `exec` failures write to stderr first), so this cannot swallow a program's own 126.\n if (outcome === 'ok' && exitCode === ULIMIT_REFUSED_EXIT_CODE && totalBytes === 0 && requestsAnyRlimit(req.limits)) {\n outcome = 'error';\n }\n\n const output = Buffer.concat(chunks);\n const sealedTail = options.redactor.sealText(rawTail).text;\n const durationMs = options.clock.monotonicMs() - startedMonoMs;\n\n return {\n result: {\n exitCode,\n outcome,\n tail: sealedTail,\n outputSha256: sha256Hex(output),\n outputBytes: totalBytes,\n truncated,\n durationMs,\n pgid: leaderPid,\n startToken,\n escapees,\n guarantees,\n ...(exitSignal !== undefined ? { signal: exitSignal } : {}),\n },\n observed,\n };\n}\n\nasync function drainStreams(child: ReturnType<typeof spawn>, wait: (ms: number) => Promise<void>): Promise<void> {\n const closed = Promise.all(\n [child.stdout, child.stderr].map(\n (stream) =>\n new Promise<void>((resolve) => {\n if (!stream || stream.destroyed) {\n resolve();\n return;\n }\n stream.once('close', () => resolve());\n }),\n ),\n );\n let timedOut = false;\n await Promise.race([\n closed.then(() => {}),\n wait(STREAM_DRAIN_TIMEOUT_MS).then(() => {\n timedOut = true;\n }),\n ]);\n if (timedOut) {\n child.stdout?.destroy();\n child.stderr?.destroy();\n }\n}\n","// The L0 isolated executor and the sandbox capability probe (PLAN U1.04, DESIGN 2.6.6, ADR-0003).\nimport type { SandboxBackend, SandboxCapabilities } from '../contract/index.ts';\nimport { computeCapabilities } from './capabilities.ts';\n\nexport { nativeShortfalls, sandboxUnavailable } from './capabilities.ts';\nexport { createExecutor, createNoneBackend, type ExecutorOptions } from './executor.ts';\nexport { processStartToken, type SweepByTokenOptions, type SweepByTokenResult, sweepGroupByToken } from './identity.ts';\nexport {\n isWrappableProgramPath,\n type UlimitLimits,\n type WrappedCommand,\n wrapWithUlimit,\n} from './ulimit.ts';\n\nexport interface ProbeSandboxOptions {\n /** the L1 backends to probe, in order of preference; none usable = L0 is reported, honestly */\n backends?: readonly SandboxBackend[];\n platform?: string;\n}\n\n/**\n * `cohorte doctor --json`'s \"sandbox\" section (spec 9 \"garanties réellement actives\"). Until U4.07 constructs a\n * real Seatbelt/bubblewrap `SandboxBackend`, this always reports the honest L0 level: the L1 binaries this machine\n * happens to have installed are detected only for `missing`/`notes`, never used to widen the claimed guarantees.\n */\nexport function probeSandbox(options: ProbeSandboxOptions = {}): Promise<SandboxCapabilities> {\n return computeCapabilities(options.backends ?? [], options.platform ?? process.platform);\n}\n","// The only module allowed to mint the compile-time Sealed<T> marker.\nimport type { JsonValue, Redaction, Sealed, SealedText } from '@cohorte/base';\n\nexport function sealText(text: string, redactions: Redaction[]): { text: SealedText; redactions: Redaction[] } {\n return { text: text as SealedText, redactions };\n}\n\nexport function sealJson<T extends JsonValue>(\n value: T,\n redactions: Redaction[],\n): { value: Sealed<T>; redactions: Redaction[] } {\n return { value: value as Sealed<T>, redactions };\n}\n","// Secret registration, recursive sealing and commit-time detectors.\nimport { type JsonValue, type Redaction, type Redactor, type Sealed, type SealedText, sha256Hex } from '@cohorte/base';\nimport { sealJson, sealText } from './seal.ts';\n\nexport interface RedactorOptions {\n /** values learned before the run starts (the dotenv files the run could see), by id */\n secrets?: Readonly<Record<string, string>>;\n}\n\nconst replacement = '[REDACTED]';\nconst escapePointerToken = (token: string): string => token.replaceAll('~', '~0').replaceAll('/', '~1');\n\nfunction scrub(\n text: string,\n path: string,\n secrets: readonly { value: string; id: string }[],\n redactions: Redaction[],\n): string {\n let result = text;\n for (const { value, id } of secrets) {\n if (result.includes(value)) {\n result = result.split(value).join(replacement);\n redactions.push({ path, reason: 'secret-value', detector: `registered:${id}` });\n }\n }\n return result;\n}\n\nexport function createRedactor(options: RedactorOptions = {}): Redactor {\n const secrets: Array<{ value: string; id: string }> = [];\n for (const [id, value] of Object.entries(options.secrets ?? {})) {\n if (value.length >= 8) secrets.push({ value, id });\n }\n secrets.sort((a, b) => b.value.length - a.value.length);\n const walk = (value: JsonValue, path: string, redactions: Redaction[]): JsonValue => {\n if (typeof value === 'string') return scrub(value, path, secrets, redactions);\n if (Array.isArray(value)) return value.map((item, index) => walk(item, `${path}/${index}`, redactions));\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, walk(item, `${path}/${escapePointerToken(key)}`, redactions)]),\n );\n }\n return value;\n };\n return {\n registerSecret(value, id): void {\n if (value.length < 8)\n throw new RangeError('registerSecret: a secret value shorter than 8 characters is rejected');\n secrets.push({ value, id });\n secrets.sort((a, b) => b.value.length - a.value.length);\n },\n sealText(text): { text: SealedText; redactions: Redaction[] } {\n const redactions: Redaction[] = [];\n return sealText(scrub(text, '', secrets, redactions), redactions);\n },\n sealJson<T extends JsonValue>(value: T): { value: Sealed<T>; redactions: Redaction[] } {\n const redactions: Redaction[] = [];\n return sealJson(walk(value, '', redactions) as T, redactions);\n },\n };\n}\n\n/** The commit-time secret scan (DESIGN 5.3): path classes + the Redactor's detectors over staged content. */\nexport function scanForSecrets(bytes: Uint8Array, path: string): Redaction[] {\n const redactions: Redaction[] = [];\n const digest = sha256Hex(bytes);\n const text = new TextDecoder().decode(bytes);\n const add = (reason: Redaction['reason'], detector: string): void => {\n redactions.push({ path: '', reason, detector, sha256: digest });\n };\n if (bytes.byteLength > 10 * 1024 * 1024) add('size', 'size:10MiB');\n if (/(^|[/\\\\])(?:\\.env|.*\\.pem|.*\\.key)$/i.test(path)) add('sensitive-path', 'path:secret-file');\n if (/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/.test(text)) add('private-key', 'pattern:private-key');\n if (/(?:AKIA|ASIA)[A-Z0-9]{16}/.test(text)) add('secret-pattern', 'pattern:aws-access-key');\n if (/(?:ghp|github_pat)_[A-Za-z0-9_]{20,}/.test(text)) add('secret-pattern', 'pattern:github-token');\n if (/sk-[A-Za-z0-9]{20,}/.test(text)) add('secret-pattern', 'pattern:openai-key');\n return redactions;\n}\n","// Frozen built-in DATA (DESIGN 2.6.3 step 5, 2.6.4, 2.6.6; PLAN F-8). None of it is overridable: no project config\n// and no approval lifts a protected root, a trampoline or the agent git deny set.\n\nconst frozen = <const T extends readonly string[]>(values: T): T => Object.freeze(values);\n\n/** Worktree-relative, any depth: `.git` (file OR directory), Cohorte's own directory, Pi's project directory. */\nexport const PROTECTED_REPO_GLOBS = frozen(['**/.git', '**/.git/**', '**/.cohorte/**', '**/.pi/**']);\n\n/**\n * Relative to the user's HOME; the caller canonicalises them into `PathResolverOptions.protectedRoots`, together with\n * Cohorte's install dir, every pinned runtime artifact and the node binary dir. `~/.cohorte/worktrees` is deliberately\n * ABSENT (DESIGN 5.1): agent worktrees live there.\n */\nexport const PROTECTED_HOME_PATHS = frozen([\n '.cohorte/keys',\n '.cohorte/versions',\n '.cohorte/pi-agent',\n '.cohorte/brains',\n '.cohorte/trust',\n '.cohorte/config.yaml',\n '.pi/agent',\n '.ssh',\n '.aws',\n '.gnupg',\n '.config/gh',\n '.config/gcloud',\n]);\n\n/** HOME-relative read denials of every L1 profile (DESIGN 2.6.6); the caller adds the project's state dir. */\nexport const L1_DENY_READ_HOME_PATHS = frozen([\n '.pi/agent',\n '.cohorte/keys',\n '.cohorte/versions',\n '.cohorte/pi-agent',\n '.cohorte/brains',\n '.cohorte/trust',\n '.ssh',\n '.aws',\n '.gnupg',\n '.config/gh',\n '.config/gcloud',\n]);\n\n/** The default `denyRead` / `denyWrite` of every AgentGrant (DESIGN 2.6.1). Deny sets always win. */\nexport const DEFAULT_DENY_GLOBS = frozen([\n '**/.env*',\n '**/*.pem',\n '**/*.key',\n '**/id_rsa*',\n '**/id_ed25519*',\n '**/.git',\n '**/.git/**',\n '**/.cohorte/**',\n '**/.pi/**',\n '**/.npmrc',\n '**/.netrc',\n]);\n\n/**\n * Programs that run OTHER programs or reach the network: denied with `overridable: false` (DESIGN 2.6.4 step 2).\n * `pi` and `cohorte` are in it: Pi has an `auth` subcommand that prints the OAuth token. A project that truly needs one\n * declares an exact-argv rule under `policy.dangerousCommands`, and every use is an `ask`.\n */\nexport const TRAMPOLINE_PROGRAMS = frozen([\n 'sh',\n 'bash',\n 'zsh',\n 'dash',\n 'fish',\n 'ksh',\n 'csh',\n 'env',\n 'xargs',\n 'sudo',\n 'su',\n 'doas',\n 'eval',\n 'exec',\n 'nohup',\n 'time',\n 'watch',\n 'npx',\n 'pnpx',\n 'bunx',\n 'corepack',\n 'ssh',\n 'scp',\n 'curl',\n 'wget',\n 'nc',\n 'perl',\n 'ruby',\n 'osascript',\n 'pi',\n 'cohorte',\n]);\n\n/** `python*`: python, python3, python3.12, pythonw ... */\nexport const TRAMPOLINE_PREFIXES = frozen(['python']);\n\nconst TRAMPOLINES: ReadonlySet<string> = new Set(TRAMPOLINE_PROGRAMS);\n\n/** `name` is the alias-normalised BARE program name; the comparison is exact-case (the name was resolved on disk first). */\nexport function isTrampoline(name: string): boolean {\n return TRAMPOLINES.has(name) || TRAMPOLINE_PREFIXES.some((prefix) => name.startsWith(prefix));\n}\n\n/** Agents have no commit capability (D9): commits and merges are Cohorte's. Built-in, non-overridable. */\nexport const AGENT_GIT_DENIED_SUBCOMMANDS = frozen([\n 'commit',\n 'push',\n 'merge',\n 'rebase',\n 'reset',\n 'checkout',\n 'switch',\n 'worktree',\n 'config',\n 'update-ref',\n 'filter-branch',\n 'gc',\n]);\n\n/** The NAMES an L0 child env may carry (DESIGN 2.6.6). Built from scratch, never inherited. */\nexport const L0_ENV_ALLOWLIST = frozen([\n 'PATH',\n 'HOME',\n 'LANG',\n 'LC_ALL',\n 'TERM',\n 'CI',\n 'TMPDIR',\n 'NO_COLOR',\n 'GIT_CONFIG_GLOBAL',\n 'GIT_CONFIG_NOSYSTEM',\n 'GIT_TERMINAL_PROMPT',\n]);\n\n/** The allowlisted names whose VALUE is fixed; PATH (pinned), HOME and TMPDIR (per-agent scratch), LANG and LC_ALL come from the run. */\nexport const L0_ENV_FIXED: Readonly<Record<string, string>> = Object.freeze({\n TERM: 'dumb',\n CI: '1',\n NO_COLOR: '1',\n GIT_CONFIG_GLOBAL: '/dev/null',\n GIT_CONFIG_NOSYSTEM: '1',\n GIT_TERMINAL_PROMPT: '0',\n});\n\n/**\n * What \"env contains only the allowlist\" means, defined once: visible ⊆ allow ∪ OS_INJECTED_ENV[platform].\n * CoreFoundation injects `__CF_USER_TEXT_ENCODING` into every macOS process (PLAN F-8). Mirrored, value for value, by\n * `@cohorte/runtime-pi/host-protocol`, which may not import this package.\n */\nexport const OS_INJECTED_ENV: Readonly<Record<string, readonly string[]>> = Object.freeze({\n darwin: Object.freeze(['__CF_USER_TEXT_ENCODING']),\n});\n\n/** The env names a child may legitimately SEE on this platform, given what it was allowed. */\nexport function visibleEnvAllowed(allow: readonly string[], platform: string): ReadonlySet<string> {\n return new Set([...allow, ...(OS_INJECTED_ENV[platform] ?? [])]);\n}\n","// Decisions, verdicts, grants and the pure engine (DESIGN 2.6.1, 2.6.2).\nimport {\n AgentId,\n ApprovalId,\n type BudgetCounters,\n type Clock,\n type JsonValue,\n JsonValueSchema,\n type RunId,\n Sha256,\n type ToolCallId,\n} from '@cohorte/base';\nimport { CommandRule, type NetworkPolicyConfig, type Ownership } from '@cohorte/config/schema';\nimport { type TUnsafe, Type } from 'typebox';\nimport type { CommandPolicy, ProgramResolver } from './commands.ts';\nimport type { CanonicalPath, PathIntent, PathResolver, ResolvedPath, SymlinkPolicy } from './paths.ts';\n\n/**\n * Spec 9, exactly. The pure engine returns allow | deny | ask. allow-once / allow-for-run are APPROVAL RESOLUTIONS:\n * rows in `approvals`, found by grantKey at stage 6, reported in the verdict with the approvalId so the audit trail\n * says WHY. An `ask` nobody can answer becomes `deny`: an unanswerable ask never silently runs.\n */\nexport const POLICY_DECISIONS = ['allow', 'deny', 'ask', 'allow-once', 'allow-for-run'] as const;\nexport type PolicyDecision = (typeof POLICY_DECISIONS)[number];\n\nexport const GATE_STAGE_NAMES = [\n 'liveness',\n 'schema',\n 'capability',\n 'path',\n 'command',\n 'network',\n 'budget',\n 'approval',\n] as const;\nexport type GateStageName = (typeof GATE_STAGE_NAMES)[number];\n\nexport interface GateCall {\n runId: RunId;\n agentId: AgentId;\n incarnation: number;\n toolCallId: ToolCallId;\n tool: string;\n input: JsonValue;\n phase: string;\n role: string;\n}\n\nexport interface GlobSet {\n include: string[];\n exclude: string[];\n}\n\n/**\n * THE glob semantics of 2.6.3 step 7, implemented once (decide/paths) and exported as a contract so `tools`\n * (list_files, search, git_diff output filtering, WorkspaceReader) and `core` (grants, zones) never configure\n * picomatch themselves. `toExcludeArgs` renders a deny set for an external enumerator.\n */\nexport interface GlobMatcher {\n matches(relativePosixPath: string, set: GlobSet): boolean;\n isDenied(relativePosixPath: string, grant: AgentGrant, intent: 'read' | 'write'): boolean;\n toExcludeArgs(set: GlobSet, dialect: 'rg-glob' | 'git-pathspec'): string[];\n}\n\nexport interface NormalizedCall {\n tool: string;\n paths: { arg: string; resolved: ResolvedPath; intent: PathIntent }[];\n command?: {\n file: CanonicalPath;\n args: string[];\n cwd: CanonicalPath;\n ruleId: string;\n replay: 'idempotent' | 'at-most-once';\n network: boolean;\n timeoutMs: number;\n };\n /** strictly validated, size-capped */\n input: JsonValue;\n /** canonical subject used for grant_key (DESIGN 4.5) */\n grantKeyMaterial: JsonValue;\n}\n\n/** facts pre-fetched; sync */\nexport interface BranchResolver {\n branchOf(\n cwd: CanonicalPath,\n ): { kind: 'branch'; name: string; protected: boolean } | { kind: 'detached-or-unknown'; protected: true };\n}\n\nexport interface BudgetReader {\n remaining(level: 'run' | 'phase' | 'agent' | 'provider' | 'tool', id: string): BudgetCounters;\n callsInLastMinute(agentId: AgentId, tool: string): number;\n}\n\n/** every verdict is schema-valid */\nexport interface PolicyVerdict {\n decision: PolicyDecision;\n stage: GateStageName;\n ruleId: string;\n /** humans / events */\n reason: string;\n /** no secrets, no absolute host paths, no policy internals; ends with \"Do not retry.\" for deny */\n modelFacingReason: string;\n /** false = built-in rule that no project config and no approval can lift */\n overridable: boolean;\n /** true => run goes BLOCKED (spec 24): symlink escape, protected path write, runtime path, MAC failure… */\n securityViolation: boolean;\n asks: { stage: GateStageName; ruleId: string; reason: string }[];\n /** every rule id evaluated, for `cohorte policy explain` and the audit event */\n evaluatedRules: string[];\n /** what will actually execute: canonical paths, resolved program realpath, clamped timeout, replay class */\n normalized: NormalizedCall | null;\n approvalId?: ApprovalId;\n grantId?: string;\n}\n\n/** computed by core from ownership.yaml + role defaults + phase contract; persisted in agents.grants_json */\nexport interface AgentGrant {\n agentId: AgentId;\n role: string;\n digest: Sha256;\n tools: string[];\n roots: { workspace: CanonicalPath | null; readOnly: CanonicalPath[] };\n read: GlobSet;\n /** write ⊆ owned paths of the surface; worktree-relative POSIX, dot:true, slash-less pattern means any depth */\n write: GlobSet;\n /** always win. Defaults: DEFAULT_DENY_GLOBS */\n denyRead: GlobSet;\n denyWrite: GlobSet;\n commands: CommandPolicy;\n /** ids only; values resolved inside the Executor and registered with the Redactor first */\n secrets: { id: string; exposeAs: 'env'; name: string }[];\n /** spec 8 \"grant temporaire audité\" */\n temporary: { grantId: string; approvalId: ApprovalId; grantKey: string; expires: 'call' | 'run' }[];\n limits: {\n maxToolCalls: number;\n maxCallsPerMinute: number;\n perTool: Record<string, { maxCalls?: number; timeoutMs: number; maxOutputBytes: number }>;\n };\n}\n\n/** all SYNCHRONOUS */\nexport interface PolicyPorts {\n paths: PathResolver;\n branches: BranchResolver;\n budgets: BudgetReader;\n programs: ProgramResolver;\n clock: Clock;\n}\n\n/** deterministic => table-testable */\nexport interface PolicyEngine {\n evaluate(call: GateCall, grant: AgentGrant, policy: PolicySnapshot, ports: PolicyPorts): PolicyVerdict;\n}\n\n/** Immutable, hashed, built from the RESOLVED config at run start and held in host memory (I4): the project file is never re-read. */\nexport interface PolicySnapshot {\n readonly digest: Sha256;\n /** `policy.commands.*`, `policy.dangerousCommands` (always `ask`) and `checks.*` (exact argv, idempotent), as one rule list */\n readonly commands: CommandPolicy;\n readonly symlinks: SymlinkPolicy;\n readonly network: NetworkPolicyConfig;\n readonly protectedBranches: readonly string[];\n /** for the `shared` / `approval: human` asks of stage 3 (DESIGN 5.6) */\n readonly ownership: Ownership;\n /** under L0 a rule flagged `network` is DENIED, not asked (DESIGN 2.6.6) */\n readonly sandboxLevel: 'L0-process' | 'L1-os';\n}\n\n/** So that stages 1 and 3 validate a call without importing `tools` (PLAN PC-4). Implemented from the tool catalogue. */\nexport interface ToolIntrospection {\n /** the STRICT JSON Schema of the tool's input; undefined = unknown tool */\n schemaOf(tool: string): JsonValue | undefined;\n /** every path-typed argument of this input, with what the tool does to it */\n pathArgsOf(tool: string, input: JsonValue): { arg: string; value: string; intent: PathIntent }[];\n}\n\nconst closed = { additionalProperties: false } as const;\nconst oneOf = <const V extends readonly string[]>(values: V): TUnsafe<V[number]> =>\n Type.Unsafe<V[number]>({ type: 'string', enum: [...values] });\nconst count = () => Type.Integer({ minimum: 0 });\nconst canonicalPath = () => Type.String({ minLength: 1 });\nconst replay = () => oneOf(['idempotent', 'at-most-once']);\nconst globSet = () => Type.Object({ include: Type.Array(Type.String()), exclude: Type.Array(Type.String()) }, closed);\n\nconst ResolvedPathSchema = Type.Object(\n {\n canonical: canonicalPath(),\n relative: Type.String(),\n root: canonicalPath(),\n exists: Type.Boolean(),\n identity: Type.Optional(Type.Object({ dev: Type.Number(), ino: Type.Number(), nlink: Type.Number() }, closed)),\n viaSymlink: Type.Boolean(),\n },\n closed,\n);\n\nconst NormalizedCallSchema = Type.Object(\n {\n tool: Type.String(),\n paths: Type.Array(\n Type.Object(\n {\n arg: Type.String(),\n resolved: ResolvedPathSchema,\n intent: oneOf(['read', 'write', 'create', 'list', 'exec-cwd']),\n },\n closed,\n ),\n ),\n command: Type.Optional(\n Type.Object(\n {\n file: canonicalPath(),\n args: Type.Array(Type.String()),\n cwd: canonicalPath(),\n ruleId: Type.String(),\n replay: replay(),\n network: Type.Boolean(),\n timeoutMs: count(),\n },\n closed,\n ),\n ),\n input: JsonValueSchema,\n grantKeyMaterial: JsonValueSchema,\n },\n closed,\n);\n\nconst ask = () => Type.Object({ stage: oneOf(GATE_STAGE_NAMES), ruleId: Type.String(), reason: Type.String() }, closed);\n\n/** [S] */\nexport const PolicyVerdict: TUnsafe<PolicyVerdict> = Type.Unsafe<PolicyVerdict>(\n Type.Object(\n {\n decision: oneOf(POLICY_DECISIONS),\n stage: oneOf(GATE_STAGE_NAMES),\n ruleId: Type.String({ minLength: 1 }),\n reason: Type.String(),\n modelFacingReason: Type.String(),\n overridable: Type.Boolean(),\n securityViolation: Type.Boolean(),\n asks: Type.Array(ask()),\n evaluatedRules: Type.Array(Type.String()),\n normalized: Type.Union([NormalizedCallSchema, Type.Null()]),\n approvalId: Type.Optional(ApprovalId),\n grantId: Type.Optional(Type.String()),\n },\n closed,\n ),\n);\n\n/** [S] */\nexport const AgentGrant: TUnsafe<AgentGrant> = Type.Unsafe<AgentGrant>(\n Type.Object(\n {\n agentId: AgentId,\n role: Type.String({ minLength: 1 }),\n digest: Sha256,\n tools: Type.Array(Type.String()),\n roots: Type.Object(\n { workspace: Type.Union([canonicalPath(), Type.Null()]), readOnly: Type.Array(canonicalPath()) },\n closed,\n ),\n read: globSet(),\n write: globSet(),\n denyRead: globSet(),\n denyWrite: globSet(),\n commands: Type.Object({ default: Type.Literal('deny'), rules: Type.Array(CommandRule) }, closed),\n secrets: Type.Array(\n Type.Object({ id: Type.String(), exposeAs: Type.Literal('env'), name: Type.String() }, closed),\n ),\n temporary: Type.Array(\n Type.Object(\n { grantId: Type.String(), approvalId: ApprovalId, grantKey: Type.String(), expires: oneOf(['call', 'run']) },\n closed,\n ),\n ),\n limits: Type.Object(\n {\n maxToolCalls: count(),\n maxCallsPerMinute: count(),\n perTool: Type.Record(\n Type.String(),\n Type.Object({ maxCalls: Type.Optional(count()), timeoutMs: count(), maxOutputBytes: count() }, closed),\n ),\n },\n closed,\n ),\n },\n closed,\n ),\n);\n","// Executor and sandbox levels (DESIGN 2.6.6, ADR-0003).\nimport type { SealedText, Sha256 } from '@cohorte/base';\nimport { type TUnsafe, Type } from 'typebox';\nimport type { CanonicalPath } from './paths.ts';\n\nexport interface ExecRequest {\n /** resolved program; NEVER a shell line */\n file: CanonicalPath;\n args: readonly string[];\n cwd: CanonicalPath;\n /** complete; the executor never reads process.env */\n env: Readonly<Record<string, string>>;\n fs: { readWrite: CanonicalPath[]; readOnly: CanonicalPath[]; denyRead: CanonicalPath[] };\n /** 'unrestricted' is legal ONLY for Cohorte-run provisioning effects (DESIGN 5.7), never for an agent call */\n network: 'none' | 'unrestricted';\n timeoutMs: number;\n maxOutputBytes: number;\n stdin: 'ignore';\n limits: { cpuSeconds?: number; fileSizeBytes?: number; openFiles?: number; processes?: number; memoryBytes?: number };\n require: 'native' | 'best-effort';\n onChunk?: (c: { stream: 'stdout' | 'stderr'; bytes: number; text: SealedText }) => void;\n}\n\nexport interface ExecResult {\n exitCode: number | null;\n signal?: string;\n outcome: 'ok' | 'error' | 'timed-out' | 'killed' | 'output-capped' | 'sandbox-denied';\n tail: SealedText;\n outputSha256: Sha256;\n outputBytes: number;\n truncated: boolean;\n fullOutputPath?: string;\n durationMs: number;\n pgid: number;\n startToken: string;\n /** processes that left the group, found by the post-run sweep */\n escapees: number;\n guarantees: SandboxCapabilities;\n}\n\n/** argv only: there is no `run(commandLine: string)` and there never will be (I3). */\nexport interface Executor {\n capabilities(): SandboxCapabilities;\n run(req: ExecRequest, signal: AbortSignal): Promise<ExecResult>;\n}\n\nexport interface SandboxBackend {\n readonly id: 'seatbelt' | 'bubblewrap' | 'none';\n probe(): Promise<SandboxCapabilities>;\n /** pure */\n wrap(file: CanonicalPath, args: readonly string[], req: ExecRequest): { file: CanonicalPath; args: string[] };\n}\n\n/**\n * Exactly what `cohorte doctor --json` prints under \"sandbox\" (spec 9 \"garanties réellement actives\").\n * 'partial': the backend is active but its escape self-test (S-28 on macOS, S-29 on Linux) has not passed here.\n */\nexport interface SandboxCapabilities {\n level: 'L0-process' | 'L1-os';\n backend: 'none' | 'seatbelt' | 'bubblewrap';\n filesystem: 'enforced' | 'partial' | 'advisory';\n network: 'enforced-off' | 'partial' | 'unenforced';\n /** LaunchServices / AppleEvents / job creation / signalling other processes / host Unix sockets */\n processEscape: 'denied' | 'partial' | 'possible';\n envFiltering: 'enforced';\n timeout: 'enforced';\n outputCap: 'enforced';\n cpuTime: 'enforced' | 'unavailable';\n memory: 'enforced' | 'node-only' | 'unavailable';\n processes: 'enforced' | 'unavailable';\n killTree: 'pid-namespace' | 'process-group-with-sweep';\n /** e.g. [\"bwrap\"], [\"kernel.apparmor_restrict_unprivileged_userns=1\"] */\n missing: string[];\n notes: string[];\n}\n\nconst oneOf = <const V extends readonly string[]>(values: V): TUnsafe<V[number]> =>\n Type.Unsafe<V[number]>({ type: 'string', enum: [...values] });\n\n/** [S]. Annotated so that Biome never infers it (docs/v3/requests/U0.02.md R1). */\nexport const SandboxCapabilities: TUnsafe<SandboxCapabilities> = Type.Unsafe<SandboxCapabilities>(\n Type.Object(\n {\n level: oneOf(['L0-process', 'L1-os']),\n backend: oneOf(['none', 'seatbelt', 'bubblewrap']),\n filesystem: oneOf(['enforced', 'partial', 'advisory']),\n network: oneOf(['enforced-off', 'partial', 'unenforced']),\n processEscape: oneOf(['denied', 'partial', 'possible']),\n envFiltering: Type.Literal('enforced'),\n timeout: Type.Literal('enforced'),\n outputCap: Type.Literal('enforced'),\n cpuTime: oneOf(['enforced', 'unavailable']),\n memory: oneOf(['enforced', 'node-only', 'unavailable']),\n processes: oneOf(['enforced', 'unavailable']),\n killTree: oneOf(['pid-namespace', 'process-group-with-sweep']),\n missing: Type.Array(Type.String()),\n notes: Type.Array(Type.String()),\n },\n { additionalProperties: false },\n ),\n);\n\n/** Where the L0 executor records what it spawned, so the post-run sweep and the Resumer can find processes that left the group. */\nexport interface PidRegistry {\n record(entry: { pgid: number; startToken: string; label: string }): void;\n remove(pgid: number): void;\n}\n","// DESIGN 2.2.6 — capabilities: honest, tri-state, doctor-reportable.\nimport { type Static, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\n\nexport const Cap = Type.Union([\n Type.Object({ value: Type.Literal('yes') }, strict),\n Type.Object({ value: Type.Literal('no'), why: Type.String() }, strict),\n Type.Object({ value: Type.Literal('partial'), why: Type.String() }, strict),\n]);\nexport type Cap = Static<typeof Cap>;\n\nexport const RuntimeCapabilities = Type.Object(\n {\n contractVersion: Type.Literal('1'),\n /** the only legal value (C1); present so conformance can assert it */\n toolExecution: Type.Literal('host-delegated'),\n streaming: Cap,\n thinkingStream: Cap,\n send: Type.Object({ steer: Cap, followUp: Cap }, strict),\n cancelCooperative: Cap,\n cancelHard: Cap,\n pause: Type.Object({ toolBoundary: Cap, modelBoundary: Cap }, strict),\n continuationFromTranscript: Cap,\n processIsolation: Cap,\n envFiltering: Cap,\n brainSandbox: Cap,\n resourceLimits: Cap,\n budgetEnforcement: Type.Object(\n { turns: Cap, modelRequests: Cap, tokens: Cap, context: Cap, wallClock: Cap, outputTokensPerRequest: Cap },\n strict,\n ),\n /** 'no' = none possible (compaction and engine retries off) */\n hiddenModelCalls: Cap,\n usageReporting: Cap,\n effectiveModelReporting: Cap,\n quotaReporting: Cap,\n authStatusWithoutSecret: Cap,\n subscriptionModeAssertion: Cap,\n systemPromptExact: Cap,\n runtimePinning: Cap,\n platforms: Type.Object({ darwin: Cap, linux: Cap, win32: Cap }, strict),\n hints: Type.Object(\n {\n memoryPerAgentMb: Type.Number({ minimum: 0 }),\n coldStartMs: Type.Number({ minimum: 0 }),\n maxConcurrentAgents: Type.Integer({ minimum: 1 }),\n },\n strict,\n ),\n },\n strict,\n);\nexport type RuntimeCapabilities = Static<typeof RuntimeCapabilities>;\n","// DESIGN 2.2.4 — handle, messages, snapshot.\nimport {\n AgentId,\n AuthMode,\n ErrorInfo,\n type IsoInstant,\n type JsonValue,\n JsonValueSchema,\n ModelRef,\n RunId,\n TokenUsage,\n ToolCallId,\n} from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\n// The explicit TUnsafe keeps Biome's type inference out of `Static<TRecord>`: it overflows its stack there and then\n// exits 0, so the lint LOOKS green while nothing was checked (docs/v3/requests/U0.02.md R1, U0.03.md R1).\nconst jsonMap = (): TUnsafe<Record<string, JsonValue>> =>\n Type.Unsafe<Record<string, JsonValue>>(Type.Record(Type.String(), JsonValueSchema));\n\n/** `format` is a label, e.g. 'jsonl-v3' | 'fake-ndjson-v1' — never interpreted by core */\nexport const TranscriptRef = Type.Object({ path: Type.String(), format: Type.String() }, strict);\nexport type TranscriptRef = Static<typeof TranscriptRef>;\n\n/** R8: opaque to clients */\nexport const RuntimeSessionRef = Type.Object(\n { runtime: Type.String(), engineVersion: Type.String(), sessionId: Type.String(), transcript: TranscriptRef },\n strict,\n);\nexport type RuntimeSessionRef = Static<typeof RuntimeSessionRef>;\n\nexport const UsageTotals = Type.Object(\n {\n tokens: TokenUsage,\n modelRequests: count(),\n toolCalls: count(),\n turns: count(),\n wallClockMs: Type.Number({ minimum: 0 }),\n },\n strict,\n);\nexport type UsageTotals = Static<typeof UsageTotals>;\n\nexport const EffectiveModel = Type.Object(\n {\n provider: Type.String(),\n model: Type.String(),\n api: Type.Optional(Type.String()),\n baseUrl: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type EffectiveModel = Static<typeof EffectiveModel>;\n\n/** The ADAPTER's typed cause, recorded by the host BEFORE it acts. The engine's own stop reason is never a discriminator [X]. */\nexport const AgentStopCause = Type.Union([\n Type.Literal('host-terminated'),\n Type.Literal('model-stop'),\n Type.Literal('output-truncated'),\n Type.Literal('budget'),\n Type.Literal('cancelled'),\n Type.Literal('engine-error'),\n Type.Literal('process-exit'),\n]);\nexport type AgentStopCause = Static<typeof AgentStopCause>;\n\nexport const AgentExit = Type.Object(\n {\n outcome: Type.Union([\n Type.Literal('completed'),\n Type.Literal('failed'),\n Type.Literal('cancelled'),\n Type.Literal('crashed'),\n ]),\n stop: AgentStopCause,\n error: Type.Optional(ErrorInfo),\n usage: UsageTotals,\n lastSeq: count(),\n },\n strict,\n);\nexport type AgentExit = Static<typeof AgentExit>;\n\nexport interface RuntimeAgentHandle {\n readonly runId: RunId;\n readonly agentId: AgentId;\n readonly incarnation: number;\n readonly session: RuntimeSessionRef;\n readonly startedAt: IsoInstant;\n /** startToken = OS process start time: orphan kill never trusts a bare pid */\n readonly process: { pid: number; pgid: number; startToken: string } | null;\n /** settles exactly once, never rejects, only AFTER the final RuntimeEvent was delivered */\n readonly exit: Promise<AgentExit>;\n}\n\nconst delivery = () => Type.Union([Type.Literal('steer'), Type.Literal('follow-up')]);\n\nexport const RuntimeMessage = Type.Union([\n Type.Object(\n { kind: Type.Literal('user'), messageId: Type.String(), text: Type.String(), delivery: delivery() },\n strict,\n ),\n // rendered as a user message prefixed \"[cohorte]\"\n Type.Object(\n { kind: Type.Literal('host-note'), messageId: Type.String(), text: Type.String(), delivery: delivery() },\n strict,\n ),\n]);\nexport type RuntimeMessage = Static<typeof RuntimeMessage>;\n\nexport const RuntimeSnapshot = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n state: Type.Union([\n Type.Literal('starting'),\n Type.Literal('running'),\n Type.Literal('awaiting-tool'),\n Type.Literal('paused'),\n Type.Literal('settling'),\n Type.Literal('exited'),\n ]),\n pausedAt: Type.Optional(Type.Union([Type.Literal('tool-boundary'), Type.Literal('model-boundary')])),\n turn: count(),\n pendingToolCalls: Type.Array(ToolCallId),\n requestedModel: ModelRef,\n effectiveModel: Type.Optional(EffectiveModel),\n authMode: Type.Optional(AuthMode),\n usage: UsageTotals,\n contextTokens: Type.Optional(count()),\n contextWindow: Type.Optional(count()),\n session: RuntimeSessionRef,\n lastSeq: count(),\n /** pid, rssMb, lastHeartbeatAt, engine flags… never secrets */\n diagnostics: jsonMap(),\n },\n strict,\n);\nexport type RuntimeSnapshot = Static<typeof RuntimeSnapshot>;\n","// DESIGN 2.2.2 — rule C1: tools are executed by the host, never by the runtime.\nimport { AgentId, type JsonValue, JsonValueSchema, RunId, type SealedText, ToolCallId } from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\n\nexport interface ToolHost {\n /**\n * Called exactly once per model tool call, in emission order (ordinal), BEFORE any effect. MUST resolve (a rejection\n * is a host bug: the runtime treats it as isError + agent failure). MUST settle promptly after ctx.signal aborts.\n * MAY take hours (human decision).\n */\n handleToolCall(call: RuntimeToolCall, ctx: ToolCallContext): Promise<RuntimeToolResult>;\n}\n\nexport const RuntimeToolCall = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n /** tc_<incarnation>_<ordinal> */\n toolCallId: ToolCallId,\n /** the engine's own id, transcript correlation only */\n engineToolCallId: Type.Optional(Type.String()),\n /** 1-based, per incarnation, gapless */\n ordinal: Type.Integer({ minimum: 1 }),\n tool: Type.String(),\n /** as produced by the model after engine-side coercion; the host re-validates strictly */\n input: JsonValueSchema,\n },\n strict,\n);\nexport type RuntimeToolCall = Static<typeof RuntimeToolCall>;\n\nexport interface ToolCallContext {\n signal: AbortSignal;\n progress(update: ToolProgress): void;\n}\n\nexport const ToolProgress = Type.Object(\n { text: Type.Optional(Type.String()), bytes: Type.Optional(Type.Integer({ minimum: 0 })) },\n strict,\n);\nexport type ToolProgress = Static<typeof ToolProgress>;\n\nexport const ToolContent = Type.Union([\n // The static type carries the seal; on a wire a sealed text is a string like any other.\n Type.Object({ type: Type.Literal('text'), text: Type.Unsafe<SealedText>(Type.String()) }, strict),\n Type.Object({ type: Type.Literal('image'), mediaType: Type.String(), dataBase64: Type.String() }, strict),\n]);\nexport type ToolContent = Static<typeof ToolContent>;\n\n/** content is SEALED: the engine transcript never holds an unredacted tool result (I7). */\nexport const RuntimeToolResult = Type.Object(\n {\n isError: Type.Boolean(),\n content: Type.Array(ToolContent),\n /** host asks the runtime to end the agent loop after this batch */\n terminate: Type.Optional(Type.Boolean()),\n /** opaque audit id, stored in the transcript */\n resultRef: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type RuntimeToolResult = Static<typeof RuntimeToolResult>;\n\nexport const TOOL_NAME_PATTERN = '^[a-z][a-z0-9_]{1,40}$';\n\n/** Root keywords a provider would have to flatten or would refuse: a grant's schema is ONE flat top-level object. */\nexport const TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS = [\n '$ref',\n '$defs',\n 'definitions',\n 'oneOf',\n 'anyOf',\n 'allOf',\n] as const;\n\n/** JSON Schema 2020-12, ONE flat top-level object: no $ref/$defs/oneOf at root (provider flattening). */\nexport const ToolInputSchema: TUnsafe<JsonValue> = Type.Unsafe<JsonValue>(\n Type.Object(\n { type: Type.Literal('object'), properties: Type.Optional(Type.Record(Type.String(), JsonValueSchema)) },\n {\n additionalProperties: true,\n not: { anyOf: TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS.map((key) => ({ required: [key] })) },\n },\n ),\n);\n\n/** What the BRAIN needs to know. No paths, no commands: what a call may touch is decided host-side. */\nexport const ToolGrant = Type.Object(\n {\n /** TOOL_NAME_PATTERN; never differs only by case from another grant (see toolGrantProblems) */\n tool: Type.String({ pattern: TOOL_NAME_PATTERN }),\n description: Type.String(),\n inputSchema: ToolInputSchema,\n /** ordering hint only */\n effect: Type.Union([\n Type.Literal('read'),\n Type.Literal('write'),\n Type.Literal('execute'),\n Type.Literal('network'),\n Type.Literal('control'),\n ]),\n /** true for the result tool */\n terminal: Type.Boolean(),\n },\n strict,\n);\nexport type ToolGrant = Static<typeof ToolGrant>;\n\n/**\n * The rule a schema cannot say: inside ONE grant list no two names are equal, or differ only by case (providers\n * fold tool names). Works on unvalidated names too, which is why it re-checks the pattern. Empty = no problem.\n */\nexport function toolGrantProblems(grants: readonly Pick<ToolGrant, 'tool'>[]): string[] {\n const pattern = new RegExp(TOOL_NAME_PATTERN);\n const problems: string[] = [];\n const seen = new Map<string, string>();\n for (const { tool } of grants) {\n if (!pattern.test(tool)) problems.push(`tool name ${JSON.stringify(tool)} does not match ${TOOL_NAME_PATTERN}`);\n const folded = tool.toLowerCase();\n const earlier = seen.get(folded);\n if (earlier === undefined) seen.set(folded, tool);\n else if (earlier === tool) problems.push(`tool ${JSON.stringify(tool)} is granted twice`);\n else problems.push(`tools ${JSON.stringify(earlier)} and ${JSON.stringify(tool)} differ only by case`);\n }\n return problems;\n}\n","// DESIGN 2.2.5 — RuntimeEvent: \"Pi-shaped, not Pi-typed\". Durability is part of the type (C5).\nimport {\n AgentId,\n AuthMode,\n ErrorInfo,\n IsoInstant,\n ModelRef,\n QuotaInfo,\n RunId,\n Sha256,\n TokenUsage,\n ToolCallId,\n} from '@cohorte/base';\nimport { type Static, type TSchema, type TUnsafe, Type } from 'typebox';\nimport { AgentExit, EffectiveModel, RuntimeSessionRef } from './session.ts';\nimport { RuntimeToolCall, ToolProgress } from './tools.ts';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\nconst boundary = () => Type.Union([Type.Literal('tool-boundary'), Type.Literal('model-boundary')]);\nconst delivery = () => Type.Union([Type.Literal('steer'), Type.Literal('follow-up')]);\nconst messageRole = () => Type.Union([Type.Literal('assistant'), Type.Literal('user'), Type.Literal('tool-result')]);\n\n/**\n * A CLOSED five-value set on this frontier: an adapter maps any other engine stop reason (Pi 0.85.1 also has\n * 'pending' and 'deferred') to 'error' and emits runtime.warning{code: ENGINE_STOP_REASON_UNMAPPED}.\n */\nexport const ModelStop = Type.Union([\n Type.Literal('stop'),\n Type.Literal('length'),\n Type.Literal('tool-use'),\n Type.Literal('error'),\n Type.Literal('aborted'),\n]);\nexport type ModelStop = Static<typeof ModelStop>;\nexport const ENGINE_STOP_REASON_UNMAPPED = 'engine-stop-reason-unmapped';\n\nexport const PREVIEW_MAX_LENGTH = 512;\n\nexport const IsolationReport = Type.Object(\n {\n level: Type.Union([Type.Literal('os'), Type.Literal('process'), Type.Literal('none')]),\n filesystem: Type.Union([Type.Literal('enforced'), Type.Literal('advisory')]),\n network: Type.Union([Type.Literal('enforced'), Type.Literal('partial'), Type.Literal('none')]),\n backend: Type.String(),\n },\n strict,\n);\nexport type IsolationReport = Static<typeof IsolationReport>;\n\nconst durable = <P extends TSchema>(data: P) => ({ durability: 'durable', data }) as const;\nconst ephemeral = <P extends TSchema>(data: P) => ({ durability: 'ephemeral', data }) as const;\n\n/**\n * One row per event type: its durability and the schema of `data`. EVERY durable type has a named target in the\n * protocol catalogue, or an explicit \"not forwarded\" rule (DESIGN 2.3.3). `authSource: 'none'` exists only for\n * runtimes that hold no credential (the fake); a fake run reports the authMode its plan requested.\n */\nexport const RUNTIME_EVENT_TYPES = {\n 'agent.spawned': durable(\n Type.Object(\n {\n session: RuntimeSessionRef,\n requestedModel: ModelRef,\n tools: Type.Array(Type.String()),\n systemPromptSha256: Sha256,\n effectiveSystemPromptSha256: Sha256,\n isolation: IsolationReport,\n },\n strict,\n ),\n ),\n 'agent.started': durable(Type.Object({ taskSha256: Sha256 }, strict)),\n 'agent.turn.started': ephemeral(Type.Object({ turn: count() }, strict)),\n 'agent.turn.completed': durable(Type.Object({ turn: count(), toolCalls: count() }, strict)),\n 'agent.message.started': ephemeral(Type.Object({ messageId: Type.String(), role: messageRole() }, strict)),\n 'agent.message.delta': ephemeral(\n Type.Object(\n {\n messageId: Type.String(),\n channel: Type.Union([Type.Literal('text'), Type.Literal('thinking'), Type.Literal('tool-input')]),\n contentIndex: count(),\n delta: Type.String(),\n },\n strict,\n ),\n ),\n 'agent.message.completed': durable(\n Type.Object(\n {\n messageId: Type.String(),\n role: messageRole(),\n textSha256: Sha256,\n textBytes: count(),\n preview: Type.String({ maxLength: PREVIEW_MAX_LENGTH }),\n stop: Type.Optional(ModelStop),\n },\n strict,\n ),\n ),\n 'model.requested': durable(\n Type.Object(\n {\n requestId: Type.String(),\n model: ModelRef,\n contextSha256: Type.Optional(Sha256),\n contextTokensEstimate: Type.Optional(count()),\n attempt: Type.Integer({ minimum: 1 }),\n },\n strict,\n ),\n ),\n 'model.responded': durable(\n Type.Object(\n {\n requestId: Type.String(),\n requestedModel: ModelRef,\n effectiveModel: EffectiveModel,\n authMode: AuthMode,\n authSource: Type.Union([Type.Literal('oauth'), Type.Literal('api-key'), Type.Literal('none')]),\n durationMs: Type.Number({ minimum: 0 }),\n usage: TokenUsage,\n httpStatus: Type.Optional(Type.Integer()),\n attempt: Type.Integer({ minimum: 1 }),\n stop: ModelStop,\n quota: QuotaInfo,\n error: Type.Optional(ErrorInfo),\n },\n strict,\n ),\n ),\n // model asked; nothing ran yet; ToolHost WILL be called\n 'tool.call.requested': durable(Type.Object({ call: RuntimeToolCall }, strict)),\n // engine refused BEFORE the host: ToolHost is NOT called [X]\n 'tool.call.rejected': durable(\n Type.Object(\n {\n engineToolCallId: Type.Optional(Type.String()),\n tool: Type.String(),\n cause: Type.Union([\n Type.Literal('unknown-tool'),\n Type.Literal('invalid-input'),\n Type.Literal('output-truncated'),\n ]),\n message: Type.String(),\n },\n strict,\n ),\n ),\n 'tool.call.progress': ephemeral(Type.Object({ toolCallId: ToolCallId, update: ToolProgress }, strict)),\n 'tool.call.delivered': durable(\n Type.Object(\n {\n toolCallId: ToolCallId,\n isError: Type.Boolean(),\n terminate: Type.Boolean(),\n waitedMs: Type.Number({ minimum: 0 }),\n },\n strict,\n ),\n ),\n 'agent.paused': durable(Type.Object({ at: boundary() }, strict)),\n 'agent.resumed': durable(Type.Unsafe<Record<string, never>>(Type.Object({}, strict))),\n 'agent.message.accepted': durable(Type.Object({ messageId: Type.String(), delivery: delivery() }, strict)),\n 'agent.exited': durable(AgentExit),\n 'runtime.warning': durable(Type.Object({ code: Type.String(), message: Type.String() }, strict)),\n} as const;\n\ntype EventTable = typeof RUNTIME_EVENT_TYPES;\nexport type RuntimeEventType = keyof EventTable;\n\ninterface Ev<T extends string, D extends 'durable' | 'ephemeral', P> {\n type: T;\n durability: D;\n runId: RunId;\n agentId: AgentId;\n incarnation: number;\n /** per incarnation, strictly increasing over BOTH durabilities */\n seq: number;\n at: IsoInstant;\n data: P;\n}\n\n/** Discriminated on `type`. */\nexport type RuntimeEvent = {\n [T in RuntimeEventType]: Ev<T, EventTable[T]['durability'], Static<EventTable[T]['data']>>;\n}[RuntimeEventType];\nexport type RuntimeEventOf<T extends RuntimeEventType> = Extract<RuntimeEvent, { type: T }>;\nexport type DurableRuntimeEvent = Extract<RuntimeEvent, { durability: 'durable' }>;\nexport type EphemeralRuntimeEvent = Extract<RuntimeEvent, { durability: 'ephemeral' }>;\n\nexport const RUNTIME_EVENT_TYPE_NAMES = Object.freeze(Object.keys(RUNTIME_EVENT_TYPES)) as readonly RuntimeEventType[];\n\nconst envelope = {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n seq: count(),\n at: IsoInstant,\n};\n\n// The annotation is deliberate: the union is assembled from the table, so there is nothing to infer from.\nexport const RuntimeEvent: TUnsafe<RuntimeEvent> = Type.Unsafe<RuntimeEvent>(\n Type.Union(\n RUNTIME_EVENT_TYPE_NAMES.map((type) => {\n const row = RUNTIME_EVENT_TYPES[type];\n return Type.Object(\n { type: Type.Literal(type), durability: Type.Literal(row.durability), ...envelope, data: row.data },\n strict,\n );\n }),\n ),\n);\n\nexport const isDurable = (event: RuntimeEvent): event is DurableRuntimeEvent => event.durability === 'durable';\n","// DESIGN 2.2.7 — pin and auth status.\nimport { IsoInstant, Sha256 } from '@cohorte/base';\nimport { type Static, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\n\n/** spec 16 */\nexport const RuntimePin = Type.Object(\n {\n runtimeId: Type.String(),\n adapterVersion: Type.String(),\n engine: Type.Union([Type.Object({ name: Type.String(), version: Type.String() }, strict), Type.Null()]),\n node: Type.Object({ version: Type.String(), execPath: Type.String() }, strict),\n artifacts: Type.Array(\n Type.Object(\n {\n role: Type.Union([\n Type.Literal('agent-host-bundle'),\n Type.Literal('engine-package-tree'),\n Type.Literal('install-lock'),\n ]),\n path: Type.String(),\n sha256: Sha256,\n files: Type.Optional(count()),\n bytes: count(),\n },\n strict,\n ),\n ),\n /** sha256(canonicalJson(all of the above)) */\n digest: Sha256,\n },\n strict,\n);\nexport type RuntimePin = Static<typeof RuntimePin>;\n\n/** never contains a token, a refresh token or an account secret */\nexport const ProviderAuthStatus = Type.Object(\n {\n provider: Type.String(),\n /** 'unknown-transient' = credential store locked: NEVER mapped to AUTH_REQUIRED */\n state: Type.Union([\n Type.Literal('oauth'),\n Type.Literal('api-key'),\n Type.Literal('absent'),\n Type.Literal('unknown-transient'),\n ]),\n subscription: Type.Boolean(),\n source: Type.Optional(Type.String()),\n checkedAt: IsoInstant,\n /** non-secret account/tenant label WHEN the engine exposes one without a secret; absent otherwise */\n accountLabel: Type.Optional(Type.String()),\n /** Cohorte's own table, not the engine's subscription flag (§3.7) */\n billing: Type.Union([Type.Literal('plan-limits'), Type.Literal('metered'), Type.Literal('unknown')]),\n caveat: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type ProviderAuthStatus = Static<typeof ProviderAuthStatus>;\n","// DESIGN 2.2.3 — SpawnRequest: the ten spec-5.1 fields + what spec 6 / 10.1 / 16 require.\nimport { AgentId, AuthMode, ModelRef, RunId, Sha256, ThinkingLevel } from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\nimport { TranscriptRef } from './session.ts';\nimport { ToolGrant } from './tools.ts';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\nconst limit = () => Type.Optional(Type.Integer({ minimum: 1 }));\nconst ceiling = () => Type.Optional(count());\n// The explicit TUnsafe keeps Biome's type inference out of `Static<TRecord>`: it overflows its stack there and then\n// exits 0, so the lint LOOKS green while nothing was checked (docs/v3/requests/U0.02.md R1, U0.03.md R1).\nconst stringMap = (): TUnsafe<Record<string, string>> =>\n Type.Unsafe<Record<string, string>>(Type.Record(Type.String(), Type.String()));\n\n/** opaque label; the runtime MUST NOT branch on it */\nexport const AgentRole = Type.String();\nexport type AgentRole = Static<typeof AgentRole>;\n\nexport const AuthRequirement = Type.Object(\n {\n mode: AuthMode,\n provider: Type.String(),\n /** pinned catalogue endpoint; a runtime that would talk to anything else MUST refuse to spawn */\n baseUrl: Type.String(),\n /** false unless the run plan carries an explicit api opt-in */\n allowApiKey: Type.Boolean(),\n },\n strict,\n);\nexport type AuthRequirement = Static<typeof AuthRequirement>;\n\n/** rendered by the host into the run snapshot dir */\nexport const TaskInput = Type.Object({ path: Type.String(), sha256: Sha256, bytes: count() }, strict);\nexport type TaskInput = Static<typeof TaskInput>;\n\n/** The fixed line that precedes `Continuation.note` when the engine cannot carry two user messages in one prompt. */\nexport const CONTINUATION_NOTE_SEPARATOR = '\\n\\n[cohorte] continuation note\\n\\n';\n\n/**\n * `note` is delivered by the runtime AFTER `task` and BEFORE the first model request: as a second user message when\n * the engine can carry two in one prompt, otherwise appended to the first user message after\n * CONTINUATION_NOTE_SEPARATOR. Either way each text is a byte-identical contiguous span and `task` comes first\n * (conformance rule 12).\n */\nexport const Continuation = Type.Object(\n {\n fromIncarnation: Type.Integer({ minimum: 1 }),\n note: TaskInput,\n /** used only if continuationFromTranscript = yes */\n transcript: Type.Optional(TranscriptRef),\n },\n strict,\n);\nexport type Continuation = Static<typeof Continuation>;\n\n/** runtime MUST verify sha256 before use */\nexport const PromptRef = Type.Object(\n { id: Type.String(), path: Type.String(), sha256: Sha256, bytes: count() },\n strict,\n);\nexport type PromptRef = Static<typeof PromptRef>;\n\nexport const ContextEntry = Type.Object(\n {\n id: Type.String(),\n tier: Type.Union([\n Type.Literal('system'),\n Type.Literal('doctrine'),\n Type.Literal('data'),\n Type.Literal('task'),\n Type.Literal('prior-results'),\n ]),\n /** agent-output and untrusted-repository can never sit above 'data' */\n trust: Type.Union([\n Type.Literal('cohorte'),\n Type.Literal('human'),\n Type.Literal('untrusted-repository'),\n Type.Literal('agent-output'),\n ]),\n source: Type.Object(\n {\n kind: Type.Union([\n Type.Literal('asset'),\n Type.Literal('project-file'),\n Type.Literal('artifact'),\n Type.Literal('event-summary'),\n Type.Literal('inline'),\n ]),\n ref: Type.String(),\n },\n strict,\n ),\n sha256: Sha256,\n bytes: count(),\n tokenEstimate: count(),\n },\n strict,\n);\nexport type ContextEntry = Static<typeof ContextEntry>;\n\n/**\n * PROVENANCE ONLY. \"Installer le contexte\" (spec 5.2) is defined as: every byte the model sees is in exactly two\n * host-rendered files — `systemPrompt` (tiers `system` + `doctrine`) and `task` (tiers `data` + `task` +\n * `prior-results`) — plus, for a later incarnation, `continuation.note`. A runtime installs those three and NOTHING\n * else: it never opens `entries[].source`, never re-orders or re-renders tiers. The manifest travels so that the\n * runtime can record `manifestSha256` on `model.requested` and so that a second runtime has nothing to guess.\n * Tiers are trust/priority tiers (spec 7), not orchestration words.\n */\nexport const ContextManifest = Type.Object(\n {\n /** sha256(canonicalJson(entries)) = \"hash du contexte\" of spec 19 */\n manifestSha256: Sha256,\n tokenLimit: count(),\n tokenEstimate: count(),\n /** deterministic order: tier, then id */\n entries: Type.Array(ContextEntry),\n reductions: Type.Array(\n Type.Object(\n {\n entryId: Type.String(),\n strategy: Type.Union([\n Type.Literal('excerpt'),\n Type.Literal('outline'),\n Type.Literal('summary-with-refs'),\n Type.Literal('dropped'),\n ]),\n fromBytes: count(),\n toBytes: count(),\n },\n strict,\n ),\n ),\n exclusions: Type.Array(\n Type.Object(\n {\n pattern: Type.String(),\n reason: Type.Union([\n Type.Literal('secret'),\n Type.Literal('outside-scope'),\n Type.Literal('size'),\n Type.Literal('binary'),\n ]),\n },\n strict,\n ),\n ),\n },\n strict,\n);\nexport type ContextManifest = Static<typeof ContextManifest>;\n\n/** Isolation of the RUNTIME'S OWN agent process (the brain). Tool isolation is host-side. */\nexport const SandboxPolicy = Type.Object(\n {\n /** spawn fails security/sandbox-unavailable below `os` */\n require: Type.Union([Type.Literal('os'), Type.Literal('os-if-available'), Type.Literal('process')]),\n /** absolute canonical roots */\n filesystem: Type.Object(\n {\n readOnly: Type.Array(Type.String()),\n readWrite: Type.Array(Type.String()),\n denyRead: Type.Array(Type.String()),\n },\n strict,\n ),\n network: Type.Object(\n {\n mode: Type.Union([Type.Literal('none'), Type.Literal('provider-only'), Type.Literal('unrestricted')]),\n allowHosts: Type.Array(Type.String()),\n },\n strict,\n ),\n /** allowlist; nothing else is inherited (D3) */\n env: Type.Object({ allow: Type.Array(Type.String()), set: stringMap() }, strict),\n limits: Type.Object({ maxOldSpaceMb: limit(), maxCpuSeconds: limit(), maxOpenFiles: limit() }, strict),\n },\n strict,\n);\nexport type SandboxPolicy = Static<typeof SandboxPolicy>;\n\n/** hard ceilings for ONE incarnation; absent = unlimited at this level */\nexport const Budget = Type.Object(\n {\n maxTurns: ceiling(),\n maxModelRequests: ceiling(),\n maxToolCalls: ceiling(),\n maxInputTokens: ceiling(),\n maxOutputTokens: ceiling(),\n maxTotalTokens: ceiling(),\n /** stop (never auto-compact) when the last request's context exceeds this */\n maxContextTokens: ceiling(),\n maxWallClockMs: ceiling(),\n maxModelRequestMs: ceiling(),\n /** 0 = every retry is the host's (spec 11.3 \"tous les retries sont visibles\") */\n maxEngineRetries: count(),\n },\n strict,\n);\nexport type Budget = Static<typeof Budget>;\n\nexport const SpawnRequest = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n role: AgentRole,\n model: ModelRef,\n systemPrompt: PromptRef,\n context: ContextManifest,\n tools: Type.Array(ToolGrant),\n sandbox: SandboxPolicy,\n budget: Budget,\n /** absolute, canonical; the path the MODEL is told about. The engine process MUST NOT use it as its cwd */\n workingDirectory: Type.String(),\n // additions (all required so that no runtime can forget them):\n /** spec 6: spawn is idempotent on (runId, agentId, incarnation) */\n incarnation: Type.Integer({ minimum: 1 }),\n thinking: ThinkingLevel,\n /** spec 10.1 / D3 */\n auth: AuthRequirement,\n /** the first user message, by reference */\n task: TaskInput,\n /** a later incarnation of the same attempt */\n continuation: Type.Union([Continuation, Type.Null()]),\n },\n strict,\n);\nexport type SpawnRequest = Static<typeof SpawnRequest>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"src-r0ECB1UJ.mjs","names":["fsConstants","oneOf","count","strict","strict","count","delivery","strict","strict","count","strict","count"],"sources":["../../../../packages/security/src/exec/capabilities.ts","../../../../packages/security/src/exec/identity.ts","../../../../packages/security/src/exec/ulimit.ts","../../../../packages/security/src/exec/executor.ts","../../../../packages/security/src/exec/index.ts","../../../../packages/security/src/redact/seal.ts","../../../../packages/security/src/redact/index.ts","../../../../packages/security/src/contract/builtin.ts","../../../../packages/security/src/contract/decisions.ts","../../../../packages/security/src/contract/exec.ts","../../../../packages/runtime-contract/src/capabilities.ts","../../../../packages/runtime-contract/src/session.ts","../../../../packages/runtime-contract/src/tools.ts","../../../../packages/runtime-contract/src/events.ts","../../../../packages/runtime-contract/src/pin.ts","../../../../packages/runtime-contract/src/spawn.ts"],"sourcesContent":["// What the L0 executor honestly guarantees, and detection of the L1 binaries this unit does not yet wrap\n// (DESIGN 2.6.6, ADR-0003: \"L1 backends are U4.07\"). `computeCapabilities` is the ONE function behind both\n// `Executor.run()`'s `ExecResult.guarantees` and the top-level `probeSandbox()`, so the two can never disagree.\nimport { accessSync, constants as fsConstants } from 'node:fs';\nimport { delimiter, join } from 'node:path';\nimport { type ErrorInfo, errorOf } from '@cohorte/base';\nimport type { SandboxBackend, SandboxCapabilities } from '../contract/index.ts';\n\n/**\n * The fixed L0-process report (every OS, the built-in `none` backend). `memory` stays `unavailable`: the ulimit\n * wrapper never attempts `-v` (toolchain.md §8: it fails outright on macOS, and this unit applies only `-t/-f/-n/-u`\n * on every platform alike, per DESIGN 2.6.6's own list of flags). `missing`/`notes` report what `probeSandbox`\n * observed about L1 binaries on this machine; the level stays `L0-process` regardless, since no backend besides\n * `none` is implemented here.\n *\n * `cpuTime` and `processes` say `enforced` because the wrapper FAILS CLOSED (ulimit.ts): a limit the kernel\n * refuses aborts the run instead of letting the program start without it, so the word is never a claim about a\n * limit that was silently dropped.\n */\nexport function l0Capabilities(missing: readonly string[] = [], notes: readonly string[] = []): SandboxCapabilities {\n return {\n level: 'L0-process',\n backend: 'none',\n filesystem: 'advisory',\n network: 'unenforced',\n processEscape: 'possible',\n envFiltering: 'enforced',\n timeout: 'enforced',\n outputCap: 'enforced',\n cpuTime: 'enforced',\n memory: 'unavailable',\n processes: 'enforced',\n killTree: 'process-group-with-sweep',\n missing: [...missing],\n notes: [...notes],\n };\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n accessSync(path, fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Is `name` an executable on the host's PATH? Scanned directly rather than through `which`, which is not part of\n * coreutils and is simply absent from many minimal Linux images and containers: there, a spawned `which` fails,\n * `bwrap` is reported missing although it is installed, and `doctor` — the report ADR-0003 makes load-bearing for\n * the `native` / `best-effort` decision — states a false negative. A `stat` per PATH entry also costs no fork.\n *\n * This is the one place the executor reads `process.env`, and it reads the HOST's PATH to answer a question about\n * the host. Nothing here ever reaches a child: the environment of a spawned command is built from `ExecRequest.env`\n * alone (S-20, executor.ts).\n */\nfunction isOnPath(name: string): boolean {\n for (const dir of (process.env.PATH ?? '').split(delimiter)) {\n if (dir !== '' && isExecutable(join(dir, name))) return true;\n }\n return false;\n}\n\nconst settledDetection = new Map<string, readonly string[]>();\n\n/**\n * Informational only (DESIGN 2.6.6 `missing` example: `[\"bwrap\"]`): this unit never wraps a command in Seatbelt or\n * bubblewrap (that is U4.07's job), so detecting them changes nothing about the reported `level`/`backend` — it\n * only tells `doctor` what is absent.\n *\n * SYNCHRONOUS, because `Executor.capabilities()` is: DESIGN 2.6.6 marks `SandboxCapabilities` `[S]` and\n * `capabilities()` returns it without awaiting anything. Priming an asynchronous detection at construction was not\n * enough — a `capabilities()` called in the same tick still read an unsettled memo and answered `missing: []` while\n * `probeSandbox()` answered `['bwrap']`, i.e. `doctor` contradicted itself depending on when it was called. A\n * handful of `stat`s is all the answer needs.\n *\n * MEMOISED per platform: DESIGN 2.6.6 says `probe()` is \"cached per Cohorte version + OS build\", and the answer is\n * a property of the machine, not of the command; without the memo it would be recomputed on every `run()`.\n */\nexport function detectMissingL1Binaries(platform: string): readonly string[] {\n const settled = settledDetection.get(platform);\n if (settled !== undefined) return settled;\n const missing: string[] = [];\n if (platform === 'darwin' && !isExecutable('/usr/bin/sandbox-exec')) missing.push('sandbox-exec');\n if (platform === 'linux' && !isOnPath('bwrap')) missing.push('bwrap');\n settledDetection.set(platform, missing);\n return missing;\n}\n\n/** The backend that produced `capabilities`, if any — `undefined` means \"nothing usable: the honest L0 report\". */\nexport interface ResolvedSandbox {\n backend?: SandboxBackend;\n capabilities: SandboxCapabilities;\n}\n\n/**\n * Tries every non-`none` backend in order and returns the FIRST one whose probe reports `L1-os`, together with its\n * report; falls back to the honest L0 report (with L1-binary detection folded into `missing`) when none is usable —\n * which, until U4.07 lands, is always, since no L1 `SandboxBackend` is constructed by this unit.\n *\n * Returning the backend and its report together is what keeps `ExecResult.guarantees` honest: the executor wraps\n * the command with exactly the backend that earned the report, so it can never claim an isolation that the argv it\n * spawned does not carry.\n */\nexport async function resolveSandbox(backends: readonly SandboxBackend[], platform: string): Promise<ResolvedSandbox> {\n for (const backend of backends) {\n if (backend.id === 'none') continue;\n try {\n const probed = await backend.probe();\n if (probed.level === 'L1-os') return { backend, capabilities: probed };\n } catch {\n // Not implemented yet, or failed to probe: fall through to the honest L0 report.\n }\n }\n return { capabilities: l0Capabilities(detectMissingL1Binaries(platform)) };\n}\n\n/** The escape self-test that gates the word `enforced` on this platform (DESIGN 2.6.6, ADR-0003 §2b). */\nfunction escapeSelfTest(platform: string): string {\n if (platform === 'darwin') return 'escape self-test S-28';\n if (platform === 'linux') return 'escape self-test S-29';\n return 'the platform escape self-test';\n}\n\n/**\n * One sentence per axis on which `guarantees` falls short of `require: 'native'`; empty exactly when it satisfies\n * it. DESIGN 2.6.6 requires the refusal to NAME the failing self-test rather than hand the caller a bare enum, so\n * these strings are what the executor appends to `guarantees.notes` on a `sandbox-denied` result and what\n * `sandboxUnavailable()` (exec/index.ts) turns into the catalogued error's message.\n *\n * `level: 'L1-os'` alone is never enough: a backend whose escape self-test has not passed here reports `partial` on\n * the axes that matter, and `native` is satisfied only by `enforced` (ADR-0003 §2b).\n */\nexport function nativeShortfalls(\n guarantees: SandboxCapabilities,\n platform: string = process.platform,\n): readonly string[] {\n if (guarantees.level !== 'L1-os') {\n const missing = guarantees.missing.length > 0 ? ` (missing: ${guarantees.missing.join(', ')})` : '';\n return [\n `sandbox: no OS sandbox backend is active${missing} — level is '${guarantees.level}', backend '${guarantees.backend}', ` +\n `so filesystem isolation is '${guarantees.filesystem}' and network '${guarantees.network}'`,\n ];\n }\n const test = escapeSelfTest(platform);\n const shortfalls: string[] = [];\n if (guarantees.filesystem !== 'enforced') {\n shortfalls.push(`sandbox: filesystem is '${guarantees.filesystem}' (${test} has not passed on this machine)`);\n }\n if (guarantees.network !== 'enforced-off') {\n shortfalls.push(`sandbox: network is '${guarantees.network}' (${test} has not passed on this machine)`);\n }\n if (guarantees.processEscape !== 'denied') {\n shortfalls.push(`sandbox: processEscape is '${guarantees.processEscape}' (${test} has not passed on this machine)`);\n }\n return shortfalls;\n}\n\n/** `resolveSandbox`'s report alone, for callers that only want to know what is guaranteed (`probeSandbox`). */\nexport async function computeCapabilities(\n backends: readonly SandboxBackend[],\n platform: string,\n): Promise<SandboxCapabilities> {\n return (await resolveSandbox(backends, platform)).capabilities;\n}\n\n/**\n * DESIGN 2.6.6: \"`require: 'native'` with no usable backend => `security/sandbox-unavailable` with the `doctor`\n * remediation.\" Minted HERE, once, from the same `nativeShortfalls` the executor already put in `guarantees.notes`\n * on the `sandbox-denied` result, so the catalogued error and the reported notes can never say different things.\n */\nexport function sandboxUnavailable(guarantees: SandboxCapabilities, platform: string = process.platform): ErrorInfo {\n const shortfalls = nativeShortfalls(guarantees, platform);\n const message = shortfalls.length > 0 ? shortfalls.join(' ') : 'no OS sandbox backend is active';\n return errorOf('security/sandbox-unavailable', message, { details: { guarantees: { ...guarantees } } });\n}\n","// Kill-tree, orphan sweep and cross-restart identity verification (DESIGN 2.6.6, 4.4 step 5). Two mechanisms, and\n// NEITHER of them ever signals a bare pid:\n//\n// - an in-run TRACKER (`trackDescendants` + `sweepTracked`): while the leader is alive, its process tree is\n// polled by PPID, because a `setsid()` escapee keeps its PPID even after it leaves the process GROUP (S-22).\n// Every descendant ever seen is remembered — a later reparent to pid 1 (the leader exits before we look again)\n// cannot make an escapee invisible — and it is remembered WITH the start time it had when first seen. Over a\n// command of minutes (`pnpm test`, a build) most of that set is long dead by the end, and the OS is free to\n// hand those numbers to unrelated processes of the same user; the sweep therefore re-reads each pid's current\n// start time and touches only the ones that are still the very process that was tracked.\n// - a STATELESS, cross-restart entry point (`sweepGroupByToken`, DESIGN 4.4 step 5, \"callable on demand by the\n// Resumer\"): after a host restart there is no in-memory tracker left, so a bare pgid is never enough — the OS\n// may have recycled it for an unrelated process. Identity is verified against the process's own START TIME\n// (`processStartToken`), the same technique `pids/*.json` files are meant to support (I1, I4: \"never kills on\n// a bare pid\").\nimport { execFile } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport { sha256Hex } from '@cohorte/base';\n\nconst execFileAsync = promisify(execFile);\n\ninterface ProcRow {\n pid: number;\n ppid: number;\n pgid: number;\n /** when this pid started, as the process table reports it — what tells a recycled number from the real process */\n start: string;\n}\n\n/**\n * One `ps` fork, four columns. `lstart=` is the last one on purpose: it is the only field with embedded spaces\n * (`Tue Sep 15 09:09:30 2026`), so everything after the third column is its value. A row that cannot produce all\n * four is DROPPED rather than tracked without an identity — a pid with no start time is a bare pid, and this file\n * does not kill those.\n */\nasync function processTable(): Promise<ProcRow[]> {\n const { stdout } = await execFileAsync('ps', ['-Ao', 'pid=,ppid=,pgid=,lstart=']);\n const rows: ProcRow[] = [];\n for (const line of stdout.split('\\n')) {\n const fields = line.trim().split(/\\s+/);\n if (fields.length < 4) continue;\n const [pidText, ppidText, pgidText] = fields;\n const pid = Number(pidText);\n const ppid = Number(ppidText);\n const pgid = Number(pgidText);\n const start = fields.slice(3).join(' ');\n if (Number.isInteger(pid) && Number.isInteger(ppid) && Number.isInteger(pgid) && start !== '') {\n rows.push({ pid, ppid, pgid, start });\n }\n }\n return rows;\n}\n\n/** Every row transitively parented by `rootPid`, whatever its CURRENT pgid (so a `setsid()` escapee still shows). */\nfunction descendantsOf(rootPid: number, table: readonly ProcRow[]): ProcRow[] {\n const byParent = new Map<number, ProcRow[]>();\n for (const row of table) {\n const siblings = byParent.get(row.ppid);\n if (siblings) siblings.push(row);\n else byParent.set(row.ppid, [row]);\n }\n const found: ProcRow[] = [];\n const queue = [...(byParent.get(rootPid) ?? [])];\n for (let next = queue.pop(); next !== undefined; next = queue.pop()) {\n found.push(next);\n queue.push(...(byParent.get(next.pid) ?? []));\n }\n return found;\n}\n\n/**\n * Is `pgid` a real process group we may address? On POSIX `kill(-0, …)` signals the CALLER's own process group —\n * the run host itself — and `kill(-1, …)` every process the user may signal. `ExecResult.pgid` is `0` on every\n * early return (nothing was spawned), so a dependant that feeds a result back into a sweep must find a closed door\n * here rather than one missing guard between it and a TERM of the run host.\n */\nfunction isAddressableGroup(pgid: number): boolean {\n return Number.isInteger(pgid) && pgid > 1;\n}\n\nexport function isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/** `true` when the signal was actually delivered; `false` when the target was gone or refused us. */\nfunction trySignal(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch {\n // Already gone, or never existed: sweeping is always best-effort.\n return false;\n }\n}\n\n/** TERM the pids that are still alive, wait `graceMs`, KILL the survivors. Returns how many were signalled. */\nasync function terminatePids(\n pids: readonly number[],\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n const alive = pids.filter((pid) => isAlive(pid));\n if (alive.length === 0) return 0;\n for (const pid of alive) trySignal(pid, 'SIGTERM');\n await wait(graceMs);\n for (const pid of alive) if (isAlive(pid)) trySignal(pid, 'SIGKILL');\n return alive.length;\n}\n\n/**\n * How often the tracker forks `ps`. Every poll is a fork plus a full process-table scan, and this executor is the\n * path that runs `pnpm test` / `pnpm build`, where a run of minutes is ordinary — a fixed fast period would cost\n * tens of thousands of forks for one check command. The period is therefore fast only while it buys something: an\n * escapee that `setsid()`s immediately must be seen before the leader is reaped, which is a matter of milliseconds,\n * whereas after the first second the tracker is merely keeping an already-known set fresh. The final snapshot at\n * exit (below) is taken at full resolution whatever the period has grown to, so the last moment is never sampled\n * coarsely.\n */\nexport interface TrackInterval {\n /** the period during the fast window */\n initialMs: number;\n /** the period never grows past this */\n maxMs: number;\n /** total polled time after which the period starts doubling */\n rampAfterMs: number;\n}\n\n/** What the tracker remembers about a descendant: the pid, and the start time it had the first time it was seen. */\nexport type TrackedDescendants = Map<number, string>;\n\n/**\n * Polls the process table until `until` settles, folding every descendant ever seen under `rootPid` into `sink`\n * AS `pid -> start time`. The start time is what makes the record an identity instead of a number: by the end of a\n * long command most of these pids are gone, and the sweep must be able to tell the process it tracked from whatever\n * the OS has since given that number to. It is kept as FIRST SEEN and never overwritten — a differing later reading\n * means the number was recycled, which is exactly what the sweep needs to notice.\n *\n * Run concurrently with the leader's own lifetime (DESIGN 2.6.6 \"post-run SWEEP ... also callable on demand by the\n * Resumer\"); its own errors (no `ps` on the machine, a transient failure) are swallowed — sweeping is advisory,\n * never a reason to fail the call it is watching.\n */\nexport async function trackDescendants(\n rootPid: number,\n sink: TrackedDescendants,\n until: Promise<unknown>,\n wait: (ms: number) => Promise<void>,\n interval: TrackInterval,\n): Promise<void> {\n let settled = false;\n const stop = (): void => {\n settled = true;\n };\n void until.then(stop, stop);\n const poll = async (): Promise<void> => {\n try {\n for (const row of descendantsOf(rootPid, await processTable())) {\n if (!sink.has(row.pid)) sink.set(row.pid, row.start);\n }\n } catch {\n // best-effort\n }\n };\n let period = interval.initialMs;\n let polledMs = 0;\n for (;;) {\n await poll();\n if (settled) return;\n try {\n await wait(period);\n } catch {\n return;\n }\n polledMs += period;\n if (polledMs >= interval.rampAfterMs) period = Math.min(interval.maxMs, period * 2);\n if (settled) {\n // One last snapshot, taken as close as possible to the moment the leader actually exited.\n await poll();\n return;\n }\n }\n}\n\n/**\n * TERM every tracked descendant that is STILL THAT DESCENDANT, wait `graceMs`, then KILL the survivors (`leaderPid`\n * itself is excluded: the caller already handled the group leader through its own `-pgid` kill).\n *\n * Identity first, always. One process-table snapshot is taken before anything is signalled, and a tracked pid takes\n * part only when its CURRENT start time still equals the one recorded when it was first seen. A `pnpm test` that\n * forks hundreds of short-lived children leaves a set whose pids are mostly dead by the end; without this check the\n * sweep would TERM+KILL whatever unrelated process of the same user the OS had meanwhile given one of those numbers\n * to — a bare-pid kill, which DESIGN 4.4 step 5 forbids here exactly as it does across a restart — and would count\n * it as an escapee on top. A pid that is gone, or whose start time has moved, is neither signalled nor counted.\n *\n * Of the survivors that ARE ours, the KILL is total — every tracked descendant, whatever its group. The COUNT is\n * not: DESIGN 2.6.6 defines `ExecResult.escapees` as \"processes that LEFT the group\". A tracked pid whose current\n * pgid still equals `leaderPid` is an ordinary grandchild outliving its parent — routine, and counting it would\n * raise a false escapee on DESIGN 4.4's resume diagnostics and on any `escapees > 0` alerting; a pid that\n * `setsid()`ed away has its own pgid and IS one (S-22). When the snapshot cannot be taken at all, nothing is\n * signalled and nothing is claimed: an unverifiable pid is not a target.\n */\nexport async function sweepTracked(\n seen: ReadonlyMap<number, string>,\n leaderPid: number,\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n if (seen.size === 0) return 0;\n let table: ProcRow[];\n try {\n table = await processTable();\n } catch {\n // No snapshot, no identity, no kill: best-effort never means \"signal a number and hope\".\n return 0;\n }\n const current = new Map(table.map((row) => [row.pid, row]));\n let escapees = 0;\n const targets: number[] = [];\n for (const [pid, start] of seen) {\n if (pid === leaderPid) continue;\n const row = current.get(pid);\n // Gone (the common case at the end of a run), or the number has been recycled since: not ours to touch.\n if (row === undefined || row.start !== start) continue;\n targets.push(pid);\n if (row.pgid !== leaderPid) escapees += 1;\n }\n await terminatePids(targets, wait, graceMs);\n return escapees;\n}\n\n/**\n * The post-exit safety net, and a BEST-EFFORT net, not an identity-verified kill — be precise about what it is:\n * once the leader has been reaped (Node emits `'exit'` AFTER `waitpid`) its pid is free for reuse, and this\n * function keys on that same bare pgid NUMBER. It is narrower than `kill(-pgid)` in one respect only — it signals\n * members one pid at a time, sparing a recycled leader (`row.pid !== pgid`) — and it does NOT verify a start token,\n * so a group that has taken over the recycled number would be signalled with its members. The window is the few\n * milliseconds between the leader's reap and this call, and pids are allocated sequentially, so a recycle inside it\n * is not realistic. The identity-verified path is `sweepGroupByToken`, which is what the Resumer (DESIGN 4.4\n * step 5, \"never kills on a bare pid\") uses across restarts, where the window is unbounded and the guarantee must\n * be real. Returns how many were signalled.\n */\nexport async function killGroupMembers(\n pgid: number,\n wait: (ms: number) => Promise<void>,\n graceMs: number,\n): Promise<number> {\n if (!isAddressableGroup(pgid)) return 0;\n let members: number[];\n try {\n members = (await processTable()).filter((row) => row.pgid === pgid && row.pid !== pgid).map((row) => row.pid);\n } catch {\n return 0;\n }\n return terminatePids(members, wait, graceMs);\n}\n\n/**\n * A string that identifies WHEN `pid` started, not just its number — the \"start token\" of DESIGN 4.4 step 5.\n * `undefined` when the pid is gone or the platform's process table cannot be read.\n *\n * The token must be EXEC-STABLE: it is minted at the `'spawn'` event, while the leader's process image is still\n * `/bin/sh -c '<ulimit script>'`, and every later reading of it — which is all the Resumer ever has — sees the image\n * the wrapper `exec`ed into. Anything image-dependent in the hash (a command line, an argv) therefore cannot round\n * trip, and `sweepGroupByToken` would never verify a group this executor recorded. Only start TIME qualifies.\n *\n * Resolution differs per platform, and it decides how narrow the pid-reuse window is. Linux reads `starttime` from\n * `/proc/<pid>/stat`, in clock ticks since boot: two processes can share a pid only if one started long after the\n * other died, so the token is effectively unique. macOS has no such counter; `ps -o lstart=` has ONE-SECOND\n * resolution, so the residual risk there is a pid recycled by a process that started in the SAME SECOND. That is\n * why nothing but a kill-tree cleanup is ever driven from this token, and why the program's identity is carried\n * separately, by `PidRegistry.record({ label: req.file })` (contract/exec.ts).\n */\nexport async function processStartToken(pid: number, platform: string = process.platform): Promise<string | undefined> {\n try {\n if (platform === 'linux') {\n const stat = await readFile(`/proc/${pid}/stat`, 'utf8');\n // `(comm)` may itself contain spaces or parentheses: skip to the LAST ')', then count fields from `state`.\n const afterComm = stat.slice(stat.lastIndexOf(')') + 2).split(' ');\n // state(3) ppid(4) pgrp(5) session(6) tty_nr(7) tpgid(8) flags(9) minflt..cstime(10-17) priority nice(18-19)\n // num_threads(20) itrealvalue(21) starttime(22) -> index 19 (0-based, starting at field 3) of `afterComm`.\n const starttime = afterComm[19];\n return starttime === undefined || starttime === '' ? undefined : `linux:${starttime}`;\n }\n const { stdout } = await execFileAsync('ps', ['-o', 'lstart=', '-p', String(pid)]);\n const identity = stdout.trim();\n return identity === '' ? undefined : `lstart:${sha256Hex(identity)}`;\n } catch {\n return undefined;\n }\n}\n\nexport interface SweepByTokenOptions {\n wait: (ms: number) => Promise<void>;\n graceMs: number;\n platform?: string;\n}\n\nexport interface SweepByTokenResult {\n /** `false` when `pgid` is dead, or alive but its start token does not match: nothing was signalled. */\n verified: boolean;\n /** `true` only when a signal was actually DELIVERED to the group — never merely \"we tried\". */\n killed: boolean;\n}\n\n/**\n * The Resumer's stateless, on-demand entry point (DESIGN 4.4 step 5): kills the process group `pgid` ONLY when its\n * CURRENT start token still equals `startToken`. After a host restart the in-memory tracker above is gone and the\n * OS may have reused `pgid` for an unrelated process since this run's host died (I1, I4) — a bare pid is never\n * enough. No match ⇒ nothing is signalled.\n */\nexport async function sweepGroupByToken(\n pgid: number,\n startToken: string,\n options: SweepByTokenOptions,\n): Promise<SweepByTokenResult> {\n if (!isAddressableGroup(pgid) || !isAlive(pgid)) return { verified: false, killed: false };\n const platform = options.platform ?? process.platform;\n const current = await processStartToken(pgid, platform);\n if (current === undefined || current !== startToken) return { verified: false, killed: false };\n const termed = trySignal(-pgid, 'SIGTERM');\n await options.wait(options.graceMs);\n const killed = isAlive(pgid) ? trySignal(-pgid, 'SIGKILL') : false;\n // `verified` says the group we found is this run's; `killed` says a signal really landed. A group that had\n // already exited between `isAlive` and here, or one every `kill` refused, reports `killed: false` — so the\n // Resumer can tell \"I stopped it\" from \"there was nothing left to stop\".\n return { verified: true, killed: termed || killed };\n}\n\n/**\n * Best-effort TERM -> grace -> KILL of the whole process group, addressed as `-pgid`. Never throws: a dead group\n * is not an error. Only ever called while the group LEADER is known alive (an escalation during the run): once the\n * leader has been reaped its pid can be recycled, and the post-exit cleanup uses `killGroupMembers` instead.\n */\nexport async function killGroup(pgid: number, wait: (ms: number) => Promise<void>, graceMs: number): Promise<void> {\n if (!isAddressableGroup(pgid)) return;\n trySignal(-pgid, 'SIGTERM');\n await wait(graceMs);\n trySignal(-pgid, 'SIGKILL');\n}\n","// The ONE shell in the product (DESIGN 2.6.6, I3, ADR-0003). `ULIMIT_WRAPPER_SCRIPT` is a compile-time constant:\n// request data is NEVER interpolated into it as text. Every limit value and every real argv element reaches the\n// program as a literal POSITIONAL PARAMETER, consumed by `shift` before `exec` replaces the shell's own process\n// image — so `; && | $()` and newlines inside an argument are never re-parsed by anything (EV-01..EV-15).\n//\n// The final `exec` goes through `/usr/bin/env -u PWD -u SHLVL` rather than straight to `\"$0\" \"$@\"`: macOS's\n// `/bin/sh` (bash) re-exports `PWD` and `SHLVL` into the process environ on every `exec`, `unset` notwithstanding\n// (verified on this machine: `unset SHLVL` is undone before the next `exec`) — two names that belong to neither\n// `ExecRequest.env` nor `OS_INJECTED_ENV`. `env` is not a shell (no word-splitting, no metacharacter handling: its\n// own arguments are plain argv), so this changes nothing about I3; it only strips the two stowaway names before the\n// real program's image ever exists. `env`'s own rlimits are inherited unchanged from `sh` (rlimits are a property\n// of the process, not reset by `execve`).\n//\n// The ONE thing `env` does parse is its operands: any operand containing `=` is a variable assignment, and the\n// first operand WITHOUT one is the utility to exec. The program path is that operand, so a path containing `=` is\n// swallowed as an assignment and `env` execs the NEXT argv element — a model-influenced argument (I3) — as the\n// program. `--` does not protect it on either BSD or GNU (assignments are operands, not options), and there is no\n// escaping form. `isWrappableProgramPath` therefore REFUSES such a path and the executor fails the run closed (I2)\n// rather than run something nobody approved. Arguments are unaffected (`env` stops scanning at the program).\n// The refusal costs exactly what it must and no more: the executor reaches for this wrapper only when a request\n// actually asks for a rlimit, so a request with empty `limits` spawns the program directly and never meets `env`.\n//\n// The script FAILS CLOSED. A `ulimit` the kernel refuses (a value above the hard limit, a limit this OS does not\n// support) must never let the program start anyway: that would run it with no limit while `SandboxCapabilities`\n// still says `cpuTime: 'enforced'` / `processes: 'enforced'` — the \"silently skipped\" case S-24 forbids. Each\n// `ulimit` is therefore guarded by `|| exit <ULIMIT_REFUSED_EXIT>`, and its own diagnostic is sent to `/dev/null`\n// rather than to the child's stderr pipe, where it would be counted as the PROGRAM's output (folded into\n// `outputSha256`, pushed to the model through `onChunk`, and put at the head of `tail`).\nconst ULIMIT_REFUSED_EXIT = 126;\nconst ULIMIT_WRAPPER_SCRIPT =\n `[ -n \"$1\" ] && { ulimit -t \"$1\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$2\" ] && { ulimit -f \"$2\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$3\" ] && { ulimit -n \"$3\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n `[ -n \"$4\" ] && { ulimit -u \"$4\" 2>/dev/null || exit ${ULIMIT_REFUSED_EXIT}; }; ` +\n 'shift 4; exec /usr/bin/env -u PWD -u SHLVL \"$0\" \"$@\"';\n\n/**\n * How the wrapper reports \"the kernel refused a limit you asked for\". The executor maps it to `outcome: 'error'`\n * when it comes with NO output at all — the shell's own `exec` failure (program not executable, ENOENT) uses the\n * same code but writes a diagnostic to stderr first, and a program is free to exit 126 by itself.\n */\nexport const ULIMIT_REFUSED_EXIT_CODE = ULIMIT_REFUSED_EXIT;\n\n/** Absolute, not resolved through PATH: the wrapper never depends on what an agent-controlled PATH would find. */\nexport const ULIMIT_SHELL = '/bin/sh';\n\n/**\n * Can the wrapper carry this program at all? `false` for a path `/usr/bin/env` would read as a variable assignment\n * (see the header): the executor turns that into `outcome: 'error'` and nothing is spawned. The check is on the\n * path the wrapper's `env` actually receives as its first operand — that is `SandboxBackend.wrap()`'s output, not\n * necessarily `ExecRequest.file`: when a backend prepends its own helper, the original program has become an\n * ARGUMENT of that helper, which `env` never inspects.\n */\nexport function isWrappableProgramPath(file: string): boolean {\n return !file.includes('=');\n}\n\n/** Why a run was refused before any spawn, in the words the result carries in `guarantees.notes`. */\nexport function unwrappableProgramNote(file: string): string {\n return (\n `exec: refused to run '${file}' under the requested rlimits: a program path containing '=' cannot be carried ` +\n `through the rlimit wrapper — '/usr/bin/env' would read it as a variable assignment and exec the next argument ` +\n 'instead. Nothing was spawned. (The same program runs when no rlimit is requested: there is no wrapper then.)'\n );\n}\n\nexport interface UlimitLimits {\n cpuSeconds?: number;\n fileSizeBytes?: number;\n openFiles?: number;\n processes?: number;\n}\n\nexport interface WrappedCommand {\n file: string;\n args: string[];\n}\n\nconst toIntArg = (value: number | undefined): string =>\n value === undefined ? '' : String(Math.max(0, Math.trunc(value)));\n\n/**\n * `ulimit -f` uses 1 KiB blocks on macOS and 512-byte blocks on Linux (the POSIX shells expose different units).\n * At least one block once a POSITIVE byte limit was asked for —\n * but `fileSizeBytes: 0` is a request in its own right (\"this command may create no file at all\"), and rounding it\n * up to one block would hand the caller 1024 writable bytes while `guarantees` still claims the limit applied.\n */\nconst toBlockArg = (bytes: number | undefined): string => {\n if (bytes === undefined) return '';\n if (bytes <= 0) return '0';\n const blockSize = process.platform === 'linux' ? 512 : 1024;\n return String(Math.max(1, Math.ceil(bytes / blockSize)));\n};\n\n/**\n * Wraps `file`/`args` so the process starts under `ulimit -t/-f/-n/-u` before `exec` hands control to it. `limits`\n * become POSITIONAL ARGUMENTS of the constant script (never text baked into it); an omitted limit is passed as an\n * empty string and the script's own `[ -n \"$k\" ]` guard skips it. A limit that IS asked for and that the kernel\n * refuses aborts with `ULIMIT_REFUSED_EXIT_CODE` instead of running unlimited. `ulimit -v` (address space) is not\n * attempted: toolchain.md §8 measured it failing outright on macOS (\"cannot modify limit: Invalid argument\"), so\n * `memoryBytes` is not enforced by this wrapper on any platform (SandboxCapabilities.memory stays `unavailable`).\n */\nexport function requestsAnyRlimit(limits: UlimitLimits): boolean {\n return (\n limits.cpuSeconds !== undefined ||\n limits.fileSizeBytes !== undefined ||\n limits.openFiles !== undefined ||\n limits.processes !== undefined\n );\n}\n\nexport function wrapWithUlimit(file: string, args: readonly string[], limits: UlimitLimits): WrappedCommand {\n return {\n file: ULIMIT_SHELL,\n args: [\n '-c',\n ULIMIT_WRAPPER_SCRIPT,\n file,\n toIntArg(limits.cpuSeconds),\n toBlockArg(limits.fileSizeBytes),\n toIntArg(limits.openFiles),\n toIntArg(limits.processes),\n ...args,\n ],\n };\n}\n","// The L0 isolated executor (DESIGN 2.6.6, ADR-0003). Every OS, pure Node: a verified cwd, an env built ONLY from\n// `ExecRequest.env`, a detached process-group kill tree with a post-run sweep, wall-clock and output-cap kills, and\n// the constant `ulimit` wrapper (I3). `fs`/`network` are recorded but not enforced here — that is L1 (U4.07); L0\n// is advisory filesystem isolation and no network isolation (DESIGN 0.3), which is exactly what `l0Capabilities`\n// reports.\n//\n// `ExecResult.outcome` describes how the EXECUTOR ended the process, never how the program judged itself: a\n// program that ran to completion is `'ok'` whatever its exit code (a non-zero exit is the caller's\n// `tool-terminal/nonzero-exit`, not this layer's business), and `'error'` is reserved for a run that produced no\n// usable process at all — an unverifiable cwd, a spawn failure, a rlimit the kernel refused.\nimport { spawn } from 'node:child_process';\nimport { realpathSync } from 'node:fs';\nimport { StringDecoder } from 'node:string_decoder';\nimport { type Clock, type Redactor, sha256Hex } from '@cohorte/base';\nimport type {\n ExecRequest,\n ExecResult,\n Executor,\n PidRegistry,\n SandboxBackend,\n SandboxCapabilities,\n} from '../contract/index.ts';\nimport { detectMissingL1Binaries, l0Capabilities, nativeShortfalls, resolveSandbox } from './capabilities.ts';\nimport {\n killGroup,\n killGroupMembers,\n processStartToken,\n sweepTracked,\n type TrackedDescendants,\n type TrackInterval,\n trackDescendants,\n} from './identity.ts';\nimport {\n isWrappableProgramPath,\n requestsAnyRlimit,\n ULIMIT_REFUSED_EXIT_CODE,\n unwrappableProgramNote,\n wrapWithUlimit,\n} from './ulimit.ts';\n\n/** Verified (toolchain.md §8: \"detached: true + negative-pid kill... put a timeout on stream draining as well\"). */\nconst GRACE_MS = 300;\nconst STREAM_DRAIN_TIMEOUT_MS = 500;\n/** 40 ms while the leader is young (an escapee must be seen before it is reaped), backing off after one second. */\nconst TRACK_INTERVAL: TrackInterval = { initialMs: 40, maxMs: 500, rampAfterMs: 1_000 };\nconst TAIL_MAX_CHARS = 64 * 1024;\n\nexport interface ExecutorOptions {\n /** chunks and the tail are sealed before they leave the executor (I7) */\n redactor: Redactor;\n pids: PidRegistry;\n clock: Clock;\n /** default: the `none` backend (L0). The L1 backends are injected by the composition root (U4.07). */\n backend?: SandboxBackend;\n}\n\n/** The built-in `none` `SandboxBackend`: wraps nothing, always reports the honest L0 level. */\nexport function createNoneBackend(): SandboxBackend {\n return {\n id: 'none',\n probe: () => Promise.resolve(l0Capabilities()),\n wrap: (file, args) => ({ file, args: [...args] }),\n };\n}\n\n/** The identity wrapper used whenever no L1 backend earned the reported guarantees. */\nconst NONE_BACKEND = createNoneBackend();\n\nfunction backendsFor(backend: SandboxBackend): readonly SandboxBackend[] {\n return backend.id === 'none' ? [] : [backend];\n}\n\n/**\n * DESIGN 2.6.6 / ADR-0003 §2b: \"`sandbox.require: native` is satisfied only by `enforced`: with a `partial`\n * backend the run refuses to start\". `level: 'L1-os'` alone is not enough — a backend whose escape self-test\n * (S-28 on macOS, S-29 on Linux) has not passed here reports `partial` on the axes that matter.\n */\nfunction satisfiesNative(guarantees: SandboxCapabilities): boolean {\n return (\n guarantees.level === 'L1-os' &&\n guarantees.filesystem === 'enforced' &&\n guarantees.network === 'enforced-off' &&\n guarantees.processEscape === 'denied'\n );\n}\n\n/**\n * DESIGN 2.6.6 L0 row: \"Filesystem and network isolation are advisory.\" The plan makes that explicit for the roots\n * a caller asked to be protected — `fs.readOnly` (the slot's dependency directories, DESIGN 5.7) and `fs.denyRead`\n * — by RECORDING them on the result rather than silently ignoring them: at L0 nothing enforces them, and U4.07 is\n * where these same roots become real. A request that asks for neither adds no note, so `ExecResult.guarantees`\n * still equals `probeSandbox()` for it.\n */\nfunction advisoryFsNotes(req: ExecRequest, guarantees: SandboxCapabilities): readonly string[] {\n if (guarantees.filesystem === 'enforced') return [];\n const parts: string[] = [];\n if (req.fs.readOnly.length > 0) parts.push(`readOnly: ${req.fs.readOnly.join(', ')}`);\n if (req.fs.denyRead.length > 0) parts.push(`denyRead: ${req.fs.denyRead.join(', ')}`);\n if (parts.length === 0) return [];\n return [\n `filesystem is '${guarantees.filesystem}' at this level: the requested roots are recorded but NOT enforced ` +\n `(${parts.join('; ')}) — an OS sandbox backend is what enforces them`,\n ];\n}\n\n/** `guarantees` plus the notes that describe THIS request; never the report cached for `capabilities()`. */\nfunction withNotes(guarantees: SandboxCapabilities, notes: readonly string[]): SandboxCapabilities {\n return notes.length === 0 ? guarantees : { ...guarantees, notes: [...guarantees.notes, ...notes] };\n}\n\n/** `req.cwd` must still refer to exactly what it claims to (defence against a TOCTOU swap between resolve and spawn). */\nfunction cwdVerifies(cwd: string): boolean {\n try {\n return realpathSync.native(cwd) === cwd;\n } catch {\n return false;\n }\n}\n\ntype EarlyOutcome = Extract<ExecResult['outcome'], 'sandbox-denied' | 'error' | 'killed'>;\n\nexport function createExecutor(options: ExecutorOptions): Executor {\n const backend = options.backend ?? NONE_BACKEND;\n const platform = process.platform;\n // What the last run observed about THIS MACHINE — `resolveSandbox`'s own report, never the per-request copy the\n // result carries (a `sandbox-denied` refusal or an advisory-filesystem record describes one call, not the\n // machine, and `capabilities()` is what `cohorte doctor --json` prints under \"sandbox\", DESIGN 2.6.6 [S]).\n let lastGuarantees: SandboxCapabilities | undefined;\n\n return {\n capabilities(): SandboxCapabilities {\n // Detection is synchronous and memoised (capabilities.ts), so a COLD `capabilities()` — called before any\n // `run()` or `probeSandbox()` — already reports the same `missing` as the probe, in the same tick.\n return lastGuarantees ?? l0Capabilities(detectMissingL1Binaries(platform));\n },\n run: async (req: ExecRequest, signal: AbortSignal): Promise<ExecResult> => {\n const run = await runOnce(options, backend, req, signal);\n lastGuarantees = run.observed;\n return run.result;\n },\n };\n}\n\n/**\n * `pgid: 0` is the \"nothing was spawned\" sentinel of every early return, NOT a process group: on POSIX `kill(-0)`\n * addresses the caller's own group, so `sweepGroupByToken`, `killGroup` and `killGroupMembers` all refuse a pgid\n * of 0 or 1 outright (identity.ts). A dependant must read it as \"no group\", never as one to sweep.\n */\nfunction emptyResult(\n outcome: EarlyOutcome,\n guarantees: SandboxCapabilities,\n redactor: Redactor,\n startedMonoMs: number,\n clock: Clock,\n): ExecResult {\n return {\n exitCode: null,\n outcome,\n tail: redactor.sealText('').text,\n outputSha256: sha256Hex(''),\n outputBytes: 0,\n truncated: false,\n durationMs: clock.monotonicMs() - startedMonoMs,\n pgid: 0,\n startToken: '',\n escapees: 0,\n guarantees,\n };\n}\n\n/** What one call produced: the result handed to the caller, and what it OBSERVED about the machine (`capabilities()`). */\ninterface RunOutput {\n result: ExecResult;\n observed: SandboxCapabilities;\n}\n\nasync function runOnce(\n options: ExecutorOptions,\n backend: SandboxBackend,\n req: ExecRequest,\n signal: AbortSignal,\n): Promise<RunOutput> {\n const platform = process.platform;\n const startedMonoMs = options.clock.monotonicMs();\n const resolved = await resolveSandbox(backendsFor(backend), platform);\n const observed = resolved.capabilities;\n // Everything below reports on THIS REQUEST; `observed` stays the untouched machine report.\n const guarantees = withNotes(observed, advisoryFsNotes(req, observed));\n const early = (outcome: EarlyOutcome, notes: readonly string[] = []): RunOutput => ({\n result: emptyResult(outcome, withNotes(guarantees, notes), options.redactor, startedMonoMs, options.clock),\n observed,\n });\n\n if (req.require === 'native' && !satisfiesNative(observed)) {\n // DESIGN 2.6.6: the refusal NAMES the failing axes rather than handing the caller a bare enum; minted from the\n // same `nativeShortfalls` that `sandboxUnavailable()` (exec/index.ts) turns into the catalogued error's message.\n return early('sandbox-denied', nativeShortfalls(observed, platform));\n }\n // A signal aborted BEFORE the spawn is a cancellation ('killed'), never `error` — `error` is reserved for a run\n // that could not produce a usable process (an unverifiable cwd, a spawn failure, a refused rlimit; R3).\n if (signal.aborted) return early('killed');\n if (!cwdVerifies(req.cwd)) return early('error');\n\n // The sandbox seam, applied by the backend that ACTUALLY earned `guarantees` (a backend whose probe failed is\n // used for neither). The `ulimit` wrapper goes OUTSIDE it, so the rlimits also cover the sandbox helper process\n // itself — a `sandbox-exec`/`bwrap` that forked without bound would otherwise escape `processes` before the real\n // program ever starts. DESIGN 2.6.6 does not fix the order; this is the choice, and `wrap()` is pure, so it is\n // free to be composed either way.\n const outer = (resolved.backend ?? NONE_BACKEND).wrap(req.file, req.args, req);\n // The `ulimit` wrapper exists to APPLY rlimits; a request that asks for none has nothing for it to do, and going\n // through it anyway would buy a shell process and its `/usr/bin/env` operand hazard for no guarantee at all. A\n // direct spawn is not a weaker path: there is still no shell, so I3 holds by construction, and with no shell\n // there is nothing to re-export `PWD`/`SHLVL` either, so S-20 holds trivially instead of by countermeasure.\n const wrapping = requestsAnyRlimit(req.limits);\n // Fail closed (I2) on the one program path the wrapper cannot carry: `/usr/bin/env` would read a path containing\n // `=` as a variable assignment and exec the next argv element — model-influenced text (I3) — in its place. The\n // refusal is scoped to the requests that actually need the wrapper: without it there is no `env` to be fooled,\n // and a worktree whose path contains `=` is not a reason to refuse every command (U1.04 request R4).\n if (wrapping && !isWrappableProgramPath(outer.file)) return early('error', [unwrappableProgramNote(outer.file)]);\n const launch = wrapping\n ? wrapWithUlimit(outer.file, outer.args, req.limits)\n : { file: outer.file, args: [...outer.args] };\n const child = spawn(launch.file, launch.args, {\n cwd: req.cwd,\n // Built ONLY from `req.env`: `process.env` is never read, never merged (S-20).\n env: { ...req.env },\n detached: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n // `child.pid` is set synchronously when the spawn succeeded, and `undefined` when it did not.\n const leaderPid = child.pid;\n\n // ---------------------------------------------------------------------------------------------------------\n // Everything the child can emit is wired HERE, before the first `await`. That is not style, it is correctness:\n // Node delivers `'exit'` once, to whoever is listening when the child is reaped, and a `stdout` that was never\n // resumed is thrown away when the process ends. A program faster than the `ps` fork of `processStartToken` below\n // — `/usr/bin/env`, `true`, anything tiny — is already gone by the time a listener added after an `await` exists:\n // measured on this machine, wiring the streams after that fork loses ALL of a fast program's output, and wiring\n // `'exit'` after it makes `await exited` wait for something that has already happened (the run then ends at its\n // own wall-clock timeout, or never, if the injected Clock ignores the timer's abort).\n // ---------------------------------------------------------------------------------------------------------\n let outcome: ExecResult['outcome'] = 'ok';\n let truncated = false;\n let totalBytes = 0;\n let rawTail = '';\n const chunks: Buffer[] = [];\n\n // One decoder per stream, kept across reads: a multi-byte UTF-8 sequence that straddles a pipe-read boundary\n // would otherwise be destroyed (U+FFFD) in both the text handed to the model and the accumulated tail. `chunks`\n // and `outputSha256` stay byte-based and are unaffected. A read that ends mid-sequence decodes to '' and is\n // still reported, so `bytes` stays an exact account of what was read.\n const decoders: Record<'stdout' | 'stderr', StringDecoder> = {\n stdout: new StringDecoder('utf8'),\n stderr: new StringDecoder('utf8'),\n };\n\n const sealChunk = (stream: 'stdout' | 'stderr', bytes: Buffer): void => {\n const text = decoders[stream].write(bytes);\n rawTail = (rawTail + text).slice(-TAIL_MAX_CHARS);\n req.onChunk?.({ stream, bytes: bytes.length, text: options.redactor.sealText(text).text });\n };\n\n let escalation: Promise<void> | undefined;\n const escalate = (why: ExecResult['outcome']): void => {\n // No pid means the spawn failed; the early return below is that call's whole story.\n if (escalation !== undefined || leaderPid === undefined) return;\n outcome = why;\n escalation = killGroup(leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n };\n\n const onData =\n (stream: 'stdout' | 'stderr') =>\n (chunk: Buffer): void => {\n if (truncated) return;\n let bytes = chunk;\n if (totalBytes + bytes.length > req.maxOutputBytes) {\n const room = Math.max(0, req.maxOutputBytes - totalBytes);\n bytes = bytes.subarray(0, room);\n truncated = true;\n }\n if (bytes.length > 0) {\n totalBytes += bytes.length;\n chunks.push(Buffer.from(bytes));\n sealChunk(stream, bytes);\n }\n if (truncated) escalate('output-capped');\n };\n child.stdout?.on('data', onData('stdout'));\n child.stderr?.on('data', onData('stderr'));\n\n let exitCode: number | null = null;\n let exitSignal: string | undefined;\n const exited = new Promise<void>((resolve) => {\n child.once('exit', (code, sig) => {\n exitCode = code;\n exitSignal = sig ?? undefined;\n resolve();\n });\n });\n\n const spawnOutcome = await new Promise<'spawned' | 'error'>((resolve) => {\n child.once('spawn', () => resolve('spawned'));\n child.once('error', () => resolve('error'));\n });\n if (spawnOutcome === 'error' || leaderPid === undefined) return early('error');\n // A later 'error' (e.g. an EPIPE after the child is gone) would otherwise throw, unhandled, once the `once`\n // listener above has fired and been removed.\n child.on('error', () => {});\n // Computed and recorded NOW, while the leader is still alive: `ps -o lstart=` (or /proc/.../stat) needs a live\n // pid, and a crash between here and exit must still leave a recoverable (pgid, startToken) trace (DESIGN 4.4).\n // A program that beat this fork to its own exit simply has no token: `unknown:<pid>` says so rather than\n // inventing one, and `sweepGroupByToken` verifies nothing against it (identity.ts).\n const startToken = (await processStartToken(leaderPid, platform)) ?? `unknown:${leaderPid}`;\n options.pids.record({ pgid: leaderPid, startToken, label: req.file });\n\n // `pid -> start time as first seen`: the sweep signals a tracked pid only while it is still that same process.\n const escapeesSeen: TrackedDescendants = new Map<number, string>();\n const trackingTask = trackDescendants(\n leaderPid,\n escapeesSeen,\n exited,\n (ms) => options.clock.sleep(ms),\n TRACK_INTERVAL,\n );\n\n // `outcome` may never depend on a Clock honouring an OPTIONAL argument: `Clock.sleep(ms, signal?)` (@cohorte/base\n // ports.ts) leaves the signal optional, so a perfectly conforming clock that ignores it would otherwise make every\n // run report `timed-out` for a program that exited in milliseconds. `finished` is the correctness condition; the\n // abort below stays what it always was — the optimisation that stops the timer early.\n let finished = false;\n const timeoutAbort = new AbortController();\n const timeoutTask = options.clock\n .sleep(req.timeoutMs, timeoutAbort.signal)\n .then(() => {\n if (!finished) escalate('timed-out');\n })\n .catch(() => {\n // Aborted because the process already ended, or the caller cancelled: nothing to do.\n });\n\n const onExternalAbort = (): void => escalate('killed');\n if (!signal.aborted) signal.addEventListener('abort', onExternalAbort, { once: true });\n\n await exited;\n finished = true;\n timeoutAbort.abort();\n signal.removeEventListener('abort', onExternalAbort);\n await timeoutTask;\n await trackingTask;\n if (escalation) await escalation;\n // Safety net: whatever ended the wait, make sure nothing of the group is left running. The leader has been\n // reaped by now, so `kill(-leaderPid)` is no longer addressable to a group we can prove is ours — this walks\n // the process table and signals only the pids still IN the group (DESIGN 4.4 step 5). `GRACE_MS`, like every\n // other kill path here: DESIGN 2.6.6 says TERM -> grace -> KILL, and a leftover grandchild of a command that\n // ended NORMALLY is the case that most deserves its chance to flush and exit on the TERM. It costs nothing when\n // the group is already empty — the grace is only waited when something was actually signalled (identity.ts).\n await killGroupMembers(leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n\n await drainStreams(child, (ms) => options.clock.sleep(ms).catch(() => {}));\n // Flush whatever incomplete sequence the decoders still hold; only the tail can still take it.\n const flushed = decoders.stdout.end() + decoders.stderr.end();\n if (flushed !== '') rawTail = (rawTail + flushed).slice(-TAIL_MAX_CHARS);\n\n const escapees = await sweepTracked(escapeesSeen, leaderPid, (ms) => options.clock.sleep(ms), GRACE_MS);\n options.pids.remove(leaderPid);\n\n // A rlimit the kernel refused: the wrapper aborted before `exec`, so no program ever ran. It is the ONE exit\n // code the wrapper mints itself, and it always comes with no output at all (the shell's own diagnostics are\n // discarded, and its `exec` failures write to stderr first), so this cannot swallow a program's own 126.\n if (outcome === 'ok' && exitCode === ULIMIT_REFUSED_EXIT_CODE && totalBytes === 0 && requestsAnyRlimit(req.limits)) {\n outcome = 'error';\n }\n\n const output = Buffer.concat(chunks);\n const sealedTail = options.redactor.sealText(rawTail).text;\n const durationMs = options.clock.monotonicMs() - startedMonoMs;\n\n return {\n result: {\n exitCode,\n outcome,\n tail: sealedTail,\n outputSha256: sha256Hex(output),\n outputBytes: totalBytes,\n truncated,\n durationMs,\n pgid: leaderPid,\n startToken,\n escapees,\n guarantees,\n ...(exitSignal !== undefined ? { signal: exitSignal } : {}),\n },\n observed,\n };\n}\n\nasync function drainStreams(child: ReturnType<typeof spawn>, wait: (ms: number) => Promise<void>): Promise<void> {\n const closed = Promise.all(\n [child.stdout, child.stderr].map(\n (stream) =>\n new Promise<void>((resolve) => {\n if (!stream || stream.destroyed) {\n resolve();\n return;\n }\n stream.once('close', () => resolve());\n }),\n ),\n );\n let timedOut = false;\n await Promise.race([\n closed.then(() => {}),\n wait(STREAM_DRAIN_TIMEOUT_MS).then(() => {\n timedOut = true;\n }),\n ]);\n if (timedOut) {\n child.stdout?.destroy();\n child.stderr?.destroy();\n }\n}\n","// The L0 isolated executor and the sandbox capability probe (PLAN U1.04, DESIGN 2.6.6, ADR-0003).\nimport type { SandboxBackend, SandboxCapabilities } from '../contract/index.ts';\nimport { computeCapabilities } from './capabilities.ts';\n\nexport { nativeShortfalls, sandboxUnavailable } from './capabilities.ts';\nexport { createExecutor, createNoneBackend, type ExecutorOptions } from './executor.ts';\nexport { processStartToken, type SweepByTokenOptions, type SweepByTokenResult, sweepGroupByToken } from './identity.ts';\nexport {\n isWrappableProgramPath,\n type UlimitLimits,\n type WrappedCommand,\n wrapWithUlimit,\n} from './ulimit.ts';\n\nexport interface ProbeSandboxOptions {\n /** the L1 backends to probe, in order of preference; none usable = L0 is reported, honestly */\n backends?: readonly SandboxBackend[];\n platform?: string;\n}\n\n/**\n * `cohorte doctor --json`'s \"sandbox\" section (spec 9 \"garanties réellement actives\"). Until U4.07 constructs a\n * real Seatbelt/bubblewrap `SandboxBackend`, this always reports the honest L0 level: the L1 binaries this machine\n * happens to have installed are detected only for `missing`/`notes`, never used to widen the claimed guarantees.\n */\nexport function probeSandbox(options: ProbeSandboxOptions = {}): Promise<SandboxCapabilities> {\n return computeCapabilities(options.backends ?? [], options.platform ?? process.platform);\n}\n","// The only module allowed to mint the compile-time Sealed<T> marker.\nimport type { JsonValue, Redaction, Sealed, SealedText } from '@cohorte/base';\n\nexport function sealText(text: string, redactions: Redaction[]): { text: SealedText; redactions: Redaction[] } {\n return { text: text as SealedText, redactions };\n}\n\nexport function sealJson<T extends JsonValue>(\n value: T,\n redactions: Redaction[],\n): { value: Sealed<T>; redactions: Redaction[] } {\n return { value: value as Sealed<T>, redactions };\n}\n","// Secret registration, recursive sealing and commit-time detectors.\nimport { type JsonValue, type Redaction, type Redactor, type Sealed, type SealedText, sha256Hex } from '@cohorte/base';\nimport { sealJson, sealText } from './seal.ts';\n\nexport interface RedactorOptions {\n /** values learned before the run starts (the dotenv files the run could see), by id */\n secrets?: Readonly<Record<string, string>>;\n}\n\nconst replacement = '[REDACTED]';\nconst escapePointerToken = (token: string): string => token.replaceAll('~', '~0').replaceAll('/', '~1');\n\nfunction scrub(\n text: string,\n path: string,\n secrets: readonly { value: string; id: string }[],\n redactions: Redaction[],\n): string {\n let result = text;\n for (const { value, id } of secrets) {\n if (result.includes(value)) {\n result = result.split(value).join(replacement);\n redactions.push({ path, reason: 'secret-value', detector: `registered:${id}` });\n }\n }\n return result;\n}\n\nexport function createRedactor(options: RedactorOptions = {}): Redactor {\n const secrets: Array<{ value: string; id: string }> = [];\n for (const [id, value] of Object.entries(options.secrets ?? {})) {\n if (value.length >= 8) secrets.push({ value, id });\n }\n secrets.sort((a, b) => b.value.length - a.value.length);\n const walk = (value: JsonValue, path: string, redactions: Redaction[]): JsonValue => {\n if (typeof value === 'string') return scrub(value, path, secrets, redactions);\n if (Array.isArray(value)) return value.map((item, index) => walk(item, `${path}/${index}`, redactions));\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [key, walk(item, `${path}/${escapePointerToken(key)}`, redactions)]),\n );\n }\n return value;\n };\n return {\n registerSecret(value, id): void {\n if (value.length < 8)\n throw new RangeError('registerSecret: a secret value shorter than 8 characters is rejected');\n secrets.push({ value, id });\n secrets.sort((a, b) => b.value.length - a.value.length);\n },\n sealText(text): { text: SealedText; redactions: Redaction[] } {\n const redactions: Redaction[] = [];\n return sealText(scrub(text, '', secrets, redactions), redactions);\n },\n sealJson<T extends JsonValue>(value: T): { value: Sealed<T>; redactions: Redaction[] } {\n const redactions: Redaction[] = [];\n return sealJson(walk(value, '', redactions) as T, redactions);\n },\n };\n}\n\n/** The commit-time secret scan (DESIGN 5.3): path classes + the Redactor's detectors over staged content. */\nexport function scanForSecrets(bytes: Uint8Array, path: string): Redaction[] {\n const redactions: Redaction[] = [];\n const digest = sha256Hex(bytes);\n const text = new TextDecoder().decode(bytes);\n const add = (reason: Redaction['reason'], detector: string): void => {\n redactions.push({ path: '', reason, detector, sha256: digest });\n };\n if (bytes.byteLength > 10 * 1024 * 1024) add('size', 'size:10MiB');\n if (/(^|[/\\\\])(?:\\.env|.*\\.pem|.*\\.key)$/i.test(path)) add('sensitive-path', 'path:secret-file');\n if (/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/.test(text)) add('private-key', 'pattern:private-key');\n if (/(?:AKIA|ASIA)[A-Z0-9]{16}/.test(text)) add('secret-pattern', 'pattern:aws-access-key');\n if (/(?:ghp|github_pat)_[A-Za-z0-9_]{20,}/.test(text)) add('secret-pattern', 'pattern:github-token');\n if (/sk-[A-Za-z0-9]{20,}/.test(text)) add('secret-pattern', 'pattern:openai-key');\n return redactions;\n}\n","// Frozen built-in DATA (DESIGN 2.6.3 step 5, 2.6.4, 2.6.6; PLAN F-8). None of it is overridable: no project config\n// and no approval lifts a protected root, a trampoline or the agent git deny set.\n\nconst frozen = <const T extends readonly string[]>(values: T): T => Object.freeze(values);\n\n/** Worktree-relative, any depth: `.git` (file OR directory), Cohorte's own directory, Pi's project directory. */\nexport const PROTECTED_REPO_GLOBS = frozen(['**/.git', '**/.git/**', '**/.cohorte/**', '**/.pi/**']);\n\n/**\n * Relative to the user's HOME; the caller canonicalises them into `PathResolverOptions.protectedRoots`, together with\n * Cohorte's install dir, every pinned runtime artifact and the node binary dir. `~/.cohorte/worktrees` is deliberately\n * ABSENT (DESIGN 5.1): agent worktrees live there.\n */\nexport const PROTECTED_HOME_PATHS = frozen([\n '.cohorte/keys',\n '.cohorte/versions',\n '.cohorte/pi-agent',\n '.cohorte/brains',\n '.cohorte/trust',\n '.cohorte/config.yaml',\n '.pi/agent',\n '.ssh',\n '.aws',\n '.gnupg',\n '.config/gh',\n '.config/gcloud',\n]);\n\n/** HOME-relative read denials of every L1 profile (DESIGN 2.6.6); the caller adds the project's state dir. */\nexport const L1_DENY_READ_HOME_PATHS = frozen([\n '.pi/agent',\n '.cohorte/keys',\n '.cohorte/versions',\n '.cohorte/pi-agent',\n '.cohorte/brains',\n '.cohorte/trust',\n '.ssh',\n '.aws',\n '.gnupg',\n '.config/gh',\n '.config/gcloud',\n]);\n\n/** The default `denyRead` / `denyWrite` of every AgentGrant (DESIGN 2.6.1). Deny sets always win. */\nexport const DEFAULT_DENY_GLOBS = frozen([\n '**/.env*',\n '**/*.pem',\n '**/*.key',\n '**/id_rsa*',\n '**/id_ed25519*',\n '**/.git',\n '**/.git/**',\n '**/.cohorte/**',\n '**/.pi/**',\n '**/.npmrc',\n '**/.netrc',\n]);\n\n/**\n * Programs that run OTHER programs or reach the network: denied with `overridable: false` (DESIGN 2.6.4 step 2).\n * `pi` and `cohorte` are in it: Pi has an `auth` subcommand that prints the OAuth token. A project that truly needs one\n * declares an exact-argv rule under `policy.dangerousCommands`, and every use is an `ask`.\n */\nexport const TRAMPOLINE_PROGRAMS = frozen([\n 'sh',\n 'bash',\n 'zsh',\n 'dash',\n 'fish',\n 'ksh',\n 'csh',\n 'env',\n 'xargs',\n 'sudo',\n 'su',\n 'doas',\n 'eval',\n 'exec',\n 'nohup',\n 'time',\n 'watch',\n 'npx',\n 'pnpx',\n 'bunx',\n 'corepack',\n 'ssh',\n 'scp',\n 'curl',\n 'wget',\n 'nc',\n 'perl',\n 'ruby',\n 'osascript',\n 'pi',\n 'cohorte',\n]);\n\n/** `python*`: python, python3, python3.12, pythonw ... */\nexport const TRAMPOLINE_PREFIXES = frozen(['python']);\n\nconst TRAMPOLINES: ReadonlySet<string> = new Set(TRAMPOLINE_PROGRAMS);\n\n/** `name` is the alias-normalised BARE program name; the comparison is exact-case (the name was resolved on disk first). */\nexport function isTrampoline(name: string): boolean {\n return TRAMPOLINES.has(name) || TRAMPOLINE_PREFIXES.some((prefix) => name.startsWith(prefix));\n}\n\n/** Agents have no commit capability (D9): commits and merges are Cohorte's. Built-in, non-overridable. */\nexport const AGENT_GIT_DENIED_SUBCOMMANDS = frozen([\n 'commit',\n 'push',\n 'merge',\n 'rebase',\n 'reset',\n 'checkout',\n 'switch',\n 'worktree',\n 'config',\n 'update-ref',\n 'filter-branch',\n 'gc',\n]);\n\n/** The NAMES an L0 child env may carry (DESIGN 2.6.6). Built from scratch, never inherited. */\nexport const L0_ENV_ALLOWLIST = frozen([\n 'PATH',\n 'HOME',\n 'LANG',\n 'LC_ALL',\n 'TERM',\n 'CI',\n 'TMPDIR',\n 'NO_COLOR',\n 'GIT_CONFIG_GLOBAL',\n 'GIT_CONFIG_NOSYSTEM',\n 'GIT_TERMINAL_PROMPT',\n]);\n\n/** The allowlisted names whose VALUE is fixed; PATH (pinned), HOME and TMPDIR (per-agent scratch), LANG and LC_ALL come from the run. */\nexport const L0_ENV_FIXED: Readonly<Record<string, string>> = Object.freeze({\n TERM: 'dumb',\n CI: '1',\n NO_COLOR: '1',\n GIT_CONFIG_GLOBAL: '/dev/null',\n GIT_CONFIG_NOSYSTEM: '1',\n GIT_TERMINAL_PROMPT: '0',\n});\n\n/**\n * What \"env contains only the allowlist\" means, defined once: visible ⊆ allow ∪ OS_INJECTED_ENV[platform].\n * CoreFoundation injects `__CF_USER_TEXT_ENCODING` into every macOS process (PLAN F-8). Mirrored, value for value, by\n * `@cohorte/runtime-pi/host-protocol`, which may not import this package.\n */\nexport const OS_INJECTED_ENV: Readonly<Record<string, readonly string[]>> = Object.freeze({\n darwin: Object.freeze(['__CF_USER_TEXT_ENCODING']),\n});\n\n/** The env names a child may legitimately SEE on this platform, given what it was allowed. */\nexport function visibleEnvAllowed(allow: readonly string[], platform: string): ReadonlySet<string> {\n return new Set([...allow, ...(OS_INJECTED_ENV[platform] ?? [])]);\n}\n","// Decisions, verdicts, grants and the pure engine (DESIGN 2.6.1, 2.6.2).\nimport {\n AgentId,\n ApprovalId,\n type BudgetCounters,\n type Clock,\n type JsonValue,\n JsonValueSchema,\n type RunId,\n Sha256,\n type ToolCallId,\n} from '@cohorte/base';\nimport { CommandRule, type NetworkPolicyConfig, type Ownership } from '@cohorte/config/schema';\nimport { type TUnsafe, Type } from 'typebox';\nimport type { CommandPolicy, ProgramResolver } from './commands.ts';\nimport type { CanonicalPath, PathIntent, PathResolver, ResolvedPath, SymlinkPolicy } from './paths.ts';\n\n/**\n * Spec 9, exactly. The pure engine returns allow | deny | ask. allow-once / allow-for-run are APPROVAL RESOLUTIONS:\n * rows in `approvals`, found by grantKey at stage 6, reported in the verdict with the approvalId so the audit trail\n * says WHY. An `ask` nobody can answer becomes `deny`: an unanswerable ask never silently runs.\n */\nexport const POLICY_DECISIONS = ['allow', 'deny', 'ask', 'allow-once', 'allow-for-run'] as const;\nexport type PolicyDecision = (typeof POLICY_DECISIONS)[number];\n\nexport const GATE_STAGE_NAMES = [\n 'liveness',\n 'schema',\n 'capability',\n 'path',\n 'command',\n 'network',\n 'budget',\n 'approval',\n] as const;\nexport type GateStageName = (typeof GATE_STAGE_NAMES)[number];\n\nexport interface GateCall {\n runId: RunId;\n agentId: AgentId;\n incarnation: number;\n toolCallId: ToolCallId;\n tool: string;\n input: JsonValue;\n phase: string;\n role: string;\n}\n\nexport interface GlobSet {\n include: string[];\n exclude: string[];\n}\n\n/**\n * THE glob semantics of 2.6.3 step 7, implemented once (decide/paths) and exported as a contract so `tools`\n * (list_files, search, git_diff output filtering, WorkspaceReader) and `core` (grants, zones) never configure\n * picomatch themselves. `toExcludeArgs` renders a deny set for an external enumerator.\n */\nexport interface GlobMatcher {\n matches(relativePosixPath: string, set: GlobSet): boolean;\n isDenied(relativePosixPath: string, grant: AgentGrant, intent: 'read' | 'write'): boolean;\n toExcludeArgs(set: GlobSet, dialect: 'rg-glob' | 'git-pathspec'): string[];\n}\n\nexport interface NormalizedCall {\n tool: string;\n paths: { arg: string; resolved: ResolvedPath; intent: PathIntent }[];\n command?: {\n file: CanonicalPath;\n args: string[];\n cwd: CanonicalPath;\n ruleId: string;\n replay: 'idempotent' | 'at-most-once';\n network: boolean;\n timeoutMs: number;\n };\n /** strictly validated, size-capped */\n input: JsonValue;\n /** canonical subject used for grant_key (DESIGN 4.5) */\n grantKeyMaterial: JsonValue;\n}\n\n/** facts pre-fetched; sync */\nexport interface BranchResolver {\n branchOf(\n cwd: CanonicalPath,\n ): { kind: 'branch'; name: string; protected: boolean } | { kind: 'detached-or-unknown'; protected: true };\n}\n\nexport interface BudgetReader {\n remaining(level: 'run' | 'phase' | 'agent' | 'provider' | 'tool', id: string): BudgetCounters;\n callsInLastMinute(agentId: AgentId, tool: string): number;\n}\n\n/** every verdict is schema-valid */\nexport interface PolicyVerdict {\n decision: PolicyDecision;\n stage: GateStageName;\n ruleId: string;\n /** humans / events */\n reason: string;\n /** no secrets, no absolute host paths, no policy internals; ends with \"Do not retry.\" for deny */\n modelFacingReason: string;\n /** false = built-in rule that no project config and no approval can lift */\n overridable: boolean;\n /** true => run goes BLOCKED (spec 24): symlink escape, protected path write, runtime path, MAC failure… */\n securityViolation: boolean;\n asks: { stage: GateStageName; ruleId: string; reason: string }[];\n /** every rule id evaluated, for `cohorte policy explain` and the audit event */\n evaluatedRules: string[];\n /** what will actually execute: canonical paths, resolved program realpath, clamped timeout, replay class */\n normalized: NormalizedCall | null;\n approvalId?: ApprovalId;\n grantId?: string;\n}\n\n/** computed by core from ownership.yaml + role defaults + phase contract; persisted in agents.grants_json */\nexport interface AgentGrant {\n agentId: AgentId;\n role: string;\n digest: Sha256;\n tools: string[];\n roots: { workspace: CanonicalPath | null; readOnly: CanonicalPath[] };\n read: GlobSet;\n /** write ⊆ owned paths of the surface; worktree-relative POSIX, dot:true, slash-less pattern means any depth */\n write: GlobSet;\n /** always win. Defaults: DEFAULT_DENY_GLOBS */\n denyRead: GlobSet;\n denyWrite: GlobSet;\n commands: CommandPolicy;\n /** ids only; values resolved inside the Executor and registered with the Redactor first */\n secrets: { id: string; exposeAs: 'env'; name: string }[];\n /** spec 8 \"grant temporaire audité\" */\n temporary: { grantId: string; approvalId: ApprovalId; grantKey: string; expires: 'call' | 'run' }[];\n limits: {\n maxToolCalls: number;\n maxCallsPerMinute: number;\n perTool: Record<string, { maxCalls?: number; timeoutMs: number; maxOutputBytes: number }>;\n };\n}\n\n/** all SYNCHRONOUS */\nexport interface PolicyPorts {\n paths: PathResolver;\n branches: BranchResolver;\n budgets: BudgetReader;\n programs: ProgramResolver;\n clock: Clock;\n}\n\n/** deterministic => table-testable */\nexport interface PolicyEngine {\n evaluate(call: GateCall, grant: AgentGrant, policy: PolicySnapshot, ports: PolicyPorts): PolicyVerdict;\n}\n\n/** Immutable, hashed, built from the RESOLVED config at run start and held in host memory (I4): the project file is never re-read. */\nexport interface PolicySnapshot {\n readonly digest: Sha256;\n /** `policy.commands.*`, `policy.dangerousCommands` (always `ask`) and `checks.*` (exact argv, idempotent), as one rule list */\n readonly commands: CommandPolicy;\n readonly symlinks: SymlinkPolicy;\n readonly network: NetworkPolicyConfig;\n readonly protectedBranches: readonly string[];\n /** for the `shared` / `approval: human` asks of stage 3 (DESIGN 5.6) */\n readonly ownership: Ownership;\n /** under L0 a rule flagged `network` is DENIED, not asked (DESIGN 2.6.6) */\n readonly sandboxLevel: 'L0-process' | 'L1-os';\n}\n\n/** So that stages 1 and 3 validate a call without importing `tools` (PLAN PC-4). Implemented from the tool catalogue. */\nexport interface ToolIntrospection {\n /** the STRICT JSON Schema of the tool's input; undefined = unknown tool */\n schemaOf(tool: string): JsonValue | undefined;\n /** every path-typed argument of this input, with what the tool does to it */\n pathArgsOf(tool: string, input: JsonValue): { arg: string; value: string; intent: PathIntent }[];\n}\n\nconst closed = { additionalProperties: false } as const;\nconst oneOf = <const V extends readonly string[]>(values: V): TUnsafe<V[number]> =>\n Type.Unsafe<V[number]>({ type: 'string', enum: [...values] });\nconst count = () => Type.Integer({ minimum: 0 });\nconst canonicalPath = () => Type.String({ minLength: 1 });\nconst replay = () => oneOf(['idempotent', 'at-most-once']);\nconst globSet = () => Type.Object({ include: Type.Array(Type.String()), exclude: Type.Array(Type.String()) }, closed);\n\nconst ResolvedPathSchema = Type.Object(\n {\n canonical: canonicalPath(),\n relative: Type.String(),\n root: canonicalPath(),\n exists: Type.Boolean(),\n identity: Type.Optional(Type.Object({ dev: Type.Number(), ino: Type.Number(), nlink: Type.Number() }, closed)),\n viaSymlink: Type.Boolean(),\n },\n closed,\n);\n\nconst NormalizedCallSchema = Type.Object(\n {\n tool: Type.String(),\n paths: Type.Array(\n Type.Object(\n {\n arg: Type.String(),\n resolved: ResolvedPathSchema,\n intent: oneOf(['read', 'write', 'create', 'list', 'exec-cwd']),\n },\n closed,\n ),\n ),\n command: Type.Optional(\n Type.Object(\n {\n file: canonicalPath(),\n args: Type.Array(Type.String()),\n cwd: canonicalPath(),\n ruleId: Type.String(),\n replay: replay(),\n network: Type.Boolean(),\n timeoutMs: count(),\n },\n closed,\n ),\n ),\n input: JsonValueSchema,\n grantKeyMaterial: JsonValueSchema,\n },\n closed,\n);\n\nconst ask = () => Type.Object({ stage: oneOf(GATE_STAGE_NAMES), ruleId: Type.String(), reason: Type.String() }, closed);\n\n/** [S] */\nexport const PolicyVerdict: TUnsafe<PolicyVerdict> = Type.Unsafe<PolicyVerdict>(\n Type.Object(\n {\n decision: oneOf(POLICY_DECISIONS),\n stage: oneOf(GATE_STAGE_NAMES),\n ruleId: Type.String({ minLength: 1 }),\n reason: Type.String(),\n modelFacingReason: Type.String(),\n overridable: Type.Boolean(),\n securityViolation: Type.Boolean(),\n asks: Type.Array(ask()),\n evaluatedRules: Type.Array(Type.String()),\n normalized: Type.Union([NormalizedCallSchema, Type.Null()]),\n approvalId: Type.Optional(ApprovalId),\n grantId: Type.Optional(Type.String()),\n },\n closed,\n ),\n);\n\n/** [S] */\nexport const AgentGrant: TUnsafe<AgentGrant> = Type.Unsafe<AgentGrant>(\n Type.Object(\n {\n agentId: AgentId,\n role: Type.String({ minLength: 1 }),\n digest: Sha256,\n tools: Type.Array(Type.String()),\n roots: Type.Object(\n { workspace: Type.Union([canonicalPath(), Type.Null()]), readOnly: Type.Array(canonicalPath()) },\n closed,\n ),\n read: globSet(),\n write: globSet(),\n denyRead: globSet(),\n denyWrite: globSet(),\n commands: Type.Object({ default: Type.Literal('deny'), rules: Type.Array(CommandRule) }, closed),\n secrets: Type.Array(\n Type.Object({ id: Type.String(), exposeAs: Type.Literal('env'), name: Type.String() }, closed),\n ),\n temporary: Type.Array(\n Type.Object(\n { grantId: Type.String(), approvalId: ApprovalId, grantKey: Type.String(), expires: oneOf(['call', 'run']) },\n closed,\n ),\n ),\n limits: Type.Object(\n {\n maxToolCalls: count(),\n maxCallsPerMinute: count(),\n perTool: Type.Record(\n Type.String(),\n Type.Object({ maxCalls: Type.Optional(count()), timeoutMs: count(), maxOutputBytes: count() }, closed),\n ),\n },\n closed,\n ),\n },\n closed,\n ),\n);\n","// Executor and sandbox levels (DESIGN 2.6.6, ADR-0003).\nimport type { SealedText, Sha256 } from '@cohorte/base';\nimport { type TUnsafe, Type } from 'typebox';\nimport type { CanonicalPath } from './paths.ts';\n\nexport interface ExecRequest {\n /** resolved program; NEVER a shell line */\n file: CanonicalPath;\n args: readonly string[];\n cwd: CanonicalPath;\n /** complete; the executor never reads process.env */\n env: Readonly<Record<string, string>>;\n fs: { readWrite: CanonicalPath[]; readOnly: CanonicalPath[]; denyRead: CanonicalPath[] };\n /** 'unrestricted' is legal ONLY for Cohorte-run provisioning effects (DESIGN 5.7), never for an agent call */\n network: 'none' | 'unrestricted';\n timeoutMs: number;\n maxOutputBytes: number;\n stdin: 'ignore';\n limits: { cpuSeconds?: number; fileSizeBytes?: number; openFiles?: number; processes?: number; memoryBytes?: number };\n require: 'native' | 'best-effort';\n onChunk?: (c: { stream: 'stdout' | 'stderr'; bytes: number; text: SealedText }) => void;\n}\n\nexport interface ExecResult {\n exitCode: number | null;\n signal?: string;\n outcome: 'ok' | 'error' | 'timed-out' | 'killed' | 'output-capped' | 'sandbox-denied';\n tail: SealedText;\n outputSha256: Sha256;\n outputBytes: number;\n truncated: boolean;\n fullOutputPath?: string;\n durationMs: number;\n pgid: number;\n startToken: string;\n /** processes that left the group, found by the post-run sweep */\n escapees: number;\n guarantees: SandboxCapabilities;\n}\n\n/** argv only: there is no `run(commandLine: string)` and there never will be (I3). */\nexport interface Executor {\n capabilities(): SandboxCapabilities;\n run(req: ExecRequest, signal: AbortSignal): Promise<ExecResult>;\n}\n\nexport interface SandboxBackend {\n readonly id: 'seatbelt' | 'bubblewrap' | 'none';\n probe(): Promise<SandboxCapabilities>;\n /** pure */\n wrap(file: CanonicalPath, args: readonly string[], req: ExecRequest): { file: CanonicalPath; args: string[] };\n}\n\n/**\n * Exactly what `cohorte doctor --json` prints under \"sandbox\" (spec 9 \"garanties réellement actives\").\n * 'partial': the backend is active but its escape self-test (S-28 on macOS, S-29 on Linux) has not passed here.\n */\nexport interface SandboxCapabilities {\n level: 'L0-process' | 'L1-os';\n backend: 'none' | 'seatbelt' | 'bubblewrap';\n filesystem: 'enforced' | 'partial' | 'advisory';\n network: 'enforced-off' | 'partial' | 'unenforced';\n /** LaunchServices / AppleEvents / job creation / signalling other processes / host Unix sockets */\n processEscape: 'denied' | 'partial' | 'possible';\n envFiltering: 'enforced';\n timeout: 'enforced';\n outputCap: 'enforced';\n cpuTime: 'enforced' | 'unavailable';\n memory: 'enforced' | 'node-only' | 'unavailable';\n processes: 'enforced' | 'unavailable';\n killTree: 'pid-namespace' | 'process-group-with-sweep';\n /** e.g. [\"bwrap\"], [\"kernel.apparmor_restrict_unprivileged_userns=1\"] */\n missing: string[];\n notes: string[];\n}\n\nconst oneOf = <const V extends readonly string[]>(values: V): TUnsafe<V[number]> =>\n Type.Unsafe<V[number]>({ type: 'string', enum: [...values] });\n\n/** [S]. Annotated so that Biome never infers it (docs/v3/requests/U0.02.md R1). */\nexport const SandboxCapabilities: TUnsafe<SandboxCapabilities> = Type.Unsafe<SandboxCapabilities>(\n Type.Object(\n {\n level: oneOf(['L0-process', 'L1-os']),\n backend: oneOf(['none', 'seatbelt', 'bubblewrap']),\n filesystem: oneOf(['enforced', 'partial', 'advisory']),\n network: oneOf(['enforced-off', 'partial', 'unenforced']),\n processEscape: oneOf(['denied', 'partial', 'possible']),\n envFiltering: Type.Literal('enforced'),\n timeout: Type.Literal('enforced'),\n outputCap: Type.Literal('enforced'),\n cpuTime: oneOf(['enforced', 'unavailable']),\n memory: oneOf(['enforced', 'node-only', 'unavailable']),\n processes: oneOf(['enforced', 'unavailable']),\n killTree: oneOf(['pid-namespace', 'process-group-with-sweep']),\n missing: Type.Array(Type.String()),\n notes: Type.Array(Type.String()),\n },\n { additionalProperties: false },\n ),\n);\n\n/** Where the L0 executor records what it spawned, so the post-run sweep and the Resumer can find processes that left the group. */\nexport interface PidRegistry {\n record(entry: { pgid: number; startToken: string; label: string }): void;\n remove(pgid: number): void;\n}\n","// DESIGN 2.2.6 — capabilities: honest, tri-state, doctor-reportable.\nimport { type Static, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\n\nexport const Cap = Type.Union([\n Type.Object({ value: Type.Literal('yes') }, strict),\n Type.Object({ value: Type.Literal('no'), why: Type.String() }, strict),\n Type.Object({ value: Type.Literal('partial'), why: Type.String() }, strict),\n]);\nexport type Cap = Static<typeof Cap>;\n\nexport const RuntimeCapabilities = Type.Object(\n {\n contractVersion: Type.Literal('1'),\n /** the only legal value (C1); present so conformance can assert it */\n toolExecution: Type.Literal('host-delegated'),\n streaming: Cap,\n thinkingStream: Cap,\n send: Type.Object({ steer: Cap, followUp: Cap }, strict),\n cancelCooperative: Cap,\n cancelHard: Cap,\n pause: Type.Object({ toolBoundary: Cap, modelBoundary: Cap }, strict),\n continuationFromTranscript: Cap,\n processIsolation: Cap,\n envFiltering: Cap,\n brainSandbox: Cap,\n resourceLimits: Cap,\n budgetEnforcement: Type.Object(\n { turns: Cap, modelRequests: Cap, tokens: Cap, context: Cap, wallClock: Cap, outputTokensPerRequest: Cap },\n strict,\n ),\n /** 'no' = none possible (compaction and engine retries off) */\n hiddenModelCalls: Cap,\n usageReporting: Cap,\n effectiveModelReporting: Cap,\n quotaReporting: Cap,\n authStatusWithoutSecret: Cap,\n subscriptionModeAssertion: Cap,\n systemPromptExact: Cap,\n runtimePinning: Cap,\n platforms: Type.Object({ darwin: Cap, linux: Cap, win32: Cap }, strict),\n hints: Type.Object(\n {\n memoryPerAgentMb: Type.Number({ minimum: 0 }),\n coldStartMs: Type.Number({ minimum: 0 }),\n maxConcurrentAgents: Type.Integer({ minimum: 1 }),\n },\n strict,\n ),\n },\n strict,\n);\nexport type RuntimeCapabilities = Static<typeof RuntimeCapabilities>;\n","// DESIGN 2.2.4 — handle, messages, snapshot.\nimport {\n AgentId,\n AuthMode,\n ErrorInfo,\n type IsoInstant,\n type JsonValue,\n JsonValueSchema,\n ModelRef,\n RunId,\n TokenUsage,\n ToolCallId,\n} from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\n// The explicit TUnsafe keeps Biome's type inference out of `Static<TRecord>`: it overflows its stack there and then\n// exits 0, so the lint LOOKS green while nothing was checked (docs/v3/requests/U0.02.md R1, U0.03.md R1).\nconst jsonMap = (): TUnsafe<Record<string, JsonValue>> =>\n Type.Unsafe<Record<string, JsonValue>>(Type.Record(Type.String(), JsonValueSchema));\n\n/** `format` is a label, e.g. 'jsonl-v3' | 'fake-ndjson-v1' — never interpreted by core */\nexport const TranscriptRef = Type.Object({ path: Type.String(), format: Type.String() }, strict);\nexport type TranscriptRef = Static<typeof TranscriptRef>;\n\n/** R8: opaque to clients */\nexport const RuntimeSessionRef = Type.Object(\n { runtime: Type.String(), engineVersion: Type.String(), sessionId: Type.String(), transcript: TranscriptRef },\n strict,\n);\nexport type RuntimeSessionRef = Static<typeof RuntimeSessionRef>;\n\nexport const UsageTotals = Type.Object(\n {\n tokens: TokenUsage,\n modelRequests: count(),\n toolCalls: count(),\n turns: count(),\n wallClockMs: Type.Number({ minimum: 0 }),\n },\n strict,\n);\nexport type UsageTotals = Static<typeof UsageTotals>;\n\nexport const EffectiveModel = Type.Object(\n {\n provider: Type.String(),\n model: Type.String(),\n api: Type.Optional(Type.String()),\n baseUrl: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type EffectiveModel = Static<typeof EffectiveModel>;\n\n/** The ADAPTER's typed cause, recorded by the host BEFORE it acts. The engine's own stop reason is never a discriminator [X]. */\nexport const AgentStopCause = Type.Union([\n Type.Literal('host-terminated'),\n Type.Literal('model-stop'),\n Type.Literal('output-truncated'),\n Type.Literal('budget'),\n Type.Literal('cancelled'),\n Type.Literal('engine-error'),\n Type.Literal('process-exit'),\n]);\nexport type AgentStopCause = Static<typeof AgentStopCause>;\n\nexport const AgentExit = Type.Object(\n {\n outcome: Type.Union([\n Type.Literal('completed'),\n Type.Literal('failed'),\n Type.Literal('cancelled'),\n Type.Literal('crashed'),\n ]),\n stop: AgentStopCause,\n error: Type.Optional(ErrorInfo),\n usage: UsageTotals,\n lastSeq: count(),\n },\n strict,\n);\nexport type AgentExit = Static<typeof AgentExit>;\n\nexport interface RuntimeAgentHandle {\n readonly runId: RunId;\n readonly agentId: AgentId;\n readonly incarnation: number;\n readonly session: RuntimeSessionRef;\n readonly startedAt: IsoInstant;\n /** startToken = OS process start time: orphan kill never trusts a bare pid */\n readonly process: { pid: number; pgid: number; startToken: string } | null;\n /** settles exactly once, never rejects, only AFTER the final RuntimeEvent was delivered */\n readonly exit: Promise<AgentExit>;\n}\n\nconst delivery = () => Type.Union([Type.Literal('steer'), Type.Literal('follow-up')]);\n\nexport const RuntimeMessage = Type.Union([\n Type.Object(\n { kind: Type.Literal('user'), messageId: Type.String(), text: Type.String(), delivery: delivery() },\n strict,\n ),\n // rendered as a user message prefixed \"[cohorte]\"\n Type.Object(\n { kind: Type.Literal('host-note'), messageId: Type.String(), text: Type.String(), delivery: delivery() },\n strict,\n ),\n]);\nexport type RuntimeMessage = Static<typeof RuntimeMessage>;\n\nexport const RuntimeSnapshot = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n state: Type.Union([\n Type.Literal('starting'),\n Type.Literal('running'),\n Type.Literal('awaiting-tool'),\n Type.Literal('paused'),\n Type.Literal('settling'),\n Type.Literal('exited'),\n ]),\n pausedAt: Type.Optional(Type.Union([Type.Literal('tool-boundary'), Type.Literal('model-boundary')])),\n turn: count(),\n pendingToolCalls: Type.Array(ToolCallId),\n requestedModel: ModelRef,\n effectiveModel: Type.Optional(EffectiveModel),\n authMode: Type.Optional(AuthMode),\n usage: UsageTotals,\n contextTokens: Type.Optional(count()),\n contextWindow: Type.Optional(count()),\n session: RuntimeSessionRef,\n lastSeq: count(),\n /** pid, rssMb, lastHeartbeatAt, engine flags… never secrets */\n diagnostics: jsonMap(),\n },\n strict,\n);\nexport type RuntimeSnapshot = Static<typeof RuntimeSnapshot>;\n","// DESIGN 2.2.2 — rule C1: tools are executed by the host, never by the runtime.\nimport { AgentId, type JsonValue, JsonValueSchema, RunId, type SealedText, ToolCallId } from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\n\nexport interface ToolHost {\n /**\n * Called exactly once per model tool call, in emission order (ordinal), BEFORE any effect. MUST resolve (a rejection\n * is a host bug: the runtime treats it as isError + agent failure). MUST settle promptly after ctx.signal aborts.\n * MAY take hours (human decision).\n */\n handleToolCall(call: RuntimeToolCall, ctx: ToolCallContext): Promise<RuntimeToolResult>;\n}\n\nexport const RuntimeToolCall = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n /** tc_<incarnation>_<ordinal> */\n toolCallId: ToolCallId,\n /** the engine's own id, transcript correlation only */\n engineToolCallId: Type.Optional(Type.String()),\n /** 1-based, per incarnation, gapless */\n ordinal: Type.Integer({ minimum: 1 }),\n tool: Type.String(),\n /** as produced by the model after engine-side coercion; the host re-validates strictly */\n input: JsonValueSchema,\n },\n strict,\n);\nexport type RuntimeToolCall = Static<typeof RuntimeToolCall>;\n\nexport interface ToolCallContext {\n signal: AbortSignal;\n progress(update: ToolProgress): void;\n}\n\nexport const ToolProgress = Type.Object(\n { text: Type.Optional(Type.String()), bytes: Type.Optional(Type.Integer({ minimum: 0 })) },\n strict,\n);\nexport type ToolProgress = Static<typeof ToolProgress>;\n\nexport const ToolContent = Type.Union([\n // The static type carries the seal; on a wire a sealed text is a string like any other.\n Type.Object({ type: Type.Literal('text'), text: Type.Unsafe<SealedText>(Type.String()) }, strict),\n Type.Object({ type: Type.Literal('image'), mediaType: Type.String(), dataBase64: Type.String() }, strict),\n]);\nexport type ToolContent = Static<typeof ToolContent>;\n\n/** content is SEALED: the engine transcript never holds an unredacted tool result (I7). */\nexport const RuntimeToolResult = Type.Object(\n {\n isError: Type.Boolean(),\n content: Type.Array(ToolContent),\n /** host asks the runtime to end the agent loop after this batch */\n terminate: Type.Optional(Type.Boolean()),\n /** opaque audit id, stored in the transcript */\n resultRef: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type RuntimeToolResult = Static<typeof RuntimeToolResult>;\n\nexport const TOOL_NAME_PATTERN = '^[a-z][a-z0-9_]{1,40}$';\n\n/** Root keywords a provider would have to flatten or would refuse: a grant's schema is ONE flat top-level object. */\nexport const TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS = [\n '$ref',\n '$defs',\n 'definitions',\n 'oneOf',\n 'anyOf',\n 'allOf',\n] as const;\n\n/** JSON Schema 2020-12, ONE flat top-level object: no $ref/$defs/oneOf at root (provider flattening). */\nexport const ToolInputSchema: TUnsafe<JsonValue> = Type.Unsafe<JsonValue>(\n Type.Object(\n { type: Type.Literal('object'), properties: Type.Optional(Type.Record(Type.String(), JsonValueSchema)) },\n {\n additionalProperties: true,\n not: { anyOf: TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS.map((key) => ({ required: [key] })) },\n },\n ),\n);\n\n/** What the BRAIN needs to know. No paths, no commands: what a call may touch is decided host-side. */\nexport const ToolGrant = Type.Object(\n {\n /** TOOL_NAME_PATTERN; never differs only by case from another grant (see toolGrantProblems) */\n tool: Type.String({ pattern: TOOL_NAME_PATTERN }),\n description: Type.String(),\n inputSchema: ToolInputSchema,\n /** ordering hint only */\n effect: Type.Union([\n Type.Literal('read'),\n Type.Literal('write'),\n Type.Literal('execute'),\n Type.Literal('network'),\n Type.Literal('control'),\n ]),\n /** true for the result tool */\n terminal: Type.Boolean(),\n },\n strict,\n);\nexport type ToolGrant = Static<typeof ToolGrant>;\n\n/**\n * The rule a schema cannot say: inside ONE grant list no two names are equal, or differ only by case (providers\n * fold tool names). Works on unvalidated names too, which is why it re-checks the pattern. Empty = no problem.\n */\nexport function toolGrantProblems(grants: readonly Pick<ToolGrant, 'tool'>[]): string[] {\n const pattern = new RegExp(TOOL_NAME_PATTERN);\n const problems: string[] = [];\n const seen = new Map<string, string>();\n for (const { tool } of grants) {\n if (!pattern.test(tool)) problems.push(`tool name ${JSON.stringify(tool)} does not match ${TOOL_NAME_PATTERN}`);\n const folded = tool.toLowerCase();\n const earlier = seen.get(folded);\n if (earlier === undefined) seen.set(folded, tool);\n else if (earlier === tool) problems.push(`tool ${JSON.stringify(tool)} is granted twice`);\n else problems.push(`tools ${JSON.stringify(earlier)} and ${JSON.stringify(tool)} differ only by case`);\n }\n return problems;\n}\n","// DESIGN 2.2.5 — RuntimeEvent: \"Pi-shaped, not Pi-typed\". Durability is part of the type (C5).\nimport {\n AgentId,\n AuthMode,\n ErrorInfo,\n IsoInstant,\n ModelRef,\n QuotaInfo,\n RunId,\n Sha256,\n TokenUsage,\n ToolCallId,\n} from '@cohorte/base';\nimport { type Static, type TSchema, type TUnsafe, Type } from 'typebox';\nimport { AgentExit, EffectiveModel, RuntimeSessionRef } from './session.ts';\nimport { RuntimeToolCall, ToolProgress } from './tools.ts';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\nconst boundary = () => Type.Union([Type.Literal('tool-boundary'), Type.Literal('model-boundary')]);\nconst delivery = () => Type.Union([Type.Literal('steer'), Type.Literal('follow-up')]);\nconst messageRole = () => Type.Union([Type.Literal('assistant'), Type.Literal('user'), Type.Literal('tool-result')]);\n\n/**\n * A CLOSED five-value set on this frontier: an adapter maps any other engine stop reason (Pi 0.85.1 also has\n * 'pending' and 'deferred') to 'error' and emits runtime.warning{code: ENGINE_STOP_REASON_UNMAPPED}.\n */\nexport const ModelStop = Type.Union([\n Type.Literal('stop'),\n Type.Literal('length'),\n Type.Literal('tool-use'),\n Type.Literal('error'),\n Type.Literal('aborted'),\n]);\nexport type ModelStop = Static<typeof ModelStop>;\nexport const ENGINE_STOP_REASON_UNMAPPED = 'engine-stop-reason-unmapped';\n\nexport const PREVIEW_MAX_LENGTH = 512;\n\nexport const IsolationReport = Type.Object(\n {\n level: Type.Union([Type.Literal('os'), Type.Literal('process'), Type.Literal('none')]),\n filesystem: Type.Union([Type.Literal('enforced'), Type.Literal('advisory')]),\n network: Type.Union([Type.Literal('enforced'), Type.Literal('partial'), Type.Literal('none')]),\n backend: Type.String(),\n },\n strict,\n);\nexport type IsolationReport = Static<typeof IsolationReport>;\n\nconst durable = <P extends TSchema>(data: P) => ({ durability: 'durable', data }) as const;\nconst ephemeral = <P extends TSchema>(data: P) => ({ durability: 'ephemeral', data }) as const;\n\n/**\n * One row per event type: its durability and the schema of `data`. EVERY durable type has a named target in the\n * protocol catalogue, or an explicit \"not forwarded\" rule (DESIGN 2.3.3). `authSource: 'none'` exists only for\n * runtimes that hold no credential (the fake); a fake run reports the authMode its plan requested.\n */\nexport const RUNTIME_EVENT_TYPES = {\n 'agent.spawned': durable(\n Type.Object(\n {\n session: RuntimeSessionRef,\n requestedModel: ModelRef,\n tools: Type.Array(Type.String()),\n systemPromptSha256: Sha256,\n effectiveSystemPromptSha256: Sha256,\n isolation: IsolationReport,\n },\n strict,\n ),\n ),\n 'agent.started': durable(Type.Object({ taskSha256: Sha256 }, strict)),\n 'agent.turn.started': ephemeral(Type.Object({ turn: count() }, strict)),\n 'agent.turn.completed': durable(Type.Object({ turn: count(), toolCalls: count() }, strict)),\n 'agent.message.started': ephemeral(Type.Object({ messageId: Type.String(), role: messageRole() }, strict)),\n 'agent.message.delta': ephemeral(\n Type.Object(\n {\n messageId: Type.String(),\n channel: Type.Union([Type.Literal('text'), Type.Literal('thinking'), Type.Literal('tool-input')]),\n contentIndex: count(),\n delta: Type.String(),\n },\n strict,\n ),\n ),\n 'agent.message.completed': durable(\n Type.Object(\n {\n messageId: Type.String(),\n role: messageRole(),\n textSha256: Sha256,\n textBytes: count(),\n preview: Type.String({ maxLength: PREVIEW_MAX_LENGTH }),\n stop: Type.Optional(ModelStop),\n },\n strict,\n ),\n ),\n 'model.requested': durable(\n Type.Object(\n {\n requestId: Type.String(),\n model: ModelRef,\n contextSha256: Type.Optional(Sha256),\n contextTokensEstimate: Type.Optional(count()),\n attempt: Type.Integer({ minimum: 1 }),\n },\n strict,\n ),\n ),\n 'model.responded': durable(\n Type.Object(\n {\n requestId: Type.String(),\n requestedModel: ModelRef,\n effectiveModel: EffectiveModel,\n authMode: AuthMode,\n authSource: Type.Union([Type.Literal('oauth'), Type.Literal('api-key'), Type.Literal('none')]),\n durationMs: Type.Number({ minimum: 0 }),\n usage: TokenUsage,\n httpStatus: Type.Optional(Type.Integer()),\n attempt: Type.Integer({ minimum: 1 }),\n stop: ModelStop,\n quota: QuotaInfo,\n error: Type.Optional(ErrorInfo),\n },\n strict,\n ),\n ),\n // model asked; nothing ran yet; ToolHost WILL be called\n 'tool.call.requested': durable(Type.Object({ call: RuntimeToolCall }, strict)),\n // engine refused BEFORE the host: ToolHost is NOT called [X]\n 'tool.call.rejected': durable(\n Type.Object(\n {\n engineToolCallId: Type.Optional(Type.String()),\n tool: Type.String(),\n cause: Type.Union([\n Type.Literal('unknown-tool'),\n Type.Literal('invalid-input'),\n Type.Literal('output-truncated'),\n ]),\n message: Type.String(),\n },\n strict,\n ),\n ),\n 'tool.call.progress': ephemeral(Type.Object({ toolCallId: ToolCallId, update: ToolProgress }, strict)),\n 'tool.call.delivered': durable(\n Type.Object(\n {\n toolCallId: ToolCallId,\n isError: Type.Boolean(),\n terminate: Type.Boolean(),\n waitedMs: Type.Number({ minimum: 0 }),\n },\n strict,\n ),\n ),\n 'agent.paused': durable(Type.Object({ at: boundary() }, strict)),\n 'agent.resumed': durable(Type.Unsafe<Record<string, never>>(Type.Object({}, strict))),\n 'agent.message.accepted': durable(Type.Object({ messageId: Type.String(), delivery: delivery() }, strict)),\n 'agent.exited': durable(AgentExit),\n 'runtime.warning': durable(Type.Object({ code: Type.String(), message: Type.String() }, strict)),\n} as const;\n\ntype EventTable = typeof RUNTIME_EVENT_TYPES;\nexport type RuntimeEventType = keyof EventTable;\n\ninterface Ev<T extends string, D extends 'durable' | 'ephemeral', P> {\n type: T;\n durability: D;\n runId: RunId;\n agentId: AgentId;\n incarnation: number;\n /** per incarnation, strictly increasing over BOTH durabilities */\n seq: number;\n at: IsoInstant;\n data: P;\n}\n\n/** Discriminated on `type`. */\nexport type RuntimeEvent = {\n [T in RuntimeEventType]: Ev<T, EventTable[T]['durability'], Static<EventTable[T]['data']>>;\n}[RuntimeEventType];\nexport type RuntimeEventOf<T extends RuntimeEventType> = Extract<RuntimeEvent, { type: T }>;\nexport type DurableRuntimeEvent = Extract<RuntimeEvent, { durability: 'durable' }>;\nexport type EphemeralRuntimeEvent = Extract<RuntimeEvent, { durability: 'ephemeral' }>;\n\nexport const RUNTIME_EVENT_TYPE_NAMES = Object.freeze(Object.keys(RUNTIME_EVENT_TYPES)) as readonly RuntimeEventType[];\n\nconst envelope = {\n runId: RunId,\n agentId: AgentId,\n incarnation: Type.Integer({ minimum: 1 }),\n seq: count(),\n at: IsoInstant,\n};\n\n// The annotation is deliberate: the union is assembled from the table, so there is nothing to infer from.\nexport const RuntimeEvent: TUnsafe<RuntimeEvent> = Type.Unsafe<RuntimeEvent>(\n Type.Union(\n RUNTIME_EVENT_TYPE_NAMES.map((type) => {\n const row = RUNTIME_EVENT_TYPES[type];\n return Type.Object(\n { type: Type.Literal(type), durability: Type.Literal(row.durability), ...envelope, data: row.data },\n strict,\n );\n }),\n ),\n);\n\nexport const isDurable = (event: RuntimeEvent): event is DurableRuntimeEvent => event.durability === 'durable';\n","// DESIGN 2.2.7 — pin and auth status.\nimport { IsoInstant, Sha256 } from '@cohorte/base';\nimport { type Static, Type } from 'typebox';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\n\n/** spec 16 */\nexport const RuntimePin = Type.Object(\n {\n runtimeId: Type.String(),\n adapterVersion: Type.String(),\n engine: Type.Union([Type.Object({ name: Type.String(), version: Type.String() }, strict), Type.Null()]),\n node: Type.Object({ version: Type.String(), execPath: Type.String() }, strict),\n artifacts: Type.Array(\n Type.Object(\n {\n role: Type.Union([\n Type.Literal('agent-host-bundle'),\n Type.Literal('engine-package-tree'),\n Type.Literal('install-lock'),\n ]),\n path: Type.String(),\n sha256: Sha256,\n files: Type.Optional(count()),\n bytes: count(),\n },\n strict,\n ),\n ),\n /** sha256(canonicalJson(all of the above)) */\n digest: Sha256,\n },\n strict,\n);\nexport type RuntimePin = Static<typeof RuntimePin>;\n\n/** never contains a token, a refresh token or an account secret */\nexport const ProviderAuthStatus = Type.Object(\n {\n provider: Type.String(),\n /** 'unknown-transient' = credential store locked: NEVER mapped to AUTH_REQUIRED */\n state: Type.Union([\n Type.Literal('oauth'),\n Type.Literal('api-key'),\n Type.Literal('absent'),\n Type.Literal('unknown-transient'),\n ]),\n subscription: Type.Boolean(),\n source: Type.Optional(Type.String()),\n checkedAt: IsoInstant,\n /** non-secret account/tenant label WHEN the engine exposes one without a secret; absent otherwise */\n accountLabel: Type.Optional(Type.String()),\n /** Cohorte's own table, not the engine's subscription flag (§3.7) */\n billing: Type.Union([Type.Literal('plan-limits'), Type.Literal('metered'), Type.Literal('unknown')]),\n caveat: Type.Optional(Type.String()),\n },\n strict,\n);\nexport type ProviderAuthStatus = Static<typeof ProviderAuthStatus>;\n","// DESIGN 2.2.3 — SpawnRequest: the ten spec-5.1 fields + what spec 6 / 10.1 / 16 require.\nimport { AgentId, AuthMode, ModelRef, RunId, Sha256, ThinkingLevel } from '@cohorte/base';\nimport { type Static, type TUnsafe, Type } from 'typebox';\nimport { TranscriptRef } from './session.ts';\nimport { ToolGrant } from './tools.ts';\n\nconst strict = { additionalProperties: false } as const;\nconst count = () => Type.Integer({ minimum: 0 });\nconst limit = () => Type.Optional(Type.Integer({ minimum: 1 }));\nconst ceiling = () => Type.Optional(count());\n// The explicit TUnsafe keeps Biome's type inference out of `Static<TRecord>`: it overflows its stack there and then\n// exits 0, so the lint LOOKS green while nothing was checked (docs/v3/requests/U0.02.md R1, U0.03.md R1).\nconst stringMap = (): TUnsafe<Record<string, string>> =>\n Type.Unsafe<Record<string, string>>(Type.Record(Type.String(), Type.String()));\n\n/** opaque label; the runtime MUST NOT branch on it */\nexport const AgentRole = Type.String();\nexport type AgentRole = Static<typeof AgentRole>;\n\nexport const AuthRequirement = Type.Object(\n {\n mode: AuthMode,\n provider: Type.String(),\n /** pinned catalogue endpoint; a runtime that would talk to anything else MUST refuse to spawn */\n baseUrl: Type.String(),\n /** false unless the run plan carries an explicit api opt-in */\n allowApiKey: Type.Boolean(),\n },\n strict,\n);\nexport type AuthRequirement = Static<typeof AuthRequirement>;\n\n/** rendered by the host into the run snapshot dir */\nexport const TaskInput = Type.Object({ path: Type.String(), sha256: Sha256, bytes: count() }, strict);\nexport type TaskInput = Static<typeof TaskInput>;\n\n/** The fixed line that precedes `Continuation.note` when the engine cannot carry two user messages in one prompt. */\nexport const CONTINUATION_NOTE_SEPARATOR = '\\n\\n[cohorte] continuation note\\n\\n';\n\n/**\n * `note` is delivered by the runtime AFTER `task` and BEFORE the first model request: as a second user message when\n * the engine can carry two in one prompt, otherwise appended to the first user message after\n * CONTINUATION_NOTE_SEPARATOR. Either way each text is a byte-identical contiguous span and `task` comes first\n * (conformance rule 12).\n */\nexport const Continuation = Type.Object(\n {\n fromIncarnation: Type.Integer({ minimum: 1 }),\n note: TaskInput,\n /** used only if continuationFromTranscript = yes */\n transcript: Type.Optional(TranscriptRef),\n },\n strict,\n);\nexport type Continuation = Static<typeof Continuation>;\n\n/** runtime MUST verify sha256 before use */\nexport const PromptRef = Type.Object(\n { id: Type.String(), path: Type.String(), sha256: Sha256, bytes: count() },\n strict,\n);\nexport type PromptRef = Static<typeof PromptRef>;\n\nexport const ContextEntry = Type.Object(\n {\n id: Type.String(),\n tier: Type.Union([\n Type.Literal('system'),\n Type.Literal('doctrine'),\n Type.Literal('data'),\n Type.Literal('task'),\n Type.Literal('prior-results'),\n ]),\n /** agent-output and untrusted-repository can never sit above 'data' */\n trust: Type.Union([\n Type.Literal('cohorte'),\n Type.Literal('human'),\n Type.Literal('untrusted-repository'),\n Type.Literal('agent-output'),\n ]),\n source: Type.Object(\n {\n kind: Type.Union([\n Type.Literal('asset'),\n Type.Literal('project-file'),\n Type.Literal('artifact'),\n Type.Literal('event-summary'),\n Type.Literal('inline'),\n ]),\n ref: Type.String(),\n },\n strict,\n ),\n sha256: Sha256,\n bytes: count(),\n tokenEstimate: count(),\n },\n strict,\n);\nexport type ContextEntry = Static<typeof ContextEntry>;\n\n/**\n * PROVENANCE ONLY. \"Installer le contexte\" (spec 5.2) is defined as: every byte the model sees is in exactly two\n * host-rendered files — `systemPrompt` (tiers `system` + `doctrine`) and `task` (tiers `data` + `task` +\n * `prior-results`) — plus, for a later incarnation, `continuation.note`. A runtime installs those three and NOTHING\n * else: it never opens `entries[].source`, never re-orders or re-renders tiers. The manifest travels so that the\n * runtime can record `manifestSha256` on `model.requested` and so that a second runtime has nothing to guess.\n * Tiers are trust/priority tiers (spec 7), not orchestration words.\n */\nexport const ContextManifest = Type.Object(\n {\n /** sha256(canonicalJson(entries)) = \"hash du contexte\" of spec 19 */\n manifestSha256: Sha256,\n tokenLimit: count(),\n tokenEstimate: count(),\n /** deterministic order: tier, then id */\n entries: Type.Array(ContextEntry),\n reductions: Type.Array(\n Type.Object(\n {\n entryId: Type.String(),\n strategy: Type.Union([\n Type.Literal('excerpt'),\n Type.Literal('outline'),\n Type.Literal('summary-with-refs'),\n Type.Literal('dropped'),\n ]),\n fromBytes: count(),\n toBytes: count(),\n },\n strict,\n ),\n ),\n exclusions: Type.Array(\n Type.Object(\n {\n pattern: Type.String(),\n reason: Type.Union([\n Type.Literal('secret'),\n Type.Literal('outside-scope'),\n Type.Literal('size'),\n Type.Literal('binary'),\n ]),\n },\n strict,\n ),\n ),\n },\n strict,\n);\nexport type ContextManifest = Static<typeof ContextManifest>;\n\n/** Isolation of the RUNTIME'S OWN agent process (the brain). Tool isolation is host-side. */\nexport const SandboxPolicy = Type.Object(\n {\n /** spawn fails security/sandbox-unavailable below `os` */\n require: Type.Union([Type.Literal('os'), Type.Literal('os-if-available'), Type.Literal('process')]),\n /** absolute canonical roots */\n filesystem: Type.Object(\n {\n readOnly: Type.Array(Type.String()),\n readWrite: Type.Array(Type.String()),\n denyRead: Type.Array(Type.String()),\n },\n strict,\n ),\n network: Type.Object(\n {\n mode: Type.Union([Type.Literal('none'), Type.Literal('provider-only'), Type.Literal('unrestricted')]),\n allowHosts: Type.Array(Type.String()),\n },\n strict,\n ),\n /** allowlist; nothing else is inherited (D3) */\n env: Type.Object({ allow: Type.Array(Type.String()), set: stringMap() }, strict),\n limits: Type.Object({ maxOldSpaceMb: limit(), maxCpuSeconds: limit(), maxOpenFiles: limit() }, strict),\n },\n strict,\n);\nexport type SandboxPolicy = Static<typeof SandboxPolicy>;\n\n/** hard ceilings for ONE incarnation; absent = unlimited at this level */\nexport const Budget = Type.Object(\n {\n maxTurns: ceiling(),\n maxModelRequests: ceiling(),\n maxToolCalls: ceiling(),\n maxInputTokens: ceiling(),\n maxOutputTokens: ceiling(),\n maxTotalTokens: ceiling(),\n /** stop (never auto-compact) when the last request's context exceeds this */\n maxContextTokens: ceiling(),\n maxWallClockMs: ceiling(),\n maxModelRequestMs: ceiling(),\n /** 0 = every retry is the host's (spec 11.3 \"tous les retries sont visibles\") */\n maxEngineRetries: count(),\n },\n strict,\n);\nexport type Budget = Static<typeof Budget>;\n\nexport const SpawnRequest = Type.Object(\n {\n runId: RunId,\n agentId: AgentId,\n role: AgentRole,\n model: ModelRef,\n systemPrompt: PromptRef,\n context: ContextManifest,\n tools: Type.Array(ToolGrant),\n sandbox: SandboxPolicy,\n budget: Budget,\n /** absolute, canonical; the path the MODEL is told about. The engine process MUST NOT use it as its cwd */\n workingDirectory: Type.String(),\n // additions (all required so that no runtime can forget them):\n /** spec 6: spawn is idempotent on (runId, agentId, incarnation) */\n incarnation: Type.Integer({ minimum: 1 }),\n thinking: ThinkingLevel,\n /** spec 10.1 / D3 */\n auth: AuthRequirement,\n /** the first user message, by reference */\n task: TaskInput,\n /** a later incarnation of the same attempt */\n continuation: Type.Union([Continuation, Type.Null()]),\n },\n strict,\n);\nexport type SpawnRequest = Static<typeof SpawnRequest>;\n"],"mappings":"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"}