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
const DefaultCoverageThreshold = 1.0DefaultCoverageThreshold is the fraction of public symbols that must be documented when a project does not say otherwise. It mirrors the historical CLI default.
#GeneratedBy
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
const SchemaFormatVersion = 1SchemaFormatVersion is the document format_version this validator accepts.
#ErrLintSuppression
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
type LintSpec structLintSpec is the registry entry for a single lint code.
#LintRegistryError
type LintRegistryError structLintRegistryError reports a registry document that failed strictspec validation: the lint registry is malformed, so selfdoc cannot know what its own lint codes are.
#Registry
type Registry structRegistry 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
type UnknownLintCodeError structUnknownLintCodeError 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
type UnsuppressableLintCodeError structUnsuppressableLintCodeError 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
type LintResult structLintResult 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
type LintTableRow structLintTableRow is one row of the rendered lint-rule table.
#Coverage
type Coverage interfaceCoverage 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
type DirectiveOutcome interfaceDirectiveOutcome 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
type LintRegistry structLintRegistry 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
type LintDescriptor structLintDescriptor 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
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
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
func Registered() *RegistryRegistered 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
func LintSeverity(code string) (string, error)LintSeverity returns the registered severity for code, or an [UnknownLintCodeError].
#ValidateLintCodes
func ValidateLintCodes(codes []string, source string) errorValidateLintCodes 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
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
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
func MustLintResult(file string, line *int, code, message string) LintResultMustLintResult 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
func FilterLints(lints []LintResult, ignoreCodes map[string]struct{}) []LintResultFilterLints 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
func LintTableRows() []LintTableRowLintTableRows returns a row per registered lint, in registry (documentation) order. The documentation's lint-rule table is rendered from this and nothing else.
#RenderLintTable
func RenderLintTable() stringRenderLintTable renders the registry as the Markdown table the documentation carries.
#CoverageBelowThreshold
func CoverageBelowThreshold(coverage Coverage, config map[string]any) boolCoverageBelowThreshold 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
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
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
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
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
func (e *LintRegistryError) Error() string { return e.Message }#Registry.Codes
func (r *Registry) Codes() []stringCodes returns every registered code in registry (documentation) order.
#Registry.Len
func (r *Registry) Len() int { return len(r.order) }Len returns how many codes the registry carries.
#Registry.Spec
func (r *Registry) Spec(code string) (LintSpec, bool)Spec returns the code's registry entry, reporting whether the registry carries it.
#Registry.Has
func (r *Registry) Has(code string) boolHas reports whether the registry carries code.
#UnknownLintCodeError.Error
func (e *UnknownLintCodeError) Error() string { return e.Message }#UnknownLintCodeError.Unwrap
func (e *UnknownLintCodeError) Unwrap() error { return ErrLintSuppression }Unwrap reports [ErrLintSuppression], so one errors.Is check covers both refusals.
#UnsuppressableLintCodeError.Error
func (e *UnsuppressableLintCodeError) Error() string { return e.Message }#UnsuppressableLintCodeError.Unwrap
func (e *UnsuppressableLintCodeError) Unwrap() error { return ErrLintSuppression }Unwrap reports [ErrLintSuppression], so one errors.Is check covers both refusals.
#LintResult.File
func (l LintResult) File() string { return l.file }File returns the diagnostic's path, relative to the docs directory.
#LintResult.Line
func (l LintResult) Line() *intLine returns the 1-based line the diagnostic sits on, or nil when it belongs to the file as a whole.
#LintResult.Code
func (l LintResult) Code() string { return l.code }Code returns the diagnostic's registered lint code.
#LintResult.Message
func (l LintResult) Message() string { return l.message }Message returns the diagnostic's human-readable message.
#LintResult.Severity
func (l LintResult) Severity() string { return l.severity }Severity returns the registry's severity for this diagnostic's code.
#LintRegistry.WithFormatVersion
func (x *LintRegistry) WithFormatVersion(v int64) *LintRegistryWithFormatVersion returns a copy of LintRegistry with FormatVersion set to the given value.
#LintRegistry.WithLints
func (x *LintRegistry) WithLints(v []*LintDescriptor) *LintRegistryWithLints returns a copy of LintRegistry with Lints set to the given value.
#LintDescriptor.WithCode
func (x *LintDescriptor) WithCode(v string) *LintDescriptorWithCode returns a copy of LintDescriptor with Code set to the given value.
#LintDescriptor.WithSeverity
func (x *LintDescriptor) WithSeverity(v string) *LintDescriptorWithSeverity returns a copy of LintDescriptor with Severity set to the given value.
#LintDescriptor.WithDescription
func (x *LintDescriptor) WithDescription(v string) *LintDescriptorWithDescription returns a copy of LintDescriptor with Description set to the given value.