UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

81 lines (80 loc) • 4.97 kB
/** * The session capture opt-out's ENTITLEMENT ADJUDICATOR (slice 3's core): one pure * function every ingress shares — the prepare-time declaration, the resume-time standing-record * re-check (§3.3), and the Runner flip verb's fresh-resolve closure — so the posture table cannot * fork across call sites. * * The separation law (§3.3) is the module's spine: THIS adjudicator answers "may the declaration / * the continued run proceed"; the one-way control-plane RECORD answers "how does this session run" * (record wins for capture — nothing here ever re-enables capture for a recorded session; the * governed/capture-required continuation arm refuses to RUN instead, keeping both promises: zero * capture and zero out-of-policy running, availability paid). * * The two fault polarities, and why both are deliberate (the code-side home of the §3.1 cost * table): * - `"open"` (and absent): a resolver fault ALLOWS the opt-out (+ named disclosure). Wrongly * allowing costs one uncaptured session — recoverable. Wrongly denying captures a session whose * user explicitly said no — irreversible (read, foldable into products, syncable). The * fail-safe faces the irreversible side's OPPOSITE, which is why this member is the documented * exception to the caps family's deny-on-outage degrade. * - `"governed"`: the deployment has EXPLICITLY declared the compliance side's irreversibility * (a retention-required principal acquiring an opt-out through an outage window) the heavier * one, so a fault/absent verdict refuses the run — fail-closed, the declared direction. * A mutation flipping the governed fault arm to the open polarity must turn the G-姿态 escape pin * red (m12). */ /** The screened posture (prepare-config-doors folds absent → `"open"`). */ export type MemoryCapturePosture = "open" | "governed" | "capture-required"; /** The per-principal entitlement input as RESOLVED for this adjudication: * - `value` — `RuntimeCaps.allowMemoryOptOut` when the resolver answered a boolean; `undefined` * when absent OR when the resolver faulted (the F2 fault-transit contract: a fault must never * be encoded as an explicit value); * - `faulted` — the resolve THREW / timed out / answered a non-boolean (the non-boolean case is * a fault by the member's own contract, never truthiness-read). Distinguished from a clean * `undefined` only for DISCLOSURE under `"open"` (both allow there) — under `"governed"` both * are the same refusal (verdict absent = face fault). */ export interface CaptureEntitlementInput { value: boolean | undefined; faulted: boolean; } export type CaptureOptOutVerdict = { allowed: true; /** Present ⇔ the open-posture fault arm fired: the opt-out takes effect AND the caller owes * the named `onError({phase:"config"})` disclosure line (this string). */ faultDisclosure?: string; } | { allowed: false; /** Always `memory.capture_optout_denied` (terminal). The caller throws it; a DECLARATION * denial must leave zero record residue (§2.1 order invariant — adjudicate BEFORE marking). */ code: "memory.capture_optout_denied"; detail: string; }; /** * Adjudicate one capture opt-out ingress. `subject` names what is being adjudicated, for the * refusal detail only: `"declaration"` (a `capture:"off"` spelling / the flip verb) or * `"standing-record"` (a resumed session whose one-way record stands — §3.3: under * governed/capture-required the question is whether the run may CONTINUE; the record's zero-capture * promise is not on the table). */ export declare function adjudicateCaptureOptOut(input: { posture: MemoryCapturePosture; entitlement: CaptureEntitlementInput; subject: "declaration" | "standing-record"; }): CaptureOptOutVerdict; /** The typed terminal refusal builder (one spelling for every ingress). */ export declare function captureOptOutDeniedError(detail: string): Error & { code: string; }; /** The typed could-not-record refusal (§2.8 — never a success notice's sibling; the caller mints * {@link import("../memory-engine/engine.js").memoryCaptureOptOutUnpersistedNotice} beside it). * * `ingress` is REQUIRED (internal builder, both call sites in prepare-memory state it): the two * arms' throws settle different things and the message must say which. The declaration arm's throw * is whitelisted out of prepare-memory's fail-open catch and refuses the RUN; the host flip verb's * throw rejects only the verb promise — `captureOptedOut` is assigned below it — so the run * continues with capture still ON. One sentence for both said "refusing to run", which was false * in the direction that matters: it told the caller the session had stopped capturing when it had * not. */ export declare function captureOptOutUnpersistedError(sessionId: string, ingress: "declaration" | "flip-verb"): Error & { code: string; };