Test quality analysis via side effect detection for Go.
Line coverage tells you which lines ran. It does not tell you whether your tests actually verified anything.
A function can have 90% line coverage and tests that assert on nothing contractually meaningful — logging calls, goroutine lifecycle, internal stdout writes — while leaving the return values, error paths, and state mutations completely unverified. That function is dangerous to change, and traditional coverage metrics will not warn you.
Gaze fixes this by working from first principles:
- Detect every observable side effect a function produces (return values, error returns, mutations, I/O, channel sends, etc.).
- Classify each effect as contractual (part of the function's public obligation), incidental (an implementation detail), or ambiguous.
- Measure whether your tests actually assert on the contractual effects — and flag the ones they don't.
This produces three actionable metrics: Contract Coverage (percentage of contractual effects asserted on), Over-Specification Score (assertions on implementation details), and GazeCRAP (a risk score combining complexity with contract coverage). For details on each metric, see the Scoring and Quality Assessment concept docs.
Gaze requires no annotations, no test framework changes, and no restructuring of your code. It analyzes your existing Go packages as-is.
Full documentation is available in docs/:
- Getting Started — Install and produce meaningful output in under 10 minutes
- Concepts — Side effects, classification, scoring, quality metrics
- CLI Reference — Flags, defaults, and output formats for every command
- Guides — CI integration, AI reports, score improvement strategies
- Architecture — Package structure, data flow, contributing guide
- Porting — Language-agnostic contracts for building "Gaze for Python/Rust/etc."
brew install unbound-force/tap/gazego install github.com/unbound-force/gaze/cmd/gaze@latestgit clone https://github.com/unbound-force/gaze.git
cd gaze
go build -o gaze ./cmd/gazeRequires Go 1.25.0 or later. For platform notes and verification steps, see Installation.
Homebrew binaries are code-signed with an Apple Developer ID certificate and notarized by Apple's notary service. macOS Gatekeeper trusts the binary on first run -- no security overrides needed.
For maintainers: Signing requires 5 GitHub secrets (Apple Developer ID certificate + App Store Connect API key). See quickstart guide for setup instructions. When secrets are not configured, the release pipeline produces unsigned binaries without error.
Detect all observable side effects each function produces. Gaze detects 37 effect types across 5 tiers (P0–P4).
gaze analyze ./internal/analysis # All exported functions
gaze analyze -f ParseConfig ./internal/config # Specific function
gaze analyze --classify ./internal/analysis # With classification labels
gaze analyze --format=json ./internal/analysis # JSON outputFor all flags and options, see gaze analyze reference.
Compute CRAP scores by combining cyclomatic complexity with test coverage.
gaze crap ./... # Analyze all packages
gaze crap --coverprofile=cover.out ./... # Use existing coverage
gaze crap --max-crapload=5 ./... # CI mode: fail on thresholdFor the CRAP formula, GazeCRAP, quadrants, and fix strategies, see Scoring. For all flags, see gaze crap reference.
Assess how well a package's tests assert on contractual side effects.
gaze quality ./internal/analysis # Analyze test quality
gaze quality --target=LoadAndAnalyze ./internal/analysis # Specific function
gaze quality --verbose ./internal/analysis # Detailed mapping infoFor all flags, see gaze quality reference.
Orchestrate all analysis operations and pipe the results to an AI model for formatting.
gaze report ./... --ai=claude # Claude adapter
gaze report ./... --ai=opencode # OpenCode adapter
gaze report ./... --format=json # JSON only (no AI needed)
gaze report ./... --ai=claude --coverprofile=coverage.out # Reuse coverageFor adapter setup, CI integration, and all flags, see gaze report reference and AI Reports guide.
| Command | Description | Reference |
|---|---|---|
gaze self-check |
Run CRAP analysis on Gaze's own source code | self-check |
gaze docscan |
Scan repository for documentation files (JSON output) | docscan |
gaze schema |
Print the JSON Schema for gaze analyze --format=json output |
schema |
gaze init |
Scaffold OpenCode agent and command files | init |
Use threshold flags for CI enforcement. Gaze exits non-zero when limits are exceeded:
gaze crap --max-crapload=5 --max-gaze-crapload=3 ./...For complete GitHub Actions workflow examples, coverage profile reuse, and threshold selection guidance, see the CI Integration guide.
The analyze, crap, quality, and self-check commands support --format=text (default) and --format=json.
JSON output conforms to documented schemas. Use gaze schema to print the analysis report schema. See JSON Schemas for annotated examples.
After running gaze init, use the /gaze command in OpenCode for AI-assisted quality reporting:
/gaze ./... # Full report: CRAP + quality + classification
/gaze crap ./internal/store # CRAP scores only
/gaze quality ./pkg/api # Test quality metrics only
For setup details, see the OpenCode Integration guide.
- Direct function body only. Gaze analyzes the immediate function body. Transitive side effects (effects produced by called functions) are out of scope for v1.
- P3-P4 side effects not yet detected. The taxonomy defines types for stdout/stderr writes, environment mutations, mutex operations, reflection, unsafe, and other P3-P4 effects, but detection logic is not yet implemented for these tiers.
- GazeCRAP accuracy is limited. The quality pipeline is wired into the CRAP command and GazeCRAP scores are computed when contract coverage data is available. However, assertion-to-side-effect mapping accuracy is currently ~86% (target: 90%), primarily affecting cross-target assertions and go-cmp patterns (tracked as GitHub Issue #6).
- No CGo or unsafe analysis. Functions using
cgoorunsafe.Pointerare not analyzed for their specific side effects. - Single package loading. The
analyzecommand processes one package at a time. Use shell loops or scripting for multi-package analysis.
Apache License 2.0. See LICENSE for details.