/** * Untrusted-text containment (design/53 §2.A — "untrusted-data-everywhere"). * * A multi-agent code-orchestration system treats **every worker's output** (report / diff / code / module) * as untrusted data: an LLM worker can be prompt-injected or adversarial, and its output flows into other * models' prompts (the L3 judge, the leader, the next worker) where it could pose as instructions — * e.g. emitting `` to escape its framing and forge a verdict (threat BUG1, verify.ts). * * The trusted side of the codebase REJECTS such sequences (runtask.ts: trusted steering / deny reasons must * not contain ``). Worker text can't be rejected — it must be **contained**: this module * NEUTRALIZES break-out sequences and wraps the text in a clearly-labeled opaque fence the consuming prompt * tells the model to treat as data, not instructions. Structural and reusable across the chain, not a * per-call point-fix. * * This is defense-in-depth, NOT a guarantee: an LLM cannot reliably honor a "this is data" boundary on its * own (instructions and data share one channel). The real boundary is decorrelation + reading the objective * artifact (the diff / working tree) rather than the worker's self-report (design/53 §3, design/54 §3). */ /** * Neutralize structural break-out sequences in UNTRUSTED text so it can't escape its framing into * model-facing instructions. Always neutralizes `` / `` (the codebase's * elevated-authority wrapper) by inserting a zero-width space after the leading `<`. Pass `extraTags` to also * neutralize a CALLER's own data-framing tags — e.g. `team.ts` embeds member output inside `` / * ``, so an untrusted member could emit `` to break out (search [46] BUG2); * the caller passes those tag names. Tag names must be literal (alphanumeric/hyphen) — they are code-supplied * wrapper names, never untrusted input. Idempotent for prompt assembly (a defused tag no longer matches). */ export declare function sanitizeUntrustedText(text: string, extraTags?: string[]): string; /** * Defuse this module's triple-angle fence sentinels (`<<<` / `>>>`) inside an untrusted body so the body * cannot forge {@link delimitUntrusted}'s own OPEN/CLOSE markers and break out of the fence. A worker (or * an external page via `web_fetch`, an MCP resource — the label format is open-source, so the close marker * `<<>>>` is guessable) could otherwise emit the literal close marker followed by * top-level injection. Caps any run of 3+ identical brackets at 2 consecutive by inserting a zero-width * space — the reader still sees the text, but no `<<<`/`>>>` triple survives. Idempotent: a capped run * (≤2) never re-matches `{3,}`. Defusing EITHER bracket breaks the marker; we defuse both for symmetry. * * Residual (council QUESTION, accepted): only ASCII `<`/`>` (U+003C/003E) are defused. A Unicode lookalike * (fullwidth `<`/`>`, U+FF1C/FF1E) is NOT — but a fullwidth marker is a DIFFERENT string from the real * ASCII close sentinel, so it cannot break out at the string level; at worst it visually resembles the * fence to the model. Consistent with this module's "defense-in-depth, NOT a guarantee" posture. * * Exported (design/138 S2-C, O-F11/C-F10): the memory write-time scan detects a forged fence by diffing * `defuseFenceMarkers(text) !== text` — the ONE sentinel definition serves both the defusing and the * detection, so the two can never drift apart. Do not hand-copy the `<<<`/`>>>` pattern anywhere else. */ export declare function defuseFenceMarkers(body: string): string; /** * Make untrusted text safe to interpolate INLINE on a trusted prompt line (not inside a {@link delimitUntrusted} * fence) — e.g. design/80 D-F echoes a chosen option label into the "The user answered:" block. Folds EVERY * line/space separator to a single space so the text cannot forge a new line — `\s` (covers CR/LF/TAB/VT/FF and * U+2028/U+2029 + the Unicode spaces) PLUS U+0085 NEL, which `\s` does NOT match — caps the length, then applies * the same tag-neutralization (``) + fence-sentinel (`<<<`/`>>>`) defusing the fenced body gets. * Defense-in-depth, NOT a guarantee (same posture as the rest of this module). */ export declare function inlineUntrusted(text: string, maxLen?: number): string; /** * Wrap untrusted text in a clearly labeled opaque fence. The consuming prompt should instruct the model to * treat everything inside as untrusted data — never as instructions. Sanitizes internally (system-reminder * neutralization + fence-sentinel defusing, on the body AND the label), so callers may pass raw * worker/external text — and labels derived from external identifiers (hostnames, resource URIs). */ export declare function delimitUntrusted(label: string, text: string): string; //# sourceMappingURL=untrusted-text.d.ts.map