diff --git a/packages/loopover-engine/src/track-record-summary.ts b/packages/loopover-engine/src/track-record-summary.ts index d7829e84a4..681005fd2e 100644 --- a/packages/loopover-engine/src/track-record-summary.ts +++ b/packages/loopover-engine/src/track-record-summary.ts @@ -433,18 +433,19 @@ export function renderTrackRecordSummaryMarkdown(summary: TrackRecordSummary): s if (summary.outcomes.openIgnored > 0) { bodyLines.push(`- Open PRs ignored for rate: ${summary.outcomes.openIgnored}`); } + + // #6772 / #7444: fail-closed on COMPUTED fields only. Caller/GitHub-sourced identity-like free text must not + // trip the blocklist: the GitHub login is appended after this scan, and public evidence URLs are structural + // links (repo/path segments can legitimately contain hyphen- or slash-bounded blocklisted substrings such as + // `wallet-connect`) — scanning them was the same false-positive crash class #6772 fixed for login. + assertPublicSummaryText(bodyLines.join("\n")); + if (summary.incidents.hasPublicIncident && summary.incidents.evidenceUrls.length > 0) { bodyLines.push( `- Public evidence: ${summary.incidents.evidenceUrls.map((url) => markdownSafe(url)).join(", ")}`, ); } - // #6772: fail-closed on the COMPUTED fields only -- a blocklisted term there would be a genuine leak. The - // GitHub login is caller-provided identity (already markdown-escaped below), not computed private data, so a - // legitimate username that merely contains a blocklisted word bounded by hyphens (e.g. "team-wallet") must - // NOT crash rendering. Scanning the whole block including the identity line was the bug. - assertPublicSummaryText(bodyLines.join("\n")); - const lines = [ "### Public contributor record", "", diff --git a/packages/loopover-engine/test/track-record-summary.test.ts b/packages/loopover-engine/test/track-record-summary.test.ts index 159017ab57..3ab568e4b7 100644 --- a/packages/loopover-engine/test/track-record-summary.test.ts +++ b/packages/loopover-engine/test/track-record-summary.test.ts @@ -621,6 +621,35 @@ test("renderTrackRecordSummaryMarkdown fails closed if a blocked public field is ); }); +test("renderTrackRecordSummaryMarkdown tolerates a login containing a blocklisted substring (#6772 / #7444)", () => { + const summary = computeTrackRecordSummary({ + login: "team-wallet", + now: NOW, + config: { includeTrackRecordSummary: true, warnings: [] }, + outcomes: [], + }); + const markdown = renderTrackRecordSummaryMarkdown(summary); + assert.match(markdown, /GitHub login: team-wallet/u); +}); + +test("renderTrackRecordSummaryMarkdown tolerates evidence URLs containing a blocklisted path substring (#7444)", () => { + const summary = computeTrackRecordSummary({ + login: "miner", + now: NOW, + config: { includeTrackRecordSummary: true, warnings: [] }, + outcomes: [], + incidents: [ + { + login: "miner", + kind: "ban", + publicEvidenceUrl: "https://example.test/org/wallet-connect/issues/1", + }, + ], + }); + const markdown = renderTrackRecordSummaryMarkdown(summary); + assert.match(markdown, /Public evidence: https:\/\/example\.test\/org\/wallet-connect\/issues\/1/u); +}); + test("computeTrackRecordSummary is byte-stable for equivalent repeated calls", () => { const input = { login: "miner", diff --git a/test/unit/track-record-summary-login-blocklist.test.ts b/test/unit/track-record-summary-login-blocklist.test.ts index 13136b8739..0bd15e547e 100644 --- a/test/unit/track-record-summary-login-blocklist.test.ts +++ b/test/unit/track-record-summary-login-blocklist.test.ts @@ -38,4 +38,18 @@ describe("renderTrackRecordSummaryMarkdown login vs public-field blocklist (#677 expect(md).toContain("- Open PRs ignored for rate: 3"); expect(md).toMatch(/- Public evidence: .*example\.test\/record/u); }); + + it("REGRESSION (#7444): renders an evidence URL whose path contains a blocklisted substring instead of throwing", () => { + const base = computeTrackRecordSummary({ login: "miner", now: NOW, config, outcomes: [] }); + const md = renderTrackRecordSummaryMarkdown({ + ...base, + incidents: { + ...base.incidents, + hasPublicIncident: true, + label: "public conduct incident present", + evidenceUrls: ["https://example.test/org/wallet-connect/issues/1"], + }, + }); + expect(md).toContain("https://example.test/org/wallet-connect/issues/1"); + }); });