Static analysis for Go contracts

Lock down the metadata that defines your API.

TagLock understands struct tags as one external contract—across serialization, validation, persistence, embedding, and version evolution.

go install github.com/theworker02/taglock/cmd/taglock@latest

taglock check ./...

internal/user/model.go:14:2
TAG104 duplicate JSON name "id"
  User.ID and User.LegacyID resolve to
  the same external field

internal/user/model.go:19:2
TAG301 external naming drift
  json="display_name"
  yaml="displayName"

internal/user/model.go:23:2
TAG401 sensitive field exposed
  PasswordHash is serialized as "password"
Go field typeJSON / YAML / XMLValidationStorageEvolution

One semantic engine

More than tag syntax.

Parse once, resolve the effective field surface, then evaluate the relationships that runtime libraries leave implicit.

01

Whole-struct analysis

Detect direct, promoted, inline, case-only, and embedded-field collisions with related source locations.

TAG104 · TAG105
02

Cross-namespace policy

Compare external names, ignore behavior, omission rules, and required namespaces across one coherent contract.

TAG301–TAG305
03

Type and security awareness

Validate options against Go types and flag public exposure of normalized sensitive-field identities.

TAG201 · TAG401
04

Contract evolution

Snapshot canonical wire surfaces, compare revisions, classify compatibility by direction, and enforce deprecation policy.

EVOL001–EVOL903
05

JSON compatibility intelligence

Model JSON v1 and v2 separately, surface uncertainty, and generate explicit runtime verification for opaque behavior.

JSONMIG001–010

Adopt incrementally

Local editor to release gate.

The same engine powers the CLI, go/analysis, custom vet tools, editor fixes, baselines, schemas, and CI reports.

  1. 1

    Check

    taglock check ./...

    Find semantic problems without changing source.

  2. 2

    Adopt

    taglock baseline create ./...

    Hide known history while reporting new findings.

  3. 3

    Snapshot

    taglock snapshot ./...

    Capture a deterministic external contract.

  4. 4

    Compare

    taglock compare --base main --head HEAD ./...

    Gate breaking and unknown changes.

Built for evidence

Static by default. Explicit when runtime proof is needed.

TagLock never claims certainty around arbitrary custom marshalers. It marks contracts partial or opaque, then lets projects generate reviewed fixture tests through an explicit command.

  • No project binary execution during static analysis
  • No automatic Git fetching or active-worktree mutation
  • No behavior-changing edits classified as safe
  • No runtime values or secrets in contract snapshots
Read the security model
SourceAST + types
NormalizeStruct contracts
ResolveNamespace surfaces
RulesProfilesSnapshots

Stable identifiers

Diagnostics built for automation.

Every finding carries a documented ID, severity, remediation, fingerprint, and fix-safety classification.

TextJSONMarkdownSARIF 2.1.0Suggested fixes

Open development

Help make Go contracts safer.

Contributions are welcome when they preserve determinism, compatibility, security, and a low false-positive rate.

Contribution guide