Skip to content
internal/lints
On this page

The lint-code registry and the verdict rules every check entry point shares, so a code's severity is declared in one embedded document and nowhere else.

#internal/lints

#internal/lints

Package lints owns the lint-code registry and the verdict rules every check entry point shares.

The embedded lints.toml is the single authority for every lint code selfdoc can emit: its severity and its one-line description are declared there and nowhere else. [LintResult] derives its severity from the registry, so a construction site cannot state a severity and cannot emit an unregistered code -- both are refused rather than discouraged. The lint-code enum in the declared check payload schema and the lint-rule table in the check guide are both pinned to the registry by tests.

selfdoc's check command, the unified check, the post-build lint pass and the posts-only check all decide the same question -- does this run pass? -- and they used to decide it with four copies of the same three conditions. One copy had drifted: it compared documented against total public symbols directly, hardcoding a 100% coverage requirement, so a project that lowered its coverage threshold passed one check and failed the other on identical state. This package owns the rules.

#DefaultCoverageThreshold

Go go
const DefaultCoverageThreshold = 1.0

DefaultCoverageThreshold is the fraction of public symbols that must be documented when a project does not say otherwise. It mirrors the historical CLI default.

#GeneratedBy

Go go
const GeneratedBy = "0.2.5"

GeneratedBy is the strictspec release that produced this file. The runtime pairing guard hard-errors unless it matches the linked runtime exactly.

#SchemaFormatVersion

Go go
const SchemaFormatVersion = 1

SchemaFormatVersion is the document format_version this validator accepts.

#ErrLintSuppression

Go go
var ErrLintSuppression = fmt.Errorf("lint suppression list refused")

ErrLintSuppression is the base every refusal of a suppression-list entry wraps.

A suppression list is refused for one of two reasons -- the code is not in the registry, or the code is error-severity and therefore not suppressible. Both are the same event to a caller (the list is bad, say so and stop), so one errors.Is check covers them.

#LintSpec

Go go
type LintSpec struct

LintSpec is the registry entry for a single lint code.

#LintRegistryError

Go go
type LintRegistryError struct

LintRegistryError reports a registry document that failed strictspec validation: the lint registry is malformed, so selfdoc cannot know what its own lint codes are.

#Registry

Go go
type Registry struct

Registry is a loaded, validated lint registry.

It keeps the document's order, which is documentation order: the lint-rule table renders in it, grouping the families rather than sorting the codes alphabetically.

#UnknownLintCodeError

Go go
type UnknownLintCodeError struct

UnknownLintCodeError reports a code the registry does not carry.

Every emittable code is declared in the registry document. An undeclared code would carry no severity, would be rejected by the JSON output schema, and would be invisible to the documentation table -- so it is refused at the construction site instead.

#UnsuppressableLintCodeError

Go go
type UnsuppressableLintCodeError struct

UnsuppressableLintCodeError reports a suppression list that named an error-severity code.

Suppression reaches warning-severity codes only. An error says the build is wrong -- a broken emitted reference, a missing description, a post whose slug moved -- and silencing it hides the defect rather than resolving it, which is how a broken build once passed its own check. The registry is the severity authority, so the refusal is decided there and nowhere else.

#LintResult

Go go
type LintResult struct

LintResult is a single lint diagnostic.

Its severity is not a construction argument: it is read from the registry for the given code. That is what keeps severities out of the construction sites scattered across the check modules, and what makes an unregistered code impossible to emit. Every field is read-only through an accessor, because a diagnostic's severity is the registry's answer for its code and nothing downstream may rewrite it after the fact.

#LintTableRow

Go go
type LintTableRow struct

LintTableRow is one row of the rendered lint-rule table.

#Coverage

Go go
type Coverage interface

Coverage is what the verdict rules need from a run's coverage measurement: how many public symbols there are and how many of them are documented.

The concrete coverage type is the check package's, which measures far more than this; declaring the dependency as an interface here keeps this package below check in the import graph, as the Python module it ports was (the former blog package depended on selfdoc-core but not on selfdoc, so a posts-only install must reach the verdict without the check module present).

Pass a nil Coverage for a run that measured no coverage. A non-nil interface holding a nil pointer is not the same thing and will panic.

#DirectiveOutcome

Go go
type DirectiveOutcome interface

DirectiveOutcome is what the verdict rules need from one directive's resolution result: its status, which is "OK" or "FAILED".

As with [Coverage], the concrete type is the check package's.

#LintRegistry

Go go
type LintRegistry struct

LintRegistry is the frozen typed binding of the "LintRegistry" record. Fields are immutable by convention (shallow-plus-generated-immutability); use With* for copy-on-write.

#LintDescriptor

Go go
type LintDescriptor struct

LintDescriptor is the frozen typed binding of the "LintDescriptor" record. Fields are immutable by convention (shallow-plus-generated-immutability); use With* for copy-on-write.

#BuildRegistry

Go go
func BuildRegistry(raw []byte) (*Registry, error)

BuildRegistry validates raw registry-document bytes and binds them into a [Registry].

strictspec is the boundary validator: the document is checked against its schema by the generated validator, and only a wholly valid document is bound. Any diagnostic is a [LintRegistryError].

#Load

Go go
func Load() (*Registry, error) { return BuildRegistry(registryDocument) }

Load reads, validates and binds the embedded registry document.

This is the error-returning door. Production code reads [Registered] instead, which loads once.

#Registered

Go go
func Registered() *Registry

Registered returns the shipped lint registry, loading and validating the embedded document on first use.

It panics when the document is malformed, which is the Go counterpart of the Python surface's import-time crash: the document is embedded in the binary, so a diagnostic here means this build of selfdoc does not know what its own lint codes are. Use [Load] where an error is wanted.

#LintSeverity

Go go
func LintSeverity(code string) (string, error)

LintSeverity returns the registered severity for code, or an [UnknownLintCodeError].

#ValidateLintCodes

Go go
func ValidateLintCodes(codes []string, source string) error

ValidateLintCodes refuses any code the registry rejects for suppression.

Two refusals, both decided by the registry:

- An unregistered code suppresses nothing and hides the fact that it suppresses nothing, so it is refused where the list is read rather than left silently inert. - A registered error-severity code is not suppressible at all. Suppression reaches warnings only; an error means the build is wrong, and silencing it hides the defect.

source names where the codes came from in the message (for instance "lint_ignore" or "--ignore"). Unregistered codes are reported before severity, so a typo is reported as a typo, and every offending code is named rather than just the first.

#ParseIgnoreCodes

Go go
func ParseIgnoreCodes(raw, source string) (map[string]struct{}, error)

ParseIgnoreCodes parses a comma-separated --ignore value into a validated code set.

source names the flag a rejection is attributed to. An empty value means no suppression, not an error. Every code is checked through [ValidateLintCodes], so an unregistered or error-severity code is refused here rather than silently suppressing nothing.

#NewLintResult

Go go
func NewLintResult(file string, line *int, code, message string) (LintResult, error)

NewLintResult builds a diagnostic for code, deriving its severity from the registry.

line is nil for a diagnostic that belongs to a file rather than to one of its lines. An unregistered code is an [UnknownLintCodeError].

#MustLintResult

Go go
func MustLintResult(file string, line *int, code, message string) LintResult

MustLintResult is [NewLintResult] for a call site whose code is a literal declared in the registry document, and panics when it is not.

The panic is the point: an unregistered literal is a defect in this repository rather than a condition a run can encounter, and the alternative -- an error return threaded through every emission site -- would make the emission sites decide what to do about a code that cannot exist.

#FilterLints

Go go
func FilterLints(lints []LintResult, ignoreCodes map[string]struct{}) []LintResult

FilterLints returns the lints whose code is not in ignoreCodes.

An empty or nil ignoreCodes returns the input unchanged, so a run with no suppression list does no work.

#LintTableRows

Go go
func LintTableRows() []LintTableRow

LintTableRows returns a row per registered lint, in registry (documentation) order. The documentation's lint-rule table is rendered from this and nothing else.

#RenderLintTable

Go go
func RenderLintTable() string

RenderLintTable renders the registry as the Markdown table the documentation carries.

#CoverageBelowThreshold

Go go
func CoverageBelowThreshold(coverage Coverage, config map[string]any) bool

CoverageBelowThreshold reports whether documented coverage is under the configured threshold.

config is the project configuration the run was driven by, read for "coverage_threshold"; a nil config means no configuration is in play, which uses [DefaultCoverageThreshold]. The answer is false whenever there is nothing to measure -- no coverage at all, or a project with no public symbols.

#CheckExitCode

Go go
func CheckExitCode(

CheckExitCode computes the process exit code for a check run.

This is the single definition of "did this check pass": a run fails when a directive failed to resolve, when any lint is error-severity, or when documented coverage is under the configured threshold. It returns 1 when the run fails and 0 when it passes.

lints are the diagnostics the run produced, already filtered through the project's suppression list. directiveResults are the per-directive resolution results, and are nil for a reduced entry point that resolved no directives (the post-build lint pass, the posts-only check). coverage is nil for an entry point that measured no coverage.

#ValidateBytes

Go go
func ValidateBytes(input []byte, syntax string) (*LintRegistry, []strictspec.Diagnostic)

ValidateBytes is the raw-bytes entry point: lossless parse of input in the given syntax ("json" | "toml" | "jsonl"), then validate. It returns the typed root value (nil when any diagnostic fired) and the ordered diagnostics.

#ValidateValue

Go go
func ValidateValue(v strictspec.Value) (*LintRegistry, []strictspec.Diagnostic)

ValidateValue is the tagged-value entry point: validate an already-parsed tagged document value (from strictspec.LoadValue or a typed constructor).

#ValidateBytesWithEvidence

Go go
func ValidateBytesWithEvidence(input []byte, syntax string, evidence map[string][]map[string]any) (*LintRegistry, []strictspec.Diagnostic)

ValidateBytesWithEvidence is ValidateBytes plus cross-document resolver evidence for the phase-2 constraint vocabulary.

#LintRegistryError.Error

Go go
func (e *LintRegistryError) Error() string { return e.Message }

#Registry.Codes

Go go
func (r *Registry) Codes() []string

Codes returns every registered code in registry (documentation) order.

#Registry.Len

Go go
func (r *Registry) Len() int { return len(r.order) }

Len returns how many codes the registry carries.

#Registry.Spec

Go go
func (r *Registry) Spec(code string) (LintSpec, bool)

Spec returns the code's registry entry, reporting whether the registry carries it.

#Registry.Has

Go go
func (r *Registry) Has(code string) bool

Has reports whether the registry carries code.

#UnknownLintCodeError.Error

Go go
func (e *UnknownLintCodeError) Error() string { return e.Message }

#UnknownLintCodeError.Unwrap

Go go
func (e *UnknownLintCodeError) Unwrap() error { return ErrLintSuppression }

Unwrap reports [ErrLintSuppression], so one errors.Is check covers both refusals.

#UnsuppressableLintCodeError.Error

Go go
func (e *UnsuppressableLintCodeError) Error() string { return e.Message }

#UnsuppressableLintCodeError.Unwrap

Go go
func (e *UnsuppressableLintCodeError) Unwrap() error { return ErrLintSuppression }

Unwrap reports [ErrLintSuppression], so one errors.Is check covers both refusals.

#LintResult.File

Go go
func (l LintResult) File() string { return l.file }

File returns the diagnostic's path, relative to the docs directory.

#LintResult.Line

Go go
func (l LintResult) Line() *int

Line returns the 1-based line the diagnostic sits on, or nil when it belongs to the file as a whole.

#LintResult.Code

Go go
func (l LintResult) Code() string { return l.code }

Code returns the diagnostic's registered lint code.

#LintResult.Message

Go go
func (l LintResult) Message() string { return l.message }

Message returns the diagnostic's human-readable message.

#LintResult.Severity

Go go
func (l LintResult) Severity() string { return l.severity }

Severity returns the registry's severity for this diagnostic's code.

#LintRegistry.WithFormatVersion

Go go
func (x *LintRegistry) WithFormatVersion(v int64) *LintRegistry

WithFormatVersion returns a copy of LintRegistry with FormatVersion set to the given value.

#LintRegistry.WithLints

Go go
func (x *LintRegistry) WithLints(v []*LintDescriptor) *LintRegistry

WithLints returns a copy of LintRegistry with Lints set to the given value.

#LintDescriptor.WithCode

Go go
func (x *LintDescriptor) WithCode(v string) *LintDescriptor

WithCode returns a copy of LintDescriptor with Code set to the given value.

#LintDescriptor.WithSeverity

Go go
func (x *LintDescriptor) WithSeverity(v string) *LintDescriptor

WithSeverity returns a copy of LintDescriptor with Severity set to the given value.

#LintDescriptor.WithDescription

Go go
func (x *LintDescriptor) WithDescription(v string) *LintDescriptor

WithDescription returns a copy of LintDescriptor with Description set to the given value.

Search