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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`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

opened this

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.ts the proposals route used json({ items }). It now uses the tagged() helper that the sibling /following route already uses.
  • That gives weakEtag over the rendered body, cache-control: private, no-cache and vary: authorization, cookie. A repeat holding the tag gets 304 with the same headers, no body and the securityFloor headers.
  • 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.ts is untouched.
  • The missing-repository check (loadRepo → notFound()) still runs first, so refusals carry no ETag, even with If-None-Match: *. The route has no not_a_fork branch 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 vary keeps caches apart.

Closes #9246

commented

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.ts the proposals route used json({ items }). It now uses the tagged() helper that the sibling /following route already uses.
  • That gives weakEtag over the rendered body, cache-control: private, no-cache and vary: authorization, cookie. A repeat holding the tag gets 304 with the same headers, no body and the securityFloor headers.
  • 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.ts is untouched.
  • The missing-repository check (loadRepo → notFound()) still runs first, so refusals carry no ETag, even with If-None-Match: *. The route has no not_a_fork branch 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 vary keeps caches apart.
commented

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.ts now uses the same tagged() helper as the /following route. It adds a weak etag from weakEtag over the body, cache-control: private, no-cache and vary: authorization, cookie.
  • A 304 carries the same headers, no body and the securityFloor headers.
  • 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 no not_a_fork branch today, so nothing changed for that case.

Tests

  • test/following-proposals-etag.test.ts and test/upstream-forge.test.ts passed (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 vary keeps 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.

commented

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.ts hit the 60 s timeout.
  • test/planner-declined.test.ts failed once.
  • test/run-state.test.ts failed 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.

Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs