Skip to content

feat(vulnerability): add status field + carry-over across re-scans#1240

Open
ocervell wants to merge 1 commit into
mainfrom
feat/vuln-status-restore
Open

feat(vulnerability): add status field + carry-over across re-scans#1240
ocervell wants to merge 1 commit into
mainfrom
feat/vuln-status-restore

Conversation

@ocervell

@ocervell ocervell commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a status field to the Vulnerability finding type (NEW | ACKNOWLEDGED | FIXED, default NEW) and makes it carry over across re-scans. This is the secator core layer (§1) of the Vulnerability status feature.

Repo 1/3 of Vulnerability status (secator → secator-api → secator-ui).

The field (output_types/vulnerability.py)

  • New status: str = field(default='NEW', compare=False)compare=False so it does not affect dedup equality; identity stays name/id/matched_at.
  • __post_init__ normalizes/validates: empty / None / unknown → 'NEW', uppercased; allowed set is NEW / ACKNOWLEDGED / FIXED (Vulnerability.STATUSES).
  • Added STATUS to _table_fields so it renders; added STATUS = 'status' to definitions.py.

Carry-over behavior

  • Added 'status' to duplicate_main_copy_fields defaults of both MongodbAddon and SqliteAddon (config.py).
  • hooks/_dedup.py (compute_duplicate_updates): introduced a small _is_unset(field, value) helper. For status it treats '' / None / 'NEW' as unset; all other fields keep the generic not value emptiness check. Applied to both the previous-value guard and the current-value copy condition, so a prior ACKNOWLEDGED/FIXED is copied forward onto a re-found main whose status is still the default NEW, while a never-touched vuln stays NEW.

Tests

  • tests/unit/test_output_types.py (TestVulnerabilityStatus): default NEW; empty/None/unknown coerce to NEW; valid values preserved + uppercased + trimmed; status does not affect equality or _compare_key().
  • tests/unit/test_dedup.py (TestComputeDuplicateUpdates): prior ACKNOWLEDGED copies onto a new NEW main; a new FIXED main is not overwritten; a prior NEW is not carried; non-status fields keep not value semantics.

All 59 relevant unit tests pass; flake8 secator/ is clean (matches CI secator test lint). Pre-existing test_config.py failures are an unrelated env-fixture issue (SECATOR_DIRS_DATA), present on origin/main without these changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01P5vSjfkBuGAAHdKxHS3ySm

Summary by CodeRabbit

  • New Features

    • Added vulnerability status tracking with supported states like NEW, ACKNOWLEDGED, and FIXED.
    • Status values are now normalized automatically for consistent display and handling.
  • Bug Fixes

    • Improved duplicate-item handling so status information carries forward correctly without overwriting finalized statuses.
    • Prevents empty or placeholder status values from being treated as real updates.

Recreates #1209 (merged in 0d7bf7d, then reverted by #1234). Same changes, re-applied on top of current main.

Add a `status` field to the Vulnerability output type (NEW / ACKNOWLEDGED /
FIXED, default NEW), marked compare=False so dedup identity (name/id/matched_at)
is unchanged. Normalize/validate in __post_init__ (coerce empty/None/unknown to
NEW, uppercase) and display it via _table_fields.

Carry status across re-scans: add `status` to the duplicate_main_copy_fields
defaults of MongodbAddon and SqliteAddon, and in compute_duplicate_updates treat
a status of ''/None/'NEW' as unset (per-field sentinel) so a prior
ACKNOWLEDGED/FIXED carries forward onto a re-found main whose status is still the
default NEW, while never-touched vulns stay NEW. Other fields keep the generic
`not value` emptiness check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5vSjfkBuGAAHdKxHS3ySm
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46127623-6369-4c18-9e9e-e6f50aec5ced

📥 Commits

Reviewing files that changed from the base of the PR and between b556414 and 4a0a027.

📒 Files selected for processing (6)
  • secator/config.py
  • secator/definitions.py
  • secator/hooks/_dedup.py
  • secator/output_types/vulnerability.py
  • tests/unit/test_dedup.py
  • tests/unit/test_output_types.py

Walkthrough

Adds a status field ('NEW' default) to the Vulnerability dataclass with normalization in __post_init__. Introduces _is_unset in the dedup hook so status='NEW' is treated as unset for copy-forward decisions. Registers 'status' in duplicate_main_copy_fields for MongoDB and SQLite addons, and adds the STATUS constant to definitions.

Changes

Vulnerability Status and Dedup Carry-Forward

Layer / File(s) Summary
Vulnerability status field and normalization
secator/definitions.py, secator/output_types/vulnerability.py
Adds STATUS = 'status' constant, defines status: str = 'NEW' field on Vulnerability, introduces STATUSES tuple, adds STATUS to _table_fields, and normalizes status to uppercase in __post_init__ (coercing unknown/empty values to 'NEW').
_is_unset helper and dedup copy-forward
secator/hooks/_dedup.py
Introduces _is_unset(field, value) treating status='NEW' (and None/blank) as unset; updates compute_duplicate_updates field-copy loop to gate copying on _is_unset for both previous and current values.
Addon config update
secator/config.py
Adds 'status' to duplicate_main_copy_fields for both MongodbAddon and SqliteAddon.
Unit tests
tests/unit/test_output_types.py, tests/unit/test_dedup.py
TestVulnerabilityStatus covers defaulting, coercion, uppercasing, and equality semantics; TestComputeDuplicateUpdates covers status carry-forward, preservation, non-carry-forward of 'NEW', and verified field copy behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • freelabz/secator#864: Configures duplicate_main_copy_fields in secator/config.py for MongoDB selective field copying during tag_duplicates—the same mechanism this PR extends to include status.
  • freelabz/secator#1209: Directly related to adding/normalizing Vulnerability.status and adjusting compute_duplicate_updates to treat 'NEW' as unset, overlapping with this PR's core changes.

Suggested labels

feature:vulnerability-status

Poem

🐇 Hippity-hop, a status is born,
'NEW' means nothing—don't carry it on!
ACKNOWLEDGED travels, FIXED holds its ground,
The dedup hook copies what truly is found.
A bunny normalizes all in a bound! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding vulnerability status support and preserving it across re-scans.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/vuln-status-restore

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant