Documentation
¶
Index ¶
- Constants
- func BuildLabelFilter(labels map[string]string) labelfilter.Filter
- func CanonicalLabelSetHash(labels map[string]string) string
- func CanonicalizeFilter(filter labelfilter.Filter) (map[string]string, bool)
- func ConstraintsToJSONMap(c Constraints) datatypes.JSONMap
- func ControlKey(catalogID uuid.UUID, controlID string) string
- func CreateRunEventTx(tx *gorm.DB, run *DashboardSuggestionRun, ...) error
- func LabelFilterFromJSONMap(m datatypes.JSONMap) *labelfilter.Filter
- func LabelFilterToJSONMap(filter *labelfilter.Filter) datatypes.JSONMap
- func NormalizeLabelSet(labels map[string]string) (map[string]string, bool)
- func OutputSchema() map[string]any
- func ParseControlKey(controlKey string) (uuid.UUID, string, error)
- func PlannedCalls(controlCount, labelSetCount int, cfg ChunkConfig) int
- type CellInput
- type ChunkConfig
- type ConflictError
- type Constraints
- type ControlInput
- type ControlRef
- type DashboardSuggestion
- type DashboardSuggestionControlResult
- type DashboardSuggestionEvent
- type DashboardSuggestionEventType
- type DashboardSuggestionRun
- type DashboardSuggestionRunCell
- type EditGroupInput
- type EditValidationError
- type FilterWithControls
- type GatherOptions
- type GatheredInput
- type GeneralizationCandidate
- type GeneralizationRunInput
- type GridCell
- type InsertMappingsResult
- type LabelKeyDocInput
- type LabelKeyInput
- type LabelSelector
- type LabelSetInput
- type ProposedFilterLabels
- type RawMapping
- type RawMappings
- type RenderedPrompt
- type Scope
- type ScopeError
- type Snapshot
- type SuggestionService
- func (s *SuggestionService) Accept(sspID uuid.UUID, suggestionIDs []uuid.UUID, actorID uuid.UUID) error
- func (s *SuggestionService) ControlKeysWithoutFilters(sspID uuid.UUID, controlKeys []string) ([]string, error)
- func (s *SuggestionService) EditGroup(sspID uuid.UUID, in EditGroupInput, actorID uuid.UUID) ([]uuid.UUID, error)
- func (s *SuggestionService) GatherCellInput(sspID uuid.UUID, cell GridCell, opts GatherOptions, filter *labelfilter.Filter) (GatheredInput, error)
- func (s *SuggestionService) GatherGeneralizationCandidates(sspID uuid.UUID, generalizableKeys []string, minShared int) ([]GeneralizationCandidate, error)
- func (s *SuggestionService) GatherLabelKeys(maxValuesPerKey int) ([]LabelKeyInput, error)
- func (s *SuggestionService) GatherLabelSets(hashes []string, filter *labelfilter.Filter) ([]LabelSetInput, error)
- func (s *SuggestionService) GenerateGeneralizations(sspID uuid.UUID, input GeneralizationRunInput) (DashboardSuggestionRun, InsertMappingsResult, int, error)
- func (s *SuggestionService) InsertGeneralizationCandidatesTx(tx *gorm.DB, runID uuid.UUID, sspID uuid.UUID, promptVersion string, ...) (InsertMappingsResult, error)
- func (s *SuggestionService) InsertValidatedMappings(runID uuid.UUID, sspID uuid.UUID, promptVersion string, ...) (InsertMappingsResult, error)
- func (s *SuggestionService) InsertValidatedMappingsTx(tx *gorm.DB, runID uuid.UUID, sspID uuid.UUID, promptVersion string, ...) (InsertMappingsResult, error)
- func (s *SuggestionService) Reject(sspID uuid.UUID, suggestionIDs []uuid.UUID, reason string, actorID uuid.UUID) error
- func (s *SuggestionService) ResolveScope(sspID uuid.UUID, scope Scope) (Snapshot, error)
- func (s *SuggestionService) SearchLabelValues(key, query string, limit int) ([]string, error)
- type SystemComponentInput
- type SystemContextInput
- type ValidatedMapping
- type ValidationCounts
- type ValidationResult
- type VisibleFilterInput
Constants ¶
const ( DefaultMaxControlsPerChunk = 40 DefaultMaxLabelSetsPerChunk = 200 DefaultMaxSuggestionsPerRun = 500 MaxMappingsPerControlPerCell = 10 MaxReasoningLength = 2000 ReasoningTruncatedMarker = "\n[truncated]" DashboardSuggestionStatusPending = "pending" DashboardSuggestionStatusAccepted = "accepted" DashboardSuggestionStatusRejected = "rejected" DashboardSuggestionStatusSuperseded = "superseded" DashboardSuggestionControlOutcomeMatched = "matched" DashboardSuggestionControlOutcomeNoMatch = "no_match" )
const ( MappingActionNewFilter = "new_filter" MappingActionExtendFilter = "extend_filter" )
const PromptVersion = "v3"
const SystemPrompt = `` /* 2156-byte string literal not displayed */
Variables ¶
This section is empty.
Functions ¶
func BuildLabelFilter ¶
func BuildLabelFilter(labels map[string]string) labelfilter.Filter
func CanonicalLabelSetHash ¶
func CanonicalizeFilter ¶
func CanonicalizeFilter(filter labelfilter.Filter) (map[string]string, bool)
func ConstraintsToJSONMap ¶
func ConstraintsToJSONMap(c Constraints) datatypes.JSONMap
ConstraintsToJSONMap serializes constraints for storage on a run. Returns nil for empty constraints so the column stays null.
func CreateRunEventTx ¶
func CreateRunEventTx(tx *gorm.DB, run *DashboardSuggestionRun, eventType DashboardSuggestionEventType, payload datatypes.JSONMap) error
func LabelFilterFromJSONMap ¶
func LabelFilterFromJSONMap(m datatypes.JSONMap) *labelfilter.Filter
LabelFilterFromJSONMap deserializes a label filter stored on a run. Returns nil when absent or empty.
func LabelFilterToJSONMap ¶
func LabelFilterToJSONMap(filter *labelfilter.Filter) datatypes.JSONMap
LabelFilterToJSONMap serializes an evidence-scoping label filter for storage on a run. Returns nil for an empty filter so the column stays null.
func OutputSchema ¶
func PlannedCalls ¶
func PlannedCalls(controlCount, labelSetCount int, cfg ChunkConfig) int
Types ¶
type CellInput ¶
type CellInput struct {
Controls []ControlInput
LabelSets []LabelSetInput
VisibleFilters []VisibleFilterInput
SameSSPFilters []VisibleFilterInput
GlobalFilterNames []string
Constraints Constraints
}
type ChunkConfig ¶
type ConflictError ¶
func (*ConflictError) Error ¶
func (e *ConflictError) Error() string
type Constraints ¶
type Constraints struct {
// MandatoryLabels must each be satisfied by a mapping's evidence label-set,
// and are injected into the proposed filter label set.
MandatoryLabels []LabelSelector `json:"mandatoryLabels,omitempty"`
// ExcludedLabels are stripped from a mapping's proposed filter label set.
ExcludedLabels []LabelSelector `json:"excludedLabels,omitempty"`
// OnlyAction, when set, keeps only mappings whose final action matches it.
// Empty means no action restriction. Valid values: MappingActionNewFilter,
// MappingActionExtendFilter.
OnlyAction string `json:"onlyAction,omitempty"`
}
Constraints are user-chosen, per-run output constraints applied to generated suggestions. They are an output constraint, not an input filter: every evidence label-set is still fed to the model, but suggestions that violate the constraints are rejected (and the constraints are surfaced in the prompt so the model self-limits and wastes fewer mappings).
func ConstraintsFromJSONMap ¶
func ConstraintsFromJSONMap(m datatypes.JSONMap) Constraints
ConstraintsFromJSONMap deserializes constraints stored on a run.
func (Constraints) IsZero ¶
func (c Constraints) IsZero() bool
IsZero reports whether no constraints are configured.
func (Constraints) Normalize ¶
func (c Constraints) Normalize() Constraints
Normalize trims keys, lowercases them to match NormalizeLabelSet semantics, drops empty-key selectors, and sorts for stable prompt rendering.
type ControlInput ¶
type ControlInput struct {
ControlKey string `json:"control_key"`
CatalogID string `json:"catalog_id"`
ControlID string `json:"control_id"`
CatalogTitle string `json:"catalog_title"`
Title string `json:"title"`
Statement string `json:"statement"`
ImplementationText string `json:"implementation_text"`
}
type ControlRef ¶
ControlRef identifies a control attached to a filter. CatalogID is the text form stored in filter_controls (the join-table uuid/text mismatch invariant); ControlID keeps its catalog-canonical casing.
type DashboardSuggestion ¶
type DashboardSuggestion struct {
relational.UUIDModel
RunID uuid.UUID `json:"runId" gorm:"type:uuid;not null;index"`
SSPID uuid.UUID `json:"sspId" gorm:"column:ssp_id;type:uuid;not null;index"`
ControlCatalogID uuid.UUID `json:"controlCatalogId" gorm:"type:uuid;not null"`
ControlID string `json:"controlId" gorm:"type:text;not null"`
LabelSet datatypes.JSONMap `json:"labelSet" gorm:"type:jsonb;not null"`
LabelSetHash string `json:"labelSetHash" gorm:"type:char(64);not null;index"`
ProposedFilterLabelSet datatypes.JSONMap `json:"proposedFilterLabelSet" gorm:"column:proposed_filter_label_set;type:jsonb"`
TargetFilterID *uuid.UUID `json:"targetFilterId" gorm:"type:uuid;index"`
ProposedFilterName string `json:"proposedFilterName" gorm:"type:text;not null"`
Reasoning string `json:"reasoning" gorm:"type:text;not null"`
Confidence float64 `json:"confidence" gorm:"type:double precision;not null"`
Status string `json:"status" gorm:"type:varchar(16);not null;index"`
AcceptedFilterID *uuid.UUID `json:"acceptedFilterId" gorm:"type:uuid;index"`
DecidedByUserID *uuid.UUID `json:"decidedByUserId" gorm:"type:uuid;index"`
DecidedAt *time.Time `json:"decidedAt"`
RejectReason *string `json:"rejectReason" gorm:"type:text"`
IsUserEdited bool `json:"isUserEdited" gorm:"not null;default:false"`
EditedByUserID *uuid.UUID `json:"editedByUserId" gorm:"type:uuid;index"`
EditedAt *time.Time `json:"editedAt"`
// AI baseline captured at first user edit (set-once) so the UI can render a
// diff of what the user changed. Nil on AI-generated, never-edited rows and
// on rows the user added during an edit (AddedByUser).
OriginalProposedFilterLabelSet datatypes.JSONMap `json:"originalProposedFilterLabelSet" gorm:"column:original_proposed_filter_label_set;type:jsonb"`
OriginalProposedFilterName *string `json:"originalProposedFilterName" gorm:"type:text"`
// AddedByUser marks rows created during a group edit (no AI baseline).
AddedByUser bool `json:"addedByUser" gorm:"not null;default:false"`
// RemovedControlIds mirrors, onto every surviving group row, the control IDs
// removed from the group during edits, so the card can show them struck-out.
RemovedControlIds datatypes.JSONSlice[string] `json:"removedControlIds" gorm:"type:jsonb"`
// IsGeneralization marks rows produced by the deterministic filter-merge
// detector (Part 2). Such a row proposes the generalized label set G that
// merges several near-duplicate SSP filters that differ by one generalizable
// label. Accepting it moves controls onto G and off the source filters.
IsGeneralization bool `json:"isGeneralization" gorm:"not null;default:false"`
// SourceFilterIDs are the SSP filters this generalization merges, recorded so
// the UI can explain the merge and the accept path can detach controls from
// them. Nil on ordinary (non-generalization) rows.
SourceFilterIDs datatypes.JSONSlice[uuid.UUID] `json:"sourceFilterIds" gorm:"type:jsonb"`
Run *DashboardSuggestionRun `json:"-" gorm:"foreignKey:RunID;references:ID;constraint:OnDelete:CASCADE"`
SystemSecurityPlan *relational.SystemSecurityPlan `json:"-" gorm:"foreignKey:SSPID;references:ID"`
TargetFilter *relational.Filter `json:"-" gorm:"foreignKey:TargetFilterID;references:ID"`
AcceptedFilter *relational.Filter `json:"-" gorm:"foreignKey:AcceptedFilterID;references:ID"`
}
func (DashboardSuggestion) TableName ¶
func (DashboardSuggestion) TableName() string
type DashboardSuggestionControlResult ¶
type DashboardSuggestionControlResult struct {
relational.UUIDModel
RunID uuid.UUID `json:"runId" gorm:"type:uuid;not null"`
SSPID uuid.UUID `json:"sspId" gorm:"column:ssp_id;type:uuid;not null;index"`
ControlCatalogID uuid.UUID `json:"controlCatalogId" gorm:"type:uuid;not null"`
ControlID string `json:"controlId" gorm:"type:text;not null"`
Outcome string `json:"outcome" gorm:"type:varchar(16);not null"`
SuggestionCount int `json:"suggestionCount" gorm:"not null;default:0"`
EvaluatedAt *time.Time `json:"evaluatedAt"`
Run *DashboardSuggestionRun `json:"-" gorm:"foreignKey:RunID;references:ID;constraint:OnDelete:CASCADE"`
}
func (DashboardSuggestionControlResult) TableName ¶
func (DashboardSuggestionControlResult) TableName() string
type DashboardSuggestionEvent ¶
type DashboardSuggestionEvent struct {
relational.UUIDModel
RunID *uuid.UUID `json:"runId" gorm:"type:uuid;index"`
SuggestionID *uuid.UUID `json:"suggestionId" gorm:"type:uuid;index"`
EventType string `json:"eventType" gorm:"type:varchar(64);not null;index"`
ActorUserID *uuid.UUID `json:"actorUserId" gorm:"type:uuid;index"`
OccurredAt time.Time `json:"occurredAt" gorm:"not null;index"`
Details *string `json:"details" gorm:"type:text"`
Payload datatypes.JSONMap `json:"payload" gorm:"type:jsonb"`
Snapshot datatypes.JSONMap `json:"snapshot" gorm:"type:jsonb"`
Run *DashboardSuggestionRun `json:"-" gorm:"foreignKey:RunID;references:ID"`
Suggestion *DashboardSuggestion `json:"-" gorm:"foreignKey:SuggestionID;references:ID"`
}
func (*DashboardSuggestionEvent) BeforeCreate ¶
func (e *DashboardSuggestionEvent) BeforeCreate(_ *gorm.DB) error
func (*DashboardSuggestionEvent) BeforeDelete ¶
func (e *DashboardSuggestionEvent) BeforeDelete(_ *gorm.DB) error
func (*DashboardSuggestionEvent) BeforeUpdate ¶
func (e *DashboardSuggestionEvent) BeforeUpdate(_ *gorm.DB) error
func (DashboardSuggestionEvent) TableName ¶
func (DashboardSuggestionEvent) TableName() string
type DashboardSuggestionEventType ¶
type DashboardSuggestionEventType string
const ( DashboardSuggestionEventTypeRunStarted DashboardSuggestionEventType = "run_started" DashboardSuggestionEventTypeRunCompleted DashboardSuggestionEventType = "run_completed" DashboardSuggestionEventTypeRunFailed DashboardSuggestionEventType = "run_failed" DashboardSuggestionEventTypeSuggestionCreated DashboardSuggestionEventType = "suggestion_created" DashboardSuggestionEventTypeAccepted DashboardSuggestionEventType = "accepted" DashboardSuggestionEventTypeRejected DashboardSuggestionEventType = "rejected" DashboardSuggestionEventTypeSuperseded DashboardSuggestionEventType = "superseded" DashboardSuggestionEventTypeEdited DashboardSuggestionEventType = "edited" )
type DashboardSuggestionRun ¶
type DashboardSuggestionRun struct {
relational.UUIDModel
SSPID uuid.UUID `json:"sspId" gorm:"column:ssp_id;type:uuid;not null;index"`
Status string `json:"status" gorm:"type:varchar(16);not null;index"`
Error *string `json:"error" gorm:"type:text"`
Model string `json:"model" gorm:"type:text;not null"`
PromptVersion string `json:"promptVersion" gorm:"type:varchar(32);not null"`
Scope datatypes.JSONMap `json:"scope" gorm:"type:jsonb;not null"`
Constraints datatypes.JSONMap `json:"constraints" gorm:"type:jsonb"`
// LabelFilter is the evidence-scoping label filter applied to this run, so the
// worker can restrict its per-cell evidence scan and the UI can show it.
LabelFilter datatypes.JSONMap `json:"labelFilter" gorm:"type:jsonb"`
PlannedCalls int `json:"plannedCalls" gorm:"not null"`
TriggeredByUserID *uuid.UUID `json:"triggeredByUserId" gorm:"type:uuid;index"`
StartedAt *time.Time `json:"startedAt"`
CompletedAt *time.Time `json:"completedAt"`
SuggestionCount int `json:"suggestionCount" gorm:"not null"`
InputTokens int `json:"inputTokens" gorm:"not null"`
OutputTokens int `json:"outputTokens" gorm:"not null"`
CacheReadInputTokens int `json:"cacheReadInputTokens" gorm:"not null;default:0"`
CacheCreationInputTokens int `json:"cacheCreationInputTokens" gorm:"not null;default:0"`
RateLimitedCount int `json:"rateLimitedCount" gorm:"not null;default:0"`
Stats datatypes.JSONMap `json:"stats" gorm:"type:jsonb;not null"`
SystemSecurityPlan *relational.SystemSecurityPlan `json:"-" gorm:"foreignKey:SSPID;references:ID"`
Cells []DashboardSuggestionRunCell `json:"cells,omitempty" gorm:"foreignKey:RunID;constraint:OnDelete:CASCADE"`
Suggestions []DashboardSuggestion `json:"suggestions,omitempty" gorm:"foreignKey:RunID;constraint:OnDelete:CASCADE"`
}
func (DashboardSuggestionRun) TableName ¶
func (DashboardSuggestionRun) TableName() string
type DashboardSuggestionRunCell ¶
type DashboardSuggestionRunCell struct {
RunID uuid.UUID `json:"runId" gorm:"type:uuid;primaryKey"`
CellIndex int `json:"cellIndex" gorm:"primaryKey"`
ControlKeys datatypes.JSONSlice[string] `json:"controlKeys" gorm:"type:jsonb;not null"`
LabelSetHashes datatypes.JSONSlice[string] `json:"labelSetHashes" gorm:"type:jsonb;not null"`
Status string `json:"status" gorm:"type:varchar(16);not null;index"`
Error *string `json:"error" gorm:"type:text"`
InputTokens int `json:"inputTokens" gorm:"not null"`
OutputTokens int `json:"outputTokens" gorm:"not null"`
CacheReadInputTokens int `json:"cacheReadInputTokens" gorm:"not null;default:0"`
CacheCreationInputTokens int `json:"cacheCreationInputTokens" gorm:"not null;default:0"`
RateLimitedCount int `json:"rateLimitedCount" gorm:"not null;default:0"`
MappingsReturned int `json:"mappingsReturned" gorm:"not null"`
MappingsRejected int `json:"mappingsRejected" gorm:"not null"`
CompletedAt *time.Time `json:"completedAt"`
Run *DashboardSuggestionRun `json:"-" gorm:"foreignKey:RunID;references:ID;constraint:OnDelete:CASCADE"`
}
func (DashboardSuggestionRunCell) TableName ¶
func (DashboardSuggestionRunCell) TableName() string
type EditGroupInput ¶
type EditGroupInput struct {
IDs []uuid.UUID
ProposedFilterName *string
Labels *map[string]string
AddControlKeys []string
RemoveIDs []uuid.UUID
}
EditGroupInput describes a user edit to a group of pending suggestions that share one proposed-filter label set (one UI card). Labels are a full replacement set; AddControlKeys/RemoveIDs adjust group membership.
type EditValidationError ¶
type EditValidationError struct {
Message string
}
EditValidationError is returned when an edit request is structurally invalid (e.g. the IDs do not form a single group, or the resulting label set is empty).
func (*EditValidationError) Error ¶
func (e *EditValidationError) Error() string
type FilterWithControls ¶
type FilterWithControls struct {
ID uuid.UUID
Name string
Labels map[string]string
Controls []ControlRef
}
FilterWithControls is one SSP-bound filter, its canonical label set, and the controls currently attached to it. It is the deterministic input to the filter-merge detector.
type GatherOptions ¶
type GatheredInput ¶
type GatheredInput struct {
Cell GridCell `json:"cell"`
Controls []ControlInput `json:"controls"`
LabelSets []LabelSetInput `json:"label_sets"`
SystemContext SystemContextInput `json:"system_context"`
LabelKeyDocs []LabelKeyDocInput `json:"label_key_docs"`
Filters []VisibleFilterInput `json:"filters"`
SameSSPFilters []VisibleFilterInput `json:"same_ssp_filters"`
GlobalFilterNames []string `json:"global_filter_names"`
Constraints Constraints `json:"constraints"`
Stats map[string]int `json:"stats"`
}
func (GatheredInput) CellInput ¶
func (g GatheredInput) CellInput() CellInput
type GeneralizationCandidate ¶
type GeneralizationCandidate struct {
DroppedKey string
GeneralizedLabels map[string]string
SourceFilterIDs []uuid.UUID
Controls []ControlRef
}
GeneralizationCandidate is a proposed merge of several near-duplicate filters that differ only by one generalizable label. GeneralizedLabels (G) is the common subset with the dropped key removed; Controls is the union of the source filters' controls, which the merged filter G will carry.
func DetectGeneralizations ¶
func DetectGeneralizations(filters []FilterWithControls, generalizableKeys []string, minShared int) []GeneralizationCandidate
DetectGeneralizations finds groups of filters whose label sets are identical after removing exactly one generalizable key. It never drops meaning-bearing keys (only keys in generalizableKeys are considered) and only proposes a merge when the candidate filters share at least minShared controls, so generalizing reflects the same control intent across instances. The result is deterministic (sorted) and contains no LLM involvement.
type GeneralizationRunInput ¶
type GeneralizationRunInput struct {
Model string
PromptVersion string
GeneralizableLabelKeys []string
MaxSuggestionsPerRun int
ActorID *uuid.UUID
}
GeneralizationRunInput carries the run-level settings for a generalization (filter-merge) run, which produces suggestion rows deterministically with no LLM cells.
type InsertMappingsResult ¶
type LabelKeyDocInput ¶
type LabelKeyInput ¶
LabelKeyInput is a distinct evidence label key with its distinct values, used to power the evidence-scoping filter builder without loading every canonical label set.
type LabelSelector ¶
LabelSelector matches an evidence/filter label. A nil Value matches any value for the given key (key-only selector); a non-nil Value requires an exact (case-insensitive key) match.
type LabelSetInput ¶
type ProposedFilterLabels ¶
func (*ProposedFilterLabels) UnmarshalJSON ¶
func (labels *ProposedFilterLabels) UnmarshalJSON(raw []byte) error
type RawMapping ¶
type RawMapping struct {
ControlKey string `json:"control_key"`
LabelSetHash string `json:"label_set_hash"`
ProposedFilterName string `json:"proposed_filter_name,omitempty"`
ProposedFilterLabels ProposedFilterLabels `json:"proposed_filter_labels,omitempty"`
Confidence float64 `json:"confidence"`
Reasoning string `json:"reasoning"`
}
RawMapping is the per-mapping shape the LLM returns. Filter targeting (action, target filter) is no longer asked of the model: the engine computes it deterministically from proposed_filter_labels in ValidateRawMappings. The model still proposes a human-readable proposed_filter_name, which the engine uses for new filters (falling back to a label-derived name when absent).
type RawMappings ¶
type RawMappings struct {
Mappings []RawMapping `json:"mappings"`
}
type RenderedPrompt ¶
RenderedPrompt holds the cacheable system/controls prefixes and the volatile tail for a single cell.
func RenderPrompt ¶
func RenderPrompt(input GatheredInput) (RenderedPrompt, error)
type Scope ¶
type Scope struct {
ControlKeys []string
LabelSetHashes []string
// LabelFilter, when set, restricts which evidence (and therefore which
// canonical label sets) feed the run. Empty/nil means all evidence.
LabelFilter *labelfilter.Filter
}
type ScopeError ¶
func (*ScopeError) Error ¶
func (e *ScopeError) Error() string
type Snapshot ¶
type SuggestionService ¶
type SuggestionService struct {
// contains filtered or unexported fields
}
func NewSuggestionService ¶
func NewSuggestionService(db *gorm.DB) *SuggestionService
func (*SuggestionService) ControlKeysWithoutFilters ¶
func (s *SuggestionService) ControlKeysWithoutFilters(sspID uuid.UUID, controlKeys []string) ([]string, error)
ControlKeysWithoutFilters returns the subset of controlKeys that have no dashboard filter attached (neither SSP-bound nor global). It powers the "only controls without filters" generation preset. Matching folds control_id case to honour the catalog-canonical casing invariant, and treats the text catalog id in filter_controls as a plain string.
func (*SuggestionService) EditGroup ¶
func (s *SuggestionService) EditGroup(sspID uuid.UUID, in EditGroupInput, actorID uuid.UUID) ([]uuid.UUID, error)
EditGroup applies a user edit to a pending suggestion group and returns the IDs of the resulting pending suggestions. The proposed filter labels are written verbatim (the subset-of-evidence rule is intentionally bypassed for human overrides); edited rows are flagged. Accept reads the stored labels, so no Accept-path change is needed.
func (*SuggestionService) GatherCellInput ¶
func (s *SuggestionService) GatherCellInput(sspID uuid.UUID, cell GridCell, opts GatherOptions, filter *labelfilter.Filter) (GatheredInput, error)
func (*SuggestionService) GatherGeneralizationCandidates ¶
func (s *SuggestionService) GatherGeneralizationCandidates(sspID uuid.UUID, generalizableKeys []string, minShared int) ([]GeneralizationCandidate, error)
GatherGeneralizationCandidates loads this SSP's filters and their attached controls, then runs the deterministic merge detector.
func (*SuggestionService) GatherLabelKeys ¶
func (s *SuggestionService) GatherLabelKeys(maxValuesPerKey int) ([]LabelKeyInput, error)
GatherLabelKeys returns distinct evidence label names and, for each, up to maxValuesPerKey distinct values, drawn from the latest stream of each evidence. It is a cheap aggregation suited to autocomplete at 100k+ evidence.
func (*SuggestionService) GatherLabelSets ¶
func (s *SuggestionService) GatherLabelSets(hashes []string, filter *labelfilter.Filter) ([]LabelSetInput, error)
func (*SuggestionService) GenerateGeneralizations ¶
func (s *SuggestionService) GenerateGeneralizations(sspID uuid.UUID, input GeneralizationRunInput) (DashboardSuggestionRun, InsertMappingsResult, int, error)
GenerateGeneralizations runs the deterministic filter-merge detector for an SSP and, when it finds candidates, creates a completed run holding one pending suggestion per merged control. It surfaces in the same pending list as LLM-generated suggestions. The run is created already completed (no cells, no LLM), so it never holds the single-active-run slot.
func (*SuggestionService) InsertGeneralizationCandidatesTx ¶
func (s *SuggestionService) InsertGeneralizationCandidatesTx(tx *gorm.DB, runID uuid.UUID, sspID uuid.UUID, promptVersion string, candidates []GeneralizationCandidate) (InsertMappingsResult, error)
InsertGeneralizationCandidatesTx inserts one suggestion row per control in the union of each candidate's source filters, tagged as a generalization with the source filter IDs recorded. Rows reuse the existing dedup so an already-merged control is skipped. Returns the number of rows inserted.
func (*SuggestionService) InsertValidatedMappings ¶
func (s *SuggestionService) InsertValidatedMappings(runID uuid.UUID, sspID uuid.UUID, promptVersion string, mappings []ValidatedMapping, maxSuggestionsPerRun int) (InsertMappingsResult, error)
func (*SuggestionService) InsertValidatedMappingsTx ¶
func (s *SuggestionService) InsertValidatedMappingsTx(tx *gorm.DB, runID uuid.UUID, sspID uuid.UUID, promptVersion string, mappings []ValidatedMapping, maxSuggestionsPerRun int) (InsertMappingsResult, error)
func (*SuggestionService) ResolveScope ¶
func (*SuggestionService) SearchLabelValues ¶
func (s *SuggestionService) SearchLabelValues(key, query string, limit int) ([]string, error)
SearchLabelValues returns distinct evidence label values for a given label key, optionally matching a substring query, drawn from the latest stream of each evidence. It is searched server-side (case-insensitive) so the filter builder can reach high-cardinality values (e.g. a specific repository) that a capped client-side list would miss.
type SystemComponentInput ¶
type SystemContextInput ¶
type SystemContextInput struct {
SystemName string `json:"system_name"`
Description string `json:"description"`
Components []SystemComponentInput `json:"components"`
}
type ValidatedMapping ¶
type ValidationCounts ¶
type ValidationResult ¶
type ValidationResult struct {
Mappings []ValidatedMapping
Counts ValidationCounts
}
func ValidateMappings ¶
func ValidateMappings(input CellInput, raw []byte) (ValidationResult, error)
func ValidateRawMappings ¶
func ValidateRawMappings(input CellInput, rawMappings []RawMapping) ValidationResult