Documentation
¶
Overview ¶
Package lint holds the design-doc anti-drift checks. The core is a PURE function (no os import, no disk I/O) so the package itself stays trivially testable and gosec never sees a file-inclusion taint; the _test.go file owns all filesystem access (statFn/readFn) and is gosec-exempt.
The motivating failure: the engine carve (core moved internal/ -> engine/) left design docs citing paths that no longer exist. A backtick span like `engine/agent/loop.go:677` is a load-bearing claim that the file is there; when it drifts, the doc lies silently. CheckCitations turns that into a CI failure. See docs/design/README.md for the citation convention.
Package lint holds the design-doc anti-drift checks.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ADRNumberDuplicate ¶
ADRNumberDuplicate identifies files that share one numeric ADR prefix.
func CheckADRNumberUniqueness ¶
func CheckADRNumberUniqueness(names []string) []ADRNumberDuplicate
CheckADRNumberUniqueness returns every duplicate number in numeric order. Filenames within each duplicate are sorted for deterministic diagnostics.
type ADRProblem ¶
ADRProblem is one missing-header-field violation in an ADR.
func CheckADRShape ¶
func CheckADRShape(docName, content string) []ADRProblem
CheckADRShape applies the ADR-shape gate to one ADR file. It is pure (no I/O); the _test.go file owns disk access. Exempt files return nil.
func (ADRProblem) Error ¶
func (p ADRProblem) Error() string
Error renders an actionable, single-line message.
type MissingLabel ¶
type MissingLabel struct {
DocName string // the architecture/*.md basename
Label string // "What this covers:" / "Prerequisites:" / "Follow-on:"
}
MissingLabel records a missing orientation label in an architecture page.
func CheckReadingMap ¶
func CheckReadingMap(readingMD string, archPages map[string]string) []MissingLabel
CheckReadingMap validates the reading map integrity:
- READING.md must list every human-authored architecture/*.md page (except the generated mecatl.modelith.md).
- Every such page must contain "What this covers:", "Prerequisites:", and "Follow-on:".
Both inputs are injected so this function imports no os.
func (MissingLabel) Error ¶
func (m MissingLabel) Error() string
type Problem ¶
type Problem struct {
DocName string // the doc the citation lives in (e.g. "CLOUD-NATIVE.md")
Citation string // the raw backtick span text, verbatim (incl. any :NN suffix)
Path string // the path with any :NN/:NN-MM/:NN,MM line suffix stripped
Kind Kind
Symbol string // for MissingSymbol: the symbol that was not found
Suggestion string // for MissingFile: a basename-rescue hint, or "" if none
}
Problem is one dead citation found in a design doc. It carries enough to point a human at the exact span and (for MissingFile) a basename-rescue suggestion when the file looks like it merely moved.
func CheckCitations ¶
func CheckCitations( docName, markdown string, statFn func(string) bool, readFn func(string) ([]byte, error), rescue func(basename string) string, ) []Problem
CheckCitations scans a single design doc's markdown for dead citations.
- statFn reports whether a repo-root-relative path exists.
- readFn reads a repo-root-relative path's bytes (used only for the (`Symbol`) form, and only after statFn confirms the file exists).
Both are injected so this function imports no os and does no I/O: the test supplies map-backed pure fns for fixtures and os-backed fns for the live guard. Line numbers are NEVER verified (they are stripped before the stat).
Grammar (two forms, both over backtick spans):
File citation: a backtick span matching fileCitation AND containing at least one '/'. A known-extension span with NO slash is a prose back-reference (e.g. `Save`, `service.go:868`, `task test`) and is IGNORED on purpose: a bare basename is not a repo-root-relative locator, so verifying it would mean guessing, and guessing produces false positives. Repo-root-relative paths (with a slash) ARE verifiable, so those we check strictly: an abbreviated-but-real citation (e.g. `grpcdriver/server.go` for internal/adapter/grpcdriver/server.go) is deliberately flagged so the author expands it, and basename rescue points the way. The ONE escape hatch is the explicit inline ignore marker (see ignoreMarker), for a slash-path that is illustrative and NOT a repo citation (e.g. the skill logical-asset-name example `references/api.md` in DRIVERS.md). The marker is opt-in and self-documenting, so it does not weaken the guard for ordinary citations.
Symbol citation (opt-in): the explicit `path` (`Symbol`) pairing. When a verifiable file citation is immediately followed by a `Symbol` span, the symbol is verified by a word-boundary match over readFn(path). We never infer symbols from anything but this explicit pairing.
rescue, when non-nil, is consulted ONLY for a MissingFile: given a basename it returns a one-line suggestion (or "") so the walk that finds a moved file is lazy and lives in the caller (the test), keeping this function I/O-free.
type ReadingMapPage ¶
type ReadingMapPage struct {
Page string // architecture/*.md path relative to docs/
Title string // as it appears in the table
}
ReadingMapPage is one entry in the READING.md topic-branch table.