Skip to content

ci(bench-canonical): in-place README badge rewrite from cron (#477) - #481

Merged
robotrocketscience merged 2 commits into
mainfrom
feat/issue-477-badge-cron-rewrite
May 8, 2026
Merged

ci(bench-canonical): in-place README badge rewrite from cron (#477)#481
robotrocketscience merged 2 commits into
mainfrom
feat/issue-477-badge-cron-rewrite

Conversation

@yoshi280

@yoshi280 yoshi280 commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Closes #477.

Wires the README reproducibility badge to update in-place from the nightly bench-canonical cron, replacing the manual 406ef03 placeholder with auto-rewrite from the cron's merged JSON.

What lands

  1. benchmarks/badge.py — pure function compute_badge_text(report_path, today=None) -> str. Iterates results[adapter][sub_key]._status == "ok" against headline_cut-derived total, returns a string of the form:

    reproducibility: ✅ 11/11 ok · last run 2026-05-08
    reproducibility: ⚠️ 6/11 ok · last run 2026-05-08
    

    Skipped invocations (per [v2.1] Bench dispatcher exit-code 3-state contract (ok / skipped / error) #479's planned 3-state contract) do not count as ok. Unit-tested at tests/test_benchmarks_badge.py.

  2. .github/workflows/bench-canonical.yml — two new steps before the existing Commit + push to bench-canonical-results:

    • Compute badge text runs python -m benchmarks.badge on the merged JSON. Gated on steps.bench.outputs.out != '' so an errored run doesn't rewrite the badge to a stale 0/N line; previous badge stays.
    • Sync README into bench-canonical-results worktree + rewrite badge copies main's README into the cron worktree on every run (so the cron branch never carries a stale README) and awk-rewrites the marker block.

    Same commit as the JSON — one cron commit per run.

Acceptance crosscheck (vs issue body)

  • README has <!-- bench-canonical-badge:start --> / <!-- bench-canonical-badge:end --> markers (already present from PR feat(bench): aelf bench all reproducibility harness (#437) #465).
  • Workflow computes pass count, total invocation count, and last-run UTC date.
  • Workflow rewrites README between markers (awk block-replace; ENVIRON-passed text avoids quoting hazards).
  • Commit lands on bench-canonical-results only; main does not auto-update.
  • when pass == total > 0; ⚠️ otherwise.

What's not in this PR

Test plan

  • uv run pytest tests/test_benchmarks_badge.py tests/test_bench_dispatcher.py tests/test_bench_tolerance.py tests/test_benchmarks_dir.py (54 passed locally).
  • python -m benchmarks.badge benchmarks/results/v2.0.0.json --today 2026-05-08reproducibility: ⚠️ 6/11 ok · last run 2026-05-08.
  • Local awk smoke against current README produced the expected rewrite (shields.io image replaced with plain text between markers).
  • First cron run after merge will exercise the workflow end-to-end. Rollback path: revert this PR; previous workflow has no badge step and leaves README alone.

Summary by Sourcery

Integrate automated generation and in-place update of the README reproducibility badge from nightly bench-canonical cron runs.

New Features:

  • Add a benchmarks.badge module that computes a one-line reproducibility badge from canonical benchmark JSON and exposes a CLI entry via python -m benchmarks.badge.

Enhancements:

  • Extend the bench-canonical GitHub Actions workflow to compute badge text from the merged benchmark report and rewrite the badge section in the bench-canonical-results README while keeping main untouched.

Tests:

  • Add unit tests for benchmarks.badge covering success, partial, skipped, zero-total, canonical baseline, and default-date scenarios.

Summary by CodeRabbit

Release Notes

  • New Features

    • Benchmark reproducibility badges now automatically generate and update in documentation, displaying successful vs. total runs and last execution date.
  • Tests

    • Added comprehensive test coverage for badge generation, validating correct rendering across pass/fail scenarios, partial failures, and edge cases.

…cal JSON (#477)

Pure helper that reads the merged bench-canonical JSON and produces the
one-line text the cron splices into the README marker block. Unit-tested
so the workflow stays free of count logic. Skipped invocations (per
#479) do not count as ok.
Adds two steps before the existing commit+push:
1. Compute badge text via `python -m benchmarks.badge` against the
   merged JSON (gated on bench succeeding so an errored run doesn't
   rewrite the badge to a stale 0/N line).
2. Sync the current main README into the bench-canonical-results
   worktree and awk-rewrite the marker block.

Same commit as the JSON entry; one cron commit per run. main is not
touched — operator cherry-picks if they want main current.
@sourcery-ai

sourcery-ai Bot commented May 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

Wires the nightly bench-canonical cron to compute a reproducibility summary line from the merged benchmark JSON via a new benchmarks.badge module, and rewrites the README badge block in the bench-canonical-results worktree in-place, with unit tests for the badge computation logic.

Sequence diagram for bench-canonical cron computing and rewriting README badge

sequenceDiagram
    actor Maintainer
    participant GitHubActions as GitHub_Actions_Cron
    participant BenchJob as Bench_Canonical_Job
    participant BadgeModule as Benchmarks_Badge_Module
    participant GitWorktree as Bench_Canonical_Results_Worktree
    participant RemoteRepo as Remote_Repository

    Maintainer->>GitHubActions: Schedule nightly bench_canonical workflow
    GitHubActions->>BenchJob: Run benchmarks and merge JSON
    BenchJob-->>GitHubActions: Set output out = merged_report_path or ''

    GitHubActions->>GitHubActions: Check steps.bench.outputs.out != ''
    alt Bench_run_succeeded
        GitHubActions->>BadgeModule: python -m benchmarks.badge merged_report_path
        BadgeModule->>BadgeModule: _count_invocations(headline_cut)
        BadgeModule->>BadgeModule: _count_ok(results)
        BadgeModule-->>GitHubActions: badge_text
        GitHubActions->>GitWorktree: Copy README.md into .bench-results-branch/README.md
        GitGitHubActions->>GitWorktree: awk replace text between bench_canonical_badge markers
        GitWorktree-->>GitHubActions: Updated README with new badge line
    else Bench_run_errored
        GitHubActions->>GitHubActions: Skip badge and README rewrite
    end

    GitHubActions->>GitWorktree: Commit JSON and updated README
    GitWorktree->>RemoteRepo: Push bench_canonical_results branch
    RemoteRepo-->>Maintainer: Updated README badge visible on bench_canonical_results
Loading

Class diagram for benchmarks.badge module structure

classDiagram
    class Benchmarks_Badge_Module {
        +int _count_invocations(headline_cut: Mapping~str, list~)
        +int _count_ok(results: Mapping~str, Mapping~str, Mapping~)
        +str compute_badge_text(report_path: Path, today: str)
        +int main(argv: list~str~)
    }
Loading

File-Level Changes

Change Details Files
Add a reusable badge text formatter for benchmark reports and test its counting logic.
  • Introduce benchmarks.badge module with helpers to count total invocations from headline_cut and successful runs from results[_status == 'ok'].
  • Implement compute_badge_text(report_path, today=None) that loads the merged JSON, computes ok/total, selects ✅ only when ok == total > 0 otherwise ⚠️, and formats the one-line badge string with the last-run date (UTC by default).
  • Provide a CLI entrypoint in benchmarks.badge (python -m benchmarks.badge) with optional --today override for tests and workflow usage.
benchmarks/badge.py
Add unit tests to validate badge text rendering against various benchmark result shapes.
  • Add helper to write synthetic report JSON fixtures with configurable headline_cut and results structures.
  • Test all-ok, partial-ok, skipped_data_missing treated as non-ok, multi-subkey counting, zero-total, canonical v2.0.0 partial run (6/11), and defaulting of today to a UTC YYYY-MM-DD string.
  • Assert both the numeric ok/total and the chosen icon (✅ vs ⚠️) and date suffix formatting.
tests/test_benchmarks_badge.py
Extend bench-canonical GitHub Actions workflow to compute badge text from merged results and rewrite the README badge block on the bench-canonical-results branch.
  • Add a Compute badge text step that runs uv run python -m benchmarks.badge on the merged JSON, gated on steps.bench.outputs.out != '' so errored runs do not overwrite the existing badge, and expose the result via GITHUB_OUTPUT.
  • Add a Sync README into bench-canonical-results worktree + rewrite badge step that copies README.md from main into .bench-results-branch/README.md on each run and uses awk to replace the content between bench-canonical-badge:start/end markers with the computed badge text passed via ENVIRON.
  • Ensure the badge rewrite only happens when badge text was successfully computed, and that the final commit containing both the JSON and README changes still occurs only on the bench-canonical-results branch.
.github/workflows/bench-canonical.yml

Assessment against linked issues

Issue Objective Addressed Explanation
#477 Cron workflow computes reproducibility badge text (pass count, total invocation count, last-run UTC date, and appropriate icon) from the merged canonical JSON report.
#477 Cron workflow rewrites the README badge text between the <!-- bench-canonical-badge:start --> and <!-- bench-canonical-badge:end --> markers in the bench-canonical-results branch only, and commits this change together with the JSON results (without auto-updating main).
#477 README contains <!-- bench-canonical-badge:start --> and <!-- bench-canonical-badge:end --> markers around the badge text for the cron job to target.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@yoshi280 yoshi280 added author-Gylf PR coordination mutex attn:review Needs review (PR open, awaiting reviewer) labels May 8, 2026
@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements automated reproducibility badge updates in the README from nightly benchmark canonical results. It introduces a badge computation module, workflow steps to sync and rewrite the badge block in README, and comprehensive tests for the badge logic.

Changes

Badge Cron Update

Layer / File(s) Summary
Core Badge Logic
benchmarks/badge.py
Module loads canonical JSON, counts total headline invocations and ok statuses, selects ✅ or ⚠️ icon based on pass/fail ratio, formats reproducibility: <icon> <ok>/<total> ok · last run <YYYY-MM-DD>.
CLI & Module Exports
benchmarks/badge.py
Adds compute_badge_text(report_path, *, today=None) public function and main(argv) CLI entrypoint using argparse; outputs badge text to stdout.
Workflow Integration
.github/workflows/bench-canonical.yml
Adds "Compute badge text" step to derive badge via benchmarks.badge, then "Sync README" step to rewrite README badge block between <!-- bench-canonical-badge:start/end --> markers using awk; commits to bench-canonical-results branch.
Tests
tests/test_benchmarks_badge.py
Test helper writes synthetic JSON reports; validates all-ok (check icon), partial failures (warning icon), correct total counting with subkeys, non-ok status handling, zero-total rendering, and UTC date formatting; includes optional validation against checked-in canonical report.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: automating the README reproducibility badge update from the cron workflow with in-place rewrites.
Description check ✅ Passed The PR description comprehensively covers all required sections: summary, linked issues, type of change (ci:), verification steps, detailed test plan, and notes for reviewers addressing tricky aspects.
Linked Issues check ✅ Passed All coding requirements from issue #477 are met: badge module computes pass/total/date, workflow gates on success, README markers are present, awk-rewrites between markers, commits to bench-canonical-results only, and uses ✅/⚠️ icons correctly.
Out of Scope Changes check ✅ Passed All changes directly support issue #477 requirements: benchmarks/badge.py computes badge text, workflow steps integrate badge generation, and tests validate the new functionality. No unrelated changes detected.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-477-badge-cron-rewrite

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.

if: steps.bench.outputs.out != ''
run: |
set -euo pipefail
text=$(uv run python -m benchmarks.badge "${{ steps.bench.outputs.out }}")
run: |
set -euo pipefail
cp README.md .bench-results-branch/README.md
new="${{ steps.badge.outputs.text }}" awk '

@sourcery-ai sourcery-ai 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.

Hey - I've found 1 issue, and left some high level feedback:

  • The badge calculation currently counts all results[adapter][sub_key] entries via _count_ok without consulting headline_cut, which can diverge from the intended "headline" subset if extra results are present; consider iterating only the (adapter, sub_key) pairs defined in headline_cut to keep the numerator/denominator semantics aligned with the issue description.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The badge calculation currently counts all `results[adapter][sub_key]` entries via `_count_ok` without consulting `headline_cut`, which can diverge from the intended "headline" subset if extra results are present; consider iterating only the (adapter, sub_key) pairs defined in `headline_cut` to keep the numerator/denominator semantics aligned with the issue description.

## Individual Comments

### Comment 1
<location path=".github/workflows/bench-canonical.yml" line_range="138-148" />
<code_context>
+        run: |
+          set -euo pipefail
+          cp README.md .bench-results-branch/README.md
+          new="${{ steps.badge.outputs.text }}" awk '
+            BEGIN { in_block=0 }
+            /<!-- bench-canonical-badge:start -->/ { print; print ENVIRON["new"]; in_block=1; next }
+            /<!-- bench-canonical-badge:end -->/   { print; in_block=0; next }
+            in_block { next }
+            { print }
+          ' .bench-results-branch/README.md > .bench-results-branch/README.md.new
+          mv .bench-results-branch/README.md.new .bench-results-branch/README.md
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Guard against shell interpretation of special characters in the badge text when passing it through the `new` env var.

Using `new="${{ steps.badge.outputs.text }}" awk ...` assumes the badge text never includes shell‑significant characters (`$`, backticks, backslashes, quotes, etc.). A future change to the badge text could cause the shell to reinterpret it and break this step. To harden this, consider passing the value to `awk` without letting the shell re‑parse it—for example, write the text to a temp file that `awk` reads, or use a safely quoted `printf` and `env NEW_TEXT="..." awk ...` pattern.

```suggestion
        run: |
          set -euo pipefail
          cp README.md .bench-results-branch/README.md
          printf '%s\n' "${{ steps.badge.outputs.text }}" > .bench-results-branch/new_badge.txt
          awk -v badge_file=".bench-results-branch/new_badge.txt" '
            BEGIN { in_block=0 }
            /<!-- bench-canonical-badge:start -->/ {
              print
              while ((getline line < badge_file) > 0) {
                print line
              }
              close(badge_file)
              in_block=1
              next
            }
            /<!-- bench-canonical-badge:end -->/   { print; in_block=0; next }
            in_block { next }
            { print }
          ' .bench-results-branch/README.md > .bench-results-branch/README.md.new
          mv .bench-results-branch/README.md.new .bench-results-branch/README.md
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +138 to +148
run: |
set -euo pipefail
cp README.md .bench-results-branch/README.md
new="${{ steps.badge.outputs.text }}" awk '
BEGIN { in_block=0 }
/<!-- bench-canonical-badge:start -->/ { print; print ENVIRON["new"]; in_block=1; next }
/<!-- bench-canonical-badge:end -->/ { print; in_block=0; next }
in_block { next }
{ print }
' .bench-results-branch/README.md > .bench-results-branch/README.md.new
mv .bench-results-branch/README.md.new .bench-results-branch/README.md

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 suggestion (security): Guard against shell interpretation of special characters in the badge text when passing it through the new env var.

Using new="${{ steps.badge.outputs.text }}" awk ... assumes the badge text never includes shell‑significant characters ($, backticks, backslashes, quotes, etc.). A future change to the badge text could cause the shell to reinterpret it and break this step. To harden this, consider passing the value to awk without letting the shell re‑parse it—for example, write the text to a temp file that awk reads, or use a safely quoted printf and env NEW_TEXT="..." awk ... pattern.

Suggested change
run: |
set -euo pipefail
cp README.md .bench-results-branch/README.md
new="${{ steps.badge.outputs.text }}" awk '
BEGIN { in_block=0 }
/<!-- bench-canonical-badge:start -->/ { print; print ENVIRON["new"]; in_block=1; next }
/<!-- bench-canonical-badge:end -->/ { print; in_block=0; next }
in_block { next }
{ print }
' .bench-results-branch/README.md > .bench-results-branch/README.md.new
mv .bench-results-branch/README.md.new .bench-results-branch/README.md
run: |
set -euo pipefail
cp README.md .bench-results-branch/README.md
printf '%s\n' "${{ steps.badge.outputs.text }}" > .bench-results-branch/new_badge.txt
awk -v badge_file=".bench-results-branch/new_badge.txt" '
BEGIN { in_block=0 }
/<!-- bench-canonical-badge:start -->/ {
print
while ((getline line < badge_file) > 0) {
print line
}
close(badge_file)
in_block=1
next
}
/<!-- bench-canonical-badge:end -->/ { print; in_block=0; next }
in_block { next }
{ print }
' .bench-results-branch/README.md > .bench-results-branch/README.md.new
mv .bench-results-branch/README.md.new .bench-results-branch/README.md

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/bench-canonical.yml:
- Around line 138-148: The AWK rewrite silently drops content if the end marker
is missing; before replacing .bench-results-branch/README.md, add a guard that
counts occurrences of the start and end markers (e.g., using grep -c on "<!--
bench-canonical-badge:start -->" and "<!-- bench-canonical-badge:end -->") and
exit non‑zero if the counts are not exactly as expected (e.g., one start and one
end or matching counts), aborting the job with a clear error; implement this
check in the same run block immediately before the AWK transform so the script
fails fast instead of producing a truncated README.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ee07a74d-1de3-47d9-bff3-63b73bd3c7a2

📥 Commits

Reviewing files that changed from the base of the PR and between 50b9876 and 1f850c4.

📒 Files selected for processing (3)
  • .github/workflows/bench-canonical.yml
  • benchmarks/badge.py
  • tests/test_benchmarks_badge.py

Comment on lines +138 to +148
run: |
set -euo pipefail
cp README.md .bench-results-branch/README.md
new="${{ steps.badge.outputs.text }}" awk '
BEGIN { in_block=0 }
/<!-- bench-canonical-badge:start -->/ { print; print ENVIRON["new"]; in_block=1; next }
/<!-- bench-canonical-badge:end -->/ { print; in_block=0; next }
in_block { next }
{ print }
' .bench-results-branch/README.md > .bench-results-branch/README.md.new
mv .bench-results-branch/README.md.new .bench-results-branch/README.md

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when badge markers are missing/unbalanced.

Line 143–Line 146 can silently truncate the README tail if the end marker is absent. Add an explicit marker-count guard before rewrite.

Suggested hardening
       - name: Sync README into bench-canonical-results worktree + rewrite badge
         if: steps.badge.outputs.text != ''
         run: |
           set -euo pipefail
           cp README.md .bench-results-branch/README.md
+          start_count=$(grep -c '<!-- bench-canonical-badge:start -->' .bench-results-branch/README.md || true)
+          end_count=$(grep -c '<!-- bench-canonical-badge:end -->' .bench-results-branch/README.md || true)
+          if [ "$start_count" -ne 1 ] || [ "$end_count" -ne 1 ]; then
+            echo "::error::README badge markers must exist exactly once (start=$start_count end=$end_count)"
+            exit 1
+          fi
           new="${{ steps.badge.outputs.text }}" awk '
             BEGIN { in_block=0 }
             /<!-- bench-canonical-badge:start -->/ { print; print ENVIRON["new"]; in_block=1; next }
             /<!-- bench-canonical-badge:end -->/   { print; in_block=0; next }
             in_block { next }
             { print }
           ' .bench-results-branch/README.md > .bench-results-branch/README.md.new
           mv .bench-results-branch/README.md.new .bench-results-branch/README.md
🧰 Tools
🪛 GitHub Check: zizmor

[notice] 141-141:
code injection via template expansion

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/bench-canonical.yml around lines 138 - 148, The AWK
rewrite silently drops content if the end marker is missing; before replacing
.bench-results-branch/README.md, add a guard that counts occurrences of the
start and end markers (e.g., using grep -c on "<!-- bench-canonical-badge:start
-->" and "<!-- bench-canonical-badge:end -->") and exit non‑zero if the counts
are not exactly as expected (e.g., one start and one end or matching counts),
aborting the job with a clear error; implement this check in the same run block
immediately before the AWK transform so the script fails fast instead of
producing a truncated README.

@yoshi280

yoshi280 commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

[claim:review:Toug:2026-05-08T07:49:51Z]

@robotrocketscience
robotrocketscience merged commit 1f850c4 into main May 8, 2026
24 of 31 checks passed
@robotrocketscience
robotrocketscience deleted the feat/issue-477-badge-cron-rewrite branch May 8, 2026 07:52
@yoshi280

yoshi280 commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

[release:review:Toug:2026-05-08T07:52:30Z]

@yoshi280

yoshi280 commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

[claim:review:Kulili:2026-05-08T07:52:35Z]

@yoshi280

yoshi280 commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

[release:review:Kulili:2026-05-08T07:53:54Z]

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

Labels

attn:review Needs review (PR open, awaiting reviewer) author-Gylf PR coordination mutex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2.1] README reproducibility-badge cron-rewrite path

3 participants