Files
vulncheck/alembic/versions/061_add_jev_config_hint.py
T
vulncheck dad8f4e0e0 feat(triage): patch plan ranked by exploited CVEs, with an advisory Jev config hint
The findings list says what is wrong, not what to patch first: one Chrome
update closes a hundred rows, and one KEV on a single host matters more
than all of them. The new /patch-plan page (GET
/api/v1/vulnerabilities/patch-plan) groups open findings (open,
patch_failed) on ACTIVE assets by the product to update, using the
vulnerability_packages rows, else package_name, else the CVE id. Each
group shows hosts, findings, CVEs, the fixed versions as reported (never
compared) and summed/max priority_score. Groups with CVEs exploited in the
wild (KEV / EUVD) rank first, then by summed priority. Every number comes
from data the tool already scores.

TypeSafe Jev (via OpenRouter Decisions, pinned typesafe/jev-1.13) is asked
one question per open CVE, nightly at 06:00 after the last ingest: is it
only exploitable with an optional feature or a non-default configuration?
It is the one triage question no feed answers. KEV, EUVD, EPSS, SSVC and
the CVSS vector already cover exploitation and attack vector, and exposure
is a property of the host, not of the CVE text. The probability is stored
in vulnerabilities.jev_config_dependent (migration 061); CVEs at 0.7 or
above show under "Check config" on the plan. It never closes a finding
(cross-source contract) and never enters priority_score. The job is off by
default (Settings, AI card, or JEV_TRIAGE_ENABLED) and reuses the
OpenRouter key. It sends only public CVE text. An account or network
failure stops the run unstamped; a failure specific to one CVE skips only
that CVE, so the job cannot stall on the same CVE every night.
2026-09-19 09:40:28 +02:00

29 lines
961 B
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Add vulnerabilities.jev_config_dependent + jev_checked_at
Revision ID: 061
Revises: 060
Create Date: 2026-09-19 10:00:00.000000
Jev's answer to "only exploitable with a non-default configuration?", per CVE
text. An operator hint on the patch plan; it never closes a finding and never
enters priority_score. No backfill: the nightly Jev job fills it when enabled.
Idempotent (IF NOT EXISTS), same shape as 053–058.
"""
from alembic import op
revision = "061"
down_revision = "060"
branch_labels = None
depends_on = None
def upgrade() -> None:
op.execute("ALTER TABLE vulnerabilities ADD COLUMN IF NOT EXISTS jev_config_dependent DOUBLE PRECISION;")
op.execute("ALTER TABLE vulnerabilities ADD COLUMN IF NOT EXISTS jev_checked_at TIMESTAMP;")
def downgrade() -> None:
op.execute("ALTER TABLE vulnerabilities DROP COLUMN IF EXISTS jev_checked_at;")
op.execute("ALTER TABLE vulnerabilities DROP COLUMN IF EXISTS jev_config_dependent;")