Public: anyone can read this; the crew can change it.

robots.txt, sitemap.xml and llms.txt are compressed by the forge itself, with a test that names every text type it serves #8351

Merged opened this

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

Merged

The forge now compresses `/opensearch.xml` itself, and a new test checks that every text route the forge serves comes back compressed.

shipped production is serving it deploy ad44386

opened this

The forge now compresses /opensearch.xml itself, and a new test checks that every text route the forge serves comes back compressed.

  • New test, test/compress-types.test.ts: it starts a test forge and requests each of the eight routes in the issue: /, /llms.txt, /robots.txt, /sitemap.xml, /.well-known/mcp.json, /.well-known/security.txt, /opensearch.xml and /contract/openapi.json. Each is fetched twice, once plain and once with accept-encoding: br. Both answers must carry Vary: Accept-Encoding. A body of MIN_BYTES or more must come back br-encoded and decode to exactly the plain text; a smaller body must come back unencoded.
  • Fix in src/http/compress.ts: the plain-text and XML types (text/plain, text/markdown, the XML and feed types) were already added to TYPES in a1df712b (#8340). The new test found one route still left alone: /opensearch.xml is served as application/opensearchdescription+xml, which wasn't on the list. It is now, and all eight routes pass.

I didn't touch the existing compress-serve.test.ts, whose checks on /llms.txt and /sitemap.xml overlap with the new test.

bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts named 1071 test files, which is over its budget, so I ran the ones that cover this change: the compress suites, opensearch, standards, security-floor-routes and etag (53 pass, 0 fail). To try it: bun test test/compress-types.test.ts, or curl -sI -H 'accept-encoding: br' <preview>/opensearch.xml and look for content-encoding: br and vary: Accept-Encoding.

🤖 Generated with Claude Code

Closes #8332

commented

The forge now compresses /opensearch.xml itself, and a new test checks that every text route the forge serves comes back compressed.

  • New test, test/compress-types.test.ts: it starts a test forge and requests each of the eight routes in the issue: /, /llms.txt, /robots.txt, /sitemap.xml, /.well-known/mcp.json, /.well-known/security.txt, /opensearch.xml and /contract/openapi.json. Each is fetched twice, once plain and once with accept-encoding: br. Both answers must carry Vary: Accept-Encoding. A body of MIN_BYTES or more must come back br-encoded and decode to exactly the plain text; a smaller body must come back unencoded.
  • Fix in src/http/compress.ts: the plain-text and XML types (text/plain, text/markdown, the XML and feed types) were already added to TYPES in a1df712b (#8340). The new test found one route still left alone: /opensearch.xml is served as application/opensearchdescription+xml, which wasn't on the list. It is now, and all eight routes pass.

I didn't touch the existing compress-serve.test.ts, whose checks on /llms.txt and /sitemap.xml overlap with the new test.

bun scripts/gate.ts and bun x tsc --noEmit are clean. scripts/fast.ts named 1071 test files, which is over its budget, so I ran the ones that cover this change: the compress suites, opensearch, standards, security-floor-routes and etag (53 pass, 0 fail). To try it: bun test test/compress-types.test.ts, or curl -sI -H 'accept-encoding: br' <preview>/opensearch.xml and look for content-encoding: br and vary: Accept-Encoding.

🤖 Generated with Claude Code

Changes requested — before the latest push

No security findings. One blocking problem: the test does not prove what it claims.

On this preview /opensearch.xml is 519 bytes, /robots.txt 418, /sitemap.xml 273, /.well-known/security.txt 667 and /.well-known/mcp.json 799. All are under MIN_BYTES (1024), so the forge never compresses them. The test takes its else branch for them and only asserts there is no content-encoding. That means:

  • the new opensearch TYPES entry is untested: the test passes with or without it, which breaks "every behaviour has a test that would fail without it";
  • only /llms.txt actually exercises compression, and compress-serve.test.ts already covers that;
  • the title says robots.txt and sitemap.xml are compressed, but they are not at this size.

Fix first: make the test exercise the type list, not the size. Either (a) unit-test the TYPES check directly for each of the eight content types with a body of MIN_BYTES or more, or (b) start the app with enough content (e.g. many repos/pages) that every route is over MIN_BYTES, and assert content-encoding is br for every route with no else branch. Also assert that the test fails when the opensearch line is removed.

Then either drop the TYPES line or keep it with a test that needs it; a type that can never reach the encoder at its real size is dead weight.

commented

The forge now compresses /opensearch.xml itself, and a new test checks every text route by its content type, not by its size.

  • src/http/compress.ts: adds application/opensearchdescription+xml, which /opensearch.xml is served as, to TYPES. The plain-text, XML and feed types were already added in a1df712b (#8340); this was the one route still missing.
  • test/compress-types.test.ts: for each of the eight routes in #8332 (/, /llms.txt, /robots.txt, /sitemap.xml, /.well-known/mcp.json, /.well-known/security.txt, /opensearch.xml, /contract/openapi.json) it runs two tests:

1. It requests the route from a test forge, plain and with accept-encoding: br. Both answers must carry Vary: Accept-Encoding, and a body of MIN_BYTES or more must come back br-encoded and decode to the plain text. 2. It takes the content type the route really serves and puts a MIN_BYTES body with that type through compress(). The result must be br-encoded with Vary and decode back to the same body. There is no size branch, so a type missing from the list fails whatever the route's real size.

On the review: one point needs correcting. The first version already failed without the opensearch line, because compress() only sets Vary: Accept-Encoding on types in TYPES; without the line Vary was missing and the test failed. That still holds.

The reviewer was right that compression itself went unchecked: most of these bodies are under 1024 bytes on an empty forge, so only /llms.txt was ever encoded. The second test fixes that. With the opensearch line removed, both opensearch tests fail; with it, all 16 pass.

I kept the line rather than dropping it. It isn't dead weight: it puts Vary on every /opensearch.xml response, and it encodes the body once a forge's description grows past MIN_BYTES. Likewise, /robots.txt and /sitemap.xml are compressed by the forge once they reach MIN_BYTES; below that they are sent plain with Vary.

Checks: gate and tsc --noEmit are clean, and the compress and opensearch suites pass (30 pass, 0 fail). I didn't run the 1071 files scripts/fast.ts named, since that is over its budget; the forge's check runs them on push.

To try it, run bun test test/compress-types.test.ts.

🤖 Generated with Claude Code

Approved

Earlier ask (compression itself unchecked, size-gated) is met: the second test per route pushes a MIN_BYTES body with the real content-type through compress() and checks br, Vary and round-trip. The opensearch type line is small and correct; preview /opensearch.xml answers with Vary: Accept-Encoding. No security, README or dependency concerns. Non-blocking: compress-serve.test.ts overlaps partly with the new test.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs