export type DeterministicDirection = 'request' | 'response'; export type DeterministicCategory = 'sensitive_file' | 'metadata_ssrf' | 'credential_command' | 'destructive_command' | 'destructive_sql' | 'infra_destroy' | 'reverse_shell' | 'secret_exfiltration' | 'honeypot'; /** * Per-rule enforcement action (org-configured, shipped in the Local Safety * snapshot). Absent everywhere = 'block' — the only behavior older CLIs and * older snapshots know, so mixed fleets stay fail-strict. * - 'block' — stop the action (today's behavior). * - 'warn' — let the action proceed; surface + report the finding as a warning. * - 'mask' — redact the matched secret where the surface can rewrite content * (MCP tool responses); surfaces that cannot rewrite treat it as block. */ export type LocalSafetyRuleAction = 'block' | 'warn' | 'mask'; export interface DeterministicFinding { blocked: true; ruleId: string; category: DeterministicCategory; categoryId: string; itemId: string; source: 'builtin' | 'custom'; reason: string; evidence: string; explanation?: string; policyHash?: string; /** Org-configured enforcement action for the matched rule. Absent = 'block'. */ action?: LocalSafetyRuleAction; /** * The exact matched secret string, present only for secret_exfiltration * findings — the seam 'mask' uses to redact tool responses. Never spooled. */ matchedSecret?: string; } export interface LocalSafetyCustomBlock { id: string; categoryId: string; pattern: string; explanation?: string; /** Absent = 'block'. */ action?: LocalSafetyRuleAction; } export interface LocalSafetyScanOptions { disabledBuiltInItemIds?: string[]; /** Built-in items with a NON-default action (absent item = 'block'). */ itemActions?: Record; /** * Whether an actual Local Safety snapshot was resolved for this scan. When * explicitly `false` (cold cache / wiped file / fetch failed with nothing on * disk) the guard must NOT hard-block on the catalog default — it mirrors the * server's warn-first gate for unarmed machines. `undefined` preserves the * legacy "absent item = block" contract for callers that don't set it. */ snapshotPresent?: boolean; customBlocks?: LocalSafetyCustomBlock[]; policyHash?: string; cwd?: string; inspectScripts?: boolean; /** Absolute paths of planted honeypot decoy files — ANY reference blocks. */ honeypotPaths?: string[]; /** * Org-managed trusted script paths (substring match on the normalized path). * Content scanning is skipped for referenced scripts under these paths — the * admin-controlled exception for repos whose test suites legitimately contain * attack fixtures (security tooling, guard regression tests). */ trustedScriptPaths?: string[]; } export declare function stripInertDataSegments(text: string): string; export declare function scanDeterministicToolCall(toolName: string, toolArgs: Record, options?: LocalSafetyScanOptions): DeterministicFinding | undefined; export declare function scanDeterministicTextResponse(text: string, options?: LocalSafetyScanOptions): DeterministicFinding | undefined; export declare function scanDeterministicPrompt(text: string, options?: LocalSafetyScanOptions): DeterministicFinding | undefined; export interface DeterministicScanOutcome { /** The finding that stops the action, if any. */ blockingFinding?: DeterministicFinding; /** warn-action findings that matched — the action proceeds; report these. */ warnings: DeterministicFinding[]; } export interface DeterministicTextResponseOutcome extends DeterministicScanOutcome { /** mask-action secret findings that WERE redacted from the text. */ maskFindings: DeterministicFinding[]; /** The response text with every masked secret redacted. */ maskedText: string; } /** * Resolve a scan under per-rule actions WITHOUT letting a warn rule shadow a * block rule. Scans return the FIRST match, so a single pass would let one * warn-mode rule hide a second, block-mode rule matching the same value. This * re-scans with each warn rule suppressed until a blocking finding surfaces or * nothing matches. Default (no itemActions configured) is a single pass * returning today's behavior exactly. * * 'mask' degrades to block here: these surfaces (tool calls, prompts, shell * commands) cannot rewrite content, so mask can only fail strict. */ export declare function resolveDeterministicOutcome(scan: (options?: LocalSafetyScanOptions) => DeterministicFinding | undefined, options?: LocalSafetyScanOptions): DeterministicScanOutcome; /** * Resolve a TOOL RESPONSE under per-rule actions. The response is the one * surface that can be rewritten, so 'mask' redacts here: each masked secret is * replaced in the text and the REDACTED text is rescanned — a second secret of * the same type is still found (rule suppression would hide it). Warn rules * are suppressed as in resolveDeterministicOutcome. Any 'block' rule match * blocks regardless of what was masked before it. */ export declare function resolveDeterministicTextResponse(text: string, options?: LocalSafetyScanOptions): DeterministicTextResponseOutcome;