Problem
A C-R1 PR sweep can enqueue ~1,300 refreshes in one batch; each refresh requests PR metadata, files, and check runs without consistently threading stored ETags, so bursts consume full budget with little 304 reuse (check-runs, PR metadata, and PR files were the next-largest 403 categories after CODEOWNERS in the 2026-08-04 incident). Separately, diagnosing the incident required sampling 403s because the budget gate exports no per-endpoint consumption attribution.
Proposed behavior
- Thread persisted ETags (C-C5 already stores them) as
If-None-Match on the REST refresh paths that lack them; verify 304 reuse via the existing C-B4 metrics.
- Stagger sweep refresh deadlines across the C-R1 bound (deadline jitter within the staleness plan) instead of a single thundering-herd batch.
- Budget gate exports a per-request counter labeled by auth context, endpoint family, and outcome (200/304/403), giving minutes-not-hours incident attribution.
Acceptance criteria
- Repeat sweeps over an unchanged repo show a measurably dominant 304 share on refresh REST calls (loadgen/fake assertion).
- Sweep enqueues spread deadlines across the plan bound; the C-R1 staleness guarantee is unchanged (existing bound tests keep passing).
- The new attribution metric appears in ops/DASHBOARD.md and has collector test coverage.
Observed on v0.3.3.
Problem
A C-R1 PR sweep can enqueue ~1,300 refreshes in one batch; each refresh requests PR metadata, files, and check runs without consistently threading stored ETags, so bursts consume full budget with little 304 reuse (check-runs, PR metadata, and PR files were the next-largest 403 categories after CODEOWNERS in the 2026-08-04 incident). Separately, diagnosing the incident required sampling 403s because the budget gate exports no per-endpoint consumption attribution.
Proposed behavior
If-None-Matchon the REST refresh paths that lack them; verify 304 reuse via the existing C-B4 metrics.Acceptance criteria
Observed on v0.3.3.