@sema-agent/core
Version:
Stateless, task-oriented AI agent core
62 lines (61 loc) • 4.95 kB
TypeScript
/**
* 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;