reclassify

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package reclassify provides the runtime glue that connects priority-change producers (threat-intel refresh, control CRUD, rule CRUD) to the PriorityReclassifyController's queue/Reclassifier contracts.

The package lives under internal/app so the app-layer wire sites (services.go) can see it directly; controller itself imports app for unrelated reasons, so placing the adapters in `app` directly would introduce a cycle. Keep new code here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type MemoryQueue

type MemoryQueue struct {
	// contains filtered or unexported fields
}

MemoryQueue is a minimal in-process ReclassifyQueue. It is intentionally unbounded (slice-backed) but tolerates burst enqueues cheaply — the controller drains at Interval=5m with BatchSize=64, so backlog in practice is small. When the API scales beyond a single replica, swap this for a Redis or Postgres queue; the interface is stable.

Order: FIFO. Dedup: none (controller-side dedup is cheaper — two enqueues for the same (tenant,asset) do the same work twice but don't produce duplicate priority_changed events thanks to the publisher's "no transition = no publish" guard).

func NewMemoryQueue

func NewMemoryQueue() *MemoryQueue

NewMemoryQueue constructs an empty queue.

func (*MemoryQueue) DequeueBatch

func (q *MemoryQueue) DequeueBatch(_ context.Context, max int) ([]controller.ReclassifyRequest, error)

DequeueBatch pops up to max requests. Returns an empty slice (nil error) when empty.

func (*MemoryQueue) Enqueue

Enqueue adds a request. Safe for concurrent use.

func (*MemoryQueue) Len

func (q *MemoryQueue) Len() int

Len is exposed for observability/dashboards. Safe for concurrent use.

type PriorityClassifier

type PriorityClassifier interface {
	ClassifyFinding(ctx context.Context, tenantID shared.ID, finding *vulnerability.Finding, a *asset.Asset) error
}

PriorityClassifier is the narrow surface the reclassifier needs from PriorityClassificationService. Narrow to keep tests cheap.

type Reclassifier

type Reclassifier struct {
	// contains filtered or unexported fields
}

Reclassifier implements controller.Reclassifier. It turns a scope (AssetIDs, CVEIDs) into concrete Finding+Asset pairs and delegates to the classifier. The classifier already handles priority_changed event emission via its attached publisher — so a sweep that re-confirms the same class is silent, and a sweep that moves a class fans out correctly.

The current impl handles the most-common sweep scope: AssetIDs (produced by control-change and asset-change publishers). A CVEIDs branch (produced by EPSS/KEV refreshes) is a follow-up — the threat intel flow already enqueues with CVEIDs, so this branch will be added alongside the next wire of that producer.

func NewReclassifier

func NewReclassifier(
	findings vulnerability.FindingRepository,
	assets asset.Repository,
	classifier PriorityClassifier,
	log *logger.Logger,
) *Reclassifier

NewReclassifier wires deps.

func (*Reclassifier) ReclassifyForRequest

func (r *Reclassifier) ReclassifyForRequest(
	ctx context.Context,
	req controller.ReclassifyRequest,
) (int, error)

ReclassifyForRequest satisfies controller.Reclassifier.

Strategy:

  1. If req.AssetIDs is non-empty → iterate each asset, page findings, classify. This is the control-change / asset-change path.
  2. Otherwise → no-op with a warn (we only drain scoped requests for now; unscoped "reclassify everything" would be a footgun without a rate limiter).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL