feat(scm): detect cross-fork PRs by scanning all project remotes#2368
Open
harshitsinghbhandari wants to merge 2 commits into
Open
Conversation
The SCM observer only polled a project's push origin for open PRs, so a PR opened from the fork against an upstream base repo (the standard fork -> upstream flow) was never discovered: GitHub lists a PR under its base repo, not its head, so an origin-only scan can't see it. Sessions that opened such PRs showed no PR on the dashboard. Scan every GitHub remote in the project checkout (origin + upstreams / mirrors) for open PRs, and attribute a PR to a session only when its head branch lives in that session's push origin. This surfaces cross-fork PRs while preserving the no-misattribution guarantee: a stranger's fork PR has a head repo no session owns and is dropped. Tracked cross-fork PRs are keyed for refresh by their own recorded repo (the upstream base) so the GraphQL refetch targets the right repo. Co-Authored-By: Harshit Singh Bhandari <dev@theharshitsingh.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a worker session opens a PR from the fork against an upstream base repo (the standard fork -> upstream contribution flow), the session never linked to that PR on the dashboard.
Root cause: the SCM observer only polled a project's push
originfor open PRs. GitHub lists a PR under its base repo, not its head, so an origin-only scan can't see a PR whose base is upstream. Concretely, sessionagent-orchestrator-23opened a PR with headharshitsinghbhandari/agent-orchestratorand baseAgentWrapper/agent-orchestrator; the observer polled only the fork, the PR was never discovered, and noprrow was written, so the dashboard PR badge stayed empty.Fix
Scan every GitHub remote in the project checkout (origin + upstreams / mirrors), read from
git remoteat the project path, and attribute a PR to a session only when its head branch lives in that session's push origin.discoverSubjectsnow builds one scan target per (session x remote repo);resolveScanReposreads all remotes and dedupes them against origin.candidatesForHeadRepo: a PR is claimed only whenpr.HeadRepoequals a candidate session's push origin and the branch prefix matches. Same-repo PRs (head == origin == scanned repo) and cross-fork PRs (head == origin, scanned repo == upstream base) both attribute; a stranger's fork PR has a head repo no session owns and is dropped, preserving the existing no-misattribution guarantee.subjectRepoForPRusespr.Repo, the upstream base) so the GraphQL refetch targets the base repo instead of the fork where the PR number doesn't exist.Cost
One extra cheap
RepoPRListGuardETag check per additional remote per 30s tick (304s when nothing changed). Negligible for the 2-3 remotes AO projects typically carry.Known ceiling
Remotes are read once per project per process; a remote added after the daemon started is picked up on restart.
Tests
TestPoll_DiscoversCrossForkPRFromUpstreamRemote: fork head + upstream base is discovered, attributed to the session, persisted with the upstream base repo, and refreshed against upstream.TestPoll_IgnoresUpstreamPRFromForeignHead: a matching-branch PR on a scanned upstream whose head lives in a third-party fork is never fetched or persisted.go build ./...,go vet ./internal/observe/..., and theobserve/scm,adapters/scm,service/sessionsuites (181 tests) all pass.🤖 Generated with Claude Code