Help us shape the future of Go! Take the 2026 Go Developer Survey

vanguard

module
v0.1.1-0...-bdc4349 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: Apache-2.0

README

Vanguard logo

Vanguard

CI Status Release Go Reference SARIF 2.1.0


Source-first API design linter — scans source code directly, auto-detects the REST + gRPC API surface, and checks API design against AIP-style (resource-oriented design) rules with precise file:line:col findings.

Status: v0.1.0. The engine, 27 rules, Java/Spring + gRPC adapters, Docker image and release pipeline are built, verified and shipped as the first tagged release. Track the working contract in docs/charter.md.

Quickstart · Demo · Documentation · Rule catalog

Why vanguard

Spec linters (spectral, speccy) only see the OpenAPI document that is generated after the service builds and runs — one loop too late, and with locations that no longer map to source. Vanguard reads the source directly:

vanguard scan /path/to/project   # no build, no spec, no file list
Feature What it enables Learn more
Source-first Parses Java/Spring and .proto files, auto-detects the API surface (REST + gRPC), no spec file required. Charter
Design-standard rules 27 rules across naming, verb semantics, pagination, payload schema, error model, versioning and gRPC conventions, each traceable to an AIP guideline. Rule catalog
CI-native Pretty / JSON / SARIF 2.1.0 output, exit code contract 0 / 1 / 2, deterministic reports, partialFingerprints for stable GitHub alerts. CI integration

Where vanguard sits relative to the ecosystem (charter §1.2): spec governance stays with spectral, breaking-change detection with oasdiff/buf, language linting with golangci-lint/Checkstyle — vanguard owns the layer none of them cover: the API design standard, checked in source, before the spec exists.

Quickstart

Requirements:

  • Docker (recommended — no Go toolchain needed; the image build pins its own)
  • Go ≥ 1.22 and a C toolchain (only for building from source — the tree-sitter grammar is cgo; see docs/install.md)

Scan with Docker

git clone https://github.com/vanguard-lint/vanguard && cd vanguard
docker build -t vanguard:local .
docker run --rm -v "$PWD/testdata/stub-repo:/src:ro" vanguard:local scan /src

Or build the CLI directly

go build -o vanguard ./cmd/vanguard
./vanguard scan testdata/stub-repo
./vanguard scan testdata/audit-sample --format sarif -o vanguard.sarif
./vanguard explain R4xx-02
./vanguard init               # scaffold a commented .vanguard.yaml

What you will see — real output of scan testdata/stub-repo (the bundled demo repo carries one deliberate violation):

 vanguard 0.1.0-dev · testdata/stub-repo · stub · stub-http
 1 services · 27 rules (27 active) · 3 files

 [WARN]  R4xx-02 field-casing (1)
 ──────────────────────────────────────────────────────────────────
 src/orders.stub.json:1:1
   Field "total_amount" is not lowerCamelCase — the payload JSON convention is lowerCamelCase.
   suggest: totalAmount
   suppress: // vanguard:ignore R4xx-02 <reason>

 ──────────────────────────────────────────────────────────────────
 1 findings · 0 ERROR · 1 WARN · 0 INFO · 0 suppressed
 1 files with findings · 3 scanned · 3 skipped · 2 parse diagnostics
 next: vanguard explain R4xx-02

Exit codes (vanguard check is the CI alias):

Code Meaning
0 clean, warnings-only, or no API surface found
1 at least one ERROR-severity finding survived config/suppressions
2 tool or config error (bad flag, unreadable/invalid .vanguard.yaml, …)

Demo

A 60-second tour — repo with a bug, scan, explanation, fix, clean rescan — lives in docs/demo.md. Highlights:


(a) vanguard scan on a 753-file Spring backend — 24 controllers, 244 design findings grouped by rule (W5 baseline artifact, TTY colors per internal/render/pretty.go)

SARIF 2.1.0 output of the same scan in an editor view
(b) the same run as SARIF 2.1.0 — GitHub Code Scanning ingests this file directly (docs/ci-integration.md §2)

vanguard documentation roadmap
(c) the documentation map (vai-skilltree format, docs/vanguard-docs.roadmap.json)

Documentation

The full set is mapped in the docs roadmap above; the pages:

  • docs/demo.md — end-to-end walkthrough: bug → scan → explain → fix → clean
  • docs/install.md — three install paths (Releases / Docker / go install), each step verified
  • docs/config.md — .vanguard.yaml schema v1: discovery, rule overrides, suppressions, error contract
  • docs/rules/README.md — the rule catalog — one page per rule, CI-enforced 1:1 with --list-rules
  • docs/ci-integration.md — gate integration: exit-code contract, GitHub Actions / GitLab recipes, SARIF upload
  • docs/charter.md — product charter: R1–R8 requirements, rule taxonomy, architecture
  • CONTRIBUTING.md — development setup and the process for adding a rule

The rule catalog

27 registered rules in six families (full index with quick examples: docs/rules/README.md, machine-readable via vanguard scan --list-rules):

Family Rules Checks Severity mix
R1xx resources & naming 5 plural collections, CRUD verbs in paths, path shape and casing, id naming 1 ERROR · 3 WARN · 1 INFO
R2xx methods & verbs 6 GET bodies, POST→201, PATCH/PUT payloads, DELETE bodies, custom methods 1 ERROR · 4 WARN · 1 INFO
R3xx pagination 3 unpaginated lists, list envelopes, unbounded page size 1 WARN · 2 INFO
R4xx payload 3 entities in payloads, field casing, time field types 1 ERROR · 1 WARN · 1 INFO
R5xx errors 3 unified error shape, no 500 for business errors, status semantics 1 ERROR · 2 WARN
R6xx http-grpc & versioning 7 versioned paths, gRPC standard methods, + 5 golden-fixture demo rules 1 ERROR · 1 WARN · 5 demo

Rules are config-tunable per family or per id (rules.R1xx-02.severity), and every finding can be suppressed inline (// vanguard:ignore R4xx-02 <reason>) or path-scoped in config with a reason — see docs/config.md.

Repository layout

Path Responsibility
cmd/vanguard/ CLI entry point
internal/ir/ ApiSurface IR — pure, language-agnostic (w2-02)
internal/engine/ rule engine, registry, suppression (w2-04)
internal/render/ pretty / JSON / SARIF output (w2-05)
internal/discovery/ tree walker, language detection, adapter registry (w2-03)
adapters/java/ Java/Spring adapter (w3-01, w3-02)
rules/ R1xx–R6xx rule metadata + check functions (w3-03..w3-06)
testdata/ stub-repo, golden, adversarial, mutation corpora
docs/ charter, test strategy, per-rule documentation
reference/api-linter/ local study clone of googleapis/api-linter — not committed

License

This project is open source under the Apache-2.0 License — the same license as googleapis/api-linter, the spiritual ancestor of the rule model.

Directories

Path Synopsis
adapters
java
Package java adapts Java sources into raw API candidates — the intermediate extraction layer between the file walk (internal/discovery) and the Spring-aware IR mapping (w3-02, the architecture boundary this package must not cross).
Package java adapts Java sources into raw API candidates — the intermediate extraction layer between the file walk (internal/discovery) and the Spring-aware IR mapping (w3-02, the architecture boundary this package must not cross).
spring
Package spring turns the raw Java candidates extracted by adapters/java (w3-01) into a meaningful Spring Boot ir.ApiSurface (w3-02): controllers become Services, mapping annotations become Methods with merged paths, binding annotations become Params/Payload, ResponseEntity/Mono/Flux returns unwrap into Response, Pageable/page-size parameters become Pagination, @ControllerAdvice handlers become the ErrorScheme, referenced records/POJOs become Types, and build files pin Source.Framework.
Package spring turns the raw Java candidates extracted by adapters/java (w3-01) into a meaningful Spring Boot ir.ApiSurface (w3-02): controllers become Services, mapping annotations become Methods with merged paths, binding annotations become Params/Payload, ResponseEntity/Mono/Flux returns unwrap into Response, Pageable/page-size parameters become Pagination, @ControllerAdvice handlers become the ErrorScheme, referenced records/POJOs become Types, and build files pin Source.Framework.
cmd
vanguard command
Command vanguard is the CLI entry point of the Vanguard linter.
Command vanguard is the CLI entry point of the Vanguard linter.
internal
benchgen
Package benchgen deterministically generates the vanguard performance bench repository (w4-03; test strategy §5.1).
Package benchgen deterministically generates the vanguard performance bench repository (w4-03; test strategy §5.1).
buildconf
Package buildconf carries the cgo link-time support files used by the release build matrix (w6-01).
Package buildconf carries the cgo link-time support files used by the release build matrix (w6-01).
cli
Package cli implements the vanguard command-line surface (charter §6.1).
Package cli implements the vanguard command-line surface (charter §6.1).
corpus
Package corpus guards the adversarial corpus contract (test-strategy §3): the manifest.yaml schema the w4-02 mutation harness reads, the manifest.json twin the corpus-check tool reads, and the per-case file discipline (≤ 40 lines, machine header, lure line).
Package corpus guards the adversarial corpus contract (test-strategy §3): the manifest.yaml schema the w4-02 mutation harness reads, the manifest.json twin the corpus-check tool reads, and the per-case file discipline (≤ 40 lines, machine header, lure line).
discovery
Package discovery walks a source tree, detects language and framework, and selects the adapter that parses the API surface — the machinery behind "vanguard scan /path auto-detects everything" (charter §5.3, R1).
Package discovery walks a source tree, detects language and framework, and selects the adapter that parses the API surface — the machinery behind "vanguard scan /path auto-detects everything" (charter §5.3, R1).
engine
Package engine implements the data-driven rule engine: selector and predicate filtering over the IR, the rule registry that binds rule metadata (YAML, go:embed) to check functions, config (.vanguard.yaml) parsing and discovery, suppression handling, and per-rule panic isolation.
Package engine implements the data-driven rule engine: selector and predicate filtering over the IR, the rule registry that binds rule metadata (YAML, go:embed) to check functions, config (.vanguard.yaml) parsing and discovery, suppression handling, and per-rule panic isolation.
golden
Package golden is the W2 golden fixture harness (w2-07; test strategy §2.1, tier 1): it runs the REAL vanguard binary via exec — exactly the way CI invokes it — against fixture directories under testdata/golden/, snapshots the output of every format, and compares the normalized bytes against the snapshot files committed next to each fixture.
Package golden is the W2 golden fixture harness (w2-07; test strategy §2.1, tier 1): it runs the REAL vanguard binary via exec — exactly the way CI invokes it — against fixture directories under testdata/golden/, snapshots the output of every format, and compares the normalized bytes against the snapshot files committed next to each fixture.
ir
Package ir defines the ApiSurface intermediate representation that every adapter produces and every rule consumes.
Package ir defines the ApiSurface intermediate representation that every adapter produces and every rule consumes.
mutation
Package mutation is the W4 mutation harness (w4-02; test strategy §4): it takes the corpus's "ok" fixtures — code the linter correctly stays silent on — applies a mutator that turns them into real violations, and demands the target rule fire.
Package mutation is the W4 mutation harness (w4-02; test strategy §4): it takes the corpus's "ok" fixtures — code the linter correctly stays silent on — applies a mutator that turns them into real violations, and demands the target rule fire.
perf
Package perf hosts the w4-03 tier-4 harness tests (test strategy §2.4): determinism of the real binary's output across repeated runs (§5.4) and the edge-case behaviour contract (§5.5).
Package perf hosts the w4-03 tier-4 harness tests (test strategy §2.4): determinism of the real binary's output across repeated runs (§5.4) and the edge-case behaviour contract (§5.5).
render
Package render renders findings in the three output formats promised by the charter: pretty (human, grouped by rule), JSON (schema 1) and SARIF 2.1.0 (charter §6.6–6.8; implementation w2-05).
Package render renders findings in the three output formats promised by the charter: pretty (human, grouped by rule), JSON (schema 1) and SARIF 2.1.0 (charter §6.6–6.8; implementation w2-05).
robustness
Package robustness hosts the W4-05 hostile-input tests (GATE CH3, brief deliverable 1): the scanner's behaviour against malicious inputs, as opposed to the merely extreme ones of w4-03's edge cases (test-strategy §5.5 draws exactly this boundary).
Package robustness hosts the W4-05 hostile-input tests (GATE CH3, brief deliverable 1): the scanner's behaviour against malicious inputs, as opposed to the merely extreme ones of w4-03's edge cases (test-strategy §5.5 draws exactly this boundary).
Package rules hosts the R1xx–R6xx rule families: one metadata record per rule (id, slug, category, default severity, AIP reference, good/bad examples) stored as data and embedded into the binary at build time, plus the Go check functions and the registry that binds them (charter §3 and §5.1; implementation: w3-03..w3-06).
Package rules hosts the R1xx–R6xx rule families: one metadata record per rule (id, slug, category, default severity, AIP reference, good/bad examples) stored as data and embedded into the binary at build time, plus the Go check functions and the registry that binds them (charter §3 and §5.1; implementation: w3-03..w3-06).
tools
audit-check command
audit-check — the FP/FN audit harness (test-strategy §7, task w4-04).
audit-check — the FP/FN audit harness (test-strategy §7, task w4-04).
corpus-check command
corpus-check runs the adversarial corpus manifest (testdata/adversarial, test-strategy §3.6) against a vanguard binary and reports agreement.
corpus-check runs the adversarial corpus manifest (testdata/adversarial, test-strategy §3.6) against a vanguard binary and reports agreement.
gen-bench-repo command
Command gen-bench-repo generates the vanguard performance bench repository (w4-03; test strategy §5.1).
Command gen-bench-repo generates the vanguard performance bench repository (w4-03; test strategy §5.1).
perfbench command
Command perfbench drives the w4-03 performance + determinism bench (test strategy §5) against a sandbox build of vanguard.
Command perfbench drives the w4-03 performance + determinism bench (test strategy §5) against a sandbox build of vanguard.
qa-label command
qa-label applies the w4-04 DRY-RUN provisional verdicts to the machine sheet — PIPELINE QA ONLY (protocol §0: the gate labels the real sheet; this artifact is evidence that the merge path works end-to-end and is never presented as the audit result).
qa-label applies the w4-04 DRY-RUN provisional verdicts to the machine sheet — PIPELINE QA ONLY (protocol §0: the gate labels the real sheet; this artifact is evidence that the merge path works end-to-end and is never presented as the audit result).
sarif-validate command
sarif-validate checks that SARIF documents are valid SARIF 2.1.0 — the GATE CH3 re-validation of vanguard's SARIF output (w4-05 deliverable 2) over the adversarial corpus and the military-youth audit sample.
sarif-validate checks that SARIF documents are valid SARIF 2.1.0 — the GATE CH3 re-validation of vanguard's SARIF output (w4-05 deliverable 2) over the adversarial corpus and the military-youth audit sample.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL