From aacd40a67aecc54f3cb09a1abf120aeba2a2501d Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 4 May 2026 15:46:24 -0500 Subject: [PATCH] Stabilize LLM wiki work item ids Co-Authored-By: Paperclip --- packages/plugins/plugin-llm-wiki/src/wiki.ts | 7 ++++++- .../plugin-llm-wiki/tests/plugin.spec.ts | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/plugins/plugin-llm-wiki/src/wiki.ts b/packages/plugins/plugin-llm-wiki/src/wiki.ts index 6581144c496..ab02bb3d896 100644 --- a/packages/plugins/plugin-llm-wiki/src/wiki.ts +++ b/packages/plugins/plugin-llm-wiki/src/wiki.ts @@ -1764,9 +1764,14 @@ export async function recordPaperclipDistillationOutcome(ctx: PluginContext, inp export async function createPaperclipDistillationWorkItem(ctx: PluginContext, input: PaperclipDistillationWorkItemInput) { const wikiId = normalizeWikiId(input.wikiId); - const itemId = randomUUID(); const scope = paperclipCursorScopeMetadata(input); const idempotencyKey = input.idempotencyKey ?? `${input.kind}:${scope.sourceScope}:${scope.scopeKey}`; + const itemId = deterministicUuid([ + "paperclip_distillation_work_item", + input.companyId, + wikiId, + idempotencyKey, + ].join(":")); if (input.kind === "backfill" && !scope.projectId && !scope.rootIssueId) { throw new Error("Backfill work items must target a projectId or rootIssueId; whole-company backfill is not allowed."); } diff --git a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts index de7a1b17a28..460a5a72c8b 100644 --- a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts +++ b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts @@ -1428,6 +1428,12 @@ Route sidebar state stays attached to the selected wiki page. projectId: "77777777-7777-4777-8777-777777777777", idempotencyKey: "manual:project:77777777-7777-4777-8777-777777777777", }); + await harness.performAction("create-paperclip-distillation-work-item", { + companyId: COMPANY_ID, + kind: "manual", + projectId: "77777777-7777-4777-8777-777777777777", + idempotencyKey: "manual:project:77777777-7777-4777-8777-777777777777", + }); await harness.performAction("create-paperclip-distillation-work-item", { companyId: COMPANY_ID, kind: "retry", @@ -1450,12 +1456,13 @@ Route sidebar state stays attached to the selected wiki page. }); const workItemWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_work_items")); - expect(workItemWrites).toHaveLength(4); - expect(workItemWrites.map((write) => write.params?.[3])).toEqual(["manual", "retry", "backfill", "manual"]); + expect(workItemWrites).toHaveLength(5); + expect(workItemWrites.map((write) => write.params?.[3])).toEqual(["manual", "manual", "retry", "backfill", "manual"]); + expect(workItemWrites[1].params?.[0]).toBe(workItemWrites[0].params?.[0]); expect(String(workItemWrites[0].params?.[9])).toContain('"sourceScope":"project"'); - expect(String(workItemWrites[1].params?.[9])).toContain('"sourceScope":"root_issue"'); - expect(String(workItemWrites[2].params?.[9])).toContain('"sourceScope":"project"'); - expect(workItemWrites[3].params?.[8]).toBe("manual:project:77777777-7777-4777-8777-777777777780"); + expect(String(workItemWrites[2].params?.[9])).toContain('"sourceScope":"root_issue"'); + expect(String(workItemWrites[3].params?.[9])).toContain('"sourceScope":"project"'); + expect(workItemWrites[4].params?.[8]).toBe("manual:project:77777777-7777-4777-8777-777777777780"); await expect(harness.performAction("create-paperclip-distillation-work-item", { companyId: COMPANY_ID,