Skip to content

fix(output): handle findings object + locations/rules in SARIF, wire into ci#155

Merged
tim-thacker-nullify merged 1 commit into
mainfrom
fix/sarif-and-ci
May 29, 2026
Merged

fix(output): handle findings object + locations/rules in SARIF, wire into ci#155
tim-thacker-nullify merged 1 commit into
mainfrom
fix/sarif-and-ci

Conversation

@tim-thacker-nullify

Copy link
Copy Markdown
Member

Claude

Why

The SARIF formatter (internal/output/sarif.go) only accepted a top-level JSON array or a {type,data} wrapper, so nullify findings -o sarif failed — the findings command emits {"findings":[...],"total":N}. The output also emitted only ruleId/level/message, with no locations[] (consumers couldn't place findings) and no rules[] driver section (so ruleId references dangled).

The ci command also didn't expose SARIF at all, ci gate reported truncated counts (it queried with limit=1 then counted the items array), and it only failed when all scanner requests errored — silently passing if some scanners failed.

What

internal/output/sarif.go

  • Unwrap the {findings,total} object shape, in addition to the existing top-level array and {type,data} wrapper.
  • Emit a locations[] entry per finding from common location keys: filePath/file/path + startLine/line/lineNumber for code, and uri/url for DAST.
  • Emit a distinct rules[] array under tool.driver.rules from the rule IDs seen, so references resolve.
  • Severity → level mapping preserved (critical/high → error, medium → warning, low/info → note, unknown → warning). Defensive against missing fields (no panics).
  • Exposed SARIFBytes() for reuse by ci report.

cmd/cli/cmd/root.go

  • --output/-o usage string now lists sarif.

cmd/cli/cmd/ci.go

  • ci report gains a --format flag: markdown (default) or sarif.
  • ci gate counts via the response total field instead of the limit-truncated items array, for accurate counts.
  • ci gate is now fail-closed: any scanner request error fails the gate (non-zero exit) instead of only failing when every request errors.

Tests

  • Table-driven SARIF tests covering the {findings,total} object, locations, rules, dedup, DAST url locations, wrapped per-type results, and missing-field defensiveness. Existing tests still pass.

Verification

  • GOWORK=off CGO_ENABLED=0 go build ./...
  • GOWORK=off go vet ./...
  • GOWORK=off go test ./...
  • golangci-lint run (0 issues)

🤖 Generated with Claude Code

…into ci

The SARIF formatter only accepted a top-level JSON array or a {type,data}
wrapper, so `findings -o sarif` failed because the findings command emits
`{"findings":[...],"total":N}`. It also emitted only ruleId/level/message,
with no `locations[]` (consumers couldn't place findings) and no `rules[]`
driver section (so ruleId references dangled).

Changes:
- internal/output/sarif.go: unwrap the {findings,total} object shape (plus
  the existing array and {type,data} wrapper); emit a `locations[]` entry
  from common location keys (filePath/file/path + startLine/line/lineNumber
  for code, uri/url for DAST); emit distinct `rules[]` under
  tool.driver.rules so references resolve. Defensive against missing fields.
  Expose SARIFBytes() for reuse.
- cmd/cli/cmd/root.go: include `sarif` in the --output flag usage string.
- cmd/cli/cmd/ci.go:
  - `ci report` gains a --format flag (markdown default, or sarif).
  - `ci gate` now counts via the response `total` field instead of the
    limit-truncated items array, so reported counts are accurate.
  - `ci gate` is fail-closed: any scanner request error fails the gate
    (exit non-zero) rather than only failing when all requests error.
- internal/output: table-driven SARIF tests covering the {findings,total}
  object, locations, rules, dedup, and missing-field defensiveness.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tim-thacker-nullify tim-thacker-nullify added the minor Minor version updates (features) label May 26, 2026
@tim-thacker-nullify

Copy link
Copy Markdown
Member Author

Claude

Status check (2026-05-28): still relevant. Verified on main:

  • internal/output/sarif.go (134 lines) still only accepts a top-level array or {type,data} wrapper — findings -o sarif against the unified {findings,total} shape still breaks.
  • No locations[] emitted, no rules[] driver section.
  • ci report has no --format flag (Short: "Generate a markdown summary for PR comments"); ci gate still counts the truncated items array.

Nothing on main supersedes any of it. Recommend rebase + un-draft.

@tim-thacker-nullify
tim-thacker-nullify marked this pull request as ready for review May 29, 2026 13:44
@tim-thacker-nullify
tim-thacker-nullify merged commit c740b98 into main May 29, 2026
3 checks passed
@tim-thacker-nullify
tim-thacker-nullify deleted the fix/sarif-and-ci branch May 29, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Minor version updates (features)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant