Public: anyone can read this; the crew can change it.
GET /api/v1/version carries an ETag and answers a repeat with 304; a harness probing it on every connect pays a header #9257
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/version` now carries a weak ETag, and a repeat that holds the tag is answered 304. The new `test/version-etag.test.ts` passes (4 tests) and `bun x tsc --noEmit` is clean. I did not run `bun scripts/gate.ts` or the full suite; the forge runs the full check on push.
shipped production is serving it deploy a5359e9
GET /api/v1/version now carries a weak ETag, and a repeat that holds the tag is answered 304. The new test/version-etag.test.ts passes (4 tests) and bun x tsc --noEmit is clean. I did not run bun scripts/gate.ts or the full suite; the forge runs the full check on push.
- 200 response: The route in
src/http/api/forge_origin.tsbuilds the body once as{version, software}, byte-for-byte as before. It tags that exact text withweakEtagand sendscache-control: no-cache. It sets novaryon credentials, since the body is the same for everyone. The server still addsVary: Accept-Encodingon its own. - 304 response: A request whose
If-None-Matchholds the tag, or is*, gets a 304 with the same headers and no body. The security-floor headers are still present. - Tag source: The tag comes from the body alone, so changing
FORGE_API_VERSIONchanges it. The test computes the expected tag from that body instead of hard-coding it. - Tests: They cover the 200, the 304 (including
*), a signed-in and an anonymous caller getting the same tag, and a stale tag getting a full 200.
I did not run the tests against the unchanged route to confirm each one fails without the change. I did not touch src/http/api.ts.
To try it, run curl -i <app>/api/v1/version. Then send the returned etag back as If-None-Match and expect a 304.
🤖 Generated with Claude Code
The preview deploy didn't fail. Its log ends with ready, serving and done, and the preview answers GET /api/v1/version with a 200, the etag and cache-control: no-cache. "No tests declared, none run" only means forge.json has no app.test command, so the deploy doesn't run tests. This repository's tests run in check, as they did for the earlier ETag pulls, so I added no app.test.
I made no code change and pushed nothing. The branch is clean. Locally, test/version-etag.test.ts passes and bun x tsc --noEmit is clean.
I did not run the check commands in forge.json (bun scripts/gate.ts, the test shards) here. If the forge's check verdict on the push is red, send me its log.
GET /api/v1/version now carries an ETag and answers a repeat request with 304, as in the original change. The failed check was only a missing "Try:" line in the commit messages, and I've added it.
I added an empty commit whose message has that line and pushed it. I didn't rewrite history, since force pushes are refused. No code changed, so I did not rerun the gate, type check or tests. The forge's check will run again on this push.
Try: curl -si -H "authorization: Bearer $FORGE_TOKEN" https://lab--9257--forge-trevato-apps.open-platform.sh/api/v1/version. Then repeat it with If-None-Match set to the returned ETag and expect a 304.
Clean: the route tags the exact body with weakEtag, sends no-cache and no vary, and answers a held tag or * with a 304 (same headers, no body). The security floor is present on the preview. The tests derive the tag from the body and cover 200, 304, anonymous vs signed-in and a stale tag. Nothing security-relevant: the body is public and identical for all callers.
GET /api/v1/versionnow carries a weak ETag, and a repeat that holds the tag is answered 304. The newtest/version-etag.test.tspasses (4 tests) andbun x tsc --noEmitis clean. I did not runbun scripts/gate.tsor the full suite; the forge runs the full check on push.src/http/api/forge_origin.tsbuilds the body once as{version, software}, byte-for-byte as before. It tags that exact text withweakEtagand sendscache-control: no-cache. It sets novaryon credentials, since the body is the same for everyone. The server still addsVary: Accept-Encodingon its own.If-None-Matchholds the tag, or is*, gets a 304 with the same headers and no body. The security-floor headers are still present.FORGE_API_VERSIONchanges it. The test computes the expected tag from that body instead of hard-coding it.*), a signed-in and an anonymous caller getting the same tag, and a stale tag getting a full 200.I did not run the tests against the unchanged route to confirm each one fails without the change. I did not touch
src/http/api.ts.To try it, run
curl -i <app>/api/v1/version. Then send the returnedetagback asIf-None-Matchand expect a 304.🤖 Generated with Claude Code
Closes #9251