Description
What happens
The rationale behind the TenantGateway TLS-passthrough restrictions is written out in full at every site that depends on it: a long preamble above TenantGatewaySpec, separate blocks on the individual fields, and sections of packages/extra/gateway/README.md. The same four arguments are restated in each place, near-verbatim: why the Cilium pin forces the HTTP-01 restriction, what the CEL cost estimator refuses without a declared bound, the grain of list-type ratcheting, and why a cert-mode is refused.
Why it matters
Every copy is a claim about a neighbouring system, and a claim in a comment is checked by nobody. Reviews of the change that introduced these blocks found three separate false statements of exactly this kind, each of which had passed both an automated reviewer and a human one: a claim that ratcheting never covers a list-type error, which the pinned apiextensions-apiserver contradicts; a claim about lowerAscii behaviour; and a claim that a tightening was inert when it was live on merge. The volume of explanatory prose is what generates them, because each restatement is an independent chance to be wrong and no diff can catch a copy that failed to move.
The failure mode is not hypothetical maintenance cost. The day the Cilium pin moves, every copy has to move with it, and the one that does not becomes a false statement sitting next to correct code.
What would fix it
Make the README the single narrative, and reduce the Go comments to the invariant at the site that enforces it plus a reference. One canonical block carries the same knowledge with one place to update, and a reader who wants the reasoning has one place to find it rather than three that may disagree.
This is out of scope for the PR that introduced the current shape: consolidating the narrative means rewriting prose that belongs to earlier commits in that branch, which is a documentation rework rather than a fix, and doing it under an open review would rewrite the commits a reviewer has already cited by SHA.
Activity
lexfrei commentedon Aug 15, 2026
Counted the actual carriers per claim, and one class of them is worse than the rest because nobody can sweep it. Per claim, counting files rather than occurrences: the Cilium pin argument lives in 6, the list-type ratchet grain in 4, the cross-protocol split in 3, the cert-mode refusal in 3, the CEL cost budget in 2.
The generated CRD is in three of those counts, and it carries the reasoning in two forms that both ship to every cluster. The
portfield'sdescriptionis whatkubectl explainprints to whoever is filling in the spec, and a CEL rule's message is what the apiserver hands the tenant when it refuses a write. Neither can be found by grepping prose, and neither can be fixed in place: the file is only written bymake generate, from godoc.So the failure mode has no author. If the pin moves and someone updates the README and the inline comments but not the godoc, the CRD keeps shipping the stale claim into clusters, and
git diffshows nothing because regeneration never ran. The reader who sees it is a tenant reading an error message.That constrains the fix. A canonical block has to live in a detached comment, which is not carried into the CRD, and everything left attached to a field has to be an invariant with no reasoning attached, or the reasoning keeps being delivered to clusters as documentation and as error text.
feat(gateway)!: add TLS-passthrough listeners to TenantGateway (#3342)