// changelog
v1.19.0
Every finding now carries a stable rule id and fingerprint, baselines and policies can target rules, reviews can be exported as SARIF for GitHub Code Scanning, and any OpenAI-compatible endpoint works as a provider through config alone.
Released October 18, 2026
Added
- Finding identity:
rule_idandfingerprinton every structured finding in--jsonoutput (schemastays1; both fields are additive and omitted when unset).rule_idcomes from a closed taxonomy of 30 ids (sec.injection,correctness.error-handling,test.flaky, …,general.other); an empty or unknown value from the model is normalised togeneral.other.fingerprintis a local hash of the file, the rule id and the symbol, so it survives rewording and unrelated edits above the finding. See Rule taxonomy. - Baseline v2.
.commitbrief/baseline.jsonnow stores finding fingerprints, so a reworded title no longer unhides a baselined finding.--update-baselinealways writes v2; an existing v1 file keeps matching the old way and prints a one-time warning. - Policy
rules..commitbrief/policy.ymlacceptsrules.deny(a single finding of that rule blocks) andrules.allow(findings of that rule are waived from thresholds andtotal). Entries are taxonomy ids or<category>.*. The guard verdict gains an additivewaivedcount. Policies withoutrulesbehave as before. - Inline
[rule_id]markers.commitbrief-ignore[sec.injection]: reasonsilences only that rule’s findings;[high]works as before. An unknown token is treated as an unscoped marker and warned about. --sarifon the root review and oncommitbrief diffwrites findings as a SARIF 2.1.0 log for GitHub Code Scanning (commitbrief diff <range> --sarif -o commitbrief.sarif). Each result carries the rule id, level, location and a partial fingerprint.--sarifcannot be combined with--json,--markdown,--suggest-commit,--clior--show-prompt, and is refused with a CLI-backed provider. It fails closed: a response that never parsed into structured findings produces an error and no file. A diff that is empty after filtering is not a failure: it writes a valid log withresults: []. See SARIF.openai-compatibleprovider points CommitBrief at any OpenAI-compatible chat-completions endpoint (vLLM, LM Studio, OpenRouter, …) through config alone.providers.openai-compatible.base_urlandmodelare required; the key is optional, for auth-less local servers. Without a declared price the cost shows asunknown. A plainhttp://base_urlto a non-loopback host prints a one-line warning on stderr (the request is still sent), anddoctorreports anapi_key_envthat points at an empty variable as a failure. See Providers.providers.<name>.api_key_envon every API provider reads the credential from the named environment variable and takes precedence over the provider’s fixed variable andapi_key. Set but empty is an error.providers.<name>.context_windowon every API provider overrides the built-in context window used by the token preflight anddry-run.
Changed
- Migrating a v1 baseline to v2 is lossy; re-run
--update-baselineto adopt v2. - The review prompt now includes the rule taxonomy. The cache key includes the system prompt, so existing cache entries miss once after upgrading.
- Any
commitbrief-ignore[token]:line is now a marker, including tokens that were not recognised before (for example[todo-1]); such lines now suppress findings on that line, as an unscoped marker, and print a warning. dry-runprints aProvider unavailable: <reason>line on stderr when the configured provider cannot be built, instead of silently estimating without it. The estimate is still printed.--verbosenow also prints debug logs on stderr.
Fixed
- Inline suppression leaked across files. A
commitbrief-ignoremarker at line N of one file also suppressed a finding at line N of another file in the same diff. Markers are now keyed by file and line, so findings that were wrongly suppressed before reappear after upgrading. - deepseek, mistral, cohere no longer send
OpenAI-OrganizationandOpenAI-Projectheaders derived fromOPENAI_ORG_ID/OPENAI_PROJECT_IDto those third-party endpoints. The API key was never affected.