Skip to content

Clarify SARIF formatter boundaries: framework-generic vs OSPS-specific #360

Description

@mlieberman85

Background

The SARIF formatter currently lives in packages/darnit-baseline/src/darnit_baseline/formatters/ and mixes:

  • Framework-generic SARIF emission (mapping CheckResult to SARIF result objects, run metadata, rule metadata lookup from TOML).
  • OSPS-baseline-specific pieces (control ID conventions, help URL patterns, severity mapping choices).

Problem

Other implementations (darnit-gittuf, darnit-reproducibility) that want SARIF output either reimplement the generic parts or import from darnit-baseline, which would violate the plugin isolation intent.

Proposal

Split the formatter along the boundary:

  • Move framework-generic SARIF emission into packages/darnit/src/darnit/formatters/sarif.py.
  • Leave OSPS-baseline-specific mapping in darnit-baseline as a thin adapter over the framework formatter.
  • Other implementations gain a shared base without cross-plugin imports.

Enforce boundary via test: the framework formatter must not reference OSPS control IDs or baseline-specific constants.

Scope

Refactor, no behavior change. Existing SARIF output for OSPS should be byte-identical (or documented deltas) after the split.

Related

  • Architecture review that surfaced this (Aug 2026)
  • Rule 1 (framework never imports implementations) in CLAUDE.md

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions