A Finding is the smallest unit of output from CodeCharter. It represents a concrete location in code where a specific rule matched.
Anatomy of a Finding
Every Finding has:
| Field | Content |
|---|---|
Rule |
Slug and display name of the rule, e.g. datetime-direct-usage |
Severity |
info, warn, or error (machine-readable output spells the middle level warning) |
Category |
Freely chosen; groups related rules |
Entity |
Name and kind (class, method, ...) of the code element that matched |
File |
Absolute or relative path to the file |
Line |
Line number |
Column |
Optional, column number |
Message |
What was specifically found here |
Description |
What the rule checks (from @description in the rule) |
Recommendation |
What to do about it (from @recommendation in the rule) |
Fingerprint |
Stable, line-independent ID of the finding across runs; used by --baseline to suppress known findings (see Baseline) |
In JSON output, findings appear as violations next to a summary block:
{
"summary": {
"totalViolations": 1,
"totalTypes": 128,
"totalMethods": 932,
"durationMs": 28400
},
"violations": [
{
"ruleId": "datetime-direct-usage",
"ruleName": "Direct DateTime/DateTimeOffset usage instead of TimeProvider",
"severity": "warning",
"category": "Testability",
"entityName": "PricingEngine.CalculatePrice",
"entityKind": "Method",
"filePath": "src/Domain/PricingEngine.cs",
"lineNumber": 42,
"column": 18,
"message": "Direct call to DateTime.UtcNow",
"description": "Direct calls to DateTime.Now/UtcNow/Today make code untestable",
"recommendation": "Inject TimeProvider via constructor and call GetUtcNow()",
"fingerprint": "a1b2c3d4..."
}
]
}
Severities
CodeCharter has three severity levels.
info
A hint. Like every finding it fails the build by default; pass --fail-on warn
or --fail-on error if info findings should not gate the build. Good for
rules that catch nice-to-haves:
"this spot would be more readable with the following refactoring idea". Be
careful not to accumulate too many of these in day-to-day work, or they will be
ignored.
warn
A warning. By default it blocks the build like any other finding, and it is
visible in the output and in the editor. Good for conventions you want to
enforce collectively, such as async methods without a CancellationToken. Pass
--fail-on warn to gate only on warn and error, letting info findings
through.
error
An error. Reserved for violations that truly must not reach the main branch: broken architecture, security vulnerabilities, explicitly forbidden APIs.
Default --fail-on behavior: when no --fail-on flag is passed, any
finding of any severity (including warn and info) causes exit code 1. Exit
code 0 means zero findings at or above the active threshold. Use --fail-on warn
to allow info findings through, or --fail-on error to allow both info and
warn findings through without gating the build.
Which Severity to Use
Rule of thumb: as strict as necessary, as friendly as possible.
- error only when the violation would cause real harm (security, stability, contract breach).
- warn for conventions the team wants to enforce collectively, with the understanding that justified exceptions exist.
- info for style recommendations that are "better, but acceptable as-is".
A rule that uses only error because "if we're writing a rule it should have
teeth" is an anti-pattern. Within days, devs will reach for // codecharter-disable
instead of fixing the issue.
Overriding a rule's severity
You change a rule's severity in .codecharter/config.yml under overrides:, and switch a rule off entirely under ignore:. Both are addressed per rule by slug, not per file or per line. See Configuration file for the full set of sections.
# .codecharter/config.yml
version: 1
overrides:
datetime-direct-usage: # a built-in rule slug
severity: warning # error | warning | info
ignore:
- rule: empty-catch-block # switch this rule off entirely
To silence findings at a specific location instead, use a // codecharter-disable comment (see Suppressions).
Aggregation
In the build output, findings are sorted by severity, then file, then line.
Duplicate findings (same rule, entity, file, and line) are reported only once.
Use --severity <level> to set the minimum severity to display (default:
info, i.e. everything). At the end of the run there is a summary; severity
buckets with zero findings are omitted:
17 violations (3 errors, 14 warnings)
Analyzed 128 types, 932 methods in 28.4s
For exit code behavior and CI integration see Exit Codes and Output Formats.