Repository navigation
feat: let a project plugin refine the findings of a run - #108
Merged
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.rule_id,span,function,messagemust be unchanged.severity,confidence, and new metadata keys. Nothing else; a dropped or added finding is rejected too.refined_by(plugin names, comma-joined when several refine) andoriginal_severity/original_confidence— set once, so the first original survives a chain.RefinementErrornaming the plugin, before the policy and suppressions run.apply_refinementinplugins/api.pyowns the check; the engine calls it afteranalyze_project.Tests
exposure: the finding carries both, the trace, and its originalsourceevidence.rule_id, droppingsourcefrom 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-prioritizationexists, deciding whether the reporter orders on severity/confidence (which refinement already moves) or on a metadata key is a small separate change.