Skip to content

ci: warn (don't fail) on Bencher main regression#3168

Merged
justin808 merged 4 commits intomainfrom
jg/benchmark-warn-not-fail
Apr 20, 2026
Merged

ci: warn (don't fail) on Bencher main regression#3168
justin808 merged 4 commits intomainfrom
jg/benchmark-warn-not-fail

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Apr 18, 2026

Summary

  • Downgrade the "fail on main regression" step in the benchmark workflow to a ::warning:: annotation so main stops being permanently red.
  • Keep everything else intact: Bencher dashboard upload, auto-opened tracking issue Performance Regression Detected on main (6a399b0) #3116, and the per-run report in the job summary still run.

Why

The gate has been failing nearly every non-docs push to main for weeks. Investigation of the Bencher alert history makes clear it's runner noise, not a real regression:

  • The failing run cited in the issue (run 24521366756 on 4eb83648b) fired 43 alerts across Core and Pro, spanning routes unrelated to the committed change (which only edits packages/react-on-rails/src/pageLifecycle.ts).
  • Comparing alert sets across six consecutive main runs, Jaccard similarity between adjacent runs is 0.01–0.08 — i.e., each run flags a near-disjoint random subset of (benchmark, measure) pairs. A real regression would produce persistent, overlapping alerts.
  • Docs-only commits "pass" simply because they skip benchmarks via paths-ignore. Every run that actually exercises the suite trips the t-test on at least one metric.

Single-run, 95%-CI t-test alerts on GitHub-hosted runners + a 70-minute suite will always produce tail-latency noise. The right long-term fix is threshold/sample-size tuning or self-hosted runners, tracked in #3169.

Change

.github/workflows/benchmark.yml step 7c: replace exit ${BENCHER_EXIT_CODE:-1} with a GitHub Actions warning annotation. Steps 7a (Bencher report) and 7b (regression issue) are untouched.

Follow-ups (not in this PR)

Test plan

  • CI passes on this PR (the change is workflow-only).
  • After merge, next push to main shows a Bencher warning annotation instead of a red check when alerts fire.

Note

Medium Risk
Changes main benchmark gating behavior by no longer failing the workflow on performance regressions, which could let real regressions merge if reviewers rely on CI status. Adds new stderr-based classification logic that could mis-detect alerts and alter when the workflow fails vs warns.

Overview
Benchmark CI on main no longer hard-fails on Bencher regression alerts. The workflow now emits a ::warning:: for regressions, while continuing to open/update the regression tracking issue.

Adds BENCHER_HAS_ALERT detection by parsing Bencher stderr and gates downstream steps on it: regression-related actions run only when an actual alert is detected, and a new step explicitly fails main only for non-regression Bencher failures (auth/API/network/CLI).

Reviewed by Cursor Bugbot for commit 12fa8f2. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

Release Notes

  • Improvements
    • Benchmarks now detect and flag regression alerts separately from general failures.
    • Main-branch workflow creates issues and emits warnings only for confirmed regression alerts.
    • CI now fails only for non-regression operational errors, reducing false positives and improving reliability.

Single-run alerts on GitHub-hosted runners are dominated by environmental
noise: the set of (benchmark, measure) pairs flagged varies almost entirely
across consecutive pushes on main (Jaccard ~0 between adjacent runs), while
every non-docs commit fails the gate. Tracking issue #3116 has accumulated
auto-regression comments with no actionable signal.

Retain the Bencher dashboard upload, the auto-opened tracking issue, and the
job-summary report (steps 7a/7b). Downgrade step 7c from `exit 1` to a
`::warning::` annotation so main stops being permanently red. Re-enable a
hard gate later when thresholds/sample-size tolerate the runner noise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 18, 2026

Walkthrough

The benchmark GitHub Actions workflow now parses Bencher stderr to set and export BENCHER_HAS_ALERT alongside BENCHER_EXIT_CODE. On main pushes, issue creation and warnings are triggered only when BENCHER_HAS_ALERT == '1'; non-alert Bencher failures cause a hard workflow failure.

Changes

Cohort / File(s) Summary
Benchmark workflow
.github/workflows/benchmark.yml
Pin Bencher action to bencherdev/bencher@v0.6.2; compute BENCHER_HAS_ALERT from stderr when BENCHER_EXIT_CODE != 0 and export it; gate issue-creation on BENCHER_HAS_ALERT == '1'; replace unconditional fail with a warn-only step for alerts and a hard-fail only for non-alert errors.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as GitHub Runner
    participant Bencher as Bencher (tool)
    participant Workflow as Workflow logic
    participant Issue as Issue Creator
    participant Summary as Job Summary

    Runner->>Bencher: run benchmarks
    Bencher-->>Runner: exit code + stderr
    Runner->>Workflow: set BENCHER_EXIT_CODE, parse stderr -> BENCHER_HAS_ALERT
    alt BENCHER_HAS_ALERT == '1'
        Workflow->>Summary: emit warning (::warning::)
        Workflow->>Issue: create regression issue
    else BENCHER_EXIT_CODE != '0' and BENCHER_HAS_ALERT != '1'
        Workflow->>Workflow: fail job (hard fail)
    else BENCHER_EXIT_CODE == '0'
        Workflow->>Summary: mark success
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed the stderr trail tonight,
I found a blip that gave a fright;
A warning hop, a ticket made,
But true failures still must fade.
I nibble logs and keep things right. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'ci: warn (don't fail) on Bencher main regression' clearly and concisely summarizes the main change: modifying the CI workflow to emit warnings instead of failures when Bencher detects regressions on main.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg/benchmark-warn-not-fail

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 18, 2026

Greptile Summary

This PR converts the main-branch Bencher regression gate from a hard workflow failure to a ::warning:: annotation, motivated by evidence that GitHub-hosted runner noise produces near-random alert sets across consecutive runs (Jaccard similarity 0.01–0.08). It adds a BENCHER_HAS_ALERT heuristic that parses Bencher stderr for alert indicators, gates the regression issue/warning on confirmed alerts only, and introduces a new step 7d that still hard-fails on operational errors (auth/API/network/CLI) where no alert indicator appears in stderr.

Confidence Score: 5/5

Safe to merge — workflow-only change with correct logic and no P0/P1 issues.

All findings are P2 or lower. The BENCHER_HAS_ALERT heuristic is well-commented and correctly scoped. Operational failures (step 7d) still hard-fail. The 404 baseline-missing case is handled before the new heuristic runs, avoiding interference. CLI pinning is intentional and explained.

No files require special attention.

Important Files Changed

Filename Overview
.github/workflows/benchmark.yml Replaces hard-fail on Bencher regression with a warning annotation; adds BENCHER_HAS_ALERT heuristic (stderr parsing) to distinguish real alerts from operational failures; pins Bencher CLI to v0.6.2; adds step 7d to still fail on non-regression errors.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[bencher run exits] --> B{BENCHER_EXIT_CODE == 0?}
    B -- Yes --> Z[✅ No action needed]
    B -- No --> C{404 baseline missing\nAND no alert indicators?}
    C -- Yes --> D[Set BENCHER_EXIT_CODE=0\nBENCHER_HAS_ALERT=0]
    C -- No --> E{stderr contains\nAlert? / threshold / boundary?}
    E -- Yes --> F[BENCHER_HAS_ALERT=1]
    E -- No --> G[BENCHER_HAS_ALERT=0]
    D --> Z
    F --> H{on main push?}
    G --> I{on main push?}
    H -- Yes --> J[Step 7b: Create/update\nregression GitHub issue]
    J --> K[Step 7c: emit ::warning::\nannotation]
    H -- No --> Z
    I -- Yes --> L[Step 7d: exit with\noriginal error code\n⛔ hard fail]
    I -- No --> Z
Loading

Reviews (3): Last reviewed commit: "ci: pin Bencher CLI, broaden alert match..." | Re-trigger Greptile

Comment thread .github/workflows/benchmark.yml Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 9cac6cff12

ℹ️ 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 .github/workflows/benchmark.yml Outdated
Comment thread .github/workflows/benchmark.yml Outdated
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 18, 2026

Review: ci: warn (don't fail) on Bencher main regression

Overall: Approve with one minor suggestion.

The motivation is well-documented and the evidence (Jaccard similarity ~0–0.08 across consecutive alert sets) is compelling. The change is minimal, surgical, and correctly scoped to push-to-main only.

What's good

  • Step 7b (issue creation/comment) and all Bencher upload/report steps are untouched — regression visibility is preserved.
  • The if: condition on step 7c (env.BENCHER_EXIT_CODE != '0') is unchanged, so the warning only fires when there's an actual Bencher signal, not unconditionally.
  • The updated step comment explains why the hard gate was removed and what it would take to re-enable it — good for future maintainers.
  • Downstream steps (step 8 summary) use if: always() so workflow completion reporting is unaffected.

One concern

The warning message hardcodes #3116 (see inline comment). Step 7b dynamically creates/updates whichever open regression issue is current, so after #3116 is closed the annotation will point to a stale issue. Suggest referencing the label instead of the number so the message stays accurate over time.

Minor notes

  • The warning message could include the run URL for a direct clickable link (e.g., ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}), but that's a nice-to-have.
  • Since step 7c is now purely cosmetic (a warning annotation with no side effects), it could be folded into step 7b — but keeping it as a separate step maintains the existing structure and makes it easy to re-enable the hard gate later by just swapping the echo back to exit.

Distinguish regression alerts from operational failures so the warn-only
policy on main only applies to genuine performance signals:

- Set BENCHER_HAS_ALERT=1 when bencher stderr mentions alert/threshold/
  boundary indicators; leave it 0 for auth/API/network/CLI failures.
- Step 7b (auto-open issue) and step 7c (::warning::) now require
  BENCHER_HAS_ALERT == 1 so operational errors do not create bogus
  regression issues.
- New step 7d fails the workflow on non-regression Bencher errors on
  main, preserving the original safety net for a broken benchmark
  pipeline (missing uploads, bad credentials, Bencher outage).
- Step 7c warning no longer hardcodes a specific issue number
  (#3116 will churn as issues are closed/reopened) and now includes
  the workflow run URL for a direct clickable link.

Addresses review feedback on #3168.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@justin808
Copy link
Copy Markdown
Member Author

Review feedback addressed (commit e39e00ba6)

I (Claude Code) addressed all three actionable review items in a single commit:

1. Keep non-regression Bencher failures blocking main (@chatgpt-codex-connector's P1)

Added a new BENCHER_HAS_ALERT env flag derived from bencher stderr (alert|threshold violation|boundary violation). The warn-only policy now applies only when that flag is set:

  • Step 7b (auto-open regression issue) now requires BENCHER_HAS_ALERT == 1 so operational errors no longer create bogus regression issues.
  • Step 7c (::warning::) now requires BENCHER_HAS_ALERT == 1.
  • New step 7d fails the workflow on main when BENCHER_EXIT_CODE != 0 and BENCHER_HAS_ALERT != 1 — preserving the hard gate for auth/API/network/CLI failures.

2. Drop hardcoded #3116, reference the label instead (@greptile-apps / @claude[bot])

The warning message now references the performance-regression label so it stays accurate as step 7b rotates issues.

3. Include the workflow run URL (@claude[bot])

The warning annotation now includes ${RUN_URL} for a direct clickable link to the run.


The automated walkthrough from @coderabbitai and the summary from @greptile-apps were noted — no separate action required; their only code-level finding (hardcoded #3116) is covered by item 2 above.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 18, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the current state of the benchmark.yml file
fd "benchmark.yml" --type f | head -5
cat .github/workflows/benchmark.yml

Length of output: 34743


@justin808 All three changes are verified in the file — the implementation looks solid:

  1. BENCHER_HAS_ALERT flag — correctly derived from stderr grep (alert|threshold violation|boundary violation) only when exit code is non-zero. The 404-override block resets BENCHER_EXIT_CODE=0 before the BENCHER_HAS_ALERT evaluation, so a missing-baseline scenario won't incorrectly set the alert flag. Steps 7b/7c gate on HAS_ALERT == '1', and step 7d inverts that (!= '1') to catch auth/API/network/CLI failures — clean separation.

  2. Label reference instead of #3116 — the warning annotation now reads "label: performance-regression" which stays accurate as issues rotate. ✅

  3. RUN_URL in warning — injected via the step's env: block and included in the ::warning:: annotation for a direct clickable link. ✅

The overall logic is sound: noise-driven regression alerts produce a warning + auto-issue, operational failures still hard-fail, and the temp-file cleanup is handled both by the trap and explicit rm -f. Nothing blocking from my side.


🧠 Learnings used
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 0
File: :0-0
Timestamp: 2026-02-22T17:08:48.268Z
Learning: In script/ci-changes-detector, the flags `run_pro_node_renderer_tests` and `run_pro_dummy_tests` written to GITHUB_OUTPUT are informational only (for local JSON mode and future use). The actual CI job gating uses Option A routing: PRO_NODE_RENDERER_CHANGED triggers RUN_PRO_LINT and RUN_PRO_TESTS, which are already declared as workflow outputs. No workflow YAML changes are needed.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: e39e00ba6e

ℹ️ 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 .github/workflows/benchmark.yml Outdated
Narrows BENCHER_HAS_ALERT from case-insensitive "alert" to word-bounded
case-sensitive "Alert" / "Alerts" so that lowercase "alert" appearing in
bencher URL paths (e.g., "/v0/.../alerts") or CLI text cannot misclassify
an operational failure as a regression and let main go green.

"threshold violation" and "boundary violation" remain case-insensitive
since those specific phrases are unlikely to appear outside real alert
output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@justin808
Copy link
Copy Markdown
Member Author

Follow-up review addressed (commit 12fa8f2ab)

One new P1 from @chatgpt-codex-connector on the prior commit (e39e00ba6) — that BENCHER_HAS_ALERT was derived from a case-insensitive substring match on "alert", which could match lowercase "alert" in Bencher URL paths (e.g., /v0/.../alerts) or CLI text and misclassify an operational failure as a regression.

I (Claude Code) tightened step 7a's alert detection:

  • "alert"\bAlerts?\b (word-bounded, case-sensitive) — matches Bencher's actual alert output (🚨 N Alerts, Alert detected) but not lowercase substrings in URLs/CLI noise.
  • "threshold violation" / "boundary violation" remain case-insensitive — those specific phrases are unlikely to appear outside real alert output.

Net effect: an operational failure whose stderr contains only a lowercase alert substring (no word-bounded Alert[s], no threshold/boundary violation phrase) now falls through to step 7d and hard-fails the workflow on main, preserving the operational gate.

The 404-override safety check on step 7a remains on the looser pattern intentionally — its safety orientation is opposite (err on the side of NOT overriding), so a broader match there stays conservative.

All review threads now resolved.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

Comment on lines +660 to +664
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pattern inconsistency with the 404 check creates a misclassification gap.

The 404 guard above (line 645) uses case-insensitive alert to detect alerts:

! grep -qiE "alert|threshold violation|boundary violation" "$BENCHER_STDERR"

But this block uses case-sensitive \bAlerts?\b. If Bencher ever emits lowercase "alert detected" or "1 alert" (e.g. after a CLI version bump), the sequence would be:

  1. 404 guard: no 404 Not Found → skip → BENCHER_EXIT_CODE stays non-zero ✓
  2. This block: \bAlerts?\b does not match lowercase → BENCHER_HAS_ALERT stays 0
  3. Step 7d fires and fails the workflow with "operational failure" — a misclassified regression.

The case-sensitivity was chosen to avoid matching /v0/.../alerts URL paths, but the same goal is achievable with a word boundary and case-insensitive flag:

Suggested change
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1

Word boundaries (\b) already prevent matching alerts inside URL path segments like /v0/orgs/foo/alerts, so the case-insensitive flag adds robustness without reintroducing the false-positive risk.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 18, 2026

Code Review

Overview

This PR converts the benchmark gate on main from a hard fail to a ::warning:: annotation when Bencher detects regression alerts, while preserving hard failures for operational errors (auth/API/network/CLI). The motivation is well-documented: single-run t-test alerts on GitHub-hosted runners are dominated by environmental noise (adjacent runs show ~0 Jaccard similarity in their alert sets), so blocking main has been producing false-positive churn.

The design — distinguish "regression alert" from "operational failure" by parsing Bencher's stderr, then route each to a different downstream step — is sound. The concerns below are about correctness of the parsing logic and long-term brittleness.


Issues

1. Pattern inconsistency between the 404 guard and BENCHER_HAS_ALERT detection (see inline comment)

The 404 guard uses case-insensitive alert; the new BENCHER_HAS_ALERT block uses case-sensitive \bAlerts?\b. If Bencher emits lowercase "alert detected" or "1 alert" — after a CLI version bump, for example — the alert would slip past BENCHER_HAS_ALERT=0, and step 7d would misclassify it as an operational failure and fail the workflow with a misleading message. A word-bounded case-insensitive match (\bAlerts?\b with -i) achieves the same false-positive protection against URL paths.

2. Fragile dependency on Bencher's undocumented output format

BENCHER_HAS_ALERT is computed by grepping for "🚨 2 Alerts" / "Alert detected" / "threshold violation" / "boundary violation" in stderr. None of these strings appear to be part of a stable, versioned API contract. A Bencher CLI upgrade could change wording silently and flip the entire classification scheme. Mitigations worth considering:

  • Pin the Bencher CLI version in the workflow and document the exact strings it emits at that version (a comment with bencher --version output would suffice).
  • Or use Bencher's --exit-code / structured JSON output if it exposes one, rather than parsing human-readable text.

3. exit 1 in step 7d loses the original exit code

The removed step used exit "${BENCHER_EXIT_CODE:-1}" to propagate the exact exit code from the Bencher CLI. Step 7d now always exits 1. This is a minor loss: the original code allowed distinguishing different Bencher error codes in CI logs. Not a blocker, but worth noting.

4. Double rm -f on $BENCHER_STDERR

trap 'rm -f "$BENCHER_STDERR"' EXIT is registered at line 589, and rm -f "$BENCHER_STDERR" is called explicitly at line 666. The double deletion is harmless (the -f flag suppresses the second error), but the explicit rm inside the script is now redundant since the trap covers cleanup. Either is fine to keep; just a minor tidying opportunity.


Positive aspects

  • The PR description's statistical analysis (Jaccard similarity ~0.01–0.08 across consecutive runs) is an unusually rigorous justification for a workflow change.
  • Splitting the single "fail or don't" step into three distinct steps (7b issue, 7c warn, 7d operational-fail) improves readability and makes the logic explicit.
  • Retaining the regression-issue creation in step 7b means regressions remain visible even without a hard gate.
  • The follow-up issue (Benchmark CI: tune thresholds / reduce flakiness so the main gate can be re-enabled #3169) for proper threshold tuning is the right long-term path.

Summary

Pragmatic fix for a genuinely broken gate. Main concern is the robustness of the stderr-parsing logic — specifically the case-sensitivity inconsistency (inline comment) and the undocumented dependency on Bencher's output format. Recommend addressing the case-sensitivity fix before merge; the output-format concern is lower priority but worth a comment or version pin.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/benchmark.yml (1)

645-665: ⚠️ Potential issue | 🟡 Minor

Minor: alert-pattern asymmetry between 404 override and new alert detection.

The 404 override at line 645 uses case-insensitive alert|threshold violation|boundary violation to decide whether to swallow a non-zero exit, while the new detection at lines 660-665 uses case-sensitive \bAlerts?\b (plus case-insensitive threshold violation|boundary violation). When stderr contains 404 Not Found together with a lowercase alert token that is not a real alert heading (e.g., a URL path like /v0/.../alerts in an error trace), the two branches behave asymmetrically:

  • Line 645 sees "alert" (case-insensitive) → override is not applied → BENCHER_EXIT_CODE stays non-zero.
  • Line 662 case-sensitive \bAlerts?\b does not match lowercase → BENCHER_HAS_ALERT stays 0.
  • Step 7d then hard-fails main for what is actually a 404.

This is fail-closed (safe), but the two predicates should ideally use the same alert signal. Consider aligning the 404 override to the same tightened pattern introduced for BENCHER_HAS_ALERT so a spurious lowercase alert token doesn't block the docs-only-baseline escape hatch.

Proposed alignment
-          if [ $BENCHER_EXIT_CODE -ne 0 ] && grep -q "404 Not Found" "$BENCHER_STDERR" && ! grep -qiE "alert|threshold violation|boundary violation" "$BENCHER_STDERR"; then
+          if [ $BENCHER_EXIT_CODE -ne 0 ] && grep -q "404 Not Found" "$BENCHER_STDERR" \
+             && ! grep -qE "\bAlerts?\b" "$BENCHER_STDERR" \
+             && ! grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; then
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/benchmark.yml around lines 645 - 665, The 404-override
conditional should match alerts the same way as BENCHER_HAS_ALERT does; change
the grep in the 404 override that currently uses case-insensitive
"alert|threshold violation|boundary violation" to the same tightened check used
later: use grep -qE "\bAlerts?\b" "$BENCHER_STDERR" || grep -qiE "threshold
violation|boundary violation" "$BENCHER_STDERR" so that the 404 override and
BENCHER_HAS_ALERT (and the symbols BENCHER_EXIT_CODE, BENCHER_STDERR,
BENCHER_HAS_ALERT and the regex \bAlerts?\b) use consistent alert detection.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.github/workflows/benchmark.yml:
- Around line 645-665: The 404-override conditional should match alerts the same
way as BENCHER_HAS_ALERT does; change the grep in the 404 override that
currently uses case-insensitive "alert|threshold violation|boundary violation"
to the same tightened check used later: use grep -qE "\bAlerts?\b"
"$BENCHER_STDERR" || grep -qiE "threshold violation|boundary violation"
"$BENCHER_STDERR" so that the 404 override and BENCHER_HAS_ALERT (and the
symbols BENCHER_EXIT_CODE, BENCHER_STDERR, BENCHER_HAS_ALERT and the regex
\bAlerts?\b) use consistent alert detection.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b061cbb5-8038-4066-80c4-367b8f811fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 9cac6cf and 12fa8f2.

📒 Files selected for processing (1)
  • .github/workflows/benchmark.yml

Addresses follow-up review feedback on the Bencher main-regression gate:

- Pin bencherdev/bencher to v0.6.2 and document the expected stderr
  phrases ("Alert[s]", "threshold violation", "boundary violation") so a
  silent CLI upgrade can't flip the alert classification.
- Switch the BENCHER_HAS_ALERT grep from case-sensitive `\bAlerts?\b` to
  case-insensitive `\bAlerts?\b` to stay consistent with the 404 guard
  and avoid misclassifying a lowercase `alert` variant as operational.
  Word boundaries still prevent matches against URL paths like
  `/v0/.../alerts`, so there's no new false-positive risk.
- Propagate the original Bencher exit code from step 7d (`exit
  "${BENCHER_EXIT_CODE:-1}"` instead of bare `exit 1`) to preserve
  diagnostic context in CI logs.
- Drop the redundant `rm -f "$BENCHER_STDERR"` now that the
  `trap 'rm -f' EXIT` registered above handles cleanup.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 6f2bb80154

ℹ️ 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 on lines +668 to +669
{ grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid classifying '/alerts' paths as regressions

The new BENCHER_HAS_ALERT gate can still misclassify operational Bencher failures as regressions, because grep -qiE "\bAlerts?\b" matches lowercase URL segments like /v0/.../alerts (word boundaries exist at / and end-of-token). When that happens on main, step 7d is skipped and the workflow only emits a warning instead of failing for auth/API/network errors. Fresh evidence in this commit is the added case-insensitive \bAlerts?\b matcher here, which reintroduces the false-positive path-match behavior.

Useful? React with 👍 / 👎.

# are not a documented API contract, so upgrading the CLI requires
# re-verifying that the expected phrases still appear in alert output.
# Expected stderr phrases at v0.6.2: "🚨 N Alerts", "Alert detected".
uses: bencherdev/bencher@v0.6.2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The pin to a mutable tag (@v0.6.2) is a meaningful improvement over @main, but a tag can still be force-pushed by the upstream maintainer, silently swapping the binary that runs in your workflow.

For a stronger supply-chain guarantee, pin to the immutable commit SHA:

Suggested change
uses: bencherdev/bencher@v0.6.2
uses: bencherdev/bencher@v0.6.2 # TODO: pin to SHA once verified, e.g. bencherdev/bencher@<sha>

Run git ls-remote https://github.com/bencherdev/bencher refs/tags/v0.6.2 to get the SHA for the tag, then use bencherdev/bencher@<sha> (with # v0.6.2 as a comment for readability). This is a low-effort hardening for a step that runs with BENCHER_API_TOKEN.

Comment on lines +661 to +665
# Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
# a word-bounded, case-insensitive "Alert[s]". The word boundary (\b) already
# prevents matching lowercase "alerts" inside URL paths (e.g., "/v0/.../alerts"),
# so the case-insensitive flag adds robustness against future CLI wording changes
# (e.g., lowercase "1 alert") without reintroducing the URL-path false positive.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The comment's claim about \b is incorrect. \b is a word-boundary assertion between \w and \W. Since / is \W and a is \w, there is a word boundary at the start of alerts in /v0/.../alerts — so \bAlerts?\b would match alerts inside a URL path.

In practice this may not matter (Bencher probably doesn't emit raw URL paths like /v0/alerts in stderr), but the stated justification is wrong and could mislead future editors into over-trusting the heuristic.

Suggested correction:

Suggested change
# Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
# a word-bounded, case-insensitive "Alert[s]". The word boundary (\b) already
# prevents matching lowercase "alerts" inside URL paths (e.g., "/v0/.../alerts"),
# so the case-insensitive flag adds robustness against future CLI wording changes
# (e.g., lowercase "1 alert") without reintroducing the URL-path false positive.
# Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
# a word-bounded, case-insensitive "Alert[s]". Note: \b does NOT prevent matching
# "alerts" inside URL paths like "/v0/alerts" (/ is \W so a word boundary exists
# before "a"). False positives are unlikely in practice because Bencher does not
# emit raw API endpoint paths in its stderr alert output.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 19, 2026

Review

Overall: approve with minor notes. The motivation is solid — the Jaccard-similarity analysis in the PR description makes a compelling case that the hard gate was generating noise, not signal. The implementation is careful and well-commented.

What's good

  • @main@v0.6.2 pin is an important security and reproducibility improvement. The accompanying comment explaining why it's pinned (heuristic depends on specific CLI output text) is exactly the right thing to document.
  • Splitting regression alerts from operational failures (steps 7c vs 7d) is the right design. A broken Bencher token or API outage should still fail fast; noisy t-test alerts should not.
  • Removing the explicit rm -f in favour of the trap is correct cleanup — one mechanism is cleaner than two.
  • The step conditions (BENCHER_HAS_ALERT == '1' / != '1') are logically consistent across 7b, 7c, and 7d.

Issues

  1. Incorrect \b comment (inline): The comment claims word boundaries prevent matching alerts inside URL paths like /v0/.../alerts. That's wrong — / is \W so there is a word boundary before a, and \bAlerts?\b would match. The heuristic is probably fine in practice (Bencher doesn't emit raw API paths in stderr), but the stated reasoning is incorrect and could mislead future editors. See inline comment at line 661–665.

  2. Tag pin vs. SHA pin (inline): bencherdev/bencher@v0.6.2 is better than @main but a tag is still mutable upstream. Pinning to the commit SHA (with the tag name as a comment) would be a stronger supply-chain guarantee, especially since this step runs with BENCHER_API_TOKEN. See inline comment at line 165.

  3. Two slightly different alert-detection regexes: The 404-suppression guard (~line 650) uses grep -qiE "alert|threshold violation|boundary violation" (plain alert, no word boundary, no s?), while the BENCHER_HAS_ALERT block uses \bAlerts?\b. Both match the same Bencher output in practice, but maintaining two divergent patterns for the same concept adds future maintenance surface.

Minor

  • Step 7d emits ::error:: but the annotation alone doesn't fail the step — the exit call is what actually fails it. This is correct, just worth noting for anyone who later refactors the step.
  • If the job crashes before BENCHER_HAS_ALERT is written to $GITHUB_ENV, env.BENCHER_HAS_ALERT will be empty (!= '1' → true) and step 7d will fire if BENCHER_EXIT_CODE was also set. That's the desired fallback behavior, but it's implicit rather than documented.

None of these block the PR — the core change (warn instead of hard-fail on regression alerts) is correct and the implementation is sound.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/benchmark.yml:
- Around line 659-671: The pattern for detecting Bencher alerts is currently
using case-insensitive grep (grep -qiE "\bAlerts?\b") which matches lowercase
"/alerts" in URLs; change that grep to be case-sensitive (remove the -i flag) so
only "Alert" or "Alerts" word-bound matches trigger setting BENCHER_HAS_ALERT=1,
leaving the other grep for "threshold violation|boundary violation" unchanged;
update the combined condition that references BENCHER_EXIT_CODE and
BENCHER_STDERR accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e1665e80-7cb9-42ad-8abd-36d16e6a1eb1

📥 Commits

Reviewing files that changed from the base of the PR and between 12fa8f2 and 6f2bb80.

📒 Files selected for processing (1)
  • .github/workflows/benchmark.yml

Comment on lines +659 to +671
# Distinguish regression alerts from operational failures (auth/API/network/CLI)
# so that main can warn-only on the former while still failing hard on the latter.
# Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
# a word-bounded, case-insensitive "Alert[s]". The word boundary (\b) already
# prevents matching lowercase "alerts" inside URL paths (e.g., "/v0/.../alerts"),
# so the case-insensitive flag adds robustness against future CLI wording changes
# (e.g., lowercase "1 alert") without reintroducing the URL-path false positive.
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
fi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

printf '%s\n' 'GET https://api.bencher.dev/v0/projects/react-on-rails-t8a9ncxo/alerts failed: 500' > "$tmp"

echo "Current regex:"
if grep -qiE "\bAlerts?\b" "$tmp"; then
  echo "FAIL: case-insensitive regex matched lowercase /alerts URL path"
else
  echo "PASS: no URL-path match"
fi

echo "Case-sensitive regex:"
if grep -qE "\bAlerts?\b" "$tmp"; then
  echo "FAIL: case-sensitive regex still matched lowercase /alerts URL path"
else
  echo "PASS: lowercase /alerts URL path is not treated as an alert"
fi

printf '%s\n' '🚨 2 Alerts' 'Alert detected' > "$tmp"
grep -qE "\bAlerts?\b" "$tmp"
echo "PASS: pinned Bencher v0.6.2 alert phrases still match"

Repository: shakacode/react_on_rails

Length of output: 282


Make the Alerts? grep case-sensitive to prevent false positives from URL paths.

Line 668 uses -i flag, causing \bAlerts?\b to match lowercase /alerts in URL paths within error messages. This incorrectly classifies auth/API/network failures as performance regressions, skipping the hard-fail step 7d and downgrading to warn-only.

🐛 Proposed fix
-          # Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
-          # a word-bounded, case-insensitive "Alert[s]". The word boundary (\b) already
-          # prevents matching lowercase "alerts" inside URL paths (e.g., "/v0/.../alerts"),
-          # so the case-insensitive flag adds robustness against future CLI wording changes
-          # (e.g., lowercase "1 alert") without reintroducing the URL-path false positive.
+          # Match Bencher's pinned v0.6.2 alert output (e.g., "🚨 2 Alerts", "Alert detected")
+          # with a case-sensitive "Alert[s]" so lowercase URL paths such as "/v0/.../alerts"
+          # in operational errors are not classified as performance regressions.
           BENCHER_HAS_ALERT=0
           if [ $BENCHER_EXIT_CODE -ne 0 ] && \
-             { grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
+             { grep -qE "\bAlerts?\b" "$BENCHER_STDERR" || \
                grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
             BENCHER_HAS_ALERT=1
           fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Distinguish regression alerts from operational failures (auth/API/network/CLI)
# so that main can warn-only on the former while still failing hard on the latter.
# Match Bencher's actual alert output (e.g., "🚨 2 Alerts", "Alert detected") via
# a word-bounded, case-insensitive "Alert[s]". The word boundary (\b) already
# prevents matching lowercase "alerts" inside URL paths (e.g., "/v0/.../alerts"),
# so the case-insensitive flag adds robustness against future CLI wording changes
# (e.g., lowercase "1 alert") without reintroducing the URL-path false positive.
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
fi
# Match Bencher's pinned v0.6.2 alert output (e.g., "🚨 2 Alerts", "Alert detected")
# with a case-sensitive "Alert[s]" so lowercase URL paths such as "/v0/.../alerts"
# in operational errors are not classified as performance regressions.
BENCHER_HAS_ALERT=0
if [ $BENCHER_EXIT_CODE -ne 0 ] && \
{ grep -qE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/benchmark.yml around lines 659 - 671, The pattern for
detecting Bencher alerts is currently using case-insensitive grep (grep -qiE
"\bAlerts?\b") which matches lowercase "/alerts" in URLs; change that grep to be
case-sensitive (remove the -i flag) so only "Alert" or "Alerts" word-bound
matches trigger setting BENCHER_HAS_ALERT=1, leaving the other grep for
"threshold violation|boundary violation" unchanged; update the combined
condition that references BENCHER_EXIT_CODE and BENCHER_STDERR accordingly.

@justin808
Copy link
Copy Markdown
Member Author

Follow-up review addressed (commit 6f2bb8015)

I (Claude Code) addressed the remaining review feedback in a single commit.

1. Pattern inconsistency between the 404 guard and BENCHER_HAS_ALERT (@claude[bot] inline comment + review summary point 1)

Changed the first grep in the BENCHER_HAS_ALERT block from case-sensitive to case-insensitive so it stays consistent with the 404 guard above it:

-   { grep -qE  "\bAlerts?\b" "$BENCHER_STDERR" || \
+   { grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
      grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then

Word boundaries (\b) still prevent matching alerts inside URL paths like /v0/.../alerts, so adding -i does not reintroduce the original false-positive risk. If Bencher ever emits lowercase "alert detected" or "1 alert" (e.g. after a CLI version bump), the alert will now be correctly classified as a regression (warn) rather than an operational failure (hard fail). Updated the accompanying comment to reflect the new rationale.

2. Fragile dependency on Bencher's undocumented stderr wording (@claude[bot] review summary point 2)

Pinned the Bencher CLI from bencherdev/bencher@mainbencherdev/bencher@v0.6.2 and added an inline comment at the install step documenting the stderr phrases the alert-detection heuristic in step 7a depends on ("🚨 N Alerts", "Alert detected", "threshold violation", "boundary violation"). A CLI upgrade now requires an intentional version bump, at which point the maintainer can re-verify those strings are still emitted. I considered switching to Bencher's structured output instead, but that's a larger change and the pin + documentation is sufficient to close the brittleness concern in the near term.

3. exit 1 in step 7d loses the original Bencher exit code (@claude[bot] review summary point 3)

Restored the original behavior:

-   exit 1
+   # Preserve the original Bencher exit code in CI logs for diagnostic context.
+   exit "${BENCHER_EXIT_CODE:-1}"

This preserves whatever non-zero code the CLI produced so CI logs keep the diagnostic signal.

4. Double rm -f "$BENCHER_STDERR" (@claude[bot] review summary point 4)

Removed the explicit rm -f "$BENCHER_STDERR" at line 666; cleanup is already handled by the trap 'rm -f "$BENCHER_STDERR"' EXIT registered right after BENCHER_STDERR=$(mktemp). Left a short comment in place noting the trap is responsible for cleanup so a future reader doesn't re-add the explicit rm.


No-action bot posts (acknowledged, no code change needed)

All unresolved review threads should now be actionable to close.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but it could not run because on-demand usage is turned off. To enable Bugbot Autofix, turn on on-demand usage and set a spend limit in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6f2bb80. Configure here.

{ grep -qiE "\bAlerts?\b" "$BENCHER_STDERR" || \
grep -qiE "threshold violation|boundary violation" "$BENCHER_STDERR"; }; then
BENCHER_HAS_ALERT=1
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Word boundary doesn't prevent URL-path false positives

Medium Severity

The comment claims \b prevents matching "alerts" inside URL paths like /v0/.../alerts, but this is incorrect. \b matches at transitions between word and non-word characters — / is non-word and a is word, so \bAlerts?\b with -i does match "alerts" in URL paths. If Bencher's stderr during an operational failure includes a URL containing /alerts, BENCHER_HAS_ALERT is incorrectly set to 1, causing step 7d's hard-fail gate to be skipped and the error silently downgraded to a warning in step 7c.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6f2bb80. Configure here.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 19, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
cat .github/workflows/benchmark.yml

Length of output: 35877


@justin808 All four changes from commit 6f2bb8015 are confirmed in the file:

  1. -i flag on \bAlerts?\bgrep -qiE "\bAlerts?\b" is present. The updated comment correctly explains that \b still blocks URL-path false positives while -i adds robustness against future lowercase wording (e.g., "1 alert"). ✅

  2. Bencher CLI pinned to v0.6.2uses: bencherdev/bencher@v0.6.2 with an inline comment at the install step documenting the four expected stderr phrases ("🚨 N Alerts", "Alert detected", "threshold violation", "boundary violation"). ✅

  3. Original exit code preserved in step 7dexit "${BENCHER_EXIT_CODE:-1}" with a comment about diagnostic context; the hardcoded exit 1 is gone. ✅

  4. Double rm -f removed — no explicit rm -f "$BENCHER_STDERR" in the step body; the trap 'rm -f "$BENCHER_STDERR"' EXIT is the sole cleanup mechanism, with a short comment left to prevent it from being re-added. ✅

Everything looks solid — no blocking issues.


🧠 Learnings used
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-12T23:15:11.806Z
Learning: Wait for the first full review pass to finish before pushing follow-up commits; batch review fixes into one follow-up push when practical

Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-21T08:53:17.309Z
Learning: For small, focused PRs (roughly 5 files or fewer with one clear purpose): use at most one AI reviewer for inline comments, batch review fixes into one follow-up push, and verify language/runtime/library claims locally before making code changes in response to AI review

Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 0
File: :0-0
Timestamp: 2026-02-22T17:08:48.268Z
Learning: In script/ci-changes-detector, the flags `run_pro_node_renderer_tests` and `run_pro_dummy_tests` written to GITHUB_OUTPUT are informational only (for local JSON mode and future use). The actual CI job gating uses Option A routing: PRO_NODE_RENDERER_CHANGED triggers RUN_PRO_LINT and RUN_PRO_TESTS, which are already declared as workflow outputs. No workflow YAML changes are needed.

@justin808 justin808 merged commit c331ad8 into main Apr 20, 2026
48 checks passed
@justin808 justin808 deleted the jg/benchmark-warn-not-fail branch April 20, 2026 03:51
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.

Performance Regression Detected on main (6a399b0)

1 participant