fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: resolve unrecoverable incarnation state (#584) - #585

Open
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state
Open

fix: resolve unrecoverable incarnation state (#584)#585
peterbraden wants to merge 3 commits into
mainfrom
fix/584-unrecoverable-incarnation-state

Conversation

@peterbraden

@peterbradenpeterbraden commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves the deadlock described in #584 where incarnations become permanently stuck after force-pushes leave the latest change with commit_pushed=False and a nonexistent commit SHA.

  • Self-healing mutation path:get_latest_change_for_incarnation_if_completed now catches IncompleteChange and runs the existing update_incomplete_change repair 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

  • Regression tests reproducing the force-push deadlock scenario (red/green verified)
  • Regression test verifying GET reports broken state without mutating, then mutation recovers
  • All existing tests pass unchanged

🤖 Generated with Claude Code

peterbradenand others added 2 commits May 21, 2026 11:48
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>
@peterbraden
peterbraden requested a review from defreng as a code ownerMay 21, 2026 10:13
@peterbraden
peterbraden marked this pull request as draft May 21, 2026 10:13
@peterbradenpeterbraden changed the title Draft: Fix #584 - unrecoverable incarnation statefix: resolve unrecoverable incarnation state (#584)May 21, 2026
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from 206ae00 to f948c9eCompareMay 21, 2026 10:33
@peterbraden
peterbraden marked this pull request as ready for review May 21, 2026 10:52
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

From review discussion:

  • Split into 2 PR's
  • We likely don't need while: True, as the theory is, only the last revision can be broken.

@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from f948c9e to d8b85bdCompareJune 2, 2026 11:45
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>
@peterbraden
peterbradenforce-pushed the fix/584-unrecoverable-incarnation-state branch from d8b85bd to 922af21CompareJune 2, 2026 11:48
@peterbraden

Copy link
Copy Markdown
ContributorAuthor

Branch name split out to #586

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@peterbraden@o1da