Skip to content
Blog

Configuration

Running gohawk without selection flags runs its core checks:

Terminal window
gohawk ./...

Every check carries a tier that records how much trust it has earned:

Tier Runs by default Meaning
core yes precision demonstrated on the repository audit and guarded by the precision replay
experimental no heuristic audits that may change or be retired

Use gohawk list to see every analyzer with its tier, and gohawk list -checks for the checks themselves. An analyzer’s tier is the most trusted tier among its checks; it runs whenever one of its checks is selected.

Terminal window
gohawk list
gohawk list -checks

Raise the tier ceiling to run experimental checks too:

Terminal window
# Run everything, including experimental audits.
gohawk -tier=experimental ./...

Choose what runs

Use analyzer names with -enable and -disable:

Terminal window
# Run two analyzers explicitly.
gohawk -enable=channelsafety,lockorder ./...
# Keep the default set, except channelsafety.
gohawk -disable=channelsafety ./...
# Run every analyzer and check at every tier.
gohawk -enable-all ./...

Naming an analyzer runs its core checks. Its experimental checks join only under -tier=experimental or when named by check ID.

You can also select a whole group:

Terminal window
# Run the concurrency group.
gohawk -enable-groups=concurrency ./...
# Run everything except the resources group.
gohawk -enable-all -disable-groups=resources ./...

To select one check rather than its whole analyzer, use the stable ID shown by gohawk list -checks:

Terminal window
# Run one experimental audit alongside the core checks.
gohawk -enable-checks=producerlifecycle/stopped-loop-send ./...
# Keep lockorder enabled, but omit one of its checks.
gohawk -disable-checks=lockorder/recursive-acquire ./...

Selections combine. Individual analyzer choices take precedence over group choices, and disabled checks are removed last. Selecting a check also enables its analyzer. Unknown or repeated names are reported as errors.

Use gohawk doc when you want to inspect an analyzer or check:

Terminal window
gohawk doc lockorder
gohawk doc lockorder/contradictory-order

These selection flags also work when gohawk runs through go vet -vettool.

Test files

gohawk checks production code, so _test.go files are skipped by default: their functions are not analyzed, they do not count as callers or users of package state, and no findings are reported in them. Fixture files, table-driven tests, and intentionally orphaned helper processes are usually true by the letter of a policy and rarely worth acting on. To analyze and report them anyway:

Terminal window
gohawk -gohawk-include-tests ./...

The reviewed precision cohorts replay with this flag so labels inside test files stay meaningful.

No analyzer options

Analyzers have no options: each check reports the same things in every project. Choose what runs with the selection flags above.

Diagnostic-only analysis

gohawk reports problems and their source locations. It does not offer or apply source edits; choose the appropriate correction for your code.

Ignore an intentional finding

Put an ignore comment on the flagged line or the line above it:

//gohawk:ignore goroutineownership worker belongs to the process lifecycle
go serveMetrics()

An ignore applies to one analyzer. The explanation is optional, but adding one helps future readers understand the decision.

Investigate a decision

When a diagnostic is surprising, tracing can show why gohawk reported or rejected it. Write the trace to a file:

Terminal window
gohawk -enable=goroutineownership \
-gohawk-trace=goroutineownership \
-gohawk-trace-file=trace.jsonl ./...

For a large run, narrow the output to the proof of one finding. Selection follows the candidate a proof serves rather than the position of each step, so the whole chain is kept, including the steps that judge a callee in another file and those that carry no position of their own:

Terminal window
gohawk -gohawk-trace=all \
-gohawk-trace-candidate=path/to/file.go:42 \
-gohawk-trace-file=trace.jsonl ./...

Tracing is off by default and does not change which diagnostics are reported. Without -gohawk-trace-file, trace records are written to standard error.

Evidence records carry the SSA text of the instruction they judged. To see the surrounding SSA form, which is what the analyzers reason over, print it for a package or one function:

Terminal window
gohawk ssa -func serveWorker ./internal/server

The dump uses the same builder as the analyzers, includes the function literals created inside the selected function, and accepts -tests to load a package’s test variant. It is a debugging aid; SSA text changes across Go versions, so do not pin it in fixtures.

Cross-package lifecycle evidence comes from summaries of exported functions. To see what a package’s functions are proven to do with their parameters, and which imported summaries its calls resolve to, print the facts:

Terminal window
gohawk facts -func CloseAll ./internal/server

Each line names a parameter and the masks proven for it on every return, such as Closed or Invoked. A summarized function always appears, even with no proven mask; a function missing from the dump was never summarized, and consumers treat calls to it as unknown.