From b2740f1575393373b914785e1442b611795a0d61 Mon Sep 17 00:00:00 2001 From: philluiz2323 Date: Fri, 12 Jun 2026 09:51:58 -0700 Subject: [PATCH] fix(agent): exclude repo identifier from scenario-summary guard assertPublicSummaryClean serialized the whole summary -- including the un-sanitized repoFullName -- and threw on FORBIDDEN_PUBLIC_LANGUAGE, so a legitimately named repo (hotkey/coldkey/wallet are Bittensor terms) made renderPublicScenarioSummary throw and fail entirely. Scan only the rendered free-text content; repoFullName/generatedAt are structural identifiers, not sanitized output. --- src/scenarios/scenario-summary.ts | 8 ++++++-- test/unit/scenario-summary.test.ts | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/scenarios/scenario-summary.ts b/src/scenarios/scenario-summary.ts index 02c04160ea..34cdbe4306 100644 --- a/src/scenarios/scenario-summary.ts +++ b/src/scenarios/scenario-summary.ts @@ -178,8 +178,12 @@ function extractDataClassification(scenarioInput: AgentScenarioInput | undefined } function assertPublicSummaryClean(summary: PublicScenarioSummary): void { - const serialized = JSON.stringify(summary); - /* v8 ignore start -- All text fields are sanitized before this guard; defensive check for future fields. */ + // Scan only rendered free-text fields. repoFullName/generatedAt are structural identifiers (the repo + // the summary is about), not sanitized content -- a legitimately named repo (e.g. "owner/hotkey-vault") + // must not make this guard throw and fail the whole summary. + const { repoFullName: _repoFullName, generatedAt: _generatedAt, ...renderedContent } = summary; + const serialized = JSON.stringify(renderedContent); + /* v8 ignore start -- Defensive: every rendered field is individually sanitized; this guards a future unsanitized field. */ if (FORBIDDEN_PUBLIC_LANGUAGE.test(serialized)) { throw new Error("Public scenario summary still contains forbidden language."); } diff --git a/test/unit/scenario-summary.test.ts b/test/unit/scenario-summary.test.ts index 9bc55c6fc4..4e74be0330 100644 --- a/test/unit/scenario-summary.test.ts +++ b/test/unit/scenario-summary.test.ts @@ -162,6 +162,16 @@ describe("renderPublicScenarioSummary", () => { expect(summary.advisoryOnly).toBe(true); }); + it("renders for a repo whose name contains a forbidden term without throwing", () => { + // "hotkey"/"wallet" are Bittensor protocol terms; a legitimately named repo must not fail the guard. + const summary = renderPublicScenarioSummary({ + repoFullName: "octo/hotkey-wallet", + generatedAt: "2026-06-12T00:00:00.000Z", + }); + expect(summary.repoFullName).toBe("octo/hotkey-wallet"); + expect(summary.headline).toMatch(/Advisory scenario summary generated from available repo signals/i); + }); + it("renders pressure options, eligibility notes, blockers, and data classification", () => { const pressureSimulation = simulateOpenPrPressure({ repoFullName: "octo/demo",