From c46ca1dc758eede098162f07304d479dce08d1e7 Mon Sep 17 00:00:00 2001 From: Koosha Paridehpour <42529354+KooshaPari@users.noreply.github.com> Date: Mon, 14 Sep 2026 19:36:36 -0700 Subject: [PATCH] fix(compression): preserve instruction blocks from lossy engines (#13523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lossy compression engines leave ``, `` and `` envelopes byte-identical. Agentic CLIs inject these into user messages, and compressing them inverted negations, dropped emphasis and broke the tags (#13453). Maintainer fixes: (1) the new test imported `../../open-sse/…` from `tests/unit/compression/`, which does not resolve, so it had never run. With the path fixed, the main case failed: the envelopes were appended to the built-in list, so fenced code and inline code inside the reminder had already become sentinels, and `replacePattern` skips any match containing one. The envelopes now form a region pass right after frontmatter, before fenced-code extraction; all 4 cases and the full compression suite (1,518) pass, and the compression budget gate reports no regression. (2) Dropped an unused `tombstoned` binding. (3) The branch also carried an unrelated `feat(sveltekit)` commit (`apps/web/**`), so it was reset to the release tip plus only this commit, authorship preserved. Validated in one consolidated batch of this series (37 PRs boarded together on `release/v3.8.51`): `typecheck:core`, `check:open-sse-typecheck` and `check:dashboard-typecheck` clean; ESLint clean on every changed file; file-size, complexity, cognitive-complexity, changelog-integrity, docs-counts, docs-sync and migration-numbering gates green (only the pre-existing `open-sse/utils/stream.ts` file-size red remains, inherited from the base); 3,743 focused `node:test` cases plus 34 vitest cases green. Thanks @KooshaPari! --- open-sse/services/compression/preservation.ts | 17 +++ .../preserve-system-reminder.test.ts | 114 ++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tests/unit/compression/preserve-system-reminder.test.ts diff --git a/open-sse/services/compression/preservation.ts b/open-sse/services/compression/preservation.ts index 3f5e6f3bfa..a55f6549a4 100644 --- a/open-sse/services/compression/preservation.ts +++ b/open-sse/services/compression/preservation.ts @@ -87,6 +87,23 @@ export function extractPreservedBlocks( let result = text; result = extractFrontmatter(result, addBlock); + + // Whole-region patterns run before fenced code and the inline built-ins: those leave + // sentinels inside a region, and replacePattern skips any match that already holds one. + // #13453: the instruction envelopes agentic CLIs inject into user messages — + // compressing them inverts negations, drops emphasis and breaks the XML tags. + const regionPatterns: CompiledPattern[] = [ + { pattern: /[\s\S]*?<\/system-reminder>/g, kind: "system_instruction" }, + { pattern: /[\s\S]*?<\/instructions?>/g, kind: "system_instruction" }, + { + pattern: /[\s\S]*?<\/project[- ]instructions?>/g, + kind: "system_instruction", + }, + ]; + for (const { pattern, kind } of regionPatterns) { + result = replacePattern(result, ensureGlobal(pattern), kind, addBlock); + } + result = extractFencedCodeBlocks(result, (content) => addBlock(content, "fenced_code")); const builtIns: CompiledPattern[] = [ diff --git a/tests/unit/compression/preserve-system-reminder.test.ts b/tests/unit/compression/preserve-system-reminder.test.ts new file mode 100644 index 0000000000..97ab9a38b7 --- /dev/null +++ b/tests/unit/compression/preserve-system-reminder.test.ts @@ -0,0 +1,114 @@ +/** + * Tests for #13453: preserve blocks from lossy compression. + * + * Agentic coding CLIs (Claude Code, Codex, etc.) inject project instructions + * into user-role messages wrapped in envelopes. + * Lossy compression engines (ultra, aggressive, caveman, etc.) were rewriting + * these instruction blocks as prose, dropping negations and breaking XML tags. + * + * The fix adds to the preservation patterns so they survive + * compression byte-identical. + */ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { extractPreservedBlocks } from "../../../open-sse/services/compression/preservation.ts"; + +const INSTRUCTION_BLOCK = ` +Project instructions (auto-injected by the coding agent CLI, role=user): + +# Deploy rules + +- NEVER run \`rm -rf\` on the target host. Always ask first. +- Do not push to \`main\` directly; open a PR. +- The backup files \`.app-prev-*\` must never be deleted. +- Never store the SSH password on disk. +- Always run \`npm test\` before \`npm run build\`. +- Do NOT edit files under \`/etc\` by hand. + +## Restart procedure + +\`\`\`bash +systemctl --user restart app.service +curl -sf http://127.0.0.1:20128/health +\`\`\` + +Docs: https://example.com/runbook +`; + +test("extractPreservedBlocks captures blocks verbatim", () => { + const userMessage = `Here is my request:\n${INSTRUCTION_BLOCK}\n\nPlease deploy the fix.`; + + const { text: tombstoned, blocks } = extractPreservedBlocks(userMessage); + + // The instruction block should be tombstoned (replaced with placeholder) + assert.ok( + !tombstoned.includes("NEVER run"), + "Original instruction text should be replaced with a placeholder" + ); + assert.ok(tombstoned.includes("Here is my request"), "Non-instruction text should remain"); + assert.ok(tombstoned.includes("Please deploy the fix"), "Trailing text should remain"); + + // The preserved block should contain the full instruction text + const instructionBlock = blocks.find((b) => b.kind === "system_instruction"); + assert.ok(instructionBlock, "Should find a preserved system_instruction block"); + assert.ok( + instructionBlock!.content.includes("NEVER run"), + "Preserved block should contain the full instruction text" + ); + assert.ok( + instructionBlock!.content.includes(""), + "Preserved block should include the opening tag" + ); + assert.ok( + instructionBlock!.content.includes(""), + "Preserved block should include the closing tag" + ); +}); + +test("extractPreservedBlocks captures blocks", () => { + const text = `Before\n\nDo NOT touch production.\n\nAfter`; + + const { text: tombstoned, blocks } = extractPreservedBlocks(text); + + const instructionBlock = blocks.find((b) => b.kind === "system_instruction"); + assert.ok(instructionBlock, "Should find a preserved system_instruction block"); + assert.ok( + instructionBlock!.content.includes("Do NOT touch production"), + "Preserved block should contain instruction text" + ); + assert.ok( + !tombstoned.includes("Do NOT touch production"), + "Instruction text should be tombstoned" + ); +}); + +test("extractPreservedBlocks captures blocks", () => { + const text = `Before\n\nNEVER delete the database.\n\nAfter`; + + const { blocks } = extractPreservedBlocks(text); + + const instructionBlock = blocks.find((b) => b.kind === "system_instruction"); + assert.ok(instructionBlock, "Should find a preserved system_instruction block"); + assert.ok( + instructionBlock!.content.includes("NEVER delete the database"), + "Preserved block should contain instruction text" + ); +}); + +test("non-instruction text outside is still compressible", () => { + const text = `Normal prose that can be compressed.\nDo NOT do X\nMore normal prose.`; + + const { text: tombstoned } = extractPreservedBlocks(text); + + // The prose around the instruction block should still be tombstoned + // (i.e. the prose can be compressed, but the instruction block is protected) + assert.ok( + tombstoned.includes("Normal prose that can be compressed"), + "Non-instruction prose should remain in the tombstoned text" + ); + assert.ok(tombstoned.includes("More normal prose"), "Trailing prose should remain"); + assert.ok( + !tombstoned.includes("Do NOT do X"), + "Instruction text should be replaced with placeholder" + ); +});