fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@saphid
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} 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(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@saphid
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } 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(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

fix(server): fall back to local worktree base when origin fails - #7667

Open
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery
Open

fix(server): fall back to local worktree base when origin fails#7667
saphid wants to merge 3 commits into
pingdotgg:mainfrom
saphid:fix/new-thread-origin-recovery

Conversation

@saphid

@saphidsaphid commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

1. Observed problem and reproduction

With Start from origin enabled, creating a worktree-backed thread aborts if checking origin, fetching it, or resolving the selected remote branch fails. This can happen while offline, with an unavailable remote, or when the selected branch has not been pushed. The provisional thread is then rolled back even when the explicitly selected local base is valid.

2. Cause

The setting is a persisted preference, but the server treated every origin-preparation step as mandatory. A recoverable remote failure therefore escaped the worktree-base selection boundary and failed the entire bootstrap.

3. Change and owning boundary

The server now attempts origin availability, fetch, and remote-ref resolution as one optional source-selection step. If any of those operations returns a typed Git error, it records a structured warning and creates the worktree from the explicitly selected local base. A successful origin path still uses the resolved remote commit.

This stays in the existing WebSocket bootstrap and Git workflow boundary. The fresh extraction preserves the old head's core fallback behavior for unavailable, check-failure, fetch-failure, and ref-resolution cases while removing unrelated earlier draft-recovery work already shipped in #7664.

4. Intentionally unchanged and deferred

  • Worktree creation, metadata update, status refresh, setup, and turn-start failures remain hard bootstrap failures and retain the existing cleanup behavior.
  • The previous head's worktree.origin-fallback activity and per-stage reason taxonomy are intentionally omitted from this smaller server reliability change.
  • A user-visible fallback notice is a named follow-up. Until then, the fallback is visible only in the server warning log, keyed by thread ID with normalized Git operation and output-length fields.
  • fix(server): unpushed branch no longer breaks thread creation #7610 overlaps the missing remote-ref case; this PR does not modify or close that contributor's branch.

5. Affected surfaces

  • Server orchestration: new-thread worktree bootstrap only.
  • Clients: web, desktop, and React Native mobile all use the shared server bootstrap behavior; no client code or wire contract changes.
  • Providers: all providers are unchanged because this runs before provider-specific turn startup.
  • Connections: local, remote, relay, and tunnel clients receive the same server behavior. No connection protocol changes.
  • Reverse path: a healthy origin continues to select the fetched commit, covered by the existing happy-path test.

6. Validation

Current base: 33b650a5b3b27382b35d2182dec6b22438c3da56.

  • CI=true vp test run apps/server/src/server.test.ts: 134 passed, 0 failed.
  • CI=true vp fmt --check apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp lint apps/server/src/ws.ts apps/server/src/server.test.ts: passed.
  • CI=true vp run --filter t3 typecheck: passed; it reported only existing Effect suggestions in unrelated files.
  • git diff --check origin/main...HEAD: passed.
  • Direct read-only Claude Opus 5 high review of the final frozen diff: exit 0, no actionable correctness or reliability findings.

The focused server seam exercises the real typed WebSocket RPC bootstrap boundary. It covers an absent origin plus check, fetch, and remote-ref failures, asserts the selected local base, successful turn continuation, short-circuit call ordering, and no rollback. The adjacent existing case verifies the successful-origin path still uses the fetched commit.

7. Risks, limitations, and untested paths

  • A local branch may be older than origin; after a transient remote failure this intentionally starts from that older local base instead of failing.
  • If the selected base exists only on origin, the local fallback can still fail at worktree creation. The client then sees the worktree-add failure, while the original origin failure stage and exit status remain in the server log.
  • No live network failure was injected. The behavior is proven at the server's Git-driver and WebSocket RPC seams with typed failures.
  • Remote, relay, and tunnel transport runs were not repeated because neither the command contract nor transport handling changed.

8. Evidence

This is server-only behavior with no UI, layout, or interaction change. Screenshots and video are not applicable. The observable proof is the focused RPC integration coverage and successful local-base worktree selection described above.

9. Owning issue and overlap

The original stuck-draft symptom in #4647 was fixed by merged #7664. This PR retains only the distinct reliability outcome: an optional origin failure no longer aborts an otherwise valid local worktree bootstrap. Related overlap: #7610.

Generated with GPT-5.6 Sol in the Codex harness through T3 Code.


Note

Medium Risk
Changes new-thread worktree bootstrap only, but silently using a stale local base after remote errors could surprise users who expected origin; failures after fallback still abort as before.

Overview
Start from origin during thread bootstrap no longer fails the whole turn when Git cannot use origin. The server still tries remote check, fetch, and remote-tracking resolution when the preference is on; any typed Git error in that path is logged as a structured warning and the worktree is created from the selected local baseBranch instead of rolling back the thread.

Integration tests now run the same fallback scenario for four cases—missing origin, failed remote check, failed fetch, and failed ref resolve—and assert bootstrap completes (response.sequence 3), worktree uses the local base, and no thread.delete cleanup runs.

Reviewed by Cursor Bugbot for commit acb73db. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fall back to local base branch when origin check, fetch, or resolve fails in thread.turn.start

  • When bootstrap.prepareWorktree.startFromOrigin is true, the origin path (check availability, fetch, resolve remote-tracking commit) is now wrapped in Effect.catch. Any failure logs a structured warning (threadId, baseBranch, remoteName, error details) and falls back to the local baseBranch instead of aborting.
  • Parameterizes the fallback test in server.test.ts over four stages: unavailable, check, fetch, and resolve, asserting response.sequence equals 3 and no thread.delete is dispatched.
  • Behavioral Change: previously an origin fetch or resolve failure would abort the bootstrap; now it silently degrades to the local base branch. The warning log is the only signal that fallback occurred.

Macroscope summarized acb73db.

@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 495efd67-ee26-41e0-9e6a-263f26b0107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 20, 2026
@macroscopeapp

macroscopeappBot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 66158c3

Macroscope's review found this PR approvable — This is a focused server bug fix that preserves healthy-origin and existing local paths while recovering from origin check, fetch, and ref-resolution failures. Targeted integration tests cover each failure stage and verify local-base worktree creation and continued bootstrap without rollback.

You can add or adjust custom eligibility rules. Learn more.

@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 6b266b7 to 4bd76c7CompareAugust 26, 2026 22:30
@saphidsaphid changed the title fix: new thread bootstrap failures no longer trap draftsfix(server): fall back to local worktree base when origin failsAug 26, 2026
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 26, 2026
@saphid
saphidforce-pushed the fix/new-thread-origin-recovery branch from 4bd76c7 to 03d8d3cCompareAugust 27, 2026 02:40
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:40

Dismissing prior approval to re-evaluate 03d8d3c

@github-actionsgithub-actionsBot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 27, 2026

@macroscopeappmacroscopeappBot 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.

One finding on the new origin-fallback logging in apps/server/src/ws.ts. The rest of the change (namespaced effect/* imports, Effect.catch over an error channel that is entirely GitCommandError, typed fallback kept inside Effect, and the parameterized it.effect.each coverage for each failure stage) matches the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/ws.ts Outdated
macroscopeapp[bot]
macroscopeappBot previously approved these changes Aug 27, 2026
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 27, 2026 02:54

Dismissing prior approval to re-evaluate 66158c3

@saphid

saphid commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Ready for human review at current head acb73db79d03dcfbb486cbf9020a5553eb3efeb1. This is a focused two-file server reliability fix with no UI-media requirement. GitHub reports MERGEABLE / CLEAN; the focused RPC suite passed 134/134, format/lint/typecheck and git diff --check passed, required CI is green, current CodeRabbit/Macroscope checks pass with no unresolved threads, and the direct read-only Claude Opus 5 high review exited 0 with no actionable findings.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@saphid