SpecSheriff
rule · _guidelines/tools/8 · s-5z5gnu7pahr82xp

The tag that binds a symbol to its rule

Checkedconfirmed by its owner

A tag is the line @spec <sid> in the comment directly above the symbol it binds, above its decorators where it has any — in TypeScript and JavaScript its doc comment, in Python a comment line — and a symbol implementing several rules carries several.

A symbol that implements no rule says so with @spec none, followed by the reason it carries none, and one standing first in a run of re-exports, with no blank line between them, says it for the whole run.

The delimiters of the comment may share a tag's line and nothing else may, so that a tag's text is found by a scan in any language. Which symbol a tag stands on is found by parsing the file with tree-sitter and the grammar of the file's language — the parser alone, with no program and no type checker — and a description of each language names what counts as a declaration and as a test in it; TypeScript, JavaScript and Python are described.

Why

A comment above a symbol is where an editor shows a tag and where a reader of the symbol is already looking. A scan finds a tag but cannot see what it is attached to, so a tag standing over nothing would pass it; the parser sees the symbol under the comment, and used alone it answers the same for the same file every time and is cheap enough to run at every commit. One parser with a grammar per language makes a further language a description rather than new code.

The links it makes

The links made to it

The decisions taken on it

2026-09-22 · textual
Problem

The tag's rule says a tag stands in the doc comment above the symbol it binds, and nothing checked it: the check read tags by scanning, which finds a tag and can say nothing about what it is attached to. A tag naming a rule and standing over a blank line, or trailing a statement, passed. For the same reason the symbols a node names in its metadata were not graded at all, only the files.

Ruling

Where a tag stands is decided by parsing the file — the parser only, no program and no type checker. A tag binds to the declaration below it where no blank line separates them, and a node that names symbols is held to the ones its tags stand on. A language server was refused for the same job: its answer depends on the state of a running server, and the checks require the same commit to get the same answer every time (§s-jau82aq9juv9zzh).

2026-10-08 · textual
Problem

The exemption stood at the top of a file, while s-kgbzk2ph9e6jfb4 now has every declaration carry its own tag.

Ruling

The owner: the exemption stands on the declaration, and on the first of a run of re-exports for the whole run.

2026-10-27 · textual
Problem

Which declaration a tag stands on was found by one language's parser alone, so the binding could not be held in any other language.

Ruling

The owner: one general parser, with a grammar per language, reads the code; a language is added by describing what counts as a declaration and as a test in it, and TypeScript, JavaScript and Python are described at launch.

The tests bound to it