Skip to content

Tiger documentation: newcomer explainer and full rule reference - #13

Merged
thrawn01 merged 9 commits into
mainfrom
thrawn01/eng-154-tiger-documentation-newcomer-explainer-full-rule-reference
Sep 17, 2026
Merged

thrawn01 merged 9 commits into
mainfrom
thrawn01/eng-154-tiger-documentation-newcomer-explainer-full-rule-reference

Conversation

@thrawn01

@thrawn01 thrawn01 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

ENG-154 | ENG-188 follow-up | Blueprint

Why the change

Tiger had no document a newcomer could read to understand what it is for, and no place a finding's rule code could be looked up, so this PR ships a teaching-first explainer and a full rule reference that a meta-test keeps in step with the rule registry.

Special things to note

  • The explainer is now the design source of truth and is ahead of the tool in three places: //nolint is disallowed outright, //tiger:restrict is removed (no-reflect and closed-dispatch are not opt-in), and map-order checking is described as ban-by-default with allowed body shapes. ENG-188 rewrites the spec and blueprints from it.
  • "Dialect" is retired everywhere (spec, README, CONTEXT.md, and Go doc comments) in favor of "rule set" or "tiger". No code behavior changes; the Go edits are comments only.
  • Two citations in the explainer are second-hand: the ISSRE 2006 assertion-density sentence comes from the paper's abstract, and the Curiosity landing details come from Holzmann's 2026 talk transcript rather than his "Mars Code" article.

Change outline

Two audience documents replace two stale ones. The spec stays the normative reference for now.

 docs/
-├── Tiger Go Documentation.html     # 58KB teaching page, described the removed "reported" tier
-├── Tiger Go Human Explainer.md     # 6KB summary, opened with "chosen for decidability"
+├── Tiger Explainer.md              # teaching-first, benefits before mechanism, 16-entry References
+├── Tiger Rule Reference.md         # one anchored entry per custom rule (42), auto-rule table, directive index
 ├── Tiger Specification.md          # new tagline, unpinned-fact behavior corrected, invariantsymmetry marked not built
+└── features/ENG-154-tiger-documentation/blueprint.md   # audit record: build-on vs scrap per document
 internal/rules/
+└── docs_test.go                    # meta-test: reference and registry cannot drift

The explainer is ordered so a reader wants the tool before meeting a concept.

Tiger Explainer.md
  Overview                        what tiger is, whose rules it enforces, no warnings, no LLM
    Benefits                      injectable nondeterminism, restricted language, declared effects,
                                  no warnings, enforced structure  (each bullet cites its source)
  golangci-lint and tiger's own analyzers
    What counts as a rule         Holzmann: "if your rule is not checkable, don't put it in the standard"
  Using Tiger
    1. Run the check              live Drain transcript
    2. Pin what matters           --show-facts, tiger pin, the four-case table
  Key Concepts
    surfaces → injectable nondeterminism → named invariants → effects as the fourth oracle
    → one pin holds the subtree → frames → excluded bug classes → severities → budget → directives
  What tiger tells a reviewer
  What tiger will not do
  Where tiger stands today
  References

The meta-test derives its expectations from the registry, so adding a rule without documenting it fails go test ./....

docs_test.go
  TestReferenceCoversEveryCustomRule
    for each rules.CustomRules() category
      exactly one "<!-- rule: <category> -->" anchor in the reference
      the entry's "**Severity:**" line matches the registry
  TestReferenceCoversEveryAutoRule
    every rules.AutoRules() rule ID and linter name appears in the reference
  TestDocsCarryNoRemovedVocabulary
    neither document contains TS-N12, TS-N13, TS-N15, or "[advisory]"   (ENG-161)

Every transcript in the explainer is real tiger check output, either against examples/ledger or against scratch packages written to trip one rule, and the footer says which is which.

… (ENG-154)

Replace the two stale audience docs with a teaching-first explainer
(docs/Tiger Explainer.html) and a complete rule reference
(docs/Tiger Rule Reference.md): 42 custom-rule entries with firing
examples and compliant rewrites from the corpora, the 45-row auto-rule
table, a directive index, and the budget/ratchet model per ADR-0011/0012.
A meta-test in internal/rules keeps the reference in lockstep with the
registry and bans the removed TS-N12/N13/N15 vocabulary. README links
the doc set; the spec is untouched as the normative source.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

tiger check ./...

Exit 0 — no blocking findings.

Clean run: no findings.

Map the TigerStyle/Power-of-Ten lineage rule by rule in the Why section,
add the What-it-buys and How-review-divides sections ported from the
deleted human explainer (trimmed to what the shipped tool enforces), add
the decidability rationale and the spec-vs-world structural limit, and
narrow one overclaiming pin sentence from the style-review pass.
Replace docs/Tiger Explainer.html with docs/Tiger Explainer.md so the
newcomer doc lives in the same format as the rule reference and renders
on GitHub without a download. README links the new path, and the docs
meta-test reads the .md file so the removed-vocabulary check keeps
covering it.
…s, bug classes

The explainer now states at the top that it describes tiger as it is meant to be
when finished, and names the surface checks (TS-I01, I03, I05, I06, I07) as the part
that is specified but not enforced. New sections: "Invariants have names", "One pin
holds the whole subtree" (replacing the transitive-pins TODO), and "Whole bug classes
are excluded, not caught". "Effects are the fourth oracle" is rewritten with tests
restored as the third oracle. Every transcript is live tiger check output; the footer
says which runs use the ledger and which use a scratch module.

The spec now matches the code: unpinned effect sets and synthesized variants print
only under --show-facts and never block; TS-A08 and the five surface rules carry an
Unimplemented status, and the analyzer table marks invariantsymmetry (ENG-182),
surfaces, and adapters as not built. TS-V01 records that //tiger:batched waives
TS-S02 but not the variant check (ENG-183).
…eview fixes

Adds "A frame is where a function writes" after the subtree-pin section, built on a
live run where a method pinned to one field calls a helper that writes another.

The mechanism sections now speak in the team's voice: "we" for what was chosen,
required, shipped, or found in trials; "tiger" for what the tool does when it runs.

"What adoption looks like" is removed as incomplete, along with the plugin caveat
box it carried; "Try it" no longer points at adoption steps and now states the
1,023-finding first run directly. The opening narrows "security holes" to denial of
service, the one such bug the trials found.

Final review fixes: the top note uses plain words instead of surface vocabulary the
page has not yet defined; the nondeterminism section opens with the concept before
rule codes; the footer attributes the Drain transcripts to scratch packages rather
than the ledger and notes the pinned Drain excerpt omits a second TS-C05 finding.
The explainer is now the authority on what tiger promises. It requires every
nondeterministic dependency to be injectable and proves that per pinned
function through effect sets; it does not require a fake, mock, or test
double, and whether a test substitutes one is the coder's call per test.
The spec follows: TS-I01 retitled and enforced through effects pins, TS-I03,
TS-I05 and TS-I07 marked review-only, TS-I06 deleted (tiger cannot classify
a wrapper), TS-X01 notes the coming test-double exemption (ENG-185), and the
surfaces and adapters analyzers are marked not planned and deleted.

The tagline now leads with what tiger does for AI-written Go and credits
Power of Ten and TigerStyle; README, spec, and CONTEXT.md open the same way.
"Dialect" is retired from every live document and Go comment in favour of
"the rules" or "the rule set"; ADRs and dated feature reports keep it as
history.

Also: grammar pass and a four-slice reviewed edit of the explainer (pin
walkthrough now names Drain, map order no longer listed as injectable,
"variant" named in prose, escape hatch -> escape directive, rule codes out
of prose), TS-A08 marked unimplemented (ENG-182), TS-V01 batched gap noted
(ENG-183).
The "Tiger is not a linter" section described golangci-lint as advisory
output tiger runs alongside. That is not how tiger uses it: half the rule
set is enforced by golangci-lint linters that tiger configures with
`tiger golangci --init` and audits with `tiger golangci`, and every issue
fails the run. The section now explains both engines, shows a real audit
transcript from a config drifted to 80 lines, and covers package
restrictions with the transitive-bound mechanism from the spec. The
unsourced claim that the analysis is "cheap" is dropped.

The "Run the check" opening now states what the command does instead of
narrating a day with tiger. Three Benefits bullets are written from
verified behaviour: a pin fails in either direction, and a failing test
that supplies the clock and store reproduces.
…bsidian

Overview and Benefits rewritten for grammar and continuity; nolint is
disallowed outright per the intended design. Adds 30 inline citations and
a 16-entry References section (Power of Ten, Mars Code, Holzmann's Systems
Distributed '26 talk, Kudrjavets/Nagappan/Ball on assertion density,
McCabe, Campbell, Floyd, TigerStyle, VOPR, FoundationDB, Bernhardt,
Cockburn). Removes every mention of //tiger:restrict, restores the spawn
sentence tying the goroutine rule to pins, renames the illustrative
surface function to Prune, and fixes the inverted correctness/liveness
sentence in the assertions paragraph.
@thrawn01
thrawn01 merged commit 5126797 into main Sep 17, 2026
5 checks passed
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.

1 participant