UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

60 lines (59 loc) • 4.58 kB
/** * The ONE door between the shell read station's establisher and the execution environment's filesystem. * * The establisher answers "where does each word of this command land" by asking the environment (a resolution, a * directory listing, a stat, a link read). An environment that does not give an answer — an error that is not a * conclusive "not there", a lookup that came back inconclusive — and a bound the station itself stops at are the same * fact for the verdict: the judge did not finish checking the command against the deny rows, so it cannot vouch for it. That * fact is recorded HERE, at the door, once per judgment, not by each producer that happens to remember to mark it: the * establisher and the write guards are handed an {@link ObservedFilesystem}, never the environment, so a lookup they make * cannot escape the record. * * What is NOT a failure: a conclusive absence (`not_found`, `not_directory` — the answer is "nothing there") and an adapter * that has no filesystem surface (`not_supported` — its answer that there is no file face: a chain it answers so keeps the * lexical reading). Everything else is, and is recorded wherever it falls — a resolver that answered nothing at all in the * command included: a lookup that failed (`permission_denied`, `timeout`, `unknown`, a throw) is a resolver failing, whose * identity of the words cannot be judged, never an adapter without a file face. */ import type { ExecutionEnv } from "../../internal/harness-types.js"; /** One thing the station could not finish: an environment lookup that gave no answer, or a bound the station stopped at. */ export interface Incomplete { /** The lookup (`canonicalPath`, `listDir`, `fileInfo`, `readLink`, `fileIdentity`) or `bound`. */ readonly op: string; /** The sentence the card discloses ("… cannot be resolved (permission_denied)"). */ readonly detail: string; } /** Only {@link observeEnvironment} mints the brand: a bare environment is not assignable where a door is asked for. */ declare const OBSERVED: unique symbol; /** The environment as the station's paths may use it: every path lookup the engine's resolvers make (`canonicalPath`, * `listDir`, `fileInfo`, `readLink`, `exists`, `absolutePath`, `canonicalChain`, `fileIdentity`) goes through the door and is * recorded when it gives no answer; everything else is the environment's own. It IS an `ExecutionEnv` to the resolvers * (`canonicalizeTarget`, the home views, a deployment's guarded-row provider) — so none of them has to be narrowed — and * nominal to the station: the establisher, the write guards, the write judgment and the home views are typed over it, so * none of them can be handed the bare environment, nor a captured one. */ export type ObservedFilesystem = ExecutionEnv & { readonly [OBSERVED]: true; }; /** The observed door for one command. */ export interface ObservedEnvironment { readonly fs: ObservedFilesystem; /** Whether the environment DECLARES its `canonicalPath` the authority on where a path lands: a chain it does not answer at all * is then not placed (the establishment's reading; the door records the lookups alike either way). */ readonly authoritative: boolean; /** What the door recorded, in the order it happened; call it after the last lookup of the command. */ incomplete(): Incomplete[]; /** The station stopped at its own bound (more directories or names than it enumerates, a link chain past its hop bound). */ bound(detail: string): void; /** Records that came from outside the door: the declared roots' own lookup and the home views a read could not be placed against. */ adopt(records: readonly Incomplete[]): void; } /** The declared roots, canonicalized ONCE per establisher (through the same door), with what that lookup could not finish — * merged into every establishment. `known`: the caller already holds them as canonical identities and they are used verbatim * (re-resolving one that was since swapped for a link would substitute the link's target for the root that was approved). */ export declare function canonicalRootsOnce(env: ExecutionEnv, readRoots: readonly string[], known: boolean): (signal?: AbortSignal) => Promise<{ readonly roots: readonly string[]; readonly incomplete: readonly Incomplete[]; }>; /** Wrap `env` so every lookup that fails inconclusively is recorded; the result a caller sees is the environment's own. */ export declare function observeEnvironment(env: ExecutionEnv): ObservedEnvironment; export {};