secret-guard: count a secret once when bash returns the same output in content and structuredContent

Measured in a full-extension session: one `echo "$SECRET"` was reported as
"redacted ... x2". pi's bash tool returns its output both as content text and
as structuredContent.output, and both are (correctly) redacted. The count
now takes, per name, the highest count from any one field instead of the
sum. A test pins it: it failed before the change and passes after. Re-run
in the full-extension TUI: the warning now reads "redacted SG_TEST_TOKEN
from bash output"; 0 raw copies sent, 0 in the session file. Suite: 46/46.
This commit is contained in:
Joakim Persson
2026-10-12 14:38:41 +02:00
parent b3dc979aba
commit a88fa99d39
3 changed files with 24 additions and 3 deletions
+9
View File
@@ -191,6 +191,15 @@ test("toolResultChange: secrets in details or structuredContent alone are redact
assert.ok(!("content" in ch.result), "unchanged content is not returned");
});
test("toolResultChange: the same output in content AND structuredContent (bash) counts once", () => {
// pi's bash returns its output twice: content text and structuredContent.output (measured 2026-10-12).
const known = envSecrets(ENV);
const out = `val=${V.a}`;
const ch = toolResultChange(bashEvent(out, { structuredContent: { output: out, exit_code: 0 } }), known);
assert.equal(ch.result.structuredContent.output, "val=<redacted:MEMPALACE_REMOTE_TOKEN>");
assert.equal(ch.hits.get("MEMPALACE_REMOTE_TOKEN"), 1);
});
test("toolResultChange: no secret anywhere -> undefined (handler returns nothing)", () => {
assert.equal(toolResultChange(bashEvent("total 12\ndrwx------ 2 developer"), envSecrets(ENV)), undefined);
assert.equal(toolResultChange(bashEvent(`x ${V.a}`), []), undefined, "no known secrets -> nothing to do");