Harden LLM wiki source redaction

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-05-04 15:37:56 -05:00
1 parent 771efddc98
commit a9d8d3eb79
3 files changed
+16 -3

No files matched your search

@@ -76,6 +76,7 @@ const DEFAULT_ROUTE_SIDEBAR_EXPANDED_PATHS = [
"wiki",
"wiki/sources",
"wiki/projects",
"wiki/areas",
"wiki/entities",
"wiki/concepts",
"wiki/synthesis",
+10 -2
View File
@@ -398,7 +398,7 @@ function redactDistillationSensitiveText(input: string): string {
function protectDistillationSourceBody(input: {
issue: Issue;
sourceKind: "comment" | "document";
sourceKind: "issue" | "comment" | "document";
sourceId: string;
body: string;
}): DistillationSourceProtectionResult {
@@ -1465,6 +1465,13 @@ export async function assemblePaperclipSourceBundle(ctx: PluginContext, input: P
const remaining = { value: maxCharacters - lines.join("\n").length };
for (const issue of issues) {
const protectedIssue = protectDistillationSourceBody({
issue,
sourceKind: "issue",
sourceId: issue.id,
body: issue.description?.trim() ? issue.description.trim() : "_No issue description._",
});
if (protectedIssue.warning) warnings.push(protectedIssue.warning);
const issueBody = [
`- Issue ID: ${issue.id}`,
issue.identifier ? `- Identifier: ${issue.identifier}` : null,
@@ -1474,7 +1481,7 @@ export async function assemblePaperclipSourceBundle(ctx: PluginContext, input: P
issue.projectId ? `- Project ID: ${issue.projectId}` : null,
`- Updated at: ${isoString(issue.updatedAt) ?? "unknown"}`,
"",
issue.description?.trim() ? issue.description.trim() : "_No issue description._",
protectedIssue.body,
].filter((line): line is string => line !== null).join("\n");
appendBoundedSection({
lines,
@@ -1488,6 +1495,7 @@ export async function assemblePaperclipSourceBundle(ctx: PluginContext, input: P
projectId: issue.projectId ?? null,
title: issue.title,
updatedAt: isoString(issue.updatedAt) ?? undefined,
...protectedIssue.refPatch,
},
remaining,
perSourceLimit,
@@ -1294,7 +1294,7 @@ Route sidebar state stays attached to the selected wiki page.
identifier: "PAP-4002",
title: "Sensitive source issue",
projectId: "77777777-7777-4777-8777-777777777777",
description: "Keep the project page current without copying credential material into the wiki.",
description: "Keep the project page current without copying OPENAI_API_KEY=sk-supersecretissuevalue1234567890 into the wiki.",
updatedAt: new Date("2026-05-04T10:00:00Z"),
});
harness.seed({
@@ -1335,11 +1335,14 @@ Route sidebar state stays attached to the selected wiki page.
expect(run.bundle.markdown).toContain("Suppressed by LLM Wiki distillation security policy");
expect(run.bundle.markdown).not.toContain("ghp_supersecretcommenttoken1234567890");
expect(run.bundle.markdown).not.toContain("sk-supersecretdocumentvalue1234567890");
expect(run.bundle.markdown).not.toContain("sk-supersecretissuevalue1234567890");
expect(run.bundle.warnings).toEqual(expect.arrayContaining([
expect.stringContaining("Suppressed issue content"),
expect.stringContaining("Suppressed comment content"),
expect.stringContaining("Suppressed document content"),
]));
expect(run.bundle.sourceRefs).toEqual(expect.arrayContaining([
expect.objectContaining({ kind: "issue", redactionStatus: "suppressed_sensitive_content" }),
expect.objectContaining({ kind: "comment", redactionStatus: "suppressed_sensitive_content" }),
expect.objectContaining({ kind: "document", redactionStatus: "suppressed_sensitive_content" }),
]));
@@ -1351,6 +1354,7 @@ Route sidebar state stays attached to the selected wiki page.
expect(storedMarkdown).toContain("Suppressed by LLM Wiki distillation security policy");
expect(storedMarkdown).not.toContain("ghp_supersecretcommenttoken1234567890");
expect(storedMarkdown).not.toContain("sk-supersecretdocumentvalue1234567890");
expect(storedMarkdown).not.toContain("sk-supersecretissuevalue1234567890");
});
it("creates source snapshots and only advances cursors after successful distillation outcomes", async () => {