codeguard is a standalone Go service and CLI for repository checks across code quality, production reliability, data correctness, design boundaries, security, CI/CD hygiene, AI prompt governance, and repo-specific policy rules.
It now supports repository exclusions, baselines, waivers, changed-lines diff scans, SARIF output, GitHub annotations, custom rule packs, natural-language custom rules through an optional AI runtime, policy profiles, scan caching, doctor checks, rule discovery from the CLI, native TypeScript/Python quality, design, security, reliability, and data-correctness heuristics, and language-specific command checks.
For a user-facing glossary of every check family and subsection, see docs/checks.md.
AI-generated-code quality coverage includes an AI-failure-mode rule pack, slop_score artifacts, provenance-aware review policy hooks, local idiom drift checks, optional provider-backed hybrid triage and semantic review passes, natural-language custom rules through an optional AI runtime, and a verified-fix flow that only returns patches after isolated patch validation plus test reruns succeed.
Rule discovery APIs expose per-check metadata, including execution_model (go-native, language-agnostic, or command-driven) and language_coverage (fixed target languages, repository-wide, or configurable).
go install github.com/devr-tools/codeguard/cmd/codeguard@latestOr build from source:
make buildOther install paths:
- GitHub Releases: tagged archives for direct download
- Homebrew:
brew install devr-tools/tap/codeguard - GitHub Marketplace Action:
Devr Codeguard
npm (installs a prebuilt binary, no Go toolchain required):
npm install -g @devr-tools/codeguard
codeguard versionpip (installs a prebuilt binary per platform; the project is devr-codeguard
because the plain codeguard name is taken, but the command is still codeguard):
pip install devr-codeguard
codeguard version- name: Devr Codeguard
uses: devr-tools/codeguard@v1.1.1Or run in Docker:
docker build -t codeguard .
docker run --rm -v "$PWD:/workspace" -w /workspace codeguard scanFor local release automation:
make commit
make release
make release-check
make deployFor SDK consumers:
go get github.com/devr-tools/codeguard/pkg/codeguardcodeguard init
codeguard validate -config codeguard.yaml
codeguard doctor -config codeguard.yaml
codeguard scan -config codeguard.yaml
codeguard scan -config codeguard.yaml -memprofile /tmp/codeguard.heap.pprof
codeguard scan -config codeguard.yaml -folder ./internal/codeguard
codeguard scan -folder ./internal/codeguard -profile startup
codeguard scan -folder ./internal/codeguard -profile startup -set checks.quality=true -set output.format=json
codeguard scan-history
codeguard waivers audit -config codeguard.yaml
codeguard rules
codeguard profiles
codeguard explain security.hardcoded-credential
codeguard baseline -config codeguard.yaml -output codeguard-baseline.json
codeguard baseline audit -config codeguard.yaml -format json
codeguard baseline prune -config codeguard.yaml -check
codeguard baseline policy -config codeguard.yaml -compare-baseline /tmp/base-baseline.jsoncodeguard rules prints each rule's level, execution model, language coverage, section, and title. codeguard explain <rule-id> includes the same metadata for a single rule.
By default, codeguard looks for codeguard.yaml, codeguard.yml, or codeguard.json in the repository root. If those are missing, it also checks for the same file names inside a .codeguard/ directory.
If you point -config at a directory such as .codeguard, codeguard will look inside it for codeguard.* or config.* files.
Long-running scans report completed sections and a 30-second heap/GOMEMLIMIT heartbeat on stderr, leaving JSON, SARIF, GitHub, and CycloneDX stdout machine-readable. Pass -memprofile <path> to keep a rolling Go heap profile (written at startup, every heartbeat, and completion), then inspect it with go tool pprof <path>. Full scans skip dependency and generated trees named node_modules, vendor, and cdk.out at any depth; use exclude for repository-specific generated paths.
Use codeguard scan -folder <path> to scan only one folder. -path <path> is accepted as an alias. If no config file exists and you did not pass -config, folder scans use CodeGuard's built-in default config; add -profile startup, -profile strict, -profile enterprise, or -profile ai-safe to choose a default profile.
Use repeatable -set key=value flags to override config values from the terminal without writing a temporary config file. Keys use dotted YAML paths and are validated against the typed CodeGuard config; mistyped fields fail before the scan runs. String lists accept comma-separated values or a JSON string array.
codeguard scan -folder . \
-profile startup \
-set targets[0].language=go \
-set checks.quality=true \
-set checks.security=false \
-set checks.quality_rules.dead_code.enabled=true \
-set checks.quality_rules.dead_code.mode=toolchain \
-set checks.quality_rules.dead_code.go.entrypoints=./cmd/codeguard \
-set output.format=jsonFor agent bootstrap flows, the shortest useful commands are:
codeguard scan -folder ./internal/codeguard -profile startupText output includes ANSI color and emoji markers by default. Set NO_COLOR=1 if you want plain terminal output.
Run codeguard waivers audit -config codeguard.yaml after upgrading CodeGuard to find waiver cleanup candidates. The audit scans with waiver instrumentation enabled and reports waivers that still match findings, are unused in the current scan, are expired, or point at unknown rules. When a previous audit snapshot exists from a different CodeGuard version, the output only marks a waiver as stale after upgrade if the same waiver matched findings before and now matches none under a comparable config and scan scope.
If you want a JSON starting point instead, use examples/codeguard.json.
For production rollout, start in a narrow mode and expand deliberately:
- Run
codeguard doctorandcodeguard validatein CI first so config and toolchain issues fail early. - Start with
codeguard scan -mode diffon pull requests so only changed lines and diff-aware checks gate merges. - Create a baseline for legacy findings with
codeguard baselinebefore turning on full-repo enforcement. - Enable stricter families such as
security,reliability,data,design,contracts,performance, andsupply_chainincrementally per repository. - Use
codeguard rulesandcodeguard explain <rule-id>to document what a failure means before asking teams to act on it.
When a scan fails:
failfindings should block merge or release until fixed, waived, or baselined intentionally.warnfindings are non-blocking by default and are best used to drive cleanup, ownership, or gradual policy hardening.- section names such as
Design Patterns,Security, orCode Qualitytell you what kind of action is expected. - rule IDs are stable handles for waivers, baselines, dashboards, and agent workflows.
Baseline creation accepts all findings visible in that scan; it is not a cleanup
operation. Use baseline audit to classify an existing baseline without adding
findings, and baseline prune -check in CI to detect stale, invalid, or duplicate
entries. After review, baseline prune -write atomically removes stale entries;
-output <path> writes a candidate instead of replacing the source.
An entry remains active when its exact fingerprint, line-shift-resilient context fingerprint, or path-insensitive content fingerprint matches a current finding. Identical snippets can legitimately collide on context or content fingerprints. Audits report those collisions and preserve every matching entry; pruning does not impose one-to-one matching or change scan suppression behavior.
Opt-in governance rejects suppression growth and selected new rule families:
baseline:
path: codeguard-baseline.json
governance:
max_entries: 9771
forbid_growth: true
require_no_stale_entries: true
prohibited_new_rule_prefixes: [security., defensive., error.]
sample_limit: 3
ownership:
- pattern: "services/**"
owner: servicesbaseline policy -compare-baseline compares exact entries with a trusted base
branch baseline. Existing prohibited-family debt remains allowed; only additions
violate that policy. Use scan -include-suppressed -format json when a consumer
needs individual baseline, waiver, and inline suppression records. Default scan
output remains unchanged.
Import the SDK from github.com/devr-tools/codeguard/pkg/codeguard.
package main
import (
"context"
"log"
"github.com/devr-tools/codeguard/pkg/codeguard"
)
func main() {
cfg := codeguard.ExampleConfig()
report, err := codeguard.Run(context.Background(), cfg)
if err != nil {
log.Fatal(err)
}
_ = report
}