Files
orca/tests
da8d128db4 feat(github): PR auto-refresh cadence setting to cap background PR/checks polling (STA-8667) (#40541)
* feat(github): add a PR auto-refresh cadence setting that caps background PR/checks polling (STA-8667)

Timed PR, review and checks refreshes were hardcoded (1/2 min visible,
15 min no-review), with no way to slow them on a busy headless `orca serve`
or a shared GitHub Enterprise Server.

Adds `prAutoRefresh: default | reduced | minimal | off` (5x / 10x / no timed
refresh). Selecting a workspace, pushing, returning to the window and manual
refresh still read at once in every mode.

- shared policy scales every timed interval from one process-wide cadence,
  set from settings in main (desktop and serve) and in the renderer
- main re-plans queued visible follow-ups when the cadence changes
- a paired server's cadence also caps clients' timed `github.prForBranch`
  reads (reuses the last answer for the same head) and stretches the hosted
  review branch cache TTLs, so more clients add no GitHub calls
- CI-line watches slow to the minimal cadence instead of stopping when off
- Settings > Git & Source Control gains a host-aware PR Auto-Refresh control

* feat(github): make the PR Auto-Refresh control say how often it checks and whose host it changes (STA-8667)

UX round UX-I1: the hint under the segmented control states the actual
cadence for the selection, derived from the shared policy, and when a paired
server is the Settings host the control says it applies to that host and every
connected client. Adds a presentational PRAutoRefreshControl with fixtures and
a component test.

* fix(github): make the PR auto-refresh cadence per execution host and close the C1 polling gaps (STA-8667)

Review round C1 on #40541 found seven places where the new cadence did not
hold. This settles the contract as one cadence per execution host and fixes
each gap with a regression test:

- The renderer schedules each workspace by the cadence of the host that runs
  its GitHub reads: its own setting for local work, the paired host's setting
  (read on contact, on settingsChanged and from the Settings control) for that
  host's workspaces. A local Off no longer stops a remote Default and the
  reverse. Policy, timers and the checks panel re-plan on any cadence change.
- github.prForBranch and github.prChecks: a paired client's timer reads carry
  reason swr/visible and the host answers them from its last read at its
  cadence; window return, screen open, manual refresh and changed-state reads
  carry foreground/noCache and always reach the provider. Mobile sends the
  same intent for its own timer.
- Off stops ordinary failure retries (main coordinator, renderer scheduler,
  checks detail policy); CI-line watches keep retrying at Minimal.
- Earlier-head CI watches follow the same watch cadence as the current head.
- The paced PR cache identity includes acceptMergedFallbackPR.

* fix(github): close the C2 PR auto-refresh gaps: checks cache freshness and scope, retry and settings-sync races, focus return under Off, mobile foreground reads (STA-8667)

- github.prChecks: every successful full read (timed, foreground, manual, noCache) is recorded as the host's last answer with start-order protection, so a later timed client never gets an older result back; the paced key now carries the execution scope, review generation and resolved gh read scope like the provider read itself.
- Renderer visible scheduler: a retry armed after a failure is dropped when the owning host's cadence becomes Off and re-timed when it is stretched, instead of firing once under the old cadence.
- Remote host cadence sync: a settingsChanged (or regained contact) during an in-flight settings.get marks it dirty and triggers one trailing read; a slow answer never reverts a value the Settings control wrote or re-adds an unpaired host.
- Checks panel: a focus-only window return (document never hidden) reads once under Off with the usual cooldown and in-flight guards, unless the checks are settled.
- Settings: the remote PR Auto-Refresh control shows the one shared, subscribed copy of the host's setting, so another client's change is reflected while mounted and the displayed option can be chosen back.
- Mobile: a branch read right after the app comes to the foreground is sent as foreground and bypasses the host's 30 s reuse of its own desktop lookup.

Each new test fails without its fix.

* fix(github): close the C3 PR auto-refresh gaps: queued main error retries on cadence change, window return under Reduced/Minimal, older paired host fallback (STA-8667)

* perf(github): share and pace timed pull request reads on the host

Reuse exact completed results for automatic refreshes, back off unchanged
settled pull requests, and route server revalidation through the existing
host budget while preserving foreground reads and older clients.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): preserve shared producer settlement and selected demand

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): cover paired receipt retries and watch fairness

* test(github): explain shared fake-clock fixture

* test(github): typecheck host and renderer integration together

* test(github): name exported fixture mock types

* Revert "test(github): typecheck host and renderer integration together"

This reverts commit 756a38787c.

* test(github): place host and renderer loops in cross-layer suite

* fix(github): say what the PR auto-refresh setting actually limits (STA-8667)

The Off hint now says CI checks a chat follows are still read at the Minimal
interval, the interval hint no longer promises a one-minute read for settled
pull requests, and the description no longer claims a cap on every client:
clients on older Orca versions keep their Default timer, and returning to the
window reads data older than its Default interval.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): close the auto-refresh review gaps (STA-8667)

- A window return or re-shown row that is due under the Default interval now
  reads past the stretched timed cache instead of being answered from it.
- Turning auto-refresh Off also retires a host revalidation that was waiting
  for quota, so it never starts or requeues afterwards.
- A newer manual checks answer stays authoritative while an older read of the
  same checks is still out, even when 256 other checks fill the cache.
- A paired host keeps no auto-refresh state after it is forgotten; a read from
  before unpairing never answers for it, and a re-paired host is read afresh.
- A host's cadence change re-plans only the visible rows that host runs, and
  this app's own setting re-plans its rows in main instead of re-reporting.
- Settled rows wait at least a minute on return under a stretched cadence;
  Default keeps its cooldown.
- The setting's copy no longer promises a read on selecting a workspace.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): preserve refresh policy and shared callers

Use the same validated freshness for cached queue reads and their follow-up. Keep forced mergeability rereads and detach cancelled consumers independently from the shared lookup.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): give checks, host reads and cadence replans their actual owners (STA-8667)

- Checks: the running read of a resource, not the cache, decides which answer
  is current. A manual answer that finishes while an older read of the same
  checks still runs is handed to that read, which answers with it and never
  publishes its own; a read replaced as stale answers with its replacement.
  The completed cache is held to 256 answers at all times.
- A cadence change on one paired host re-plans only that host's visible
  targets from their own Default interval, without rebuilding any rows.
- Off no longer re-queues a failed row at its gate when the cadence is
  retimed; Off back to Default still resumes timed reads and error retries.
- Tests cover a full cache of rows being read again, mixed-host replans and
  the full life of a forgotten host's read, including a failing one.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): let a replaced checks read answer only with its successor (STA-8667)

Overlapping reads of one PR head share the newest accepted answer while any of
them runs. A read replaced as stale or by a user refresh publishes nothing and
answers its callers with that newer answer, even after it was evicted from the
completed cache, or with its successor still running; its own result is used
only when no newer answer exists, and its error only when there is no answer.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): preserve refresh policy and shared callers

Use the same validated freshness for cached queue reads and their follow-up. Keep forced mergeability rereads and detach cancelled consumers independently from the shared lookup.

Carried from fc3b99db2a (#42033).

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): keep queued PR reads on their own job and validated freshness (STA-8667)

- A host revalidation retired by Off while it awaited quota, then replaced by
  a new read of the same PR, can no longer start, delete or requeue over that
  new read; the quota pause it learned still holds the key for the new read.
- A queued local read decides whether its cached answer is fresh with the same
  validated interval that schedules its follow-up; a foreground return is
  judged by the Default interval that made it due, and later follow-ups go back
  to the cadence (none under Off).

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): keep overlap authority, foreground reads and failure retries owned (STA-8667)

- Checks: overlapping reads of one PR head share one record kept until the last
  of them settles, so a read replaced by a user refresh that has already ended
  still answers with a newer manual answer after it was evicted, rechecked after
  waiting on its successor.
- A row shown again after its settled age reads instead of being answered by a
  cached settled result; one foreground age decides both whether the return
  earns a read and whether the current cached answer satisfies it.
- Off back to Default restores a failed row's own retry from its failure, still
  an error retry the next Off retires, without a new report or manual action.
- Test fixes: advance the replaced job's start cooldown, run the checks reads
  without command-slot limits, typed fixtures and clock-rule notes.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): refresh settled rows when exposed again

Use the same finite foreground age to admit and consume the queued read. A recent exact result can still satisfy it, and settled rows do not acquire a recurring timer.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): keep the real command slots in the checks capacity proof (STA-8667)

The all-live case now runs through the real four-slot command limiter: 256
rereads are live while four gh commands run, the new manual read waits its
turn and then reads, and cleanup settles every queued read through its slot.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): keep a failure's retry and a restored follow-up automatic (STA-8667)

- Each exact PR read now has one resource record (its timed and fresh probes,
  the provider reads running for it and the newest start). A failed full read
  claims that record for the retry it owes even when the exact cache had no
  room to keep the outcome, so the retry keeps its original failure time and
  count, Off retires it, and Default restores it as a retry. A newer read of the
  same request, a scope change or another HEAD ends the claim; a failure that a
  newer read had already replaced owes no retry.
- A row no longer shown releases its failure's claim; dropping an old gate
  index entry no longer forgets a visible row's failure.
- When timed cadence resumes, a row without a failure gets the automatic
  follow-up its interval gives it, still a follow-up, so the next Off retires
  it; one derivation decides creation, retiming and the check after a quota
  wait. A genuine return or action already queued keeps its own reason.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(mobile): run the PR timer as a client

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): plan automatic PR reads from the newest read and end them with their demand (STA-8667)

- A newer provider read of the same request starting retires a failure that
  is already settled: its queued retry and its claim go, while its count and
  rate gate stay. The retry check before a start, including after a quota
  wait, re-validates that the failure still owns the request and row.
- A full read whose caller brings no settlement of its own (another client's
  read, a host job, a provider lookup) plans the visible row's next automatic
  work, as the row's own read would. A late failure that a newer read
  replaced owes no retry and leaves the newer read's plan in place.
- A routine report of a row still shown as the same request keeps its
  automatic work automatic. Only a return, a new row or another request
  earns a read the cadence does not give.
- After a quota wait an automatic read takes its current plan: retired,
  later (it waits for the plan and the learned pause, without displacing
  work queued since) or ready.
- Visibility ends a row's demand where it is removed: a report that drops
  it, a window cleared or pruned once its renderer is gone, a removed
  workspace. Only the affected window's rows are checked, so a report no
  longer walks every window's rows.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): accept only current PR read completions

Keep shared publication and retry planning on the accepted actual read. Preserve legacy own replies, terminal loading and ordinary work after a superseded lookup, and honor the accepted error gate before automatic recovery.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): follow moved request contracts

* fix(github): keep PR refresh delivery and demand current

Use the accepted provider completion for publication and retry planning. Recheck live demand before automatic starts, preserve user actions under Off, and keep the current failure schedule after interval changes.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): explain the partial event fixture type assertion

* fix(github): resolve a PR read's scope once per demand decision

An admission decision now resolves the request's current scope once and compares each window's
row in it through the same exact-key definition, instead of resolving the project account for
the captured request and again for every compared alias. A row with other repository or
execution inputs is still another request; the decision after preparation still checks the
prepared read's own scope.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(github): preserve queued deadlines and detachable PR waits

* fix(github): compare refresh wakes on the elapsed clock

* test(github): format queued refresh deadline cases

* fix(github): charge actual producers and fence retry gates

* fix(github): preserve fresh intent and producer error policy

* fix(github): retain owned cold-read retry gates

* fix(github): refresh checks after a delayed background return

Keep one qualified foreground return after a delayed automatic read, preserve GitLab background guards, and use the existing fresh fetch path when the panel returns.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* Keep retimed PR retry gates on their current request

* Remove unused PR admission adapter restored by main merge

* Clarify watch plan types and fake-clock regression fixtures

* Align PR refresh fixtures with current read ownership and elapsed time

* fix: retain shown pull request aliases through admission

* fix: preserve new pull request row exposure with timers off

* test: match fake clock exceptions to TSX lint rules

* test: explain deliberate fake timer fixture waits

* test: align PR revisit recording and remove duplicate fixture

* test: honor default freshness in Off exposure proof

* refactor(mobile): simplify PR read intent branches

* fix(github): preserve alias actions and foreground refresh intent

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): release obsolete failures before queued restoration

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): retain provider retry holds on foreground return

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): keep both quota aliases visibly demanded

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(github): use fixed intervals for provider hold proof

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test: align PR refresh mocks with existing request types

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* perf(github): compare PR demand without rediscovering account ownership

Keep live scope fences on prepared reads and compare captured request inputs for demand. Tighten the existing fleet contract, keep narrow settings panels readable, and follow the moved mobile polling owner.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* fix(github): retain project account authority in shared PR demand

Treat explicit and implicit bindings alike for a known project, and retire that equivalence when project ownership changes. Preserve unknown-account separation without restoring inventory scans. Use the existing muted icon button variant for PR Updates.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

* test(settings): mount PR Updates with its tooltip provider

Keep the late-response ordering regression focused on host state and option selection, without assertions on UI copy.

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-14 14:10:09 -08:00
..