UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

62 lines (61 loc) • 4.95 kB
/** * The environment a spawned child inherits: which of this process's variables it must not see. * * A child the engine spawns may run what the MODEL chose (a tool shell, a gate over model-written code, a language * server). Under the `"scrub"` policy (the default) it inherits every variable but those the judgment below names — * deleted whole, never rewritten; `"all"` and a `string[]` allow list are the caller's explicit alternatives * ({@link inheritedHostEnv}). One judgment per variable ({@link classifySecretEnvEntry}), the first rule that answers: * 1. exempt — git's environment config and the proxy variables, handed on as written ({@link isExemptEnvName}); * 2. `exact-name` — a known credential name ({@link CREDENTIAL_ENV_NAMES}); * 3. `prefix-rule` — the OpenTelemetry settings ({@link OTEL_ENV_RE}); * 4. `namespace-rule` — a credential word as any segment of a name in the engine's own `SEMA_` namespace; * 5. `name-rule` — a credential-shaped name ({@link nameIsCredentialShaped}) off {@link NON_SECRET_ENV_EXACT_NAMES}; * 6. `value-rule` — a value that carries a credential ({@link valueCarriesCredential}). * {@link isSecretEnvKey} and {@link scrubSecretEnv} both answer with this one judgment. The exempt families, the * credential names, the name shape and the value predicate follow the reference implementation's subprocess-env scrub * as written, three ways stricter: plural `TOKENS` is a credential word unless a count word touches it, the GitHub * token names are not held back from the name shape, and the name shape always runs. */ import type { RedactionConfidence, RedactionSource } from "./arg-summary.js"; import { type EngineNotice } from "./engine-notice.js"; /** Which rule withheld an entry. */ export type SecretEnvFindingKind = "exact-name" | "name-rule" | "namespace-rule" | "prefix-rule" | "value-rule"; /** One env entry the `"scrub"` policy withheld (deleted): its name — never its value, so the record is loggable —, the * rule that withheld it, how strong that claim is, and the minting module. */ export interface SecretEnvFinding { key: string; kind: SecretEnvFindingKind; confidence: RedactionConfidence; source: RedactionSource; } /** Does the `"scrub"` policy withhold `key`? With `value`, exactly the answer {@link scrubSecretEnv} gives for that * entry; without it, the answer for its name alone (the value rule then has nothing to read). */ export declare function isSecretEnvKey(key: string, value?: string): boolean; /** The `"scrub"` policy: `env` without every entry {@link isSecretEnvKey} withholds, the rest as written. `findings` is * an optional caller-owned collector: each withheld entry is pushed onto it (name, rule, confidence), none of them * present in the result. `env` itself is not modified. */ export declare function scrubSecretEnv(env: NodeJS.ProcessEnv, findings?: SecretEnvFinding[]): NodeJS.ProcessEnv; /** How much of this process's environment a child spawned on this host inherits — the `inheritEnv` value. */ export type InheritEnvPolicy = "all" | "scrub" | string[]; /** * The environment a child spawned ON THIS HOST inherits, by an {@link InheritEnvPolicy}: `"scrub"` (and absent) is * this process's environment through {@link scrubSecretEnv}; `"all"` is this process's environment * verbatim (the explicit opt-out); a `string[]` is exactly the named variables that are set, verbatim — a strict allow * list, so a name it leaves out (`PATH` included) is not inherited. `findings` collects what the scrub withheld, and * only the `"scrub"` arm adds to it. Any other value reads as `"scrub"`; both spawn sites that take a policy — the * tool shell's `NodeExecutionEnv` (at construction) and the oracle gate (per gate) — refuse a malformed one through * {@link inheritEnvPolicyProblem} before it gets here. */ export declare function inheritedHostEnv(policy: InheritEnvPolicy | undefined, findings?: SecretEnvFinding[]): NodeJS.ProcessEnv; /** Why `value` is not an {@link InheritEnvPolicy} (absent counts as one — the scrub), or `undefined` when it is. */ export declare function inheritEnvPolicyProblem(value: unknown): string | undefined; /** Test seam: never called by production code. */ export declare function __resetSecretEnvScrubNoticeAnnouncement(): void; /** * The ONE disclosure point for a scrub's withheld keys. Routed through {@link deliverEngineNotice} — the * engine's one notice throat — so a wired `onNotice` seat REPLACES the console line exactly as every * other `EngineNotice` does, and an absent seat prints the same words `console.warn` always printed here. * `detail.names` carries every withheld key. Once per PROCESS, never per call or per site; an EMPTY * findings array is a no-op. */ export declare function announceSecretEnvScrub(onNotice: ((notice: EngineNotice) => void) | undefined, findings: readonly SecretEnvFinding[]): void;