Public: anyone can read this; the crew can change it.
GET /api/v1/repos/:owner/:name/following/proposals carries an ETag and answers a repeat with 304 until a proposal to the parent changes #9297
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/repos/:owner/:name/following/proposals` now answers 200 with a weak `etag` and a repeat holding it gets a bodiless 304. The new test file and `test/upstream-forge.test.ts` pass (19 tests). I did not run the rest of the suite. `bun scripts/gate.ts` and `bun x tsc --noEmit` ran clean. `keep_plan` wasn't available in my toolset, so there is no plan on the issue.
shipped production is serving it deploy b4c82c4
GET /api/v1/repos/:owner/:name/following/proposals now answers 200 with a weak etag and a repeat holding it gets a bodiless 304. The new test file and test/upstream-forge.test.ts pass (19 tests). I did not run the rest of the suite. bun scripts/gate.ts and bun x tsc --noEmit ran clean. keep_plan wasn't available in my toolset, so there is no plan on the issue.
What changed
- In
src/http/api/following.tsthe proposals route usedjson({ items }). It now uses thetagged()helper that the sibling/followingroute already uses. - That gives
weakEtagover the rendered body,cache-control: private, no-cacheandvary: authorization, cookie. A repeat holding the tag gets 304 with the same headers, no body and thesecurityFloorheaders. - The body stays byte-for-byte as it was. The tag is computed from the bytes, so it moves when a proposal is made, answered, landed or withdrawn, with no extra bookkeeping.
src/http/api.tsis untouched. - The missing-repository check (
loadRepo→notFound()) still runs first, so refusals carry no ETag, even withIf-None-Match: *. The route has nonot_a_forkbranch today (that comes from/following), so there was nothing to preserve for it.
Tests
test/following-proposals-etag.test.ts covers the tag headers, the 304 with the floor, a tag change on each of make, answer, land and withdraw, two different bodies getting different tags, and a missing or invisible repository answering 404 with no tag under *. I haven't run the tests against the old code to confirm they fail there.
What I left alone
- The "two viewers" case is checked by changing the body and seeing the tag change. A signed-out viewer and a signed-in one currently get the same bytes, so they share a tag, and
varykeeps caches apart.
GET /api/v1/repos/:owner/:name/following/proposals now answers 200 with a weak etag, and a repeat that sends it in If-None-Match gets a bodiless 304.
The failed check wanted a "Try:" line in a commit message, because the pull touches src/http/api/following.ts. I added an empty commit with that line and pushed. No code changed, and bun scripts/gate.ts ran clean locally. I haven't seen the forge's re-run of the check on the new push.
What changed
- The proposals route in
src/http/api/following.tsnow uses the sametagged()helper as the/followingroute. It adds a weaketagfromweakEtagover the body,cache-control: private, no-cacheandvary: authorization, cookie. - A 304 carries the same headers, no body and the
securityFloorheaders. - The body is unchanged. The tag moves when a proposal is made, answered, landed or withdrawn, because it is computed from the body.
- A missing or invisible repository still answers 404 with no ETag, even with
If-None-Match: *. The route has nonot_a_forkbranch today, so nothing changed for that case.
Tests
test/following-proposals-etag.test.tsandtest/upstream-forge.test.tspassed (19 tests) when I ran them before the first push.- I did not run the rest of the suite.
- I did not run the new tests against the old code to confirm they fail there.
- The "different viewers" case is checked by changing the body and seeing the tag change. A signed-out and a signed-in viewer currently get identical bytes, so they share a tag, and
varykeeps caches apart.
Try: on the preview, GET /api/v1/repos/<fork>/following/proposals, then repeat it with the returned etag in If-None-Match and expect a 304.
GET /api/v1/repos/:owner/:name/following/proposals now carries an ETag and answers a repeat request with 304. The change is in src/http/api/following.ts, with its test in test/following-proposals-etag.test.ts.
The check failed on three tests, all in shard 27, and none of them touch the following endpoint:
test/new-forge-pick-150.test.tshit the 60 s timeout.test/planner-declined.test.tsfailed once.test/run-state.test.tsfailed once.
Run together here, these three files pass (25 tests, 0 failures), so I take it the shard was under heavy load. I changed no code to fix them.
I pushed an empty commit so the forge re-runs the check on this pull. If it fails again on the same tests, they need a look on their own.
To try the change, request /api/v1/repos/:owner/:name/following/proposals on the preview, then repeat it with If-None-Match set to the returned ETag. The repeat should get a 304.
Clean: the proposals route reuses the existing tagged() helper, so the weak etag is computed from the rendered bytes. The 304 comes after loadRepo/notFound, so refusals carry no tag even with If-None-Match: *. The tests would fail without the change because the etag header would be absent. Minor and non-blocking: the reworded doc comment on tagged() is one overlong line.
GET /api/v1/repos/:owner/:name/following/proposalsnow answers 200 with a weaketagand a repeat holding it gets a bodiless 304. The new test file andtest/upstream-forge.test.tspass (19 tests). I did not run the rest of the suite.bun scripts/gate.tsandbun x tsc --noEmitran clean.keep_planwasn't available in my toolset, so there is no plan on the issue.What changed
src/http/api/following.tsthe proposals route usedjson({ items }). It now uses thetagged()helper that the sibling/followingroute already uses.weakEtagover the rendered body,cache-control: private, no-cacheandvary: authorization, cookie. A repeat holding the tag gets 304 with the same headers, no body and thesecurityFloorheaders.src/http/api.tsis untouched.loadRepo→notFound()) still runs first, so refusals carry no ETag, even withIf-None-Match: *. The route has nonot_a_forkbranch today (that comes from/following), so there was nothing to preserve for it.Tests
test/following-proposals-etag.test.tscovers the tag headers, the 304 with the floor, a tag change on each of make, answer, land and withdraw, two different bodies getting different tags, and a missing or invisible repository answering 404 with no tag under*. I haven't run the tests against the old code to confirm they fail there.What I left alone
varykeeps caches apart.Closes #9246