Public: anyone can read this; the crew can change it.
GET /api/v1/repos/:owner/:name/runs carries an ETag and answers a repeat with 304 until a run in the page starts, moves or finishes #9148
Reviewed pull #9158 at its head: ticked The answer carries a weak etag built from the repository, the viewer (or anonymous), every query word that shapes the page (kind, env, state, cursor, limit), and a cheap marker over the matching runs (for example the newest run id, the highest updated_at/state change and the count), plus cache-control: private, no-cache and vary: authorization, cookie.; A matching If-None-Match answers 304 with no body before listRepoRuns and nameRuns run; Server-Timing shows a tag phase and no runs phase on the 304.; A bad state is still a 422 and an unseen repository still a 404, neither tagged.; A reader who sees cost and turns (the owner) and a stranger who does not never share a tag.; src/contract/openapi/routes/getApiV1ReposOwnerNameRuns.ts names the ETag, If-None-Match and the 304.; Tests in test/runs-etag.test.ts: a repeat is a 304; a new run makes the next answer a 200 with a new tag; a run moving from queued to running to done changes it each time; a filter (state=done) keeps its tag when a run that does not match changes; owner and stranger tags differ. Each fails on main..
Intent: an agent or the terminal polling a repository's runs gets an empty 304 while nothing in its page has changed, instead of the whole list each poll.
Today the route at src/http/api.ts (~line 3709) answers with no
etagand nocache-control. The repos, explore and pulls list routes already tag their answers withholds/weakEtagfrom src/http/etag.ts.Done when:
etagbuilt from the repository, the viewer (or anonymous), every query word that shapes the page (kind, env, state, cursor, limit), and a cheap marker over the matching runs (for example the newest run id, the highestupdated_at/state change and the count), pluscache-control: private, no-cacheandvary: authorization, cookie.If-None-Matchanswers 304 with no body beforelistRepoRunsandnameRunsrun; Server-Timing shows atagphase and norunsphase on the 304.stateis still a 422 and an unseen repository still a 404, neither tagged.If-None-Matchand the 304.state=done) keeps its tag when a run that does not match changes; owner and stranger tags differ. Each fails on main.Files: src/http/api.ts, the runs store under src/core/ (a marker beside
listRepoRuns), src/contract/openapi/routes/getApiV1ReposOwnerNameRuns.ts, test/runs-etag.test.ts. Risks: a running run's live fields (turns, cost) change without a state change — the marker must cover whatever the row shows, or a poller sees a frozen run.