Two green PRs, two production gaps
fix/3687-frontmatter-and-vary. Both earlier PRs passed CI and both
were incomplete in production. The common cause is one habit: asserting the
layer we write instead of the byte a caller receives.
Why CI could not see either gap
| Gap | What the test asserted | What production served |
|---|---|---|
| frontmatter | withFrontmatter() plus 3 route handlers |
/developers.md renders on a 4th path, no block |
Vary |
a grep of next.config.mjs for the string |
string is in the config, absent from the response |
Both assertions were true. Neither was about what a client gets.
Gap 1: 5 of 7 surfaces had a header block measured live
| Surface | Renders via | Before | After |
|---|---|---|---|
/auth.md | standalone route | --- | --- |
/pricing.md | standalone route | --- | --- |
/api-policy.md | standalone route | --- | --- |
/index.md | api/md | --- | --- |
/docs/*.md | api/md | --- | --- |
/developers.md | page-markdown.ts | # OrchestKit by… | --- |
/yonyon.md | page-markdown.ts | # Yonyon: the… | --- |
Wrapped in pageMarkdown(), the choke point every twin passes
through, so a new slug cannot be added with a body and no header.
Gap 2: cache-key simulator pick a URL and what a cache stored first
One URL, two bodies. Whether a shared cache may reuse a stored response
depends on the Vary that response carried when it was stored.
Why the config value never arrives
Not a guess. Next's own source, then confirmed against production bytes.
// next/dist/server/base-server.js
setVaryHeader(req, res, isAppPath, resolvedPathname) {
...
res.appendHeader('vary', baseVaryHeader); // appends, never overwrites
}
On the same production response that shows only the RSC tokens in
Vary, every other header from the same next.config
block is present: Link, X-Frame-Options,
Referrer-Policy, Strict-Transport-Security,
Access-Control-Allow-Origin. So the block applies, and
Vary specifically does not survive. The fix sets it on the
response middleware returns, which is the object the framework then
appends to.
Verified, and not yet verified
- Verified pre-merge: both gaps re-measured on live prod before any code changed; 559 tests green; 4 mutations each turn the new assertions red.
- Not verified pre-merge: that middleware's
Varysurvives Next's pipeline onto the HTML response. The mechanism argument is strong (Next appends), but that is an argument, not a measurement, and arguing from the layer we control is the exact habit this PR exists to correct. It gets re-probed on the deployed bytes. - Deliberately not done: a Playwright spec. The harness exists but is not wired into CI, so the test would never run, which is the silently-dead pattern this repo already warns about.
- Deliberately not done: adding
Varyto single-representation URLs. Varying a URL that only ever returns one body fragments its cache per crawler and buys nothing.
44 test files / 559 tests green in docs/site, 21 of them new and
asserting response bytes rather than source strings.