Skip to content

test(contract): enforce Vary: Accept-Encoding is declared wherever it ships#231

Merged
SyniRon merged 2 commits into
developfrom
agent/issue-230
Jun 30, 2026
Merged

test(contract): enforce Vary: Accept-Encoding is declared wherever it ships#231
SyniRon merged 2 commits into
developfrom
agent/issue-230

Conversation

@SyniRon

@SyniRon SyniRon commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Closes #230. Followup to #228 / #229.

#229 added Vary: Accept-Encoding to GzipMiddleware and documented it in the spec, but nothing kept the two in step the way TestSpec_Every200DeclaresCacheControl does for Cache-Control. This adds that guard.

TestSpec_VaryAccompaniesEveryGzippedResponse walks the spec and asserts Vary is declared on every response that reaches the gzip layer (all 2xx and the shared Error tier) and absent on the one that does not (the 401 Unauthorized tier, which short-circuits in auth before gzip). It checks the same schema rigor as the Cache-Control test: present, optional, string, const: Accept-Encoding.

Test-only change. The spec was already correct as of #229, so the guard passes today; its job is to fail a future PR that documents Cache-Control but forgets Vary. Proven non-vacuous against three temporary spec mutations (a missing 200 Vary, a missing Error Vary, and a stray Unauthorized Vary), each restored.

This was generated by AI

SyniRon added 2 commits June 29, 2026 22:33
… ships

GzipMiddleware adds Vary: Accept-Encoding to every response that reaches a
handler (#229), and the spec documents it on the 2xx responses and the shared
Error response. Nothing kept that documentation honest, so a new endpoint could
declare Cache-Control (already enforced by TestSpec_Every200DeclaresCacheControl)
but forget Vary, and the spec would drift from the wire again, which is the same
problem #228 fixed.

TestSpec_VaryAccompaniesEveryGzippedResponse closes the gap, modeled on the
Cache-Control test. The discriminator is wider, because gzip runs inside auth
but outside the mux: Vary ships on all 2xx and on the JSON error tier, and only
the 401 responses lack it (auth short-circuits before the gzip layer). The test
keys on that seam rather than on 2xx-vs-non-2xx. The shared Error component and
every non-401 response must declare Vary; the Unauthorized component and any
literal 401 must not.

The spec was already correct as of #229, so this is a forward-looking guard.
Proved it is non-vacuous by deleting a Vary block and confirming the test fails
naming the offending response, then restoring it.

> *This was generated by AI*
The Vary spec guard keyed wantVary on `code != "401"`, treating the 401 as
the only response that short-circuits before GzipMiddleware. The auth path
has a second pre-gzip tier: rest/auth.go returns codeUnavailable (503) on a
ValidateApiKey lookup failure, before next.ServeHTTP, so a wire 503 from
auth carries no Vary either.

The test passes today only because the spec folds 503 into the operation
`default`, which resolves to the Vary-carrying Error shape. But the
discriminator was brittle: declaring an explicit "503" with the faithful
no-Vary body (mirroring how "401" is declared) would flip wantVary to true
and fail the guard, blocking a more faithful spec.

Key wantVary on the full auth short-circuit set (`code != "401" && code !=
"503"`) so an explicit 503 is expected to carry no Vary, like the 401. The
`default` arm stays Vary-expecting, since the handler errors that resolve to
it do. Correct the docstring and comments so they no longer call the 401 the
only pre-gzip tier. Test and comments only, no behavior change.

> *This was generated by AI*
@SyniRon SyniRon merged commit f1a70ab into develop Jun 30, 2026
3 checks passed
@SyniRon SyniRon deleted the agent/issue-230 branch June 30, 2026 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce in the spec that Vary: Accept-Encoding is declared wherever it ships

1 participant