Skip to content

Let findings be dismissed as false positives or accepted risk - #33

Merged
0xCardinal merged 1 commit into
mainfrom
feat/dismiss-findings
Sep 27, 2026
Merged

0xCardinal merged 1 commit into
mainfrom
feat/dismiss-findings

Conversation

@0xCardinal

Copy link
Copy Markdown
Owner

Closes #22.

What it does

  • Dismiss / Restore in the issue details panel, with an optional reason (up to 500 chars).
  • Dismissed findings leave the graph colouring, counts, search and the node panel. The Results panel shows "N dismissed findings hidden", and the Findings table has a Show N dismissed toggle that lists them greyed out.
  • A dismissal is remembered for the audited repository or action, so it applies to later audits of it and to runs stored before it was made. Findings from pasted-YAML audits can't be dismissed, since there's no target to remember them against.

How

  • backend/dismissals.py: every issue gets a fingerprint: a hash of its node id, type, identifying fields and message, leaving out what shifts between runs (line_number, latest_version, days_old, commit_date, digits in the message). A finding mirrored onto a package or image node shares its source's fingerprint.
  • DismissalStore keeps dismissals per target in data/dismissals.json. They are applied when an audit is built and whenever a stored analysis is read.
  • GraphBuilder leaves dismissed issues out of issue_count, node severity and the statistics, and adds dismissed_issues. It can also rebuild itself from stored graph data.
  • New endpoints: POST /api/analyses/{id}/dismissals, DELETE /api/analyses/{id}/dismissals/{fingerprint}, GET /api/dismissals?target=.

Worth knowing

  • Tested on all 201 stored analyses: the fingerprint never merged two distinct findings. If the finding itself changes (e.g. its step is edited), a dismissal of it no longer applies.
  • unfiltered_network_traffic sometimes reports the exact same finding twice on one workflow. It's now counted and listed once, so some existing analyses show two fewer findings.
  • Storage is server-side for now. A repo-level ignore file for team-wide and CI use could build on the same fingerprints.

Testing

  • 17 new backend tests (fingerprint stability, mirrors, stats, store, endpoints); the full suite passes (558 tests).
  • Checked in the browser against a stored analysis: dismissing one finding took every count from 148 to 147 and applied to other stored runs of the repo; restoring brought everything back to 148.
  • Usage page, API reference (regenerated) and AGENTS.md are updated.

🤖 Generated with Claude Code

Each issue now carries a fingerprint: its node, type, identifying fields
and message, leaving out what shifts between runs (line numbers, latest
version, commit ages, digits in the message). Dismissals are stored per
repository or action in data/dismissals.json and applied when an audit
is built and whenever a stored analysis is read, so they hold across
re-runs. Dismissed issues drop out of node counts, severity and
statistics; dismissed_issues counts them.

The issue details panel gets Dismiss (with an optional reason) and
Restore. Every view works on active findings; the findings table can
show dismissed ones. Findings reported twice on one node are now
counted and listed once.

Closes #22

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying actsense with  Cloudflare Pages  Cloudflare Pages

Latest commit: 14eab24
Status: ✅  Deploy successful!
Preview URL: https://5fd233a1.actsense.pages.dev
Branch Preview URL: https://feat-dismiss-findings.actsense.pages.dev

View logs

@0xCardinal
0xCardinal merged commit 4001f97 into main Sep 27, 2026
10 checks passed
@0xCardinal
0xCardinal deleted the feat/dismiss-findings branch September 27, 2026 21:20
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.

Feature: mark or dismiss false positive findings

1 participant