UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

46 lines (45 loc) • 2.8 kB
/** * The task root's CANONICAL spelling — and the one loud outlet for a host that hands in another one. * * Containment is judged on the canonical form: the roots fence resolves every target through the same * `ExecutionEnv` and compares canonical keys, the shell read boundary compares a command's words * against the declared roots, and every refusal message quotes them. A deployment that hands the * runner a root which is NOT its own realpath (a symlinked temp directory; `/var` → `/private/var` on * macOS) therefore reasons in one spelling while the engine judges in another, and a target the * deployment considers inside the root can be judged outside it. Before this seat that difference was * SILENT — the engine simply canonicalized and carried on. * * The bad-value discipline's announcement dialect applies (announce, do not refuse): an existing * deployment may well be running correctly on the non-canonical spelling, so the judgment is unchanged * and only the difference is disclosed. Nothing here repairs the host's spelling either — the engine * cannot know which of the two the deployment's own gates key on, and rewriting one into the other * would move a fence nobody asked to move. */ import type { ExecutionEnv } from "../../internal/harness.js"; import type { RunnerDeps } from "../runner-deps.js"; /** The canonical root plus whether the difference was announced (the pin's observable). */ export interface TaskRootCanonical { /** The spelling every fence judges with — the env's canonical form, or the given spelling when the * env cannot resolve it (an unresolvable root narrows nothing here; the fence's own skip speaks). */ canonical: string; /** True exactly when the given spelling differed and the notice was delivered. */ announced: boolean; } /** * Resolve the run's task root to the spelling its fences judge with, announcing a host spelling that is * not that spelling. * * @contract task_root.canonical_is_the_judge — the engine judges containment on the task root's * CANONICAL spelling; when the root the host handed in is not its own canonical form the run announces * `config.task_root_not_canonical` exactly once, carrying both spellings, and then judges by the * canonical form exactly as before. The notice discloses the difference — it never repairs the host's * spelling, never narrows the fence, and never fires for a root that already is its own canonical form. */ export declare function resolveTaskRootCanonical(input: { env: Pick<ExecutionEnv, "canonicalPath">; /** The root as the host spelled it (`deps.rootPath` / the restored workspace root). */ given: string; onNotice: RunnerDeps["onNotice"]; sessionId: string; runId: string; }): Promise<TaskRootCanonical>;