From 4fa34d07b969303a8b299ce4ece7baa2aa01ddc6 Mon Sep 17 00:00:00 2001 From: Mathews-Tom Date: Thu, 16 Jul 2026 00:43:59 +0530 Subject: [PATCH] fix(advisor): clear rewritten thinking signatures --- .../src/advisor/__tests__/advisor.test.ts | 29 +++++++++++++++++++ packages/coding-agent/src/advisor/runtime.ts | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/advisor/__tests__/advisor.test.ts b/packages/coding-agent/src/advisor/__tests__/advisor.test.ts index f5c6a8d3a..f565b9a88 100644 --- a/packages/coding-agent/src/advisor/__tests__/advisor.test.ts +++ b/packages/coding-agent/src/advisor/__tests__/advisor.test.ts @@ -1776,6 +1776,35 @@ describe("advisor", () => { expect(restored).toContain("OTHERSECRET"); expect(restored).toContain("tok_abc123"); }); + it("clears advisor thinking signatures when collision scrubbing rewrites their text", async () => { + const obfuscator = new SecretObfuscator([ + { type: "plain", content: "OTHERSECRET", friendlyName: "TOKABC123" }, + { type: "regex", content: "tok_[a-z0-9]+" }, + ]); + const promptInputs: string[] = []; + const agent = makeAgent(promptInputs); + const staleThinking = obfuscator.obfuscate("OTHERSECRET"); + agent.state.messages.push({ + role: "assistant", + content: [{ type: "thinking", thinking: staleThinking, thinkingSignature: "signed-thinking" }], + timestamp: 1, + } as unknown as AgentMessage); + const messages: AgentMessage[] = [{ role: "user", content: "later tok_abc123", timestamp: 2 } as AgentMessage]; + const host: AdvisorRuntimeHost = { + snapshotMessages: () => messages, + enqueueAdvice: () => {}, + obfuscator, + }; + const runtime = new AdvisorRuntime(agent, host); + + runtime.onTurnEnd(); + await runtime.waitForCatchup(1000, 1); + + const storedAssistant = agent.state.messages[0] as AssistantMessage; + const thinking = storedAssistant.content.find(block => block.type === "thinking"); + expect(thinking?.thinking).not.toContain("TOKABC123_"); + expect(thinking?.thinkingSignature).toBeUndefined(); + }); it("skips raw image payload bytes when collecting regex-protected values, so image data cannot spuriously trigger friendly-prefix collision avoidance", async () => { // Regression: collectAdvisorRegexSecretValues's generic tree walk only diff --git a/packages/coding-agent/src/advisor/runtime.ts b/packages/coding-agent/src/advisor/runtime.ts index a663a17ae..6ffdca034 100644 --- a/packages/coding-agent/src/advisor/runtime.ts +++ b/packages/coding-agent/src/advisor/runtime.ts @@ -692,7 +692,7 @@ function obfuscateAssistantMessage( const thinking = obfuscator.obfuscate(block.thinking, sharedRegexSecretValues); if (thinking === block.thinking) return block; changed = true; - return { ...block, thinking }; + return { ...block, thinking, thinkingSignature: undefined }; } if (block.type === "toolCall") { const args = obfuscateToolArguments(obfuscator, block.arguments, sharedRegexSecretValues);