Skip to content

results-payload splices result.title into the 'public-safe' summary with zero sanitization #7249

Description

@JSONbored

Context

packages/loopover-engine/src/results-payload.ts's ResultsPayload.summary field is documented (line 32) as:

One readable, public-safe sentence a customer can act on without assembling anything.

buildResultsPayload (line 39-64) constructs this "public-safe" sentence by splicing result.title in verbatim, with zero sanitization:

const prPart = hasPr ? `Opened PR #${result.prNumber} in ${result.repoFullName}` : `No pull request was opened for ${result.repoFullName}`;
const changePart = /* ... */;
const summary = `${prPart}: ${result.title}. ${changePart}. Status: ${status}.`;

result.title is IterationResult.title — sourced from the actual PR/task title of a completed loop iteration, which is ultimately contributor/miner-authored free text, not a value this module controls or has validated. Other public-facing text-composition modules in this same package treat exactly this kind of pass-through text as something that needs scrubbing before it reaches a customer-facing surface: pr-body-draft.ts runs every line through sanitizeLine() before assembly, and advisory/gate-advisory.ts/miner/agent-sdk-driver.ts both call a shared redactSecrets helper (subprocess-env.ts) on any free text that might reach a result surface. buildResultsPayload does neither — despite explicitly documenting its output as "public-safe," it never redacts or scrubs result.title at all before splicing it into the one string this whole module exists to produce for a customer.

Concretely: a title containing something that should never reach a customer-facing message (a secret-looking token, an internal path, or any of the same content classes redactSecrets/sanitizeLine exist to catch elsewhere in this package) would flow straight through into ResultsPayload.summary unredacted, silently violating the module's own "public-safe" contract. This is scoped specifically to packages/loopover-engine/src/results-payload.ts's own buildResultsPayload function — it does not require touching anything outside the loopover-engine package.

Requirements

  • buildResultsPayload must sanitize result.title before splicing it into summary, using the same redaction primitive already used elsewhere in this package for free text reaching a public/customer surface (redactSecrets from subprocess-env.ts, or an equivalent already-proven helper — do not invent a new redaction implementation when an existing one is available in this package).
  • The sanitization must apply only to the text embedded in summary — it must not change IterationResult/ResultsPayload's data shape or any other field.
  • Preserve existing behavior for a title that contains nothing sensitive (i.e. the fix must be additive/defensive, not change the visible summary text for the common case).

Deliverables

  • result.title is redacted/sanitized before being embedded into ResultsPayload.summary in buildResultsPayload
  • Regression test: an IterationResult.title containing a secret-shaped string (matching whatever pattern class redactSecrets already catches elsewhere in this package's test suite) produces a summary with that content redacted, not passed through verbatim
  • Regression test: a normal, non-sensitive title still produces the same summary text as before this change (no regression for the common case)

Test Coverage Requirements

This repo's Codecov patch gate is 99%+ hard (branch-counted) on every changed line/branch in src/**/packages/**. The regression tests above must reproduce the exact unsanitized-passthrough gap described and assert it's fixed, plus confirm no visible regression for benign titles.

Expected Outcome

ResultsPayload.summary is genuinely public-safe as documented — a task/PR title containing sensitive-looking content is redacted before reaching the customer-facing results summary, consistent with how this package already treats free text elsewhere (pr-body-draft.ts, gate-advisory.ts).

Links & Resources

packages/loopover-engine/src/results-payload.ts:32 (the "public-safe" doc contract), :39-64 (buildResultsPayload, the unsanitized splice at line 61). packages/loopover-engine/src/pr-body-draft.ts (sanitizeLine, the sibling pattern) and packages/loopover-engine/src/subprocess-env.ts (redactSecrets, the existing shared primitive) as the precedent to reuse.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions