aitriage

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package aitriage provides domain entities for AI-powered vulnerability triage.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTokenLimitExceeded is returned when the monthly token limit is exceeded.
	ErrTokenLimitExceeded = errors.New("monthly token limit exceeded")

	// ErrAlreadyProcessing is returned when the triage job is already being processed.
	ErrAlreadyProcessing = errors.New("triage job is already being processed")

	// ErrSlotNotAvailable is returned when unable to acquire a processing slot.
	ErrSlotNotAvailable = errors.New("unable to acquire processing slot")

	// ErrDuplicateRequest is returned when a triage request already exists for the finding.
	ErrDuplicateRequest = errors.New("triage request already in progress for this finding")
)

Repository errors

Functions

This section is empty.

Types

type Exploitability

type Exploitability string

Exploitability represents how easily a vulnerability can be exploited.

const (
	ExploitabilityHigh        Exploitability = "high"        // Actively exploited or easy to exploit
	ExploitabilityMedium      Exploitability = "medium"      // Requires some skill/conditions
	ExploitabilityLow         Exploitability = "low"         // Difficult to exploit
	ExploitabilityTheoretical Exploitability = "theoretical" // Not practically exploitable
)

func (Exploitability) IsValid

func (e Exploitability) IsValid() bool

IsValid checks if the exploitability is valid.

type FindingExistsChecker

type FindingExistsChecker interface {
	// ExistsByIDs returns a map of finding ID -> exists (true/false).
	ExistsByIDs(ctx context.Context, tenantID shared.ID, findingIDs []shared.ID) (map[shared.ID]bool, error)
}

FindingExistsChecker is an interface for checking if findings exist. This allows batch validation without N+1 queries.

type ListFilters

type ListFilters struct {
	TenantID  shared.ID
	FindingID *shared.ID
	Status    *TriageStatus
	Type      *TriageType
	Limit     int
	Offset    int
}

Filters for listing triage results.

type RemediationStep

type RemediationStep struct {
	Step        int    `json:"step"`
	Description string `json:"description"`
	Effort      string `json:"effort"` // "low", "medium", "high"
}

RemediationStep represents a step in the remediation process.

type Repository

type Repository interface {
	// Create creates a new triage result.
	Create(ctx context.Context, result *TriageResult) error

	// Update updates an existing triage result.
	Update(ctx context.Context, result *TriageResult) error

	// GetByID retrieves a triage result by ID.
	GetByID(ctx context.Context, tenantID, id shared.ID) (*TriageResult, error)

	// GetByFindingID retrieves the latest triage result for a finding.
	GetByFindingID(ctx context.Context, tenantID, findingID shared.ID) (*TriageResult, error)

	// ListByFindingID retrieves all triage results for a finding (history).
	ListByFindingID(ctx context.Context, tenantID, findingID shared.ID, limit, offset int) ([]*TriageResult, int, error)

	// GetPendingJobs retrieves pending triage jobs for processing.
	// SECURITY NOTE: Results are ordered by tenant_id for proper isolation.
	// Consider using GetPendingJobsByTenant for better tenant isolation.
	GetPendingJobs(ctx context.Context, limit int) ([]*TriageResult, error)

	// GetPendingJobsByTenant retrieves pending jobs for a specific tenant.
	// SECURITY: This is the preferred method for workers - ensures tenant isolation.
	GetPendingJobsByTenant(ctx context.Context, tenantID shared.ID, limit int) ([]*TriageResult, error)

	// GetTenantsWithPendingJobs returns tenant IDs that have pending jobs.
	// SECURITY: Use with GetPendingJobsByTenant for proper tenant isolation.
	GetTenantsWithPendingJobs(ctx context.Context, limit int) ([]shared.ID, error)

	// CountByTenantThisMonth counts triage jobs for token usage tracking.
	CountByTenantThisMonth(ctx context.Context, tenantID shared.ID) (int, error)

	// SumTokensByTenantThisMonth sums tokens used this month.
	SumTokensByTenantThisMonth(ctx context.Context, tenantID shared.ID) (int, error)

	// GetTriageContext retrieves triage result with tenant settings and token usage in one call.
	// This optimizes the ProcessTriage flow by reducing multiple queries to one.
	GetTriageContext(ctx context.Context, tenantID, resultID shared.ID) (*TriageContext, error)

	// AcquireTriageSlot atomically checks token limit and reserves a slot for processing.
	// Uses SELECT FOR UPDATE to prevent race conditions when multiple workers process concurrently.
	// Returns:
	// - (context, nil) if slot acquired successfully
	// - (nil, ErrTokenLimitExceeded) if token limit exceeded
	// - (nil, ErrAlreadyProcessing) if result is already being processed
	// - (nil, err) for other errors
	AcquireTriageSlot(ctx context.Context, tenantID, resultID shared.ID) (*TriageContext, error)

	// HasPendingOrProcessing checks if a finding has a pending or processing triage job.
	// Used for deduplication to prevent multiple concurrent triage requests for the same finding.
	HasPendingOrProcessing(ctx context.Context, tenantID, findingID shared.ID) (bool, error)

	// FindStuckJobs finds triage jobs that have been in pending/processing state for too long.
	// Used by recovery job to mark them as failed.
	// stuckDuration: how long a job must be stuck before being considered for recovery
	FindStuckJobs(ctx context.Context, stuckDuration time.Duration, limit int) ([]*TriageResult, error)

	// MarkStuckAsFailed marks a stuck triage job as failed.
	// Returns true if the job was updated, false if it was already in a terminal state.
	MarkStuckAsFailed(ctx context.Context, id shared.ID, errorMessage string) (bool, error)
}

Repository defines the interface for triage result persistence.

type TriageAnalysis

type TriageAnalysis struct {
	Provider         string
	Model            string
	PromptTokens     int
	CompletionTokens int

	SeverityAssessment      string
	SeverityJustification   string
	RiskScore               float64
	Exploitability          Exploitability
	ExploitabilityDetails   string
	BusinessImpact          string
	PriorityRank            int
	RemediationSteps        []RemediationStep
	FalsePositiveLikelihood float64
	FalsePositiveReason     string
	RelatedCVEs             []string
	RelatedCWEs             []string
	RawResponse             map[string]any
	Summary                 string
}

TriageAnalysis holds the parsed analysis from the LLM.

func ParseTriageAnalysis

func ParseTriageAnalysis(content string, provider, model string, promptTokens, completionTokens int) (*TriageAnalysis, error)

ParseTriageAnalysis parses the LLM response into a TriageAnalysis.

type TriageContext

type TriageContext struct {
	Result            *TriageResult
	TenantSettings    map[string]any // Raw tenant settings JSON
	TokensUsedMonth   int            // Tokens used this month
	MonthlyTokenLimit int            // Monthly limit (0 = unlimited)
}

TriageContext contains all data needed to process a triage job. Used to reduce N+1 queries during triage processing.

type TriageResult

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

TriageResult represents the result of an AI triage analysis.

func NewTriageResult

func NewTriageResult(
	tenantID shared.ID,
	findingID shared.ID,
	triageType TriageType,
	requestedBy *shared.ID,
) (*TriageResult, error)

NewTriageResult creates a new pending triage result.

func Reconstitute

func Reconstitute(
	id, tenantID, findingID shared.ID,
	triageType TriageType,
	requestedBy *shared.ID,
	requestedAt time.Time,
	status TriageStatus,
	startedAt, completedAt *time.Time,
	errorMessage string,
	llmProvider, llmModel string,
	promptTokens, completionTokens int,
	severityAssessment, severityJustification string,
	riskScore float64,
	exploitability Exploitability,
	exploitabilityDetails, businessImpact string,
	priorityRank int,
	remediationSteps []RemediationStep,
	falsePositiveLikelihood float64,
	falsePositiveReason string,
	relatedCVEs, relatedCWEs []string,
	rawResponse map[string]any,
	analysisSummary string,
	metadata map[string]any,
	createdAt, updatedAt time.Time,
) *TriageResult

Reconstitute creates a TriageResult from database values.

func (*TriageResult) AnalysisSummary

func (r *TriageResult) AnalysisSummary() string

func (*TriageResult) BusinessImpact

func (r *TriageResult) BusinessImpact() string

func (*TriageResult) CompletedAt

func (r *TriageResult) CompletedAt() *time.Time

func (*TriageResult) CompletionTokens

func (r *TriageResult) CompletionTokens() int

func (*TriageResult) CreatedAt

func (r *TriageResult) CreatedAt() time.Time

func (*TriageResult) ErrorMessage

func (r *TriageResult) ErrorMessage() string

func (*TriageResult) Exploitability

func (r *TriageResult) Exploitability() Exploitability

func (*TriageResult) ExploitabilityDetails

func (r *TriageResult) ExploitabilityDetails() string

func (*TriageResult) FalsePositiveLikelihood

func (r *TriageResult) FalsePositiveLikelihood() float64

func (*TriageResult) FalsePositiveReason

func (r *TriageResult) FalsePositiveReason() string

func (*TriageResult) FindingID

func (r *TriageResult) FindingID() shared.ID

func (*TriageResult) ID

func (r *TriageResult) ID() shared.ID

func (*TriageResult) LLMModel

func (r *TriageResult) LLMModel() string

func (*TriageResult) LLMProvider

func (r *TriageResult) LLMProvider() string

func (*TriageResult) MarkCompleted

func (r *TriageResult) MarkCompleted(result TriageAnalysis) error

MarkCompleted marks the triage as completed with results.

func (*TriageResult) MarkFailed

func (r *TriageResult) MarkFailed(errMsg string) error

MarkFailed marks the triage as failed with an error message.

func (*TriageResult) MarkProcessing

func (r *TriageResult) MarkProcessing() error

MarkProcessing marks the triage as processing.

func (*TriageResult) Metadata

func (r *TriageResult) Metadata() map[string]any

func (*TriageResult) PriorityRank

func (r *TriageResult) PriorityRank() int

func (*TriageResult) PromptTokens

func (r *TriageResult) PromptTokens() int

func (*TriageResult) RawResponse

func (r *TriageResult) RawResponse() map[string]any

func (*TriageResult) RelatedCVEs

func (r *TriageResult) RelatedCVEs() []string

func (*TriageResult) RelatedCWEs

func (r *TriageResult) RelatedCWEs() []string

func (*TriageResult) RemediationSteps

func (r *TriageResult) RemediationSteps() []RemediationStep

func (*TriageResult) RequestedAt

func (r *TriageResult) RequestedAt() time.Time

func (*TriageResult) RequestedBy

func (r *TriageResult) RequestedBy() *shared.ID

func (*TriageResult) RiskScore

func (r *TriageResult) RiskScore() float64

func (*TriageResult) SeverityAssessment

func (r *TriageResult) SeverityAssessment() string

func (*TriageResult) SeverityJustification

func (r *TriageResult) SeverityJustification() string

func (*TriageResult) StartedAt

func (r *TriageResult) StartedAt() *time.Time

func (*TriageResult) Status

func (r *TriageResult) Status() TriageStatus

func (*TriageResult) TenantID

func (r *TriageResult) TenantID() shared.ID

func (*TriageResult) TotalTokens

func (r *TriageResult) TotalTokens() int

func (*TriageResult) TriageType

func (r *TriageResult) TriageType() TriageType

func (*TriageResult) UpdatedAt

func (r *TriageResult) UpdatedAt() time.Time

type TriageStatus

type TriageStatus string

TriageStatus represents the status of a triage job.

const (
	TriageStatusPending    TriageStatus = "pending"
	TriageStatusProcessing TriageStatus = "processing"
	TriageStatusCompleted  TriageStatus = "completed"
	TriageStatusFailed     TriageStatus = "failed"
)

func (TriageStatus) IsTerminal

func (s TriageStatus) IsTerminal() bool

IsTerminal returns true if the status is final (completed or failed).

func (TriageStatus) IsValid

func (s TriageStatus) IsValid() bool

IsValid checks if the status is valid.

type TriageType

type TriageType string

TriageType represents how the triage was initiated.

const (
	TriageTypeAuto   TriageType = "auto"   // Triggered automatically on finding creation
	TriageTypeManual TriageType = "manual" // Triggered by user request
	TriageTypeBulk   TriageType = "bulk"   // Part of a bulk triage operation
)

func (TriageType) IsValid

func (t TriageType) IsValid() bool

IsValid checks if the type is valid.

Jump to

Keyboard shortcuts

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