Documentation
¶
Overview ¶
Package curator is the file-time learning gate: it dedups a finding against the catalog and open PRs, gates on quality, and drafts a merge-ready PR for novel, quality findings. Uncertain/low-quality findings produce NO repo artifact (the chat delivery already informed the human). It never opens issues — the only issues are knowledge-gap issues, opened by the curate agent (Phase 2).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DupFingerprint ¶
func DupFingerprint(inv providers.Investigation) string
DupFingerprint is a deterministic identity for "the same incident", used to dedupe curated PRs across re-investigations. It prefers the trigger key stamped at trigger time (a structured K8s signal — the alert fingerprint, or the failing resource + condition reason): re-investigations of one ongoing incident reword the LLM's prose cause but share the same trigger, so keying on the trigger is what coalesces them to a single open PR (#137). When no trigger key is present (e.g. a human `lore investigate "<symptom>"`), it falls back to the affected- resource ref plus the significant-token set of the top root cause. Unlike Fingerprint (a fuzzy BM25 query) it is an exact hash. It returns "" when there is nothing to key on — an empty fingerprint must never match another.
func Fingerprint ¶
func Fingerprint(inv providers.Investigation) string
Fingerprint builds the dedup query string for a finding: the alert/title, the top root-cause signature, and the affected workload. It is a BM25 query (fuzzy), not a hash — matched against the catalog index and open-PR titles.
func IncidentKey ¶ added in v0.3.0
IncidentKey builds a host-invariant, per-class dedup key for an alert: the alert class + affected workload family + cluster, with the volatile pod-hash suffix stripped. The same alert on a different pod/node yields the same key (so it dedupes to one KB entry), while a different cluster stays distinct. Returned as the alert TriggerKey and folded into DupFingerprint. "" when there is no signal.
Types ¶
type Curator ¶
type Curator struct {
Forge providers.CurationForge
Catalog catalog.ScoredSearcher // nil ⇒ no catalog dedup
Metrics *telemetry.Metrics // optional; nil-safe — dedup score unrecorded when unset
DupScore float64 // catalog BM25 dup threshold
MinConfidence float64 // quality gate: minimum overall confidence
Log *slog.Logger
}
Curator is the file-time learning gate. It dedups, quality-gates, and drafts a merge-ready PR for novel quality findings; everything else produces no repo artifact.
type Novelty ¶
type Novelty struct {
Catalog catalog.ScoredSearcher // nil → everything is novel (no catalog configured)
DupScore float64 // top-hit BM25 score ≥ this ⇒ duplicate
}
Novelty decides whether a finding duplicates an existing catalog entry, by scoring its fingerprint against the BM25 catalog index.
func (Novelty) IsDuplicate ¶
func (n Novelty) IsDuplicate(ctx context.Context, inv providers.Investigation) (bool, catalog.Entry, error)
IsDuplicate returns true and the matching entry when the top hit's score is ≥ DupScore. Returns false (novel) when no catalog is configured, there are no hits, or the top score falls below the threshold.
func (Novelty) TopHit ¶
func (n Novelty) TopHit(ctx context.Context, inv providers.Investigation) (catalog.ScoredEntry, bool, error)
TopHit returns the highest-scoring catalog entry for a finding's fingerprint. ok is false when no catalog is configured or there are no hits. It surfaces the score regardless of any threshold, so callers can both observe it and decide.