fix(publish): recover exact state races without full reset#723
Merged
Conversation
Contributor
Author
|
@clawsweeper review |
Contributor
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
This was referenced Jul 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
statetreeProblem and causal proof
#722 serialized exact state mutations, but it did not restore publication throughput. At the 2026-07-20T16:29:45Z post-merge baseline the publication lane still had 354 pending, 352 ready, 40/40 leases occupied, an oldest item age of 13,786 seconds, and net drain of -52/hour over 15 minutes and -56/hour over 60 minutes.
A 2026-07-20T16:40:52Z workflow inventory separated the 40 occupied publication slots into 28 pre-#722 publishers, 12 post-#722 executions, and one dispatch reservation. Thirty-seven of the 39 running publishers were already inside
Publish event result and apply safe close. Ten post-#722 publishers then exhausted the new 180-second lease acquisition bound.The lease was not deadlocked and GitHub access was not failing. The active owner repeatedly lost
statecompare-and-swap races to pre-lease publishers, then rangit reset --hardacross a 434,644-file state worktree. Individual resets took roughly 25-30 seconds; one observed owner recorded 22 state races and 21cannot lock reffailures. That work allowed its two-minute lease to expire while it was still recovering, leaving new writers queued behind an owner that could no longer complete under its lease. Affected logs contained no 401/403 or token-access signature.The incident predates #712, and high publication concurrency predates the #711/#712 window. However, the renewed capacity stall immediately after #712 is high-confidence attributable to #712's synchronous missing-object/history recovery: every losing publisher could perform serial 60-second refetch, deepen, and unshallow operations before retrying. #714 showed the object-fetch premise was invalid, #716 moved no-base reconciliation onto the remote head, and #720 removed hydration from one exact path. The remaining full-worktree reset in exact race recovery is the first fault addressed here.
Implementation
mktree --missing, then create a child commit withcommit-tree. Arbitrary remote sibling paths are preserved.read-tree,update-ref, and materialization/removal of only paths changed between the prior and replacement trees. The exact recovery path no longer performs a fullgit reset --hard.This does not repair #711's separate broad no-common-base replacement risk. That path is not required to release the currently blocked exact publication leases and should be handled independently.
Validation
Crabbox Docker behavioral proof
Crabbox local-container,
node:24-bookworm, leasecbx_d76c6b7f57f2, exit 0:origin/main; it failed as expectedtest/repair/git-publish.test.tscases passedttl_ms: 120000, a lease renewal before recovery, no post-racegit reset, the bounded tuple-tree rebuild, and preservation/materialization of both the local tuple and an unleased concurrent remote siblingProof command:
Static and build proof
pnpm run build:allpnpm run lint:repairpnpm exec oxlint test/repair/git-publish.test.ts --deny-warnings --report-unused-disable-directives -D correctnesspnpm exec oxfmt --check src/repair/git-publish.ts test/repair/git-publish.test.tsgit diff --checkAll passed. A separate
test/sweep-workflow.test.tsprobe passed 66/67 cases; its only failure was an untouched fixture requiringjq, which is absent from the stock unprivileged Node/Playwright Crabbox images. The authoritative widened proof is the complete 52-case publisher suite in Crabbox.Retrospective #712 review
codex review --commit 25135198f921b062b6d276931ca794d0222129c6identified the synchronous recovery/history-fetch amplification, the invalid assumption that GitHub would serve unavailable object IDs, and a Windows-only historical test portability defect.25135198f921b062b6d276931ca794d0222129c6against parent611b3f165d05254c9ec20ee69953167c517e6c7bcompleted with high confidence but reported no actionable finding and rated the patch correct. Production evidence and the retrospective Codex review therefore expose a review gap; the local review added no further code requirement./usr/bin/gittest portability defect is unrelated to the production incident and is intentionally excluded.Codex review closeout
codex review --uncommittedfound three actionable issues: an overlong lease TTL weakened crash recovery, that TTL still could not cover every broad recovery fetch, and the state-tree diff used Git's default 16 MiB output buffer.codex review --uncommitted: clean; no actionable findings.codex review --base origin/main: clean; "The bounded reconciliation rebuild and lease-renewal changes preserve the selected record tuples and maintain the lease across a lost push race. No actionable regressions were identified in the diff."Risk and rollout
Credit
This repair preserves and narrows the remote-head reconciliation work from Peter Steinberger's #711, #712, #714, #716, and #721, together with the bounded exact recovery from #720 and lease fencing from #722.