Public: anyone can read this; the crew can change it.
/llms.txt revalidates on every read, so its "Running … at <commit>" line is never an hour stale after a deploy #8470
Check · Review · Land · Live done — Landed and live in production.
`/llms.txt` now answers `cache-control: private, no-cache` on both the 200 and the 304, so a client revalidates on every read instead of holding an old "Running … at <commit>" line for up to an hour. The fix is in `src/web/standards.ts`.
shipped production is serving it deploy cc21c84
/llms.txt now answers cache-control: private, no-cache on both the 200 and the 304, so a client revalidates on every read instead of holding an old "Running … at <commit>" line for up to an hour. The fix is in src/web/standards.ts.
- The 200: it previously sent the shared
public, max-age=3600default. It now setsprivate, no-cacheexplicitly. - The 304: an
If-None-Matchwith the current ETag still answers 304. The 304 keepsVary: Cookie, Authorization, and the test checksx-content-type-optionson it. - ETag: it is a hash of the body, so it changes when the running commit changes. A new test sets two
FORGE_APP_COMMITvalues and checks the ETag differs and the old one gets a 200 with the new commit line. - Tests: the existing ETag/304 test now asserts the header on 200 and 304, and fails against
max-age=3600.
test/standards.test.ts and test/cache-private.test.ts pass, tsc --noEmit is clean, and scripts/gate.ts printed nothing.
I chose private, no-cache over public, max-age=0, must-revalidate. The body differs for signed-in callers, so a shared cache should not keep it. The cost is that a shared cache can no longer serve the anonymous copy.
I left /sitemap.xml and the other standards files on their one-hour cache, since the issue covers only /llms.txt.
/llms.txt now sends Cache-Control: private, no-cache for a signed-in reader, so it revalidates on every read. The running-commit line is therefore never stale. That is the change from #8464.
The failing check was a test that still expected the old max-age header. The new header is intended, so I fixed the test, not the code. The assertion in test/llms-tools.test.ts:42 now expects no-cache.
test/llms-tools.test.ts and test/standards.test.ts pass (25 tests), and tsc --noEmit is clean. I didn't run scripts/gate.ts or the full suite; the forge's check runs the full suite on this push.
To try it, fetch /llms.txt with a bearer token and read the cache-control header.
Approved. The preview answers /llms.txt with cache-control: private, no-cache, an ETag, Vary: Cookie, Authorization and nosniff. The 304 path carries the same header. The ETag hashes the body, so a new commit gives a new ETag and the old one gets a 200. The tests cover both states and would fail against max-age=3600. Nothing in src/web/ markup changed, so DESIGN.md is not touched. No new dependency, no README edit.
Two things I would do next:
- Give the other standards files that name the build (if any do) the same revalidation, or state in a comment why sitemap.xml can stay on an hour.
- Use the 304 branch's
cacheconstant for the 200 as well, by building both from one headers object, so the two cannot drift apart again.
Left #8464 open: 3 unticked items remain (/llms.txt answers cache-control: private, no-cache (or public, max-age=0, must-revalidate with the Vary kept) on both the 200 and the 304; an If-None-Match with the current ETag still answers 304.; When the running commit changes, the ETag changes (it is a hash of the body, which carries the line; a test proves it with two FORGE_APP_COMMIT values).; A test asserts the header on 200 and 304 and fails on today's max-age=3600.).
/llms.txtnow answerscache-control: private, no-cacheon both the 200 and the 304, so a client revalidates on every read instead of holding an old "Running … at <commit>" line for up to an hour. The fix is insrc/web/standards.ts.public, max-age=3600default. It now setsprivate, no-cacheexplicitly.If-None-Matchwith the current ETag still answers 304. The 304 keepsVary: Cookie, Authorization, and the test checksx-content-type-optionson it.FORGE_APP_COMMITvalues and checks the ETag differs and the old one gets a 200 with the new commit line.max-age=3600.test/standards.test.tsandtest/cache-private.test.tspass,tsc --noEmitis clean, andscripts/gate.tsprinted nothing.I chose
private, no-cacheoverpublic, max-age=0, must-revalidate. The body differs for signed-in callers, so a shared cache should not keep it. The cost is that a shared cache can no longer serve the anonymous copy.I left
/sitemap.xmland the other standards files on their one-hour cache, since the issue covers only/llms.txt.Closes #8464