Skip to content

feat: compare paired same-runner baselines - #3

Merged
cpunion merged 3 commits into
mainfrom
codex/paired-run-baseline-20260803
Aug 3, 2026
Merged

cpunion merged 3 commits into
mainfrom
codex/paired-run-baseline-20260803

Conversation

@cpunion

@cpunion cpunion commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • accept an optional same-runner baseline benchmark file in recorder artifacts
  • validate and merge paired baselines across platform/shard artifacts
  • use the paired baseline only for PR report deltas, with a linked base commit and vs base label
  • preserve historical-main comparison when no paired baseline is supplied
  • keep stored current-series history and Pages behavior unchanged

This lets a caller benchmark its base and head in one runner job, avoiding cross-machine variance without coupling the action to repository-specific benchmark commands.

Validation

  • npm run check
  • npm audit --omit=dev
  • npm run build
  • bundled dist and publish/dist updated

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: same-runner paired baseline

Solid, well-tested feature — the baseline path mirrors the result path, validation is reused, and the report changes correctly thread the vs base/vs main provenance through to the rendered comment. README and action.yml docs match the implementation. One security finding worth addressing before merge, plus a couple of minor notes.

Security (please address)

Baseline source.url / source.sha are rendered into the privileged PR comment without identity pinning.
The trust model (.github/workflows/publish.yml) is: record runs in the untrusted CI context and emits artifacts (result.json + the new baseline.json), while render/publish runs on workflow_run with pull-requests: write and posts the bot PR comment. For the primary result, bindSource (src/commands.js:262) re-pins identity against expected-source-repository/expected-source-sha and overrides source.url with the trusted source-url from publish.yml.

The baseline gets none of this. bindSource is only called on loaded.results (src/commands.js:315); pairedBaseline comes straight from the untrusted baseline.json via entryFromResults(loaded.baselines, ...) (src/commands.js:322-326), and src/report.js:71 renders its source.url into a markdown link and source.sha.slice(0,12) as the link text. validURL (src/artifact.js:31) allows any https host, so a fork PR author can make the "base commit" link in the authoritative bot comment point to an arbitrary URL and display a fabricated SHA — a spoofing/phishing primitive in a trusted-context comment. (Markdown breakout itself is blocked: the URL sits in a <...> destination and validURL forbids <> and CR/LF, so impact is a misleading link/label rather than arbitrary HTML.)

Suggested fix: pin the baseline the same way the primary result is pinned — apply a bindSource-equivalent to loaded.baselines (e.g. expected-baseline-* / a trusted baseline-source-url), or at minimum constrain the rendered baseline URL host to GITHUB_SERVER_URL and the repository to the known base before rendering.

Minor

  • Baseline runUrl/timestamp copied from the current run (src/commands.js:200-203): the baseline source reuses the current run's runUrl and timestamp. This may be intentional for the same-runner model (this run measured the baseline), but it is easy to misread later. timestamp currently only affects mergeShards tie-breaking; runUrl is not surfaced in the report. A one-line comment recording the intent would prevent a future "fix" from breaking it.
  • bindSource intentionally does not re-bind baselines (src/commands.js:315): assuming the security finding above is resolved by explicitly pinning baselines, add a short comment documenting whichever invariant you land on, so the asymmetry between results and baselines is not mistaken for an oversight.

View job run

Comment thread src/report.js
);
let comparisonNote;
if (baseline && sameRunner) {
comparisonNote = `_Compared with [\`${baseline.source.sha.slice(0, 12)}\`](<${baseline.source.url}>) measured in the same runner job._`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The baseline's source.url and source.sha rendered here come straight from the untrusted baseline.json artifact — unlike the primary result, the baseline is never passed through bindSource (src/commands.js:315), so its identity is not pinned against expected-source-* and its URL is not replaced with a trusted value.

validURL (src/artifact.js:31) allows any https host, so a fork PR author can make this "base commit" link in the privileged bot comment point to an arbitrary URL and display a fabricated 12-hex SHA. Recommend pinning the baseline source (apply a bindSource-equivalent to loaded.baselines, e.g. expected-baseline-* / a trusted baseline-source-url) or constraining the URL host to GITHUB_SERVER_URL / the known base repository before rendering.

@cpunion

cpunion commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the baseline identity finding in b8112c9:

  • the trusted publisher now resolves the current PR base through the GitHub API and passes its repository/SHA/ref to the renderer;
  • paired baseline artifacts must match that identity, and their link/run metadata is overwritten with trusted values before rendering;
  • added a regression test that tampers baseline.json with a malicious URL and verifies it cannot reach the bot comment, plus mismatch/missing-identity tests.

Also changed the reusable workflow to invoke publish@v1, so the paired artifact is rendered by the matching publisher version. npm run check, bundle build, actionlint, and audit all pass locally.

@cpunion
cpunion force-pushed the codex/paired-run-baseline-20260803 branch from f99a49d to ba2187a Compare August 3, 2026 06:22
@cpunion

cpunion commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up in ba2187a: I removed the live exact-base-SHA lookup after checking the queued-workflow case. The target branch can advance between measurement and trusted publishing, so comparing against the PR API's current base SHA would reject a valid paired artifact.

The final publisher follows the review's minimum safe boundary: it requires the artifact baseline repository to equal the PR target repository and always reconstructs the commit URL on GITHUB_SERVER_URL; an optional exact-SHA input remains available to direct callers. The malicious external URL regression still verifies that the untrusted URL cannot reach the bot comment. This also removes the extra PR API parsing and avoids failures when main advances.

@cpunion
cpunion merged commit 7c7ef59 into main Aug 3, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant