Skip to content

fix(pr): prevent same-PR operations from overlapping#103669

Merged
steipete merged 2 commits into
mainfrom
codex/pr-operation-lock
Jul 10, 2026
Merged

fix(pr): prevent same-PR operations from overlapping#103669
steipete merged 2 commits into
mainfrom
codex/pr-operation-lock

Conversation

@steipete

@steipete steipete commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Closes #103666

What Problem This Solves

Fixes an issue where maintainers running scripts/pr commands for the same pull request could overlap and concurrently mutate the shared worktree and review, prepare, or merge evidence.

Why This Change Was Made

State-changing review, prepare, and merge commands now serialize through a per-PR Git ref shared by every linked worktree. A process-group supervisor releases the exact owner only after clean synchronous completion; interrupted, failed, controller-lost, or otherwise indeterminate operations stay locked for explicit exact-OID recovery, and garbage collection skips active or uncertain owners.

User Impact

Maintainers can run operations for different pull requests concurrently while same-PR operations queue safely. A crashed operation no longer silently exposes its worktree to another landing command or garbage collection.

Evidence

  • Blacksmith Testbox tbx_01kx5xbmvm9hb939tx3hcd8hrc: node scripts/run-vitest.mjs test/scripts/pr-operation-lock.test.ts test/scripts/test-projects.test.ts test/scripts/pr-wrappers.test.ts — 3 files, 241 tests passed.
  • Static validation: bash -n for the touched shell entry points, node --check scripts/pr-lib/process-group-runner.mjs, git diff --check, and the exact scripts oxlint lane passed with zero warnings/errors.
  • Exact-byte read-only audits covered CAS ownership, signal and controller-loss behavior, test routing, macOS Bash 3.2, paths containing spaces/backslashes, /var canonicalization, symlink aliases, and GC cleanup postconditions; no remaining findings.
  • Fresh Codex autoreview of the full patch at 8e90eaeebb7 reported no accepted/actionable findings (0.91 confidence); a second fresh review of follow-up b16d4d41df0 was also clean.

AI-assisted: implemented and reviewed with Codex. I understand the locking, supervision, recovery, and cleanup paths in this change.

@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: XL maintainer Maintainer-authored PR labels Jul 10, 2026

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

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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e90eaeebb

ℹ️ 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 +218 to +226
const postExitGroupStatus = child.pid ? processGroupStatus(child.pid) : "dead";
if (postExitGroupStatus === "indeterminate") {
notificationFailure ??= new Error("scripts/pr process-group state became indeterminate");
} else if (postExitGroupStatus === "live") {
// A wrapper exit does not end same-group background work. Bound and drain
// forgotten jobs, but keep the lock because their terminal state is unknown.
hadLingeringGroup = true;
notificationFailure ??= new Error("scripts/pr process group remained active after wrapper exit");
signalProcessGroup("SIGTERM");

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.

P2 Badge Avoid signalling a reused process group

When the PR command's process group has already exited, a high-PID-churn host can reuse child.pid as a new process-group id before this post-exit probe runs. In that case processGroupStatus(child.pid) reports live, and the branch below sends SIGTERM/SIGKILL to that unrelated process group and retains the PR lock even though the operation completed; the shell lock owner checks supervisor birth to avoid this kind of reuse, but the supervisor's own group-drain path does not.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready proof for exact head b16d4d41df05250ca275bf047a4341cbf0beb7fb:

  • Hosted CI run 29091570792: 64 relevant checks passed; no failed or pending checks.
  • Blacksmith Testbox tbx_01kx5xbmvm9hb939tx3hcd8hrc: node scripts/run-vitest.mjs test/scripts/pr-operation-lock.test.ts test/scripts/test-projects.test.ts test/scripts/pr-wrappers.test.ts — 3 files, 241 tests passed.
  • Targeted lint: node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.scripts.json scripts/pr-lib/process-group-runner.mjs — 0 warnings, 0 errors.
  • Static checks: bash -n on touched shell scripts, node --check scripts/pr-lib/process-group-runner.mjs, and git diff --check passed.
  • Fresh full-patch autoreview and follow-up autoreview: no accepted or actionable findings.
  • Native review artifacts validate on the exact head; OPENCLAW_TESTBOX=1 scripts/pr prepare-run 103669 completed with gates_mode=hosted_exact_or_recent_rebase and did not change the head.

Known proof gaps: none.

@steipete
steipete merged commit ea6aa1d into main Jul 10, 2026
88 checks passed
@steipete
steipete deleted the codex/pr-operation-lock branch July 10, 2026 12:34
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 11, 2026
* fix(pr): serialize operations per pull request

* fix(pr): tighten supervisor error handling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: scripts/pr operations can overlap on the same pull request

1 participant