fix: resolve unrecoverable incarnation state (#584)#585
Open
peterbraden wants to merge 3 commits into
Open
Conversation
Three tests reproducing the unrecoverable incarnation state described in issue #584. Marked xfail until the fix is implemented: - Committed change with missing SHA (force-push scenario): update_incomplete_change short-circuits on commit_pushed=True, leaving a broken change as the latest. - Multiple broken changes: repairing each change individually still leaves the incarnation pointing at a nonexistent commit. - Stale branch from closed MR: deterministic branch name collides with an orphaned remote branch, blocking new change creation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Four tests reproducing the unrecoverable incarnation state described in issue #584. Marked xfail until the fix is implemented: - Single broken change: after force-push, creating a new direct change should self-heal by invalidating the broken change and succeeding. - Multiple broken changes: same recovery across a chain of invalid commits. - GET reports broken state without mutating: verifies GET returns UNKNOWN for broken incarnations, and that recovery only occurs via mutation. - Stale branch: a branch from a closed MR should not block new changes. Tests verify both the mutation (create_change_direct) and the read path (get_incarnation_with_details) — no /fix endpoint needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
206ae00 to
f948c9e
Compare
o1da
approved these changes
May 26, 2026
Contributor
Author
|
From review discussion:
|
f948c9e to
d8b85bd
Compare
get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair logic (which deletes changes whose commits no longer exist in git). Only the latest change can be in this state, since creating a new change requires the previous one to be complete — so a single retry is sufficient. This means PUT, PATCH, and direct changes automatically recover from broken state without manual intervention. No schema changes, no new endpoints, no API contract changes. Closes #584 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d8b85bd to
922af21
Compare
Contributor
Author
|
Branch name split out to #586 |
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
Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with
commit_pushed=Falseand a nonexistent commit SHA.get_latest_change_for_incarnation_if_completednow catchesIncompleteChangeand runs the existingupdate_incomplete_changerepair logic. Only the latest change can be in this state (creating a new change requires the previous one to be complete), so a single retry suffices. All mutation paths (PUT, PATCH, direct changes) automatically recover.No schema changes, no new endpoints, no API contract changes.
The stale branch collision (root cause 2 from #584) is addressed separately in #586.
Test plan
🤖 Generated with Claude Code