Skip to content

feat(performance): compare baseline reports - #87

Open
ben-ranford wants to merge 11 commits into
mainfrom
feat/57-performance-baseline
Open

ben-ranford wants to merge 11 commits into
mainfrom
feat/57-performance-baseline

Conversation

@ben-ranford

@ben-ranford ben-ranford commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Closes #57

Summary

Adds the unreleased stave-performance-compare command and opt-in stave.performance.comparison/v1 envelope. It compares saved reports without changing the existing report schema or absolute budget behavior.

Comparison requires matching host, Go version, OS/architecture, CPU count, fixtures, capabilities, budget schema, and reproducibility parameters. Source revisions are preserved as comparison metadata and may differ. The executable location and report artifact destination are excluded from invocation matching because they are not measurement settings. All remaining arguments are compared.

Each p95 metric and allocation uses a 10% same-host noise tolerance; idle CPU uses 0.10 percentage points. Deltas are machine-readable. The API rejects negative, NaN, and infinite tolerance values and invalid direct-report measurements. Neither the command nor API refreshes a failed baseline.

Validation

  • go test ./performance ./cmd/stave-performance-compare -count=1
  • make generated-refresh
  • Full make ci passed after rebasing onto current main.
  • go test -race -count=1 ./performance ./cmd/stave-performance-compare passed on the rebased commit.
  • A compiled comparison of reports from the identical benchmark binary at two paths was rejected as invalid before the fix; it now emits comparison deltas and preserves actual timing regressions. Synthetic tests independently assert path equivalence and rejection of changed measurement flags.

Release Notes

Unreleased v1.1.0 development tooling adds same-environment performance-report comparison. Existing stave-performance JSON output and its absolute budgets are unchanged.

Scope firewall

This PR is limited to the #57 comparator library, CLI, deterministic synthetic tests, documentation, and generated inventories. It does not alter benchmark collection, release budget thresholds, dependencies, Go version, or baseline artifacts.

@ben-ranford ben-ranford added area:rendering Capabilities, colour, themes, layout, surfaces, and renderers type:feature Additive user-facing library capability or workflow priority:p2 Normal milestone priority labels Sep 13, 2026
@ben-ranford ben-ranford self-assigned this Sep 13, 2026
@ben-ranford ben-ranford added this to the v1.1.0 milestone Sep 13, 2026
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 12:09
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-16T04:28:07.333597Z 19e6026 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ben-ranford
ben-ranford requested a lite review from Copilot September 13, 2026 12:09
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 12:12
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 12:12

Copilot AI 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.

🟡 Changes recommended

Unresolved critical and moderate review findings remain in report validation and compatibility handling.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds an opt-in same-host performance report comparator with API, CLI, tests, documentation, and refreshed inventories.

Changes:

  • Adds report validation, compatibility checks, and tolerance-based deltas.
  • Adds stave-performance-compare with documented exit codes.
  • Adds deterministic tests and generated inventory updates.
File summaries
File Description
scripts/rigor/generated/public-api.txt Updated public API inventory
scripts/rigor/generated/dependency-inventory.json Updated dependency inventory
README.md Comparator documentation link
performance/comparison.go Comparison and report-validation logic
performance/comparison_test.go Comparator and decoder tests
docs/performance-baseline.md Usage and comparison policy documentation
cmd/stave-performance-compare/main.go Comparison CLI
cmd/stave-performance-compare/main_test.go CLI behavior tests
Review details

Suppressed comments (4)

performance/comparison.go:110

  • measurementByName linearly scans the candidate list for every baseline metric, and compatibleEnvironment repeats the same lookup. Because DecodeReport accepts any number of metrics up to 16 MiB, this makes comparison O(n²) and allows a bounded but hostile artifact to consume excessive CPU; index candidate measurements by name once for both checks.
		candidateMetric := measurementByName(candidate.Measurements, metric.Name)

performance/comparison.go:135

  • stave-performance writes the sentinel "unknown" when os.Hostname() fails, but this validation accepts it as a usable host. Reports from unrelated machines can therefore both pass the host equality check and receive same-host tolerance even though same-host provenance is unavailable. Reject unknown-host reports (or carry a verifiable host identity) before comparing them.
	if report.Host == "" || report.GoVersion == "" || report.GOOS == "" || report.GOARCH == "" || report.CPUs < 1 || report.Nodes < 1 || report.NodeShape == "" || report.Renderer == "" || report.Viewport.Width < 1 || report.Viewport.Height < 1 {

performance/comparison.go:144

  • IdleCPU.Window and the optional IdleCPU.Attempts values are part of the report measurement but are never validated. A direct caller can supply a negative window or NaN/infinite/negative attempts and Compare will accept the report, despite this API promising to reject invalid direct-report measurements. Validate the window and every supplied attempt before comparison.
	if report.IdleCPU.Name != "idle_cpu.percent_one_core" || math.IsNaN(report.IdleCPU.Value) || math.IsInf(report.IdleCPU.Value, 0) || math.IsNaN(report.IdleCPU.Limit) || math.IsInf(report.IdleCPU.Limit, 0) || report.IdleCPU.Value < 0 || report.IdleCPU.Limit <= 0 || report.IdleCPU.Value >= report.IdleCPU.Limit || !report.IdleCPU.AllWithinBudget {

performance/comparison.go:215

  • When baseline == 0 and candidate > 0, PercentDelta remains 0 even though Delta is positive and WithinTolerance is false. Consumers of the machine-readable envelope will interpret a regression from zero as no percentage change; represent a zero-baseline percentage as explicitly undefined rather than emitting zero.
	percent := 0.0
	withinTolerance := candidate == 0
	if baseline > 0 {
		percent = delta / baseline
		withinTolerance = percent <= tolerance
  • Files reviewed: 6/8 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread performance/comparison.go Outdated
Comment thread performance/comparison.go Outdated
Comment thread performance/comparison.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34c13eb12f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go Outdated
@ben-ranford
ben-ranford requested a lite review from Copilot September 13, 2026 13:35
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 13:35
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 13:35

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3d4b4ebda

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go Outdated
Comment thread performance/comparison.go Outdated
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 14:05
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 14:05

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 90d020a99d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go Outdated
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 14:44
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 14:44

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5fe13726db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go
Comment thread performance/comparison.go
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 15:20
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 15:20

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f90cbe3d5d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go Outdated
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 15:40
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 15:40

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e198316b1f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go Outdated
Comment thread performance/comparison.go Outdated
Comment thread performance/comparison.go
@ben-ranford
ben-ranford force-pushed the feat/57-performance-baseline branch from e198316 to 7dbfd6f Compare September 13, 2026 16:00
@ben-ranford
ben-ranford marked this pull request as draft September 13, 2026 16:00
@ben-ranford
ben-ranford marked this pull request as ready for review September 13, 2026 16:00
@ben-ranford
ben-ranford marked this pull request as draft September 16, 2026 04:24
@ben-ranford
ben-ranford marked this pull request as ready for review September 16, 2026 04:24
@ben-ranford
ben-ranford force-pushed the feat/57-performance-baseline branch from 7dbfd6f to 19e6026 Compare September 16, 2026 04:24
@sonarqubecloud

Copy link
Copy Markdown

@ben-ranford

Copy link
Copy Markdown
Owner Author

Sonar API audit

Reviewed commit: 19e60263275ba70aeb999f5a1e96ec1112f973ed.

Live public SonarCloud API queries for PR #87 returned:

  • Open issues: 0 (api/issues/search, resolved=false, all severities; complete result).
  • Security hotspots: 0 (api/hotspots/search; complete result).
  • Current-head Sonar check: passed (check run 104664644604).
  • Sonar pull-request analysis commit matches the current head; quality gate OK.

Audited via CLI at 2026-09-16T04:24:43.592620+00:00. Project visibility was verified as public. No findings were changed or suppressed.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19e6026327

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread performance/comparison.go
percent := 0.0
withinTolerance := candidate == 0
if baseline > 0 {
percent = delta / baseline

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Emit percentDelta in percentage units

When a metric rises from 100 to 105, this calculation serializes percentDelta as 0.05, even though the actual percentage delta is 5%. Machine consumers displaying or otherwise interpreting the versioned field according to its name will understate every nonzero change by a factor of 100; either multiply this value by 100 for the wire field or name it as a relative fraction instead.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:rendering Capabilities, colour, themes, layout, surfaces, and renderers priority:p2 Normal milestone priority type:feature Additive user-facing library capability or workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compare performance reports against a checked-in baseline

2 participants