56 lines
2.9 KiB
Markdown
56 lines
2.9 KiB
Markdown
# GitHub PR status synchronization
|
|
|
|
Apply these rules to watch identity, PR lifecycle persistence, and batched lookup changes.
|
|
Paths and symbols refer to this package unless a path starts with `apps/`.
|
|
|
|
## Watch identity
|
|
|
|
A `github_pr_watches` row is unique per session, repository, and branch.
|
|
Once a watch finds a PR, it remains that PR's synchronization handle.
|
|
Both the poller and on-demand synchronization iterate these watches.
|
|
|
|
On branch switches, re-point only a searching watch (`pr_number=0`) for the same repository.
|
|
Otherwise, add a watch for the new branch.
|
|
Apply this rule in `resetPRWatchForBranchSwitch` and `syncPRWatchBranch`.
|
|
Retain one searching watch per session/repository and one watch per discovered PR.
|
|
|
|
## Lifecycle persistence
|
|
|
|
Watches cannot cover every task PR because sessions can disappear and users can link PRs by URL.
|
|
Keep the orphan sweep in `service_pr_unwatched.go`.
|
|
It reconciles unwatched `github_task_prs` rows and writes lifecycle fields,
|
|
the current `head_sha`, and stored `workflow_attention` when already present.
|
|
Exclude terminal and detached rows to bound the sweep.
|
|
Actions workflow reads belong to watched sync and feedback paths; the orphan
|
|
sweep does not collect new workflow evidence. Check and review aggregates belong
|
|
to the watch-driven path that fetches their evidence.
|
|
The REST PR response alone cannot supply those aggregates.
|
|
|
|
The backend is the only writer of `github_task_prs`.
|
|
The feedback read persists through `SyncTaskPR` in `service_pr_feedback_sync.go`.
|
|
Its `github.task_pr.updated` event updates every frontend surface.
|
|
Do not patch lifecycle fields only in a frontend store copy.
|
|
|
|
Keep both derivations on `newPRStatus`.
|
|
Persist inside the TTL cache's fetch closure so a cache hit causes no write.
|
|
Log persistence failures without failing the feedback read.
|
|
Use workspace-scoped `ListTaskPRsByPRNumber` to match the authorized credential scope.
|
|
|
|
`resolveTerminalMergeState` prevents a merged PR from leaving `merged`.
|
|
Do not extend this rule to `closed`: GitHub permits `closed -> open`.
|
|
|
|
## Batched lookup budget
|
|
|
|
An alias with zero nodes definitively means no open PR on that branch.
|
|
Carry this result through `branchBatchResult.ResolvedEmpty` to `applyBatchedSearchingWatch`.
|
|
Do not repeat that lookup with `client.FindPRByBranch`.
|
|
|
|
After a definitive negative result, only the unqueried fork parent needs another lookup.
|
|
Cache fork identity with `forkParentRepositoryForLookup` per credential scope, owner, and repository.
|
|
Two or more open PRs are ambiguous, not a definitive negative result.
|
|
For ambiguity or an unresolved alias, retain the full fork-network fallback.
|
|
Throttle this production batched path with `last_checked_at` and `PRSyncFreshnessWindow`, as `triggerPRDetection` does.
|
|
|
|
For lookup changes, run `service_pr_watch_batched_budget_test.go` coverage.
|
|
Retain call-count assertions: a correct final `PRStatus` cannot detect duplicate API requests.
|