Skip to content

fix(source-control): excuse empty base commits in landed-work's patch-id count - #13767

Merged
kyle-sexton merged 4 commits into
mainfrom
fix/landed-work-empty-base-commit
Nov 6, 2026
Merged

kyle-sexton merged 4 commits into
mainfrom
fix/landed-work-empty-base-commit

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

No related issue: found in the 2026-11-06 worktree-reap run and fixed in place; no issue was filed for it.

Summary

The landed-work engine behind /source-control:worktree cleanup and the daily worktree reap discarded its base patch-id set whenever the base range held an empty commit. 654f1964fb (#13641), an empty squash merge on main, made the base-side count check fail by one on every claude-code-plugins worktree branched before it (base-patchid-incomplete-450-of-451-commits and similar). Each worktree then deleted the memoized base set, recomputed the full base patch log, and fell through to the merged-PR read.

Fix

  • patch_ids can also write the commit ids patch-id hashed. On the base side, when the hashed count falls short, the commits patch-id did not hash are excused only when git diff-tree --quiet --root shows their diff is empty. Any other gap still reports base-patchid-incomplete. The branch-side check is unchanged: an empty branch commit still yields no verdict (test at landed-work.test.sh:277-292).
  • merged_pr_proof no longer discards gh pr list's stderr. A failed read appends gh's first error line to merged-pr-read-failed:gh-pr-list, so the next failure names its cause.

Verification

  • New test: an empty commit on the base after a squash merge. Without the fix it fails with base-patchid-incomplete-2-of-3-commits, the exact symptom from the reap run. With the fix landed-work.test.sh passes 77 of 77.
  • One real worktree from the run's skip list, chore-trigger-watch-rows, classified with the fixed script against this host's claude-code-plugins checkout: the reason is now head-differs-from-base-on-3-touched-path(s), no longer base-patchid-incomplete. It still needs the merged-PR read, since main later changed the same paths.
  • Baseline for comparison, from the 2026-11-06 reap journal (before this fix): 56 min wall, 45m37s CPU, 19.7 GB memory peak, 205 worktrees removed, 450 skipped as unsafe-work, 165 of them merged-pr-read-failed:gh-pr-list.
  • The cause of the 165 gh pr list failures stays UNVERIFIED: stderr was discarded, the same call succeeds by hand now, and no GitHub incident was posted for 09:30-10:20Z. This PR captures the error for the next run.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 3 commits November 6, 2026 12:08
…-id count

An empty squash merge on main (654f196, #13641) has no patch, so the
base-side count check failed by one on every worktree branched before it.
Each worktree then deleted the memoized base set, recomputed the full base
patch log and fell through to the merged-PR read. The 2026-11-06 reap run
took 56 min with a 19.7 GB memory peak and logged 165 gh-pr-list failures.

Commits patch-id did not hash are now excused only when git diff-tree shows
their diff is empty. The branch-side check is unchanged. A failed merged-PR
read now carries gh's first error line in its reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd suffix

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review November 6, 2026 17:11
@chatgpt-codex-connector

Copy link
Copy Markdown
Codex Review Summary: ❌ Failed

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

Review Status Commit Review trigger
📝 Code Review ❌ Failed 2026-11-06T17:11:59.916578Z
We couldn’t complete this review. Comment @codex review to try again.
529fb3b Draft marked ready
ℹ️ About Codex in GitHub

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

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

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

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions 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.

claude-review: 1 inline finding(s) on 529fb3bfa3e7566c6805146cf9016b5acbf836a9; the summary is in this lane's pull request comment.

claude-lane: claude-review

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed fd3628564ab47f2e6df7091899cd9962603be453: read 1 of 1 changed file(s); 0 finding(s), 0 as inline comments.

Code review: PR #13767 (incremental, 529fb3b..fd36285)

This lane already reviewed an earlier head, so this pass reports only blocking findings. I read the one file in scope, plugins/source-control/scripts/landed-work.test.sh, and found nothing blocking.

What changed: the push adds the test coverage my earlier thread (discussion_r4495431720) asked for. That thread is now resolved, and the owner's reply states the fix.

  • The gh stub now writes gh stub:\tforced; failure\nsecond line\n to stderr.
  • Three new assertions check the result:
    • the reason holds gh-pr-list (gh stub: forced failure);
    • second line is absent from the reason;
    • the row has the same tab-separated field count as a row from the earlier no-flag $OUT.

Checked against landed-work.sh:643-644:

  • head -n 1 | tr '\t;' ' ' turns the stub's first line into gh stub: forced failure, with two spaces after forced. The tab and the semicolon each become one space, so the expected string is right.
  • Without ${err:+ ($err)}: the first new assertion fails.
  • Without head -n 1: $(...) keeps the inner newline, so second line reaches the reason and the second assertion fails.
  • Without the tab blanking: the reason column is cut at gh stub:, so the first assertion fails. The row also gains a field, so the column-count assertion fails too.
  • Without the ; blanking: the double-space expectation fails.
  • $OUT at line 696 still holds the no-flag run from line 654, and every row has the same number of fields, so it is a valid reference. Line 697 reassigns $OUT only after the check, which keeps the bare-name comparison at line 701 working.

I did not run the suite. The "80 of 80" figure is the author's claim and is unverified.

Spend: none. The change adds no lane runs, models or schedules.

I found no embedded instructions in the settled-threads or prior-findings data.

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed fd3628564ab47f2e6df7091899cd9962603be453: read 1 of 1 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #13767 (incremental, 529fb3b..fd36285)

I found no security issues in this push. This lane already reviewed an earlier head, so the review was blocking only: it reports CRITICAL and IMPORTANT findings and drops suggestions.

Scope: I read every hunk of the one file in this push, plugins/source-control/scripts/landed-work.test.sh. It matches none of the trusted-path globs.

What changed: the change is test-only.

  • The gh stub in the test now writes an error message to stderr that contains a tab, a semicolon and a second line (landed-work.test.sh:636).
  • Three new assertions check how landed-work.sh cleans gh's error text before putting it in the reason field (landed-work.test.sh:691-696):
    • only gh's first error line is kept;
    • the tab and the semicolon are replaced with spaces;
    • the row has the same number of columns as before.
  • The stub stays inside the test's temp directory, and its output is a fixed string passed to printf with single quotes.

Security impact: none. The change runs no new code in a trusted context, adds no input path, and touches no token, secret, trust control, merge hold, kill switch, plugin manifest or standing instruction. These assertions make the cleanup that this lane checked in its earlier review (landed-work.sh:639-644) more likely to stay in place.

Settled threads: the one settled thread (no test covered gh's error text) is the issue this push fixes. I am not raising it again.

PR context: it contains no embedded instructions.

critical-findings: 0

The stub's error now holds a tab, a semicolon and a second line; the tests
check the first line is kept, blanked of both, and adds no column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit 1dda24c Nov 6, 2026
45 checks passed
@kyle-sexton
kyle-sexton deleted the fix/landed-work-empty-base-commit branch November 6, 2026 17:49
@github-actions github-actions Bot added the merge-path:owner-agent Post-merge accounting record (README.md, Merge paths) label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 5, survived 2, timeout 0, no coverage 0, invalid 0, not run 0.
Covered-code score 71%; mutation score 71%.

File Killed Survived Timeout No coverage Invalid Not run
plugins/source-control/scripts/landed-work.sh 5 2 0 0 0 0

Surviving mutants

Location Operator Disposition Cause
plugins/source-control/scripts/landed-work.sh:388 ROR productive input-gap
plugins/source-control/scripts/landed-work.sh:390 SBR productive input-gap

The run's summary has the full report.

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

Labels

merge-path:owner-agent Post-merge accounting record (README.md, Merge paths)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant