//#region src/redaction/imperative-patterns.d.ts /** * Imperative-pattern catalogue for inbound prompt-injection defence. * * Sibling to `BUILT_IN_PATTERNS` (PII / secrets) - the two * catalogues are disjoint by construction. The imperative catalogue * is consumed by the inbound sanitization layer in `@graphorin/tools` * to scan tool / MCP results before they reach the agent's message * store; the PII / secrets catalogue is consumed by the outbound * exporter validators to scan span attributes before they reach an * exporter. * * The patterns target the canonical English "ignore previous * instructions" / "system override" injection family - the concrete * surface that an untrusted-skill or MCP server result might use to * smuggle imperative content into the next provider call. The * catalogue is intentionally conservative: every entry has a fixed- * substring prefilter so the per-byte scan budget stays sub-millisecond * on typical 16 KB tool results. * * @packageDocumentation */ /** * Stable name of an imperative pattern. The catalogue is curated; * user-supplied patterns can use any identifier they want and will be * passed through the sanitization layer alongside the built-ins. * * @stable */ type ImperativePatternName = 'ignore-previous-instructions' | 'forget-instructions' | 'override-instructions' | 'system-prompt-leak' | 'role-reassignment' | 'developer-mode' | 'jailbreak-marker' | 'tool-call-injection' | 'role-tag-injection' | 'untrusted-content-delimiter-injection'; /** * One entry in the imperative-pattern catalogue. The shape mirrors * `BUILT_IN_PATTERNS` so consumers can share scan / replace * machinery, but the fields are typed as imperative-only so the two * catalogues do not accidentally merge. * * @stable */ interface ImperativePattern { readonly name: ImperativePatternName | (string & {}); readonly description: string; /** * Cheap substring prefilter applied before the regex; if the body * does not contain any of the prefilter substrings the regex is * skipped entirely. The prefilter is case-insensitive. */ readonly prefilter: ReadonlyArray; /** * Full regex applied when the prefilter matches. Always carries the * `g` and `i` flags; the catalogue construction validates this. */ readonly regex: RegExp; /** Replacement string applied by the `'detect-and-strip*'` policies. */ readonly mask: string; } /** * The default-on imperative-pattern catalogue. Stable across patches; * additions during the pre-1.0 window are minor-bumps because new * patterns may produce additional `tool.inbound.sanitization.hit{...}` * counter increments on existing deployments. * * @stable */ declare const BUILT_IN_IMPERATIVE_PATTERNS: readonly ImperativePattern[]; /** * Combined Aho-Corasick-style prefilter set across every pattern. * Lower-cased substrings; consumers test the body once with the * combined filter before iterating regexes. * * @stable */ declare const IMPERATIVE_PREFILTER_SUBSTRINGS: ReadonlyArray; /** * Compiled scan helper. Returns the list of pattern names that fired * AND the number of bytes the strip would remove if applied. Bounded * by the budget hint - when exceeded, returns `null` to let the caller * apply the best-effort `'detect-failed'` annotation. * * @stable */ interface ScanResult { readonly hits: ReadonlyArray<{ readonly pattern: string; readonly matchCount: number; }>; readonly bytesMatched: number; readonly scanDurationUs: number; } /** * Run the imperative-pattern scan against `body`. Patterns are * iterated in catalogue order; the prefilter shortcut returns early * for bodies that do not contain any imperative-family substring. * * @stable */ declare function scanImperativePatterns(body: string, patterns?: ReadonlyArray, budgetMs?: number): ScanResult | null; /** * Apply `pattern.mask` to every match of every pattern in `body`. Used * by the `'detect-and-strip*'` policies. The mask is calibrated to NOT * match any imperative pattern itself, so post-strip bodies do not * trigger another scan hit on round trips. * * @stable */ declare function stripImperativePatterns(body: string, patterns?: ReadonlyArray): string; //#endregion export { BUILT_IN_IMPERATIVE_PATTERNS, IMPERATIVE_PREFILTER_SUBSTRINGS, ImperativePattern, ImperativePatternName, ScanResult, scanImperativePatterns, stripImperativePatterns }; //# sourceMappingURL=imperative-patterns.d.ts.map