limits-gen

command
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MPL-2.0 Imports: 13 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

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

  • 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 refusal that has no hand-written entry of its own - the identity, pass-through, stamping and discovery registries. Their DocsRef points at the heading written here, which is what closes the loop: internal/live/check's TestEveryRefusalDocsRefIsResolvable fails if this has not been run.

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.

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