Table of Contents
Lint
Module: forge.lthn.ai/core/lint
Binary: core-lint
Pattern-based lint tool for Go, PHP, TypeScript, JavaScript, Python, and C++. Rules are defined in embedded YAML catalog files with regex detection, severity levels, and auto-fix suggestions. Includes Go AST cyclomatic complexity analysis, test coverage tracking, govulncheck integration, and a full PHP quality pipeline (Pint, PHPStan, Psalm, security auditing, mutation testing).
Architecture
The lint engine has three layers:
- Catalog — YAML rule files loaded from embedded filesystem or external paths.
- Matcher — Compiled regex rules applied line-by-line to source files.
- Scanner — Directory walker that detects file languages and dispatches to matcher.
Key Types
Rule
type Rule struct {
ID string // unique identifier
Title string // human-readable name
Severity string // info, low, medium, high, critical
Languages []string // target languages (go, php, ts, js, cpp, py)
Tags []string // categorisation tags
Pattern string // regex or AST pattern
ExcludePattern string // lines/files matching this are skipped
Fix string // suggested fix description
Detection string // "regex" or "ast"
AutoFixable bool // whether automatic fix is possible
ExampleBad string // bad code example
ExampleGood string // good code example
}
Validate() checks required fields and compiles regex patterns.
Finding
type Finding struct {
RuleID string
Title string
Severity string
File string
Line int
Match string
Fix string
Repo string
}
Matcher
Holds compiled rules. NewMatcher(rules) (*Matcher, error) compiles regex-detection rules. Match(filename, content) []Finding scans line-by-line, checking exclude patterns on both lines and filenames.
Scanner
NewScanner(rules) (*Scanner, error) creates a scanner with default directory exclusions (vendor, node_modules, .git, testdata, .core).
ScanDir(root) ([]Finding, error)— walks directory tree, detects language by extension, matches rules.ScanFile(path) ([]Finding, error)— scans single file.
Language detection: .go->go, .php->php, .ts/.tsx->ts, .js/.jsx->js, .cpp/.cc/.c/.h->cpp, .py->py.
Catalog
LoadFS(fs, dir) (*Catalog, error) loads rules from embedded or external filesystem. LoadEmbeddedCatalog() loads from catalog/*.yaml.
Shipped catalogs:
go-correctness.yamlgo-modernise.yamlgo-security.yaml
Additional Packages
pkg/lint/
| File | Description |
|---|---|
| complexity.go | Go AST cyclomatic complexity analysis |
| coverage.go | Test coverage snapshot, regression tracking |
| vulncheck.go | govulncheck JSON output parsing |
| tools.go | Toolkit subprocess wrappers (external tools) |
| report.go | Output formatting (JSON, JSONL, text) |
pkg/detect/
Project type detection: Detect(path) string identifies project type from files present (go.mod, composer.json, package.json, etc.).
pkg/php/
Full PHP quality pipeline:
| File | Description |
|---|---|
| format.go | Laravel Pint code formatting |
| analyse.go | PHPStan + Psalm static analysis |
| audit.go | Composer security auditing |
| security.go | Security checks |
| test.go | Pest/PHPUnit test runner |
| refactor.go | Rector refactoring |
| mutation.go | Infection mutation testing |
| pipeline.go | Orchestrated QA pipeline |
| runner.go | Pipeline execution engine |
CLI
Entry point: cmd/core-lint/. Also cmd/qa/ for quality assurance commands.
Dependencies
Direct: core/cli, go-i18n, go-io, go-log, go-scm, testify, yaml.v3.
Usage
catalog, _ := lint.LoadEmbeddedCatalog()
scanner, _ := lint.NewScanner(catalog.Rules())
findings, _ := scanner.ScanDir("./src")