Documentation
¶
Overview ¶
Package store provides SQLite database access for benchmrk.
Index ¶
- Variables
- func IsValidAnnotationStatus(status AnnotationStatus) bool
- func IsValidDisposition(d Disposition) bool
- func IsValidGroupRole(role string) bool
- type Annotation
- type AnnotationGroup
- type AnnotationGroupMember
- type AnnotationSet
- type AnnotationStatus
- type CorpusProject
- type Disposition
- type Evidence
- type ExecutionMode
- type Experiment
- type Finding
- type FindingDisposition
- type FindingMatch
- type Run
- type RunStatus
- type Scanner
- type Store
- func (s *Store) AddAnnotationToGroup(ctx context.Context, groupID, annotationID int64, role string) error
- func (s *Store) AddProjectToExperiment(ctx context.Context, experimentID, projectID int64) error
- func (s *Store) AddScannerToExperiment(ctx context.Context, experimentID, scannerID int64) error
- func (s *Store) AddVulnAnnotator(ctx context.Context, vulnID int64, annotatedBy string) error
- func (s *Store) AddVulnCWE(ctx context.Context, vulnID int64, cweID string) error
- func (s *Store) AnnotationHash(ctx context.Context, projectID int64) (string, error)
- func (s *Store) BulkCreateAnnotations(ctx context.Context, annotations []Annotation) error
- func (s *Store) BulkCreateFindings(ctx context.Context, findings []Finding) error
- func (s *Store) BulkCreateVulnerabilities(ctx context.Context, vulns []VulnWithDetail) error
- func (s *Store) ClearFindingMatchesForRun(ctx context.Context, runID int64) (int64, error)
- func (s *Store) Close() error
- func (s *Store) CreateAnnotation(ctx context.Context, a *Annotation) (int64, error)
- func (s *Store) CreateAnnotationGroup(ctx context.Context, g *AnnotationGroup) (int64, error)
- func (s *Store) CreateDisposition(ctx context.Context, d *FindingDisposition) (int64, error)
- func (s *Store) CreateEvidence(ctx context.Context, e *Evidence) (int64, error)
- func (s *Store) CreateExperiment(ctx context.Context, e *Experiment) (int64, error)
- func (s *Store) CreateFinding(ctx context.Context, f *Finding) (int64, error)
- func (s *Store) CreateFindingMatch(ctx context.Context, m *FindingMatch) (int64, error)
- func (s *Store) CreateProject(ctx context.Context, p *CorpusProject) (int64, error)
- func (s *Store) CreateRun(ctx context.Context, r *Run) (int64, error)
- func (s *Store) CreateScanner(ctx context.Context, sc *Scanner) (int64, error)
- func (s *Store) CreateVulnerability(ctx context.Context, v *Vulnerability) (int64, error)
- func (s *Store) DeleteAnnotation(ctx context.Context, id int64) error
- func (s *Store) DeleteAnnotationGroup(ctx context.Context, id int64) error
- func (s *Store) DeleteAnnotationsByProject(ctx context.Context, projectID int64) (int64, error)
- func (s *Store) DeleteDisposition(ctx context.Context, id int64) error
- func (s *Store) DeleteExperiment(ctx context.Context, id int64) error
- func (s *Store) DeleteFinding(ctx context.Context, id int64) error
- func (s *Store) DeleteProject(ctx context.Context, id int64) error
- func (s *Store) DeleteRun(ctx context.Context, id int64) error
- func (s *Store) DeleteScanner(ctx context.Context, id int64) error
- func (s *Store) DeleteVulnerabilitiesByProject(ctx context.Context, projectID int64) (int64, error)
- func (s *Store) DeleteVulnerability(ctx context.Context, id int64) error
- func (s *Store) GetAnnotation(ctx context.Context, id int64) (*Annotation, error)
- func (s *Store) GetAnnotationGroup(ctx context.Context, id int64) (*AnnotationGroup, error)
- func (s *Store) GetAnnotationSetByHash(ctx context.Context, hash string) (*AnnotationSet, error)
- func (s *Store) GetDisposition(ctx context.Context, id int64) (*FindingDisposition, error)
- func (s *Store) GetDispositionByFinding(ctx context.Context, findingID int64) (*FindingDisposition, error)
- func (s *Store) GetExperiment(ctx context.Context, id int64) (*Experiment, error)
- func (s *Store) GetExperimentByName(ctx context.Context, name string) (*Experiment, error)
- func (s *Store) GetFinding(ctx context.Context, id int64) (*Finding, error)
- func (s *Store) GetProject(ctx context.Context, id int64) (*CorpusProject, error)
- func (s *Store) GetProjectByName(ctx context.Context, name string) (*CorpusProject, error)
- func (s *Store) GetRun(ctx context.Context, id int64) (*Run, error)
- func (s *Store) GetScanner(ctx context.Context, id int64) (*Scanner, error)
- func (s *Store) GetScannerByName(ctx context.Context, name string) (*Scanner, error)
- func (s *Store) GetScannerByNameVersion(ctx context.Context, name, version string) (*Scanner, error)
- func (s *Store) GetVulnerability(ctx context.Context, id int64) (*Vulnerability, error)
- func (s *Store) GetVulnerabilityByName(ctx context.Context, projectID int64, name string) (*Vulnerability, error)
- func (s *Store) ListAllGroupMembersByProject(ctx context.Context, projectID int64) ([]AnnotationGroupMember, error)
- func (s *Store) ListAnnotationGroupsByProject(ctx context.Context, projectID int64) ([]AnnotationGroup, error)
- func (s *Store) ListAnnotationSetsByProject(ctx context.Context, projectID int64) ([]AnnotationSet, error)
- func (s *Store) ListAnnotationsByProject(ctx context.Context, projectID int64) ([]Annotation, error)
- func (s *Store) ListDispositionsByRun(ctx context.Context, runID int64) ([]FindingDisposition, error)
- func (s *Store) ListEvidenceByProject(ctx context.Context, projectID int64) ([]Evidence, error)
- func (s *Store) ListEvidenceByVuln(ctx context.Context, vulnID int64) ([]Evidence, error)
- func (s *Store) ListExperimentProjects(ctx context.Context, experimentID int64) ([]CorpusProject, error)
- func (s *Store) ListExperimentScanners(ctx context.Context, experimentID int64) ([]Scanner, error)
- func (s *Store) ListExperiments(ctx context.Context) ([]Experiment, error)
- func (s *Store) ListFindingMatchesByRun(ctx context.Context, runID int64) ([]FindingMatch, error)
- func (s *Store) ListFindingsByRun(ctx context.Context, runID int64) ([]Finding, error)
- func (s *Store) ListGroupMembers(ctx context.Context, groupID int64) ([]AnnotationGroupMember, error)
- func (s *Store) ListGroupsByAnnotation(ctx context.Context, annotationID int64) ([]AnnotationGroup, error)
- func (s *Store) ListPendingRuns(ctx context.Context, experimentID int64) ([]Run, error)
- func (s *Store) ListProjects(ctx context.Context) ([]CorpusProject, error)
- func (s *Store) ListRunsByExperiment(ctx context.Context, experimentID int64) ([]Run, error)
- func (s *Store) ListRunsByProject(ctx context.Context, projectID int64) ([]Run, error)
- func (s *Store) ListRunsByScannerProject(ctx context.Context, scannerID, projectID int64) ([]Run, error)
- func (s *Store) ListSatisfiedVulns(ctx context.Context, runID, projectID int64) ([]Vulnerability, error)
- func (s *Store) ListScanners(ctx context.Context) ([]Scanner, error)
- func (s *Store) ListUnmatchedAnnotations(ctx context.Context, runID, projectID int64) ([]Annotation, error)
- func (s *Store) ListUnmatchedFindings(ctx context.Context, runID int64) ([]Finding, error)
- func (s *Store) ListUnsatisfiedVulns(ctx context.Context, runID, projectID int64) ([]Vulnerability, error)
- func (s *Store) ListVulnAnnotatorsByProject(ctx context.Context, projectID int64) (map[int64][]string, error)
- func (s *Store) ListVulnCWEs(ctx context.Context, projectID int64) (map[int64][]string, error)
- func (s *Store) ListVulnerabilitiesByProject(ctx context.Context, projectID int64) ([]Vulnerability, error)
- func (s *Store) Migrate() error
- func (s *Store) MigrateDown() error
- func (s *Store) RecordAnnotationSet(ctx context.Context, set *AnnotationSet) (int64, error)
- func (s *Store) RemoveAnnotationFromGroup(ctx context.Context, groupID, annotationID int64) error
- func (s *Store) RemoveProjectFromExperiment(ctx context.Context, experimentID, projectID int64) error
- func (s *Store) RemoveScannerFromExperiment(ctx context.Context, experimentID, scannerID int64) error
- func (s *Store) StampRunScorer(ctx context.Context, runID int64, matcherVersion, annotationHash string) error
- func (s *Store) UpdateAnnotation(ctx context.Context, a *Annotation) error
- func (s *Store) UpdateRunStatus(ctx context.Context, id int64, status RunStatus, ...) error
- func (s *Store) VulnConsensus(ctx context.Context, projectID int64) (map[int64]int, error)
- type VulnWithDetail
- type Vulnerability
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a requested entity does not exist.
var ValidAnnotationStatuses = []AnnotationStatus{AnnotationStatusValid, AnnotationStatusInvalid, AnnotationStatusDisputed}
ValidAnnotationStatuses lists all allowed annotation status values.
var ValidDispositions = []Disposition{DispositionTP, DispositionFP, DispositionNeedsReview}
ValidDispositions lists all allowed disposition values.
var ValidGroupRoles = []string{"source", "sink", "related"}
ValidGroupRoles lists allowed group member roles.
Functions ¶
func IsValidAnnotationStatus ¶
func IsValidAnnotationStatus(status AnnotationStatus) bool
IsValidAnnotationStatus checks if a status string is valid.
func IsValidDisposition ¶
func IsValidDisposition(d Disposition) bool
IsValidDisposition checks if a disposition string is valid.
func IsValidGroupRole ¶
IsValidGroupRole checks if a role string is valid.
Types ¶
type Annotation ¶
type Annotation struct {
ID int64
ProjectID int64
FilePath string
StartLine int
EndLine sql.NullInt64
CWEID sql.NullString
Category string
Severity string
Description sql.NullString
Status AnnotationStatus
AnnotatedBy sql.NullString
CreatedAt time.Time
UpdatedAt time.Time
}
Annotation represents a ground-truth vulnerability annotation in a project.
type AnnotationGroup ¶
AnnotationGroup represents a logical grouping of related annotations.
type AnnotationGroupMember ¶
type AnnotationGroupMember struct {
GroupID int64
AnnotationID int64
Role string // "source", "sink", "related"
}
AnnotationGroupMember represents membership of an annotation in a group.
type AnnotationSet ¶
type AnnotationSet struct {
ID int64
ProjectID int64
Hash string
SourcePath sql.NullString
GitSHA sql.NullString
VulnCount int
Format string // import-format tag written by the importer
ImportedAt time.Time
}
AnnotationSet records one import of an annotation file. The hash joins to runs.annotation_hash so you can recover "which file produced the ground truth this run was scored against."
type AnnotationStatus ¶
type AnnotationStatus string
AnnotationStatus is the validity state of a ground-truth annotation.
const ( AnnotationStatusValid AnnotationStatus = "valid" AnnotationStatusInvalid AnnotationStatus = "invalid" AnnotationStatusDisputed AnnotationStatus = "disputed" )
type CorpusProject ¶
type CorpusProject struct {
ID int64
Name string
SourceURL sql.NullString
LocalPath string
Language sql.NullString
CommitSHA sql.NullString
CreatedAt time.Time
}
CorpusProject represents a project in the corpus that we scan.
type Disposition ¶
type Disposition string
Disposition is a human triage judgment on a finding.
const ( DispositionTP Disposition = "tp" DispositionFP Disposition = "fp" DispositionNeedsReview Disposition = "needs_review" )
type Evidence ¶
type Evidence struct {
ID int64
VulnID int64
FilePath string
StartLine int
EndLine sql.NullInt64
Role string // sink | source | helper | related — informational
Category string
Severity string
CreatedAt time.Time
}
Evidence is one location where a vulnerability manifests. The matcher works at this granularity — findings match evidence rows, not vulns — and metrics rolls evidence matches up to vulnerability satisfaction.
IDs inherit from the old annotations table (migration 010 preserved them) so the compat shim's GetAnnotation(id) is a direct lookup.
type ExecutionMode ¶
type ExecutionMode string
ExecutionMode describes how a scanner is invoked.
const ( ExecutionModeDocker ExecutionMode = "docker" ExecutionModeLocal ExecutionMode = "local" )
type Experiment ¶
type Experiment struct {
ID int64
Name string
Description sql.NullString
Iterations int
CreatedAt time.Time
}
Experiment represents a benchmarking experiment configuration.
type Finding ¶
type Finding struct {
ID int64
RunID int64
RuleID sql.NullString
FilePath string
StartLine int
EndLine sql.NullInt64
CWEID sql.NullString
Severity sql.NullString
Message sql.NullString
Snippet sql.NullString
Fingerprint sql.NullString
CreatedAt time.Time
}
Finding represents a parsed finding from scanner output.
type FindingDisposition ¶
type FindingDisposition struct {
ID int64
FindingID int64
Disposition Disposition
Notes sql.NullString
ReviewedBy sql.NullString
CreatedAt time.Time
}
FindingDisposition records a human triage judgment on an unmatched finding.
type FindingMatch ¶
type FindingMatch struct {
ID int64
FindingID int64
// AnnotationID is stored in the evidence_id column post migration 010.
// The Go name stays so the matcher, metrics, and analysis code keep
// compiling — and semantically it IS still "the annotation this finding
// matched" since evidence row IDs inherit from the old annotation IDs.
// New code should think of this as an evidence ID; the name is compat.
AnnotationID int64
MatchType string
Confidence sql.NullFloat64
CreatedAt time.Time
}
FindingMatch represents a match between a finding and a ground-truth annotation.
type Run ¶
type Run struct {
ID int64
ExperimentID int64
ScannerID int64
ProjectID int64
Iteration int
Status RunStatus
StartedAt sql.NullTime
CompletedAt sql.NullTime
DurationMs sql.NullInt64
MemoryPeakBytes sql.NullInt64
SarifPath sql.NullString
LogPath sql.NullString
ErrorMessage sql.NullString
// Scorer pinning — stamped at MatchRun time, not experiment-run time.
// The scorer that matters is the one that produced finding_matches.
// NULL on rows scored before migration 009.
MatcherVersion sql.NullString
AnnotationHash sql.NullString
CreatedAt time.Time
}
Run represents a single scan execution.
type Scanner ¶
type Scanner struct {
ID int64
Name string
Version string
DockerImage string
ConfigJSON sql.NullString
ExecutionMode ExecutionMode // ExecutionModeDocker or ExecutionModeLocal
ExecutablePath sql.NullString // path to local executable (when execution_mode = "local")
CreatedAt time.Time
}
Scanner represents a registered SAST scanner.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps a SQLite database connection.
func New ¶
New opens a SQLite database at the given path with WAL mode and foreign keys enabled. Use ":memory:" for an in-memory database.
func (*Store) AddAnnotationToGroup ¶
func (*Store) AddProjectToExperiment ¶
AddProjectToExperiment links a project to an experiment.
func (*Store) AddScannerToExperiment ¶
AddScannerToExperiment links a scanner to an experiment.
func (*Store) AddVulnAnnotator ¶
func (*Store) AddVulnCWE ¶
func (*Store) AnnotationHash ¶
AnnotationHash computes a stable digest of the project's ground truth. Two runs with different hashes were graded against different annotation sets and their metrics are not comparable.
Covers every field the matcher and ComputeVulnMetrics read: vulnerability name/status/criticality, evidence location/category/ severity, CWE set. Excludes description, annotators, timestamps — edits that don't affect scoring shouldn't churn the hash.
Stable across insert order: everything is sorted before hashing, and IDs are resolved to positions so two DBs with the same content inserted differently hash the same.
func (*Store) BulkCreateAnnotations ¶
func (s *Store) BulkCreateAnnotations(ctx context.Context, annotations []Annotation) error
BulkCreateAnnotations inserts N single-evidence vulns in one transaction via the Annotation compat type. Retained alongside the Annotation shim for one-row-at-a-time callers; the file-import path uses BulkCreateVulnerabilities directly.
func (*Store) BulkCreateFindings ¶
BulkCreateFindings inserts multiple findings in a single transaction. If any insert fails, the entire batch is rolled back.
func (*Store) BulkCreateVulnerabilities ¶
func (s *Store) BulkCreateVulnerabilities(ctx context.Context, vulns []VulnWithDetail) error
BulkCreateVulnerabilities inserts a set of vulnerabilities with their evidence, CWEs, and annotators in one transaction. This is the sole file-import path.
func (*Store) ClearFindingMatchesForRun ¶
ClearFindingMatchesForRun deletes every finding_matches row produced by a run's findings. This is derived state — the findings themselves are untouched — so the next MatchRun call will recompute from scratch and re-stamp the run's matcher_version and annotation_hash. Returns the number of rows deleted.
func (*Store) CreateAnnotation ¶
CreateAnnotation creates a single-evidence vulnerability and returns the evidence row's ID — which callers treat as "the annotation ID" exactly as before. The vulnerability name is synthesized from category + location, matching what migration 010 did for solo annotations.
func (*Store) CreateAnnotationGroup ¶
func (*Store) CreateDisposition ¶
CreateDisposition inserts or replaces a finding disposition and returns its ID.
func (*Store) CreateEvidence ¶
func (*Store) CreateExperiment ¶
CreateExperiment inserts a new experiment and returns its ID.
func (*Store) CreateFinding ¶
CreateFinding inserts a new finding and returns its ID.
func (*Store) CreateFindingMatch ¶
CreateFindingMatch inserts a new finding match and returns its ID. The Go field FindingMatch.AnnotationID lands in the evidence_id column — migration 010 renamed it, evidence IDs inherit the old annotation ID space, so the value round-trips unchanged.
func (*Store) CreateProject ¶
CreateProject inserts a new corpus project and returns its ID.
func (*Store) CreateScanner ¶
CreateScanner inserts a new scanner and returns its ID.
func (*Store) CreateVulnerability ¶
func (*Store) DeleteAnnotation ¶
DeleteAnnotation removes one evidence row. If it was the vuln's only evidence, the vuln goes too — a vulnerability with no observable location is meaningless. If other evidence remains, the vuln stays and only this location is removed.
func (*Store) DeleteAnnotationGroup ¶
func (*Store) DeleteAnnotationsByProject ¶
DeleteAnnotationsByProject removes everything. Under the hood this is DeleteVulnerabilitiesByProject — the cascade takes evidence, cwes, and annotators with it. Returns the evidence-row count (not the vuln count) because callers expect "number of annotations deleted."
func (*Store) DeleteDisposition ¶
DeleteDisposition removes a disposition by ID.
func (*Store) DeleteExperiment ¶
DeleteExperiment removes an experiment by ID. Cascade deletes experiment_scanners and experiment_projects.
func (*Store) DeleteFinding ¶
DeleteFinding removes a finding by ID. Finding matches are cascade deleted.
func (*Store) DeleteProject ¶
DeleteProject removes a project by ID. Annotations are cascade deleted.
func (*Store) DeleteScanner ¶
DeleteScanner removes a scanner by ID.
func (*Store) DeleteVulnerabilitiesByProject ¶
func (*Store) DeleteVulnerability ¶
func (*Store) GetAnnotation ¶
func (*Store) GetAnnotationGroup ¶
GetAnnotationGroup synthesizes a group from a multi-evidence vuln. The "group ID" is the vuln ID. Single-evidence vulns return ErrNotFound — they're not groups.
func (*Store) GetAnnotationSetByHash ¶
func (*Store) GetDisposition ¶
GetDisposition retrieves a disposition by ID.
func (*Store) GetDispositionByFinding ¶
func (s *Store) GetDispositionByFinding(ctx context.Context, findingID int64) (*FindingDisposition, error)
GetDispositionByFinding retrieves a disposition by finding ID.
func (*Store) GetExperiment ¶
GetExperiment retrieves an experiment by ID.
func (*Store) GetExperimentByName ¶
GetExperimentByName retrieves an experiment by name.
func (*Store) GetFinding ¶
GetFinding returns a single finding by ID.
func (*Store) GetProject ¶
GetProject retrieves a project by ID.
func (*Store) GetProjectByName ¶
GetProjectByName retrieves a project by its unique name.
func (*Store) GetScanner ¶
GetScanner retrieves a scanner by ID.
func (*Store) GetScannerByName ¶
GetScannerByName retrieves the first scanner matching a name (newest version).
func (*Store) GetScannerByNameVersion ¶
func (s *Store) GetScannerByNameVersion(ctx context.Context, name, version string) (*Scanner, error)
GetScannerByNameVersion retrieves a scanner by its unique name+version combination.
func (*Store) GetVulnerability ¶
func (*Store) GetVulnerabilityByName ¶
func (s *Store) GetVulnerabilityByName(ctx context.Context, projectID int64, name string) (*Vulnerability, error)
GetVulnerabilityByName looks up a vulnerability by its name within a project. Names are unique per project by convention, not constraint — if duplicates exist, the oldest wins. Used by triage --attach-to.
func (*Store) ListAllGroupMembersByProject ¶
func (s *Store) ListAllGroupMembersByProject(ctx context.Context, projectID int64) ([]AnnotationGroupMember, error)
ListAllGroupMembersByProject is what the scorer hash reads. Synthesized from multi-evidence vulns: each evidence row becomes a "member" of its vuln-as-group.
func (*Store) ListAnnotationGroupsByProject ¶
func (s *Store) ListAnnotationGroupsByProject(ctx context.Context, projectID int64) ([]AnnotationGroup, error)
ListAnnotationGroupsByProject returns vulns with >1 evidence row.
func (*Store) ListAnnotationSetsByProject ¶
func (*Store) ListAnnotationsByProject ¶
func (*Store) ListDispositionsByRun ¶
func (s *Store) ListDispositionsByRun(ctx context.Context, runID int64) ([]FindingDisposition, error)
ListDispositionsByRun returns all dispositions for findings in a given run. Returns an empty slice (not nil) if none exist.
func (*Store) ListEvidenceByProject ¶
func (*Store) ListEvidenceByVuln ¶
func (*Store) ListExperimentProjects ¶
func (s *Store) ListExperimentProjects(ctx context.Context, experimentID int64) ([]CorpusProject, error)
ListExperimentProjects returns all projects linked to an experiment. Returns an empty slice (not nil) if no projects are linked.
func (*Store) ListExperimentScanners ¶
ListExperimentScanners returns all scanners linked to an experiment. Returns an empty slice (not nil) if no scanners are linked.
func (*Store) ListExperiments ¶
func (s *Store) ListExperiments(ctx context.Context) ([]Experiment, error)
ListExperiments returns all experiments. Returns an empty slice (not nil) if none exist.
func (*Store) ListFindingMatchesByRun ¶
ListFindingMatchesByRun returns all finding matches for a run. Returns an empty slice (not nil) if none exist.
func (*Store) ListFindingsByRun ¶
ListFindingsByRun returns all findings for a run. Returns an empty slice (not nil) if none exist.
func (*Store) ListGroupMembers ¶
func (s *Store) ListGroupMembers(ctx context.Context, groupID int64) ([]AnnotationGroupMember, error)
ListGroupMembers returns evidence rows for a multi-evidence vuln. GroupID == vuln_id, AnnotationID == evidence_id.
func (*Store) ListGroupsByAnnotation ¶
func (s *Store) ListGroupsByAnnotation(ctx context.Context, annotationID int64) ([]AnnotationGroup, error)
ListGroupsByAnnotation returns the "group" (vuln) an evidence row belongs to — but only if that vuln has siblings. Solo evidence belongs to no group in compat terms.
func (*Store) ListPendingRuns ¶
ListPendingRuns returns all pending or failed runs for an experiment (for resume). Returns an empty slice (not nil) if none exist.
func (*Store) ListProjects ¶
func (s *Store) ListProjects(ctx context.Context) ([]CorpusProject, error)
ListProjects returns all projects. Returns an empty slice (not nil) if none exist.
func (*Store) ListRunsByExperiment ¶
ListRunsByExperiment returns all runs for an experiment. Returns an empty slice (not nil) if none exist.
func (*Store) ListRunsByProject ¶
ListRunsByProject returns all runs for a project across all scanners and experiments. Used by rescore to enumerate everything that needs re-matching when the project's ground truth changes.
func (*Store) ListRunsByScannerProject ¶
func (s *Store) ListRunsByScannerProject(ctx context.Context, scannerID, projectID int64) ([]Run, error)
ListRunsByScannerProject returns all runs for a scanner/project combination. Returns an empty slice (not nil) if none exist.
func (*Store) ListSatisfiedVulns ¶
func (s *Store) ListSatisfiedVulns(ctx context.Context, runID, projectID int64) ([]Vulnerability, error)
ListSatisfiedVulns returns vulnerabilities where at least one evidence row was matched by a finding in this run. These are the TPs (valid) or matched-FPs (invalid) under vulnerability-level accounting.
func (*Store) ListScanners ¶
ListScanners returns all scanners. Returns an empty slice (not nil) if none exist.
func (*Store) ListUnmatchedAnnotations ¶
func (s *Store) ListUnmatchedAnnotations(ctx context.Context, runID, projectID int64) ([]Annotation, error)
ListUnmatchedAnnotations returns evidence rows that have no match for a given run+project. Pre-010 this was per-annotation; now it's per-evidence, which is the same thing via the compat shim. Callers still computing metrics from this (reports, detail views) get the old per-location counting. The headline compare flow uses ListUnsatisfiedVulns instead.
func (*Store) ListUnmatchedFindings ¶
ListUnmatchedFindings returns findings that have no match entry (false positives). Returns an empty slice (not nil) if none exist.
func (*Store) ListUnsatisfiedVulns ¶
func (s *Store) ListUnsatisfiedVulns(ctx context.Context, runID, projectID int64) ([]Vulnerability, error)
ListUnsatisfiedVulns returns vulnerabilities where NO evidence row was matched. Valid ones are FNs; invalid ones are TNs. This plus ListSatisfiedVulns plus ListUnmatchedFindings is everything ComputeVulnMetrics needs.
func (*Store) ListVulnAnnotatorsByProject ¶
func (s *Store) ListVulnAnnotatorsByProject(ctx context.Context, projectID int64) (map[int64][]string, error)
ListVulnAnnotatorsByProject returns the annotator list per vulnerability for a project. Map[vulnID][]annotator — mirror of ListVulnCWEs, used by the exporter to reconstitute the annotated_by array.
func (*Store) ListVulnCWEs ¶
ListVulnCWEs returns the acceptable CWE set per vulnerability for a project. Map[vulnID][]cweString — the matcher turns these into a normalized-int set and checks finding CWEs against it.
func (*Store) ListVulnerabilitiesByProject ¶
func (*Store) MigrateDown ¶
MigrateDown rolls back all database migrations.
func (*Store) RecordAnnotationSet ¶
func (*Store) RemoveAnnotationFromGroup ¶
func (*Store) RemoveProjectFromExperiment ¶
func (s *Store) RemoveProjectFromExperiment(ctx context.Context, experimentID, projectID int64) error
RemoveProjectFromExperiment unlinks a project from an experiment.
func (*Store) RemoveScannerFromExperiment ¶
func (s *Store) RemoveScannerFromExperiment(ctx context.Context, experimentID, scannerID int64) error
RemoveScannerFromExperiment unlinks a scanner from an experiment.
func (*Store) StampRunScorer ¶
func (s *Store) StampRunScorer(ctx context.Context, runID int64, matcherVersion, annotationHash string) error
StampRunScorer records which matcher version and annotation set produced this run's finding_matches rows. Called by analysis.MatchRun immediately before matching — not by the experiment executor — because the scorer that matters is the one that wrote the matches, not the one that was current when the scanner ran. Re-scoring after clearing finding_matches re-stamps.
func (*Store) UpdateAnnotation ¶
func (s *Store) UpdateAnnotation(ctx context.Context, a *Annotation) error
UpdateAnnotation writes through to both the evidence row (location, category, severity) and its parent vuln (status, description). The CWE and annotator fields replace the vuln's FIRST entry — callers going through this shim are thinking in single-CWE terms anyway.
If the evidence belongs to a multi-evidence vuln, the status and description changes affect the whole vuln. That's arguably surprising, but it's what "update this annotation's status" meant under the old group semantics too (groups never had their own status; they inherited from members).
func (*Store) UpdateRunStatus ¶
func (s *Store) UpdateRunStatus(ctx context.Context, id int64, status RunStatus, startedAt, completedAt sql.NullTime, durationMs, memoryPeakBytes sql.NullInt64, sarifPath, logPath, errorMessage sql.NullString) error
UpdateRunStatus updates the status and related fields of a run.
func (*Store) VulnConsensus ¶
VulnConsensus returns how many distinct annotators agree each vulnerability exists. 1 = single annotator's call; 3 = strong consensus. Compare's --min-consensus filter reads this.
type VulnWithDetail ¶
type VulnWithDetail struct {
Vulnerability
Evidence []Evidence
CWEs []string
Annotators []string
}
VulnWithDetail bundles a vulnerability with its evidence locations, acceptable CWEs, and annotator list — everything needed to score it without further round trips. This is what the matcher and the importer want; the flat types above are for CRUD.
type Vulnerability ¶
type Vulnerability struct {
ID int64
ProjectID int64
Name string
Description sql.NullString
// Criticality tiers findings for separate recall reporting. A tool
// that misses a 'must' is worse than one that misses a 'may' at the
// same overall recall.
Criticality string // must | should | may
Status string // valid | invalid | disputed
CreatedAt time.Time
UpdatedAt time.Time
}
Vulnerability is the unit of ground truth. One vulnerability may be evidenced at many locations (vuln_evidence rows) and may be correctly described by many CWEs (vuln_cwes rows). A scanner finding matches the vulnerability if it matches any evidence location with any acceptable CWE; the vulnerability is then satisfied and scores one TP regardless of how many evidence locations were hit.