@sema-agent/core
Version:
Stateless, task-oriented AI agent core
100 lines (99 loc) • 6.01 kB
TypeScript
import type { DenyFace, PathRowReach } from "../tools/fs/read-deny.js";
/** Which reading of a target one view is: the placed spelling, the environment's canonical answer, a hop of the leaf's
* symlink chain, or the home's own spelling of a canonical key (read-deny-home.ts). */
export type GuardViewKind = "lexical" | "canonical" | "hop" | "home";
/** ONE view of a target as the judgment reads it. */
export interface GuardView {
/** The view's spelling — absolute, or (for an operand a station could not place) as spelled. */
readonly path: string;
readonly kind: GuardViewKind;
/** The canonical key's minter reports the real filesystem already collapsed any win32 component alias in it. */
readonly aliasResolved?: true;
/** The view's remainder below an exempt root (`""` = the root itself), computed by the reading's owner. */
readonly exemptRemainder?: string;
}
/** A target as a judgment reads it: its present views, and `unreadable` — the call names a target this reading cannot
* locate, or where the target really lands (its canonical view, its link chain) could not be determined (the reason).
* `identityExempt`: the reading's OWN canonical key lies inside an exempt root. */
export interface TargetViews {
readonly views: readonly GuardView[];
readonly unreadable?: string;
readonly identityExempt?: true;
}
/** The views' spellings, in order, without repeats — what a reader that only needs the strings reads. */
export declare function viewSpellings(views: TargetViews): readonly string[];
/** Views from bare spellings (each read as the kind given, the first as `lexical` when no kind is given). */
export declare function spelledViews(spellings: readonly string[], kind?: GuardViewKind): TargetViews;
/** The language a row is written in — a column, not a judgment: every grammar is judged by {@link judgePathRows}. */
export type PathGuardGrammar =
/** A literal name (the write-protection table): the target's last segment, any segment, or a consecutive run. */
{
readonly kind: "literal-name";
readonly match: "basename" | "segment" | "segment-run";
readonly name: string;
}
/** A `/`-separated segment glob (`*` the one metacharacter) matched as a contiguous run (the sensitive list, the read
* deny set's segment rows). */
| {
readonly kind: "segment-glob";
readonly run: string;
}
/** A permission rule's path pattern, judged by its own reach (the rule DSL's rows and their twins). */
| {
readonly kind: "rule";
readonly rule: string;
}
/** The directories a write may land in, from one SOURCE (the write domains — an ALLOW row): the run's advertised writable
* roots (frozen canonical keys), the deployment's configured structural domains, the person's session-won grants, a
* session rule's `allowDirs` confinement. */
| {
readonly kind: "domain";
readonly dirs: readonly string[];
readonly source: "advertised" | "configured" | "accepted" | "session";
};
/** Where a row is placed: anywhere its grammar matches; at a home; at the filesystem root; below a declared root. A placed
* row is judged in a ROOTED view only, except that a home row in a view that cannot be placed holds wider. */
export type PathGuardPlacement = "anywhere" | "home" | "rooted" | {
readonly below: string;
};
/** How a row folds case: `protective` (the built-in tables: case, the two confusable letters, the invisible format
* characters, across every platform reading), `ascii` (the read deny set's contract), `host` (case-insensitive exactly
* where the host's filesystem is), `exact`. A fold only ever WIDENS what a tightening row matches; no exemption folds. */
export type PathGuardFold = "protective" | "ascii" | "host" | "exact";
/** The minimum a row offers the judgment: its reach over one view, and whether the data-root exemption applies to it. */
export interface GuardRowReach {
readonly reach: (view: GuardView) => PathRowReach;
readonly exemptible?: boolean;
}
/** ONE guarded path. */
export interface PathGuardRow extends GuardRowReach {
/** The row's name wherever a refusal, a card or the classifier cites it (the table name, the glob, the rule text). */
readonly name: string;
readonly grammar: PathGuardGrammar;
readonly polarity: "deny" | "ask" | "allow";
readonly faces: readonly DenyFace[];
readonly placement: PathGuardPlacement;
readonly fold: PathGuardFold;
readonly exemptible: boolean;
/** The built-in tier that activates the row (absent on a row no tier selects). */
readonly tier?: string;
/** Where the row came from: a built-in default, a deployment REPLACEMENT of a default table, an ADDITION to one, a rule. */
readonly origin: "builtin" | "replacement" | "addition" | "rule";
}
/** What {@link judgePathRows} found: the row, the view it met there (its spelling and kind; absent on an unreadable hold),
* and — when nothing was reached and some row could not be judged — the reason of the first such row. */
export interface PathRowsHit<R> {
readonly row: R;
readonly view?: string;
readonly viewKind?: GuardViewKind;
readonly unreadable?: string;
}
/**
* THE one judgment of guarded rows over a target's views, for every table and every lane: rows outer, views inner — the
* first row (in the caller's order) that some view reaches is the answer. `tighten` (deny / ask): any present view reaching
* the row reaches it; a row that cannot be judged (or a target that cannot be read) is held and answered only when no row
* reaches. `allow`: a row admits the target only when it admits EVERY view (a link out of an allowed directory is not
* admitted through its spelling); an unreadable target is admitted by nothing. An exemptible row reads each view through
* the exemption law (the module header).
*/
export declare function judgePathRows<R extends GuardRowReach>(rows: readonly R[], views: TargetViews, direction: "tighten" | "allow"): PathRowsHit<R> | undefined;