Documentation
¶
Overview ¶
Package curate is the Phase-2 grooming agent: it dedups the KB backlog, gates the decision-ready queue on incident resolution, surfaces recurring blind spots as knowledge-gap issues, and drives lifecycle/decay. It writes to the forge only — it never merges and never touches a human-labelled artifact.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Dedup ¶
type Dedup struct {
Forge Forge
Threshold float64 // title-Jaccard fallback threshold for markerless PRs; default 0.6 when 0
Log *slog.Logger
}
Dedup collapses near-identical open KB PRs: the lowest-numbered PR in a cluster is canonical; the rest are closed with a back-ref comment. Conservative by design (high similarity threshold) — a missed merge is cheaper than a wrong close.
type Forge ¶
type Forge interface {
ListPRsByLabel(ctx context.Context, label string) ([]providers.CuratedIssue, error)
ListIssuesByLabel(ctx context.Context, label string) ([]providers.CuratedIssue, error)
Comment(ctx context.Context, number int, body string) error
ReplaceLabel(ctx context.Context, number int, remove, add string) error
Close(ctx context.Context, number int) error
OpenIssue(ctx context.Context, inv providers.Investigation) (providers.Ref, error)
}
Forge is the forge surface the groomer needs (all read/label/close — never merge).
type LedgerResolutionChecker ¶
LedgerResolutionChecker reports a curated PR's incident has resolved when the outcome ledger holds a matching resolved episode. The join is keyed on the deterministic dedup fingerprint (resource+cause) carried in the PR body and stamped on every ledger open — stable across the LLM's prose, so a reworded re-investigation of one incident still resolves the matching PR. A PR filed before the fingerprint was wired carries no marker; it falls back to a whitespace-normalized title join. Source-agnostic: it reads the ledger's episodes, never a trigger-specific API.
func (LedgerResolutionChecker) IsResolved ¶
func (c LedgerResolutionChecker) IsResolved(_ context.Context, pr providers.CuratedIssue) (bool, error)
IsResolved implements ResolutionChecker.
type Lifecycle ¶
type Lifecycle struct {
Forge Forge
StaleAfter time.Duration // 0 disables the sweep
Now func() time.Time // injectable clock; nil ⇒ time.Now
Log *slog.Logger
}
Lifecycle closes stale, unprotected KB artifacts — those with no forge activity within StaleAfter. A PR whose age is unknown (zero UpdatedAt) is never closed.
type Pass ¶
Pass is one grooming pass (dedup, queue, lifecycle…). Each is independent and resilient: a pass error is logged, not fatal — the agent runs the rest.
type Queue ¶
type Queue struct {
Forge Forge
Checker ResolutionChecker
Log *slog.Logger
}
Queue applies the merge condition: a quality-passing (solved) PR becomes ready-to-merge when the incident is resolved, OR when a human has labelled it accepted. Unresolved + unaccepted PRs wait (surfaced, never auto-queued).
type Recurrence ¶
type Recurrence struct {
Forge Forge
Ledger interface {
Episodes() ([]outcome.Episode, error)
}
Threshold int // default 3 when 0
Log *slog.Logger
}
Recurrence opens ONE knowledge-gap issue when an unresolved incident pattern recurs at least Threshold times. It is ledger-driven and idempotent: it recomputes counts from the outcome ledger every run and opens an issue only when no knowledge-gap issue for that pattern already exists — so re-running never double-opens (no mutable store or watermark).
type ResolutionChecker ¶
type ResolutionChecker interface {
IsResolved(ctx context.Context, pr providers.CuratedIssue) (bool, error)
}
ResolutionChecker reports whether the incident behind a curated PR has cleared (alert resolved / resource healthy). Implemented read-only over the cluster.