limits-gen

command
v0.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2026 License: MPL-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Command limits-gen writes live/LIMITATIONS.md's per-refusal content from the registries that define the refusals, instead of from someone's memory of them.

This is GitHub issue #110's second acceptance criterion. The document's job is to tell an operator whether their configuration can move to live markers, and it was hand-written against a set nothing could enumerate. Thirteen of the sixteen lint rules had an entry here; three cited the issue tracker instead. The thirty-two identity refusals had three between them. And the largest single blocker in the #102 corpus, along with two more of the top seven, was in no table at all. Anything hand-maintained against a set that large drifts, and the drift is invisible until someone hits an undocumented refusal.

What it generates, and what it does not

Three spans, marked the way tools/survey-gen already marks its own (see internal/live/mdspan). Two sit inside live/LIMITATIONS.md's "Every refusal, enumerated" section:

  • refusal-table: every refusal in internal/live/check's AllRefusals, ranked by how many corpus configurations it blocks, with where it is documented and which package raises it.
  • refusal-entries: a heading and a description per non-lint refusal. Most point their DocsRef at the heading written here, which is what closes the loop: internal/live/check's TestEveryRefusalDocsRefIsResolvable fails if this has not been run. The seven whose registry defers to a hand-written entry get a section that says what they are and then names it, so a What that has drifted from the prose is visible instead of invisible (#698).

The third heads the hand-written half:

  • lint-roster: one row per lint rule - the rule, its summary, its severity, the entry below that documents it, and that entry's fixture directory under live/e2e/limits. The prose stays hand-written; the roster of it does not, so a rule with no entry or an entry whose fixture directory was renamed fails the render (#698).

The render fails, writing nothing, when a refusal it would give an entry to has no description, and when a refusal points at a heading in this document that nobody wrote. Both used to be tests over the committed file alone; a generator that will happily write a broken document and leave the finding to CI is one round trip worse than one that refuses.

AllRefusals rather than Catalog is deliberate. The corpus ranks the two passes it can run without a cloud; documentation covers all five, and a stamping refusal shows a dash in the frequency columns because it has never been measured rather than because it blocks nothing.

The narrative sections stay hand-written, per #110's own scope: the "Enforced today" entries, which carry a Construct / Why banned / Forwarding address / Enforcement treatment per lint rule, are prose nobody should generate. The table links to them, and the roster indexes them.

Measured at #698's commit: 378397 bytes, of which 59.1% were already inside a generated span - this generator's and survey-gen's - and 40.9% hand prose, 109611 bytes of it the "Enforced today" entries.

Frequency comes from live/corpus-refusals.json when it is present. A refusal missing from that artifact is rendered as unmeasured rather than as zero, because those are different claims and only one of them is true when the corpus has not been regenerated.

Usage, from anywhere in the checkout:

go run ./tools/limits-gen

No provider, no network, no cloud. It reads compiled-in tables and one committed artifact.

The "Attribute-level residue" section's three figures - write-only, sensitive-and-settable, and how many of the latter are unconditionally required - were hand-quoted from GitHub issue #126's comment ("10 types / 21 attributes", "53 types / 132 attributes", "7 ... unconditionally required") and never revisited. The admission table issue #126 measured against had 846 types; live/LIMITATIONS.md's own denominator (identity.AdmittedTypes()) is 905 today, and the true figures against the same rule and the same provider version are 12/23, 60/140 and 8. Same probe, same version, different table - the doc just never re-ran it.

These three now render from live/wo-sweep.json, tools/wo-sweep's own committed output (`just wo-sweep` regenerates it; it is the one input to this generator that needs a provider, which is why it is committed rather than computed here). tools/limits-gen/residue_render_test.go is the drift guard: it re-renders from the committed artifact and fails if the shipped spans disagree, so a table that grows without a `just wo-sweep && just limits` run is caught rather than quoted stale a second time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL