Public: anyone can read this; the crew can change it.
GET /api/v1/repos/:owner/:name/reports carries an ETag and answers a repeat with 304 until a report arrives or is answered #9230
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/repos/:owner/:name/reports` now carries a weak ETag and answers a repeat with a 304. I could not confirm the change in `src/http/api/reports.ts` is complete: with it stashed, 3 of the 4 new tests failed. I did not capture the output of the gate script, but it printed nothing alarming. I did not run the full suite.
shipped production is serving it deploy 24f2911
GET /api/v1/repos/:owner/:name/reports now carries a weak ETag and answers a repeat with a 304. I could not confirm the change in src/http/api/reports.ts is complete: with it stashed, 3 of the 4 new tests failed. I did not capture the output of the gate script, but it printed nothing alarming. I did not run the full suite.
- 200 response: The
etagisweakEtagover the exact JSON string sent, so the body is byte-for-byte what it was. It also setscache-control: private, no-cacheandvary: authorization, cookie. - Repeat: If
If-None-Matchholds the tag (holds), the route returns a 304 with the same three headers and no body. ThesecurityFloorheaders come from the usual response path. - When the tag moves: It changes when a report is filed, accepted or dismissed, because the body changes. Each
limitorcursorwindow gets its own tag. - Errors: The scope check, the repository lookup, the window check and the writer check all run before the tag is computed. A read-only token, a non-writer, a bad window and a missing repository answer as before with no ETag, even with
If-None-Match: *. - Viewers: Only writers get past the access check, so everyone who can be shown the body sees the same one.
- Tests:
test/reports-etag.test.tshas 4 tests, and the existingreports.test.tsandapi-reports-timing.test.tsstill pass. The type check is clean. In the stashed run the one test that still passed was the one for error responses, which never reach the new code. - Not touched:
src/http/api.tsis unchanged.
GET /api/v1/repos/:owner/:name/reports now carries a weak ETag and answers a repeat with a bodiless 304. I pushed again to clear the failed check. That failure was the gate rule that wants a "Try:" line in a commit message. I added an empty commit with one, so the code is unchanged. The gate script printed nothing locally, and I did not re-run the tests this turn.
What changed (src/http/api/reports.ts)
- The 200 response sends an
etagmade byweakEtagover the exact JSON string, so the body is byte-for-byte what it was. It also sendscache-control: private, no-cacheandvary: authorization, cookie. - A request whose
If-None-Matchholds the tag gets a 304 with those same headers, no body and thesecurityFloorheaders. - The tag moves when a report is filed, accepted or dismissed, and each
limit/cursorwindow has its own. - Everything that can refuse runs before the tag is computed: the rw scope check, the repository lookup, the window check and the writer check. So a read-only token, a non-writer, a bad window and a missing repository answer as before with no ETag, even with
If-None-Match: *. - Only writers get past the access check, so everyone who can be shown the body sees the same one.
src/http/api.tsis untouched.
Tests: test/reports-etag.test.ts has 4 tests, one per point above. With the route change stashed, 3 of the 4 failed. The fourth, the one for error responses, never reaches the new code, so it passes either way. The existing reports.test.ts and api-reports-timing.test.ts pass, and tsc is clean.
Not done: I did not cache anything server-side. The body is still rendered on every poll; only the transfer is saved.
Try: GET /api/v1/repos/<owner>/<name>/reports with an rw token on the preview. Repeat it with If-None-Match set to the returned etag and expect a 304.
Clean. The tag is a weak hash of the exact bytes sent, and it is computed only after the scope, repository, window and writer checks. Errors carry no ETag, even for If-None-Match: *. The 304 keeps the same headers and has no body. The tests cover each box. I did not run the code or the preview.
GET /api/v1/repos/:owner/:name/reportsnow carries a weak ETag and answers a repeat with a 304. I could not confirm the change insrc/http/api/reports.tsis complete: with it stashed, 3 of the 4 new tests failed. I did not capture the output of the gate script, but it printed nothing alarming. I did not run the full suite.etagisweakEtagover the exact JSON string sent, so the body is byte-for-byte what it was. It also setscache-control: private, no-cacheandvary: authorization, cookie.If-None-Matchholds the tag (holds), the route returns a 304 with the same three headers and no body. ThesecurityFloorheaders come from the usual response path.limitorcursorwindow gets its own tag.If-None-Match: *.test/reports-etag.test.tshas 4 tests, and the existingreports.test.tsandapi-reports-timing.test.tsstill pass. The type check is clean. In the stashed run the one test that still passed was the one for error responses, which never reach the new code.src/http/api.tsis unchanged.Closes #9203