fix(server): refresh linked PRs without a checkout#17167

merged2
main
GitHub fork: pixpmusic/fix-no-project-pr-snapshots
opened17d agobyPPixPMusic
View on GitHubTwo-way sync enabledPR last imported 5d ago

Problem

Linked PRs in “No project” scratch threads can remain at “Pull request · Status pending” indefinitely, even when the host can read them through gh. PullRequestService.requireProject refuses a hosted reference before reading the provider when no registered Git-backed project exists on that host. The same service failure prevents PR watches from reading the linked PR.

Fixes #17166.

Change

Keep the existing checkout routing first. When no checkout route exists for github.com, bitbucket.org, or codeberg.org, use the selected project's directory and the reference's explicit host and repository to call the registered provider. Preserve the normalized remote used by current upstream caches.

Regression tests cover summary and stack reads without a checkout on all three hosts, matching-checkout preference, missing project directories, hostless references, and unavailable providers. GitLab, Azure, and self-hosted routing retain their existing checkout requirements. GitLab is excluded because its adapter selects the endpoint through the checkout or CLI configuration rather than explicitly targeting the reference's host.

Scope and approval

This is a focused fix for an obvious failure in the existing linked-PR workflow: the reference already identifies a readable PR, but an unrelated checkout requirement blocks its metadata. It qualifies for CONTRIBUTING.md's focused bug-fix exception.

The change stays in the existing server service, shared by PR sync, PR watches, client RPCs, and MCP tools. Web, desktop, and mobile consume the same persisted snapshots over local, remote, and T3 Connect connections. No client UI, wire contract, provider-agent adapter, or documentation changes are needed.

Verification

  • vp test run apps/server/src/pullRequest/PullRequestService.test.ts apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts: 216 passed on this branch.
  • The three new no-checkout tests fail with PullRequestUnavailableError against the pinned upstream implementation and pass with the fix.
  • vp run --filter t3 typecheck: passed.
  • Targeted vp lint, vp fmt --check, and git diff --check: passed.
  • On the affected MacBook Air, ran gh pr view 1 --repo pixpmusic/theatrebot --json title,state through the remote T3 terminal in the scratch directory; it returned the real title and MERGED. Both Android and desktop displayed pending metadata before the fix.

The updated server has not been installed on that MacBook Air. Native mobile end-to-end verification was not performed; verification of the fix uses server service and sync-reactor tests.

Model: GPT-6.1 Sol | Harness: Codex in T3 Code

Checks

All checks passed
Synced from GitHub

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — Although the PR targets a focused linked-PR refresh failure, its shared routing change also enables other pull-request reads and authenticated write operations without a matching checkout. That broader production behavior warrants human review.

Notes:

  • Diff unchanged. Approvability was decided on eligibility alone.

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

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: eb3c5cc0-f7e5-4b71-94ce-ce5e77982f6c

📥 Commits

Reviewing files that changed from the base of the PR and between f28c005c5d0ed6032c8f369d0ff11ac6b7f99a76 and bfa28802e25672a283c640a9258b808d3cbaf919.


📒 Files selected for processing (2)
  • apps/server/src/pullRequest/PullRequestService.test.ts
  • apps/server/src/pullRequest/PullRequestService.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Walkthrough

Walkthrough

When no matching checkout exists, requireProject can route GitHub, Bitbucket, and Codeberg pull requests through the selected project. GitLab and other unsupported hosts still require a matching checkout. Tests cover routing and unavailable cases.

Changes

Hosted pull-request routing

Layer / File(s)Summary
Resolve hosted pull requests without a checkout
apps/server/src/pullRequest/PullRequestService.ts, apps/server/src/pullRequest/PullRequestService.test.ts
requireProject now routes GitHub, Bitbucket, and Codeberg references through the selected project when no matching checkout exists. Tests cover provider arguments, checkout preference, and unavailable cases.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge


Merge Risk | ⚪ Minimal · up to bfa28

Merge Risk: ⚪ Minimal · up to bfa28

Supported hosted pull requests can use the selected project directory without a matching checkout. No actionable merge-blocking issue remains after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to bfa28

The fallback is restricted to three public hosts and preserves matching-checkout preference and existing provider authorization. No authorization bypass was established. However, the routing change also enables existing writes without a checkout, and their partial-failure and concurrent recovery behavior was not fully verified.

Retained concerns No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Callers able to submit hosted references can now request operations on repositories on the three supported hosts without a local checkout. The effective data and mutation scope includes private repositories accessible to the configured provider credential, not merely the selected project's repository. The fallback does not itself grant additional provider privileges.

Trust Boundaries and Controls

  • observed — runAction checks provider capabilities and freshly queries permissions for the same explicit repository and host before invoking the mutation. A null repositoryKey does not bypass this check or substitute the selected project's repository as the mutation target.
  • observed — When expectedAccountId is supplied, the routing wrapper requires a matching host and provider credential verification, then rejects an account mismatch before executing the operation. This account-pinning control is optional; it must not be assumed for references that omit expectedAccountId.

Resilience and Maintainability Implications

  • observed — Read-cache identity includes project, host, repository and PR number rather than repositoryKey. Persisted keys additionally include provider and workspace; expected account and verified credential fingerprint are included when present. The fallback therefore does not collapse unrelated explicit repository targets into a shared null-key entry.

Pre-merge checks | Passed 4
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main server fix: refreshing linked pull requests when no checkout exists.
Description checkPassedThe description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the failure, implementation, focused-fix justification, test results, manual checks, a…
Linked Issues checkPassedIssue #17166 requires linked PR title and state to load from the authenticated provider without a Git checkout. PullRequestService.requireProject keeps matching-checkout routing first and falls back…
Out of Scope Changes checkPassedThe changes remain in PullRequestService and its focused tests. The equivalent fallback for bitbucket.org and codeberg.org supports the same explicit-host linked PR workflow. Tests verify retain…

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Added 2 commits

  • fix(server): refresh linked PRs without a checkout9547755
  • fix(server): retain checkout routing for GitLabbfa2880