GeezerVison is showing github.com — Release train PR 1: release.py core (offline stamp, rc versions, CHANGELOG sync/fold, blocker gate) by mikolalysenko · Pull Request #643 · SocketDev/socket-patch
Conversation
Review complete on f43c3e36; ready to merge as-is from this review. 339 successful checks, 6 skipped, and all six workflows successful. Bugbot is clear on this commit; no unresolved review threads or new actionable findings. Four release-lint assertions now handle both terminal stderr and GitHub Actions stdout annotations. The complete Python suite passes with Actions settings: 214 passed and one platform-specific skip. Independent source review and 48 additional changelog scenarios are clear.
Release train PR 1: release.py core, offline stamp, rc-aware release-lint
Summary
This is the first of the four PRs in docs/release-train/DESIGN.md §7. It adds the tested core that the weekly release train is built on. No workflow publishes anything new yet.
scripts/release.py (stdlib Python, one file). Subcommands:
semver: the X.Y.Z / X.Y.Z-rc.N grammar and precedence.
stamp: an offline, byte-deterministic version stamp of Cargo.toml, Cargo.lock, the 15 npm manifests and the npm wrapper lock.
npm-lock-check
next-version: derived from git tags and burned release/* branches, never from main's own version.
changelog cut|promote|sync-main|check
sync-main
notes
blockers: the §3.5 release-blocker gate.
scripts/version-sync.sh is now a thin wrapper over release.py stamp. The networked npm install --package-lock-only is gone, which ends the fix(maven): send the official Maven CLI user agent to the maven2 registry; refresh npm wrapper lock for published 4.0.0 platform packages #233/test(e2e): demote the cargo production legs to canary status — free cargo tier is unpublished #235 lock-drift class.
scripts/release-lint.sh:
- accepts
X.Y.Z-rc.N;
- check 2 is now the offline
stamp --check plus npm-lock-check;
- check 3 is rc-aware;
- new
--stable-only and --tag-exists flags.
ci.yml release-readiness: a same-repo release-sync PR into main runs release-lint.sh --tag-exists. Every other PR behaves as before.
- Deleted:
version-bump.yml and scripts/bump-version.sh. Every reference is fixed (release.yml comments, docs/releasing.md, the CHANGELOG header, the ci.yml shellcheck list).
- Tests:
scripts/tests/test_release.py plus fixtures, which include a recorded #454/#456 PR-merge close. CI's existing unittest discover already runs them.
Design decisions (maintainer decisions D1–D4 applied)
- D2: version and CHANGELOG reach main on every rc.
sync-main brings main to the newest cut tag, rc or stable. It inserts each pending rc's ## [X.Y.Z-rc.N] section from the tag and removes exactly those blocks from [Unreleased].
- At promotion,
changelog promote --rc K folds rc.1..rc.K into one ## [X.Y.Z] section. When that stable is synced, every rc section of the core is dropped, and its blocks that did not ship go back to [Unreleased], oldest rc first and in their original chronological place. That covers an abandoned rc.K+1 and a train rc cut beside a hotfix.
- Blocks are matched exactly and counted as a multiset everywhere:
- the fold keeps every occurrence;
- removal takes one occurrence per shipped block;
- rc sections on main are charged against the stable's blocks before
[Unreleased] is touched.
- So
next-version and changelog cut give byte-identical results whether or not the release-sync PR merged.
- Version selection reads only tags and
release/* branches. An unmerged sync PR never changes what gets cut.
release-lint accepts main at an rc.
- D4:
APPROVED_MAJORS = (5,), so the first train cut is 5.0.0-rc.1. A breaking heading that would open an unapproved major is refused, and a major is never skipped.
- D3: blocker gate.
mikolalysenko is a routine actor, so he is never trusted to clear a blocker.
- Config lists are parsed strictly, and an empty or degenerate config fails closed.
- A PR-merge auto-close (
commit_id: null) resolves only through a PR merged by the close actor whose merge commit is in the base.
since comes from merge-base(L, base) (never a tag's date) and is never later than base − 35 days, so a forged tag cannot shrink the window further.
- A missing or renamed label, a vanished label, and a deleted or transferred issue all block. Any API error blocks.
- D1 (App + tag ruleset) is implemented in PR 3. Until the ruleset (S9) is live, the 35-day lookback bounds what a forged tag can hide. S9 is a hard prerequisite for any live gate run.
- CRLF: a Windows
core.autocrlf checkout works. CHANGELOG transforms keep CRLF, and every stamped file keeps its own line endings, so stamp --check is a byte no-op there.
- No half-synced trees:
sync-main computes the CHANGELOG and every stamped file before it writes any of them.
Acceptance results (DESIGN.md §7 PR 1, run end to end on this branch)
End-to-end script on the worktree (the tree was restored afterwards and git status is clean):
PASS version-sync.sh 4.0.0 -> no diff (Synced version to 4.0.0)
PASS release-lint.sh passes on main at 4.0.0
PASS stamp 5.0.0-rc.1 x2 offline: identical bytes (18 files changed, digest 4c0128e8f32d3674)
PASS stamp --check 5.0.0-rc.1 is a no-op after the stamp
PASS stamp diff is inside the release allowlist
PASS release-lint.sh passes at 5.0.0-rc.1: release-lint: all checks passed for 5.0.0-rc.1
PASS release-lint --stable-only refuses 5.0.0-rc.1
PASS cargo build --locked -j4 -p socket-patch-cli on the stamped tree (socket-patch 5.0.0-rc.1)
PASS npm install --no-save --ignore-scripts in npm/socket-patch (added 4 packages in 4s)
PASS npm install --no-save left the stamped files as stamped
PASS 5.0.0-rc.1 < 5.0.0
PASS next-version on this branch's CHANGELOG + real tags = 5.0.0-rc.1
PASS sync-main --check: main is in sync with the real tags (no train tags yet)
PASS tree restored, git status clean
Unit tests (python3 -B -m unittest discover -s scripts/tests -v, as CI runs them): Ran 215 tests in 766.415s — OK (skipped=1); 82 of them are in test_release.py, all passing.
Accept-list items covered by scripts/tests/test_release.py:
- Versions and the main CHANGELOG snapshot:
- version selection on the main CHANGELOG snapshot gives
5.0.0-rc.1 (test_first_train_on_the_main_snapshot_is_5_0_0_rc_1);
- rc.2 while rc.1 is pending, with the sync PR merged or not;
- after v5.0.0 with the sync PR unmerged,
5.0.1-rc.1 or 5.1.0-rc.1;
- burned branches are skipped;
- an unapproved major is refused, and a major is never skipped.
- Blocker fixtures:
- a missing or renamed label, and case variants of the label;
- a label that vanished without an
unlabeled event, and a deleted, converted or transferred issue;
- an empty, unset or malformed actor config, and the newline-, space- and
@-separated forms;
since comes from the merge-base, a forged high tag cannot move it past the lookback, and a since after the base fails closed;
- a PR-merge close resolves through the merge commit only, and a manual close after an unrelated mentioning PR does not;
- an open issue untouched for 200 days blocks;
- closed by a commit that is not in the base blocks, and closed by an ancestor commit passes;
- closed by a trusted human after t blocks;
- unlabelled or closed by a routine actor (mik included) blocks;
- a trusted unlabel passes;
- an API error blocks.
- D2 scenarios:
- an rc syncs to main, and
release-lint passes on that rc;
- a stable fold with an abandoned later rc gives the same end state whether or not the sync PR merged;
sync-main is idempotent;
- byte-identical cuts with the sync PR merged or unmerged, including:
- a repeated identical entry (also repeated across folded rcs, and re-added after a promotion);
- abandoned later rcs;
- subsection order left over from shipped history;
- a hotfix promoted beside a train rc of the same core;
- CRLF CHANGELOG transforms and a CRLF stamp;
sync-main writes nothing when the stamp refuses;
release-lint (no flags and --tag-exists) on a sync-mained rc tree;
- hermetic stamp tests (baselines 4.0.0 and an rc);
- npm dependency drift caught offline.
What PRs 2–4 do next
- PR 2,
release-qa.yml + smoke:
- one
workflow_dispatch run at release/v<V> builds the 14 archives and 15 npm tarballs once, smokes those bytes, and calls ci.yml plus the 9 compat workflows through workflow_call;
- adds
release_smoke.py (Tier 0/1), the verify-qa verdict, and the Tier 0 step in the ci.yml e2e-build leg;
- must pass probes P1 and P2 first.
- PR 3,
release.yml rc path:
plan (blocker gate, green-SHA window, version), then cut (a signed createCommitOnBranch stamp commit with a tree assertion), then QA with reruns and a fallback, then publish in env publish (the App mints the tag, then crates → npm next → GitHub prerelease), then verify-channels and report;
- adds the Latest-release audit;
- deletes
publish-*.yml and dispatch-publish.sh;
- needs P3, S8 and S9 before merge, and S3 and S4 at merge.
- PR 4, stable + hotfix + docs:
- the
approve environment gate;
- stable
plan/cut (rc commit + stamp + changelog promote), re-finding the rc's full-QA run;
- hotfix mode with
waive_soak;
- cancelling parked runs;
docs/releasing.md runbook, ROUTINE.md and the CHANGELOG header.
- After that, the daily
release-train routine maintains the rolling release-sync PR.
Phase 0 manual checklist (DESIGN.md §6)
Setup
- S1 Routine identity:
mikolalysenko for now (D3). Set RELEASE_ROUTINE_ACTORS to every account any Claude routine runs as (today mikolalysenko). Add the bot when it exists, and remove mik only once no routine runs as him.
- S2 Team
socket-patch-release-approvers with at least 2 humans, none of them in RELEASE_ROUTINE_ACTORS. Mirror it in RELEASE_APPROVERS.
- S3 Environments:
release: reviewers = the team, branch main, admin bypass off, self-review prevention off;
publish: no reviewers, branch main, admin bypass off;
- delete
pypi and rubygems.
- S4 Trusted publishers: 15 npm packages and 2 crates →
SocketDev/socket-patch / release.yml / env publish. Do this when PR 3 merges; it is an atomic cutover for npm. Confirm the org policy allows direct OIDC publish.
- S5 Repository setup:
- enable immutable releases;
- create the labels
release-blocker (exact name; the gate fails closed with label: until it exists), release, release:train and release:sync;
- add the secrets
NTFY_TOPIC and SLACK_WEBHOOK_URL (optional);
- pin the "Release train" issue.
- S6 Human triage of
release-blocker on remove <purl> garbage-collects the beforeHash blobs of every other patch still in the manifest, so a later offline rollback of those patches fails missing_blob #559, scan/get --json drop the agent-mode apply failure: exit 1 with failed: 0, the patch shown as "added", and no error anywhere (e.g. a read-only global ~/.m2) #424, npm VEX attests not_affected while a bundled (inBundle) copy of the same package@version stays unpatched #325/npm agent-mode apply never patches an npm-aliased install (lp@npm:left-pad), yet VEX attests the package not_affected #356/In a yarn classic Plug'n'Play project, vex attests a hosted patch as not_affected while the copy .pnp.js loads is still unpatched #519/npm vendored vex and vendor --check pass while a second registry copy of the patched package@version in the same package-lock.json stays unwired and installs unpatched #588 and Perf regression: bun/hosted wall +110% (1169ae68, #472) #578/Perf regression: vlt/hosted wall +127% (1169ae68, #472) #579.
- S7 Run
e2e_npm, e2e_pypi, e2e_gem and e2e_scan --ignored by hand on main. Drop any suite that is chronically red because of the public proxy from live-e2e, and document why.
- S8 Create the GitHub App
socket-patch-release (D1):
- permission
contents: write only, no webhooks;
- installed on
SocketDev/socket-patch only;
RELEASE_APP_ID and RELEASE_APP_PRIVATE_KEY stored as secrets of env publish.
- S9 Tag ruleset on
refs/tags/v*:
- creations, updates and deletions restricted;
- bypass list = the App only.
- It needs an enterprise/org admin. Schedule it before PR 3 merges. It is a hard prerequisite for any live blocker-gate run.
Must-run probes
- P1 On scratch
release/v0.0.0-rc.1, GITHUB_TOKEN can POST /git/refs and createCommitOnBranch, and the result is a verified commit that ruleset 14265462 accepts.
- P2
release-qa.yml runs ci + 9 compat as one run. Check that:
- the job count is accepted;
- no concurrency group stalls;
e2e-docker and hosted-e2e (force) execute;
- artifact names don't collide;
rerun-failed-jobs works.
- Also measure p95 wall time.
- P3 With immutable releases and the tag ruleset on:
- the App token can create a scratch
v0.0.0-rc.1 tag that GITHUB_TOKEN cannot;
- a draft created on that existing tag accepts uploads;
- publishing the draft keeps the tag at its SHA.
🤖 Generated with Claude Code
Note Medium Risk
Touches release versioning, lockfile stamping, and CI release gates; mistakes could block releases or allow version drift, though legacy stable releases stay gated with --stable-only and extensive tests are added.
Overview
Release train PR 1 lays the tested foundation for the weekly train in docs/release-train/DESIGN.md: a new stdlib scripts/release.py (semver including X.Y.Z-rc.N, offline stamp across Cargo/npm locks, CHANGELOG cut/promote/sync-main, next-version, release-blocker gate, and related helpers), with scripts/version-sync.sh delegating to stamp instead of running networked npm install --package-lock-only.
scripts/release-lint.sh and CI/release workflows are updated for rc versions, offline coherence (stamp --check + npm-lock-check), --stable-only on the legacy Release workflow, and a dedicated release-sync → main path using --tag-exists. The Version Bump workflow and bump-version.sh are removed; docs and the CHANGELOG header describe release.py and the train instead.
Unit tests and fixtures cover stamping, changelog sync/fold, version selection, and blocker scenarios.
Reviewed by Cursor Bugbot for commit f43c3e3. Configure here.
Generated by Claude Code
CI follow-up: one PDM 2.6.1 Ubuntu job initially stopped on an API HTTP 504 before patching. Its single targeted retry passed: 34 supported/expected-refusal cases and two documented unsupported PEP582 cases, with no failed checks. The fresh artifact digest and source revision were verified.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…ckers
PR 1 of the weekly release train (docs/release-train/DESIGN.md §7). One
stdlib-only Python file with argparse subcommands:
- stamp <V> [--check]: offline, byte-deterministic version stamp of
Cargo.toml (workspace version + =V core pin), Cargo.lock (source-less
workspace-member entries, so --locked builds), the 15 npm manifests and
npm/socket-patch/package-lock.json (JSON edit; platform entries for any
other version are dropped instead of re-resolved over the network, which
ends the #233/#235 lock-drift class).
- semver: X.Y.Z and X.Y.Z-rc.N only, semver precedence.
- next-version: from git tags + burned release/* branches + the
[Unreleased] headings of sync-main(C) computed in memory, never from
main's Cargo version. New majors need APPROVED_MAJORS (5 is
pre-approved) and are never skipped; otherwise refused with an error.
- changelog cut|promote|sync-main|check: rc sections reach main on every
rc; promotion folds rc.1..rc.K into one [X.Y.Z] section and returns
later abandoned rc blocks to [Unreleased]. Exact-match, deterministic,
idempotent; newer [Unreleased] entries are never touched.
- notes: release notes with a link to the open-P1 query, never titles.
- blockers --base <sha>: the §3.5 release-blocker rule over REST
(injectable transport); any API error blocks.
Tests: scripts/tests/test_release.py with temp git repos driven through
the train timeline and recorded REST shapes under
scripts/tests/fixtures/release/.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- scripts/version-sync.sh is now a thin wrapper over `release.py stamp`
(same CLI contract; also stamps Cargo.lock's workspace entries). On the
clean tree `version-sync.sh 4.0.0` is a byte no-op.
- scripts/release-lint.sh: the grammar accepts X.Y.Z and X.Y.Z-rc.N;
check 2 is `release.py stamp --check` (byte compare, offline, no
clean-tree requirement, writes nothing); check 3 is `release.py
changelog check` (rc sections; a stable fails while rc sections remain
unfolded); new --stable-only and --tag-exists.
- ci.yml release-readiness: the rolling `release-sync` PR (which moves
main to the newest cut tag, rc or stable) runs `release-lint.sh
--tag-exists`; every other PR keeps today's behavior.
- release.yml (legacy pipeline until the train replaces it): lint with
--stable-only so it can never publish an rc as Latest/npm latest.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
version-bump.yml's unsigned push is rejected by the main ruleset and it
never ran; the release train cuts versions with scripts/release.py
instead. The CHANGELOG header and docs/releasing.md now point at
docs/release-train/DESIGN.md (the full runbook rewrite is PR 4), the
interim manual bump uses `release.py changelog cut` + version-sync.sh,
and ci.yml stops shellchecking the deleted script.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
D1: GitHub App socket-patch-release + refs/tags/v* ruleset (App-only
bypass); the App mints the tag in the publish job (PR 3). D2: version and
CHANGELOG reach main on every rc via the release-sync PR, folded at
promotion. D3: routines run as mikolalysenko (a routine actor, not an
approver) until a bot exists; npm stable is direct OIDC; newest-line
hotfixes only. D4: the first train release is 5.0.0 (pre-approved major).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
CHANGELOG (sync-main / cut / promote):
- The fold no longer classifies rc sections by rc number. Every rc
section whose core shipped is replaced by its blocks (tag text) minus
[S]'s blocks, as a multiset shared with the [Unreleased] removal. A
train rc cut beside a same-core hotfix now returns its entries instead
of losing them, whichever was cut first. TagSource.promoted_from is gone.
- Matching counts occurrences: a shipped block removes one occurrence,
so a repeated entry ("- Updated dependencies.") survives an unmerged
sync PR and no longer changes the bump level.
- Returned blocks go before the blocks already in their subsection, and
a cut orders its ### subsections canonically (breaking, then Keep a
Changelog, then the rest). The next cut is now byte-identical with or
without the sync PR, including subsection order left by shipped history.
- CRLF CHANGELOGs round-trip, and every generated line uses CRLF.
Blocker gate:
- Fails closed unless GET /labels/release-blocker returns that exact
name. Label names compare case-insensitively. labeled events since L
are candidates, and a label that vanished without an unlabeled event
still blocks. Deleted, converted and transferred issues block.
- RELEASE_APPROVERS / RELEASE_ROUTINE_ACTORS split on commas and
whitespace and accept a leading @. A malformed login, an empty list, or
no trusted approver blocks with a config error, in cmd_blockers and in
evaluate_blockers.
- since = committer date of merge-base(L, base), clamped to the base
date, not a forgeable tag date. A since later than the base fails
closed.
- PR-merge closes (closed event with commit_id null, recorded from #454)
resolve through the closing PR's merge_commit_sha being in base.
- Malformed event shapes fail closed.
Lint / CI:
- release-lint check 2 also runs the new offline `release.py
npm-lock-check`: the wrapper lock's packages[""] must match
package.json, and every non-optional dependency needs a node_modules
entry. This restores the dependency-drift check the networked lock
refresh used to give.
- ci.yml takes the release-sync --tag-exists path only for a same-repo
release-sync branch into main.
- rel.Git ignores GIT_DIR/GIT_WORK_TREE and similar variables.
Tests:
- StampTests are hermetic: they run on a temp tree stamped to a fixed
baseline (4.0.0, and 5.0.0-rc.1 via a subclass), so the suite passes on
main after the release-sync PR.
- The temp repos ignore the git env and global config.
- New coverage: release-lint (plain and --tag-exists) on a sync-main'ed
tree at an rc, the CI gate step run with stubs, and a regression test
for each finding.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- §1: rc.2's section is synced to main and its unshipped blocks return
to [Unreleased] when the stable is synced.
- §2: the release.py list adds semver, npm-lock-check, next-version and
changelog.
- §3.1: U = [Unreleased] of sync-main(C) computed in memory (this
replaces the pre-D2 "minus L's section" rule).
- §3.4: hotfix cuts use --no-sync, and same-core train rcs return to
[Unreleased].
- §3.5: the label check, case-insensitive names, labeled-event
candidates, vanished labels and gone issues, the merge-base `since`,
strict config parsing, and PR-merge close resolution.
- §3.7: multiset fold, chronological returns, canonical cut order,
CRLF, and the same-repo-only release-sync CI path.
- §4: npm-lock-check and the ci.yml condition.
- §5 I1 and PR 4: the stable tree is stamp + promote (fold), not a
heading rename.
- S5: the release-blocker label must exist before the gate can pass.
- §7 PR 1: the accept list adds the new scenarios.
- §8: APPROVED_MAJORS is kept (D4), and multiset counting is kept.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
- promote keeps every occurrence when folding rcs, so [X.Y.Z] is the
multiset sum of its rcs and sync-main charges them with the same count
(a repeated entry no longer returns as unshipped or raises the bump);
a later abandoned rc returns all of its blocks.
- sync-main charges the rc sections on main against [S] before removing
the rest of [S] from [Unreleased], so a newer identical entry keeps its
place whether or not the release-sync PR merged.
- blockers: since is never later than base - 35 days, so a forged high
stable tag at the base cannot shrink the candidate window further; S9
is a hard prerequisite for live gate runs.
- blockers: a PR-merge close resolves only through PRs merged by the
close actor (merged_by.login, recorded for #456).
- stamp keeps each file's line endings (CRLF checkouts check clean).
- sync-main computes CHANGELOG and stamp before writing anything.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
cursor
Bot
left a comment
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Burn-down agent: Ready for review at 056d955 (marked ready from draft).
- CI: 97/97 non-skipped checks green on the head SHA (3 skipped by path filters); mergeable with main.
- Bugbot: reviewed
056d955, no issues found; no unresolved review threads.
- Reviewer focus: this deletes
version-bump.yml / scripts/bump-version.sh and makes version-sync.sh offline, and the blocker gate (D3) assumes the S9 tag ruleset before any live run.
Generated by Claude Code
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Review updated for f43c3e366c16ddd37afa0b37f25aace41509d350: Ready to merge as-is from this review. 339 successful checks, 6 skipped, and all six workflows successful. Bugbot is clear on this commit; no unresolved review threads or new actionable findings.
Four release-lint test assertions now inspect stdout and stderr together, preserving the failure-status and diagnostic-content checks. This handles GitHub Actions annotations correctly. Production code is unchanged by the correction.
Validation: the full Python suite passed with GITHUB_ACTIONS=true (214 passed, 1 existing macOS-specific skip). All 82 release tests passed in that environment, and the five affected tests also passed with ordinary terminal output. Independent review covered the offline stamp, version/ref selection, blocker gate, workflow integration, and changelog transforms; 48 additional modeled scenarios confirmed identical next-cut bytes across partial sync merges, repeated entries, and abandoned release candidates.
The tested files match this commit, the diff is clean, and it merges cleanly with main 045d7ec. No remaining actionable finding from the review. Ready for review has been restored. GitHub still requires the normal human approval before merge.
CI note: a PDM 2.6.1 Ubuntu case initially hit API HTTP 504 before patching. One targeted retry passed all 34 supported/expected-refusal cases, with two explicitly unsupported PEP582 cases and no failures. The previously failing case now verifies patch bytes, repeat install/sync/rescan, rollback, and unchanged lock/manifest files; the fresh result artifact digest was verified.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
BugBot review
Please review the test correction on f43c3e366c16ddd37afa0b37f25aace41509d350.
|
cursor[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit f43c3e3. Configure here.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
Ready for review
Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|