Skip to content

feat: let a project plugin refine the findings of a run - #108

Merged
SizzleUnrlsd merged 3 commits into
mainfrom
feat/refine-findings
Sep 22, 2026
Merged

SizzleUnrlsd merged 3 commits into
mainfrom
feat/refine-findings

Conversation

@SizzleUnrlsd

Copy link
Copy Markdown
Contributor

Closes #106.

Contract

ProjectPlugin.refine(ctx, findings) -> Sequence[Finding], identity by default, called once per project plugin in load order after every plugin has reported.

  • Identity preserved: rule_id, span, function, message must be unchanged.
  • Evidence preserved: every metadata key the finding carried keeps its value.
  • Refinable fields, explicitly: severity, confidence, and new metadata keys. Nothing else; a dropped or added finding is rejected too.
  • Trace: a reclassified finding gains refined_by (plugin names, comma-joined when several refine) and original_severity / original_confidence — set once, so the first original survives a chain.
  • Violations raise RefinementError naming the plugin, before the policy and suppressions run.

apply_refinement in plugins/api.py owns the check; the engine calls it after analyze_project.

Tests

  • A plugin lowers severity and adds exposure: the finding carries both, the trace, and its original source evidence.
  • Parametrised: changing rule_id, dropping source from metadata, dropping a finding → RefinementError.

904 passed; ruff and mypy clean. Plugin guide documents the contract.

Not in this PR

The text reporter does not sort findings today; once exposure-prioritization exists, deciding whether the reporter orders on severity/confidence (which refinement already moves) or on a metadata key is a small separate change.

ProjectPlugin.refine(ctx, findings) is called once with every finding after
all plugins have reported. It may change severity and confidence and add
metadata; the engine rejects a refinement that changes the rule, location,
message or evidence of a finding, or drops one, and records refined_by and
the original values on every reclassified finding.

Closes #106
@SizzleUnrlsd SizzleUnrlsd self-assigned this Sep 22, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit ead8621 into main Sep 22, 2026
10 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the feat/refine-findings branch September 22, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin API: let a project plugin refine the findings of a run

1 participant