/** * @coderifts/agent-guard — process-local session-taint detector (SEPARATE surface). * * Implements session-taint-detector-SPEC.md verbatim: a multi-call taint tracker that flags when a * session both accumulates contract taint AND emits an SSOT sink — closing the gap where a sequence * passes single-call DG-1 yet mutates SSOT. Additive: the frozen `builtinDetector.detect()` is NOT * touched. Versioned SEPARATELY (session-taint/1.0.0), monotonic toward caution. * * Normative: flag ⇔ ssot_sink_events ≠ ∅ ∧ tainted. Fixture-faithful classifier order (§1.6: NON_SINK * first, so snapshot/prettier stay under-set — a documented, Peter-accepted quirk; flag unaffected). */ import type { ToolCallDescriptor } from './types.js'; export declare const SESSION_TAINT_VERSION = "session-taint/1.0.0"; export type PathClass = 'prose' | 'scratch' | 'migration' | 'ssot' | 'code_or_config' | 'other'; export declare function pathClass(p: string): PathClass; export type PendingRename = { from: string; to: string; } | { drop: string; }; export interface SessionState { scratch_writes: string[]; contract_looking_scratch: string[]; encoded_fragments: string[]; intermediate_artifacts: string[]; pending_renames: PendingRename[]; optional_fields_added: string[]; required_fields_declared: string[]; ssot_paths_touched: string[]; ssot_sink_events: string[]; ssot_invalidated: boolean; reverse_snapshot: boolean; formatter_only_ssot: boolean; store_keys: string[]; tainted: boolean; } export declare function emptySessionState(): SessionState; /** Serialize to the fixture's projected form (pending_renames -> "from->to" | "drop:name"). */ export declare function projectState(s: SessionState): Record; export type CmdClass = 'non_sink' | 'ssot_invalidate' | 'ssot_sink' | 'reverse_snapshot' | 'formatter' | 'unknown_script'; export declare function classifyCommand(command: string, action: string, cfg?: SessionTaintConfig): CmdClass; export declare function updateSession(state: SessionState, call: { toolName?: string; arguments?: unknown; }, cfg?: SessionTaintConfig): SessionState; export declare function computeTainted(s: SessionState): boolean; export interface SessionEval { flag: boolean; trip: boolean; key_signal: string | null; } export declare function deriveKeySignal(s: SessionState): string; /** flag ⇔ (ssot_sink_events ≠ ∅ || sink_seen) ∧ (tainted || overflow). */ export declare function evaluate(state: SessionState, prevFlagged?: boolean, opts?: { overflow?: boolean; sinkSeen?: boolean; }): SessionEval; export interface SessionTaintConfig { extraSinkPatterns?: RegExp[]; extraNonSinkPatterns?: RegExp[]; maxCalls?: number; maxPathsTracked?: number; maxSinkEvents?: number; maxStateBytes?: number; ttlMs?: number; bindCwd?: boolean; sessionId?: string; sessionTaintSeverity?: 'caution' | 'stop'; } export interface SessionTaintObservation { flag: boolean; trip: boolean; key_signal: string | null; state: Readonly; version: typeof SESSION_TAINT_VERSION; overflow: boolean; severity: 'caution' | 'stop'; } export declare class SessionTaintTracker { readonly version = "session-taint/1.0.0"; private state; private prevFlag; private callCount; private overflow; private sinkSeen; private lastObserveAt; private cfg; constructor(config?: SessionTaintConfig); private pathTotal; observe(call: ToolCallDescriptor): SessionTaintObservation; status(): SessionTaintObservation; reset(): void; private snapshot; private now; } //# sourceMappingURL=session-taint.d.ts.map