Documentation
¶
Overview ¶
Package outcome records, in an append-only JSONL ledger, whether an investigated incident later resolved and which answer was used for it — the "did it actually work?" signal the learning loop reads. The ledger keeps an in-memory index of still-open incidents, rebuilt by replaying the file on startup so a resolve survives a restart / leader failover.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Aggregate ¶
Aggregate is a per-entry roll-up of recall episodes: how often the entry was recalled, how often the incident then resolved, and when it last resolved.
type Episode ¶
type Episode struct {
Kind, Entry, Title, Resource string
DupFingerprint string // curator dedup fingerprint; stable join key for the curated-PR resolution check
OpenedAt, ResolvedAt time.Time
Duration time.Duration
Resolved bool
}
Episode is a matched open→resolve pair (or, from Episodes(), an unresolved open when Resolved is false).
type Event ¶
type Event struct {
Event string `json:"event"` // "open" | "resolve"
Fingerprint string `json:"fingerprint"` // Alertmanager fingerprint (stable firing↔resolved)
DupFingerprint string `json:"dup_fingerprint,omitempty"` // curator dedup fingerprint (resource+cause); the curated-PR resolution join key
Kind string `json:"kind,omitempty"` // open: "recall" | "fresh"
Entry string `json:"entry,omitempty"` // open+recall: the recalled entry path
Title string `json:"title,omitempty"`
Resource string `json:"resource,omitempty"`
At time.Time `json:"at"`
}
Event is one ledger line: an investigation opened, or an incident resolved.
type Ledger ¶
type Ledger struct {
// contains filtered or unexported fields
}
Ledger is an append-only outcome log with an in-memory open-index.
func New ¶
New opens (replaying) the ledger at path. An empty path returns a disabled, no-op ledger (the feature is off).
func (*Ledger) Episodes ¶
Episodes replays the full ledger and turns every open into an Episode, pairing each resolve with the most-recent (LIFO) unresolved open for the same fingerprint — so recurrence is preserved (N opens + 1 resolve ⇒ N episodes, 1 resolved). Pairing is order-independent: a resolve that arrives BEFORE its open (a transient incident that cleared mid-investigation, so the resolve webhook landed before the open was recorded) is buffered and paired with the next open for that fingerprint. Episodes are returned in open order; all kinds are included. A disabled/empty ledger yields nil.
func (*Ledger) OpenCounts ¶
OpenCounts rolls Episodes up per catalog entry, counting recall episodes only (fresh investigations carry no entry). It is the input to recall decay: resolve-rate ≈ (Resolved+k)/(Recalls+k). A disabled/empty ledger yields an empty (non-nil) map.
type Status ¶
type Status struct {
Path string // the configured ledger path ("" when disabled)
Configured bool // a non-empty ledger_path was set
Present bool // the file exists (true even when empty)
Events int // number of replayable events (0 for absent/empty)
}
Status is a cheap snapshot of the ledger's on-disk reality, used to tell apart "feature off" (Configured=false) from "configured but the file the curate pod can see is absent/empty" (Configured=true, Present=false or Events==0) — the silent-no-op the `lore curate` startup warning surfaces. It re-reads the file (no cached open-index) so it reflects what a fresh process actually sees.