runlore

module
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0

README ΒΆ

RunLore

RunLore

An open-source SRE agent that investigates incidents β€” and remembers what it learns.

CI Go Report Card Go Version Status


RunLore is an open-source SRE agent that investigates any incident β€” what changed? what's wrong? β€” and posts a confidence-scored root cause to chat (Slack, Matrix…). It is read-only by default: it reads your cluster, metrics, logs, and network flows β€” its only writes go to Git, via reviewed PRs.

What sets it apart: it learns your platform. Every investigation opens a PR in a Git repo you own; a human merges it, building a knowledge base of your incidents and context. The same pattern next time gets an instant answer β€” no fresh investigation.

Learns your platform Β· single Go binary Β· runs in your cluster Β· on your models.

The autonomy ladder. Teams that want more than the read-only default can climb suggest β†’ approve: even at the top supported rung RunLore only executes reversible GitOps operations after an explicit human approval β€” a human stays in the loop at every step (see Project status).

Who it's for β€” SRE and platform teams who want their incident knowledge portable and self-hosted (no lock-in, your models, your data), and would rather an agent say "I don't know" than guess. It shines if you run GitOps (Flux/Argo CD) β€” RunLore turns "what changed?" into an exact Git diff β€” but GitOps isn't required: every data source is pluggable, and an unset one simply disables its tool.

See it in action

Two sides of the same incident, delivered to your chat (shown here in Slack; Matrix delivers the same findings) β€” the whole point of the learning loop in one place.

First time β€” a full investigation. A verdict-first summary: the actionability call (no action / suggested / required / inconclusive), the confidence-scored root cause, the alert metadata and recurrence, top-cause "why", suggested next steps, ruled-out hypotheses and data gaps, and a link to the pull request it opened in your knowledge base. With the Slack notifier's bot token, the full analysis lands as a threaded reply under that summary. The footer shows the real cost β€” model calls and tokens.

Next time β€” an instant recall. Once that entry is merged, the same incident β€” even under a different, generic alert β€” is answered straight from your knowledge base: no investigation, no new PR, just the known cause, the human-reviewed resolution, and the entry's resolve-rate track record. An order of magnitude cheaper (two model calls vs a full ReAct loop), delivered in seconds.

How it works

flowchart LR
    A["Incident<br/>any alert Β· event"] -->|"trigger policy<br/>(prod Β· critical Β· ns…)"| B
    subgraph B["πŸ”Ž Investigate"]
      direction TB
      W["what changed?<br/>deploys Β· infra Β· certs Β· scaling<br/>(GitOps β†’ exact Git diff)"]
      C["what's wrong?<br/>saturation Β· network Β· nodes Β· deps"]
    end
    B --> R["🎯 Root cause<br/>+ confidence + evidence"]
    R --> D["πŸ’¬ Chat<br/>(Slack Β· Matrix…)<br/>findings + suggested fix"]
    R -. learn .-> K[("πŸ“š GitHub PR<br/>draft entry in your KB")]
    K -. instant recall .-> B
  1. An event fires β€” a pluggable source triggers RunLore: an Alertmanager webhook, a GitOps failure event, or any adapter you register.
  2. RunLore investigates β€” it reads your cluster, metrics, logs, and network flows.
  3. Findings land in chat β€” ranked root causes with confidence, the evidence trail, and suggested next steps, delivered through a pluggable notifier (Slack, Matrix, a generic webhook…).
  4. A PR opens in your KB repo β€” RunLore drafts what it found as a knowledge-base entry.
  5. A human reviews and merges β€” after adding resolution context, the PR is merged. That entry is indexed: the same incident next time gets an instant answer, no re-investigation.

πŸ“ Detailed architecture: docs/architecture/runlore-architecture.md β€” the full component diagram (the flow above is the summary).

πŸ“š The learning loop

flowchart LR
    R["πŸ”Ž Retrieve<br/>recall a past answer"] --> C["πŸ§ͺ Capture<br/>record what happened"]
    C --> U["πŸ“ Curate<br/>write the entry (PR)"]
    U --> P["♻️ Compound<br/>merged note re-indexed"]
    P --> R
    classDef s fill:#eef,stroke:#557,stroke-width:1px,color:#113;
    class R,C,U,P s;

The autonomous alert β†’ RCA β†’ chat loop is a commodity. What isn't: a knowledge base that compounds in a catalog you own. Every merged PR becomes a searchable entry β€” plain markdown in a Git repo you control, PR-reviewed, with full provenance. Knowledge that consistently resolves incidents gains trust; knowledge that keeps failing decays.

β†’ How the learning loop works Β· Reviewing & approving knowledge

πŸ”Œ Supported integrations

Every backend is pluggable behind an interface β€” wire what you run; an unset source just disables its tool. GitOps (Flux / Argo CD) anchors the what-changed spine; everything else is optional and additive. Full setup detail in Data sources.

Category Supported Config
GitOps β€” what changed Flux Β· Argo CD gitops.engine
Metrics VictoriaMetrics Β· Prometheus (PromQL) metrics.url
Logs VictoriaLogs (LogsQL) logs.url
Network flows Cilium Hubble Β· AWS VPC Flow Logs Β· GCP Firewall Logs network.provider
Cloud AWS β€” CloudTrail + EC2 / ASG / EKS cloud.provider
Kubernetes client-go β€” pod status, events, controller logs (in-cluster)
LLM Anthropic Β· Google Gemini Β· any OpenAI-compatible (vLLM, Ollama, OpenRouter…) model.provider
Triggers (sources) Alertmanager webhook Β· GitOps failures Β· PagerDuty webhook (new) sources.*
Notifiers Slack (bot token: threaded summary + detail; opt-in πŸ‘/πŸ‘Ž buttons) Β· Matrix (opt-in πŸ‘/πŸ‘Ž reactions) β€” both feed the learning loop Β· Slack incoming webhook / generic webhook (single verdict-first message) notify.*
Knowledge base (git forge) GitHub (App auth) forge.*

⚑ Try it in one minute β€” no cluster, no keys

Before you wire up a cluster, see the front of the pipeline for yourself. This runs lore serve locally with a keyless demo config and fires a batch of mocked Alertmanager alerts at it β€” no Kubernetes, no LLM, no credentials. You only need Go and curl:

hack/demo.sh

It builds the binary, starts the server, POSTs examples/alertmanager-webhook.json to the webhook, and prints the trigger policy deciding which alerts become incidents:

=== trigger-policy decisions ===
msg=incident alert=HarborProbeFailure severity=critical namespace=apps investigate=true  reason="matched trigger policy"
msg=incident alert=HarborProbeFailure severity=critical namespace=apps investigate=false reason="deduplicated (still-firing)"
msg=incident alert=NoisyWarn        severity=warning  namespace=apps investigate=false reason="filtered by trigger policy"
msg=incident alert=StagingCrit      severity=critical namespace=apps investigate=false reason="filtered by trigger policy"
msg=incident alert=Watchdog         severity=critical namespace=apps investigate=false reason="filtered by trigger policy"

That's one alert admitted (critical + prod), the rest correctly deduped, severity-filtered, environment-filtered, and ignore-listed β€” the exact gate that controls noise and LLM cost in production. The demo stops there: a full investigation (root cause β†’ chat β†’ PR) needs a real cluster, an LLM, and a knowledge base, which is the production install below. To exercise every feature end-to-end on a throwaway cluster, hack/e2e-k3d.sh spins one up with k3d.

πŸš€ Getting started (production install)

Ready to point it at real incidents? RunLore runs in your Kubernetes cluster as a single Go binary, deployed via Helm. Before installing, you need:

  • Data sources β€” at least one wired source (each is pluggable, an unset one just disables its tool); for the what-changed anchor, a cluster running Flux or Argo CD, plus optionally Prometheus/VictoriaMetrics, VictoriaLogs, Hubble for richer signals
  • An LLM β€” any OpenAI-compatible endpoint, Anthropic, or Gemini (in-cluster or external)
  • A knowledge-base repo β€” a private GitHub repo + a scoped GitHub App; this is where RunLore commits what it learns
  • A notification destination β€” a pluggable notifier: Slack, Matrix, a generic outgoing webhook, or your own

Wire your credentials into a Kubernetes Secret, point the chart at them via a values.yaml (GitOps engine, LLM endpoint, KB repo, notification), and install:

helm install runlore deploy/helm/runlore -n runlore --create-namespace -f values.yaml

The chart ships in this repo (git clone first) β€” there is no helm repo add / OCI registry yet. A minimal starting point for values.yaml is deploy/helm/runlore/values-minimal.yaml.

Then point a source at RunLore β€” for example, route your Alertmanager alerts to http://runlore.runlore.svc:8080/webhook/alertmanager β€” and it starts investigating immediately.

β†’ Full getting-started guide β€” KB repo setup, GitHub App, credentials, complete values.yaml reference, data sources, and verification steps.

Why RunLore

What it is What RunLore adds
k8sgpt A detector β€” analyzers + LLM explanation An investigation loop, cross-signal correlation, real Git diffs, and learning
HolmesGPT The strongest OSS investigation agent Relies on your hand-curated runbooks (it doesn't learn); RunLore is what-changed-first and self-improving
kagent A generic in-cluster agent framework A focused, opinionated SRE agent (RunLore can run on kagent later)

RunLore is GitOps-engine-agnostic (Flux + Argo CD), metrics-backend-agnostic (VictoriaMetrics + Prometheus), with pluggable logs and CNI-agnostic network signals. Change-aware RCA isn't unique β€” commercial tools (Komodor, Anyshift) diff changes too (prior art). The wedge is the combination the open tools don't have: that signal feeding an open, portable catalog you own (OKF-compatible markdown, not a proprietary store), from an agent that's honest about the sub-50% reality:

  • unresolved is a first-class answer;
  • an adversarial verify pass can only ever lower a finding's confidence, never raise it;
  • every claim is checked by a shipped eval harness.

Project status & stability

RunLore is pre-1.0 and under active development β€” interfaces and config may shift between commits. It's usable today, but "stable" means different things across the surface:

  • The supported golden path is eval-tested and stable. That's Flux + VictoriaMetrics / Prometheus + an Anthropic or OpenAI-compatible model + a chat notifier (Slack in the eval) + GitHub for the knowledge base. This is the path the nightly eval and the k3d e2e suite exercise β€” run it with confidence.
  • Argo CD is now end-to-end tested, alongside Flux: the k3d suite reconfigures to the argocd engine and drives an Application Degraded failure through a full investigation.
  • Functional but less exercised: Matrix, Gemini, the PagerDuty webhook source, cloud integrations, and the network (Hubble) provider. They work and are unit-tested, but see less real-world mileage β€” expect rougher edges and please file issues.
  • The auto autonomy rung is experimental, frozen, and not recommended on real clusters. The supported posture is read-only β†’ suggest β†’ approve: RunLore reads and recommends, a human reviews and merges. Hands-off auto remains on the roadmap, off by default, and should not be pointed at production.

If you stay on the golden path with a human in the approval loop, you're on the surface we test hardest.

Docs

πŸ“ Design Β· πŸ“š Learning loop Β· βœ… Reviewing knowledge Β· πŸš€ Getting started Β· πŸ§ͺ Worked example Β· πŸ”Œ Data sources Β· βš™οΈ Configuration Β· πŸ”— MCP β€” server & client Β· πŸ“Š Observability Β· 🩺 Troubleshooting Β· πŸ”’ Security model Β· πŸ›‘ LLM security architecture Β· ⬆️ Upgrade & uninstall Β· 🧭 Prior art Β· πŸ“Š Benchmarking models Β· πŸ›  Contributing

License

Apache-2.0.

Directories ΒΆ

Path Synopsis
cmd
lore command
Command lore is the RunLore CLI and in-cluster agent entrypoint.
Command lore is the RunLore CLI and in-cluster agent entrypoint.
internal
action
Package action gates proposed remediations against the autonomy-ladder policy (config.actions: off | suggest | approve | auto).
Package action gates proposed remediations against the autonomy-ladder policy (config.actions: off | suggest | approve | auto).
app
Package app holds the dependency-injection builders and config predicates that assemble the RunLore agent.
Package app holds the dependency-injection builders and config predicates that assemble the RunLore agent.
audit
Package audit provides an append-only, tamper-evident record of every action the agent attempts β€” the accountability backbone for the autonomy ladder.
Package audit provides an append-only, tamper-evident record of every action the agent attempts β€” the accountability backbone for the autonomy ladder.
catalog
Package catalog loads and searches an OKF knowledge catalog (a directory of markdown files with YAML frontmatter) β€” the read half of RunLore's Learn pillar.
Package catalog loads and searches an OKF knowledge catalog (a directory of markdown files with YAML frontmatter) β€” the read half of RunLore's Learn pillar.
coalesce
Package coalesce folds correlated Alertmanager incidents into a single investigation, suppressing the redundant per-alert investigations a storm would otherwise spawn.
Package coalesce folds correlated Alertmanager incidents into a single investigation, suppressing the redundant per-alert investigations a storm would otherwise spawn.
config
Package config defines RunLore's configuration, including provider wiring and the trigger policy that decides which incidents start an investigation.
Package config defines RunLore's configuration, including provider wiring and the trigger policy that decides which incidents start an investigation.
curate
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.
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.
curator
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.
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.
embed
Package embed provides an OpenAI-compatible embeddings client and the similarity + fusion primitives for hybrid (BM25 + vector) catalog retrieval.
Package embed provides an OpenAI-compatible embeddings client and the similarity + fusion primitives for hybrid (BM25 + vector) catalog retrieval.
eval
Package eval replays recorded incident cases through the investigation loop and scores whether the agent identifies the root cause β€” a reproducible RCA benchmark (cf.
Package eval replays recorded incident cases through the investigation loop and scores whether the agent identifies the root cause β€” a reproducible RCA benchmark (cf.
executor/flux
Package flux executes safe, reversible Flux operations (suspend / resume / reconcile) on the cluster β€” the executable half of the autonomy ladder.
Package flux executes safe, reversible Flux operations (suspend / resume / reconcile) on the cluster β€” the executable half of the autonomy ladder.
forge/github
Package github is RunLore's GitHub forge client (curation + re-investigation) over the GitHub REST API, authenticated with short-lived GitHub App installation tokens.
Package github is RunLore's GitHub forge client (curation + re-investigation) over the GitHub REST API, authenticated with short-lived GitHub App installation tokens.
httpx
Package httpx provides small HTTP helpers shared across providers.
Package httpx provides small HTTP helpers shared across providers.
investigate
Package investigate routes triggers (incident alerts, GitOps failures) into a single async investigation queue and runs them.
Package investigate routes triggers (incident alerts, GitOps failures) into a single async investigation queue and runs them.
kbmcp
Package kbmcp exposes the OKF knowledge catalog as MCP tools (kb_search, kb_get) for the `lore mcp` stdio server β€” so any MCP client (Claude Code, HolmesGPT, editors) can recall RunLore's learned incident knowledge without a cluster or a model.
Package kbmcp exposes the OKF knowledge catalog as MCP tools (kb_search, kb_get) for the `lore mcp` stdio server β€” so any MCP client (Claude Code, HolmesGPT, editors) can recall RunLore's learned incident knowledge without a cluster or a model.
kbvalidate
Package kbvalidate provides deterministic structural validation of OKF knowledge-base entries (the merge gate) and an LLM-assisted semantic advisory.
Package kbvalidate provides deterministic structural validation of OKF knowledge-base entries (the merge gate) and an LLM-assisted semantic advisory.
logging
Package logging builds RunLore's slog logger with a configurable output format (human-readable text or structured JSON) and verbosity level.
Package logging builds RunLore's slog logger with a configurable output format (human-readable text or structured JSON) and verbosity level.
logs/victorialogs
Package victorialogs implements providers.LogsProvider against VictoriaLogs, querying with LogsQL and normalizing the NDJSON response into log lines.
Package victorialogs implements providers.LogsProvider against VictoriaLogs, querying with LogsQL and normalizing the NDJSON response into log lines.
mcp
Package mcp is a minimal Model Context Protocol server over the stdio transport (newline-delimited JSON-RPC 2.0) β€” enough to expose RunLore tools to MCP clients such as HolmesGPT, kagent, or Claude Desktop.
Package mcp is a minimal Model Context Protocol server over the stdio transport (newline-delimited JSON-RPC 2.0) β€” enough to expose RunLore tools to MCP clients such as HolmesGPT, kagent, or Claude Desktop.
metrics/prometheus
Package prometheus implements providers.MetricsProvider against the Prometheus HTTP API β€” also spoken by VictoriaMetrics β€” for instant and range PromQL queries.
Package prometheus implements providers.MetricsProvider against the Prometheus HTTP API β€” also spoken by VictoriaMetrics β€” for instant and range PromQL queries.
model/anthropic
Package anthropic implements providers.ModelProvider against the Anthropic Messages API (native tool use).
Package anthropic implements providers.ModelProvider against the Anthropic Messages API (native tool use).
model/clientcore
Package clientcore provides the plumbing shared by the hand-rolled model provider clients (anthropic, gemini, openai): common construction defaults, the streaming request pipeline (retry, status classification, idle-timeout guard), SSE event decoding, and error-detail sanitization.
Package clientcore provides the plumbing shared by the hand-rolled model provider clients (anthropic, gemini, openai): common construction defaults, the streaming request pipeline (retry, status classification, idle-timeout guard), SSE event decoding, and error-detail sanitization.
model/gemini
Package gemini implements providers.ModelProvider against the Gemini API (streamGenerateContent with native function calling).
Package gemini implements providers.ModelProvider against the Gemini API (streamGenerateContent with native function calling).
model/openai
Package openai implements providers.ModelProvider against an OpenAI-compatible /chat/completions endpoint (OpenAI, in-cluster vLLM, Ollama, OpenRouter).
Package openai implements providers.ModelProvider against an OpenAI-compatible /chat/completions endpoint (OpenAI, in-cluster vLLM, Ollama, OpenRouter).
network/awsvpc
Package awsvpc implements providers.NetworkProvider against AWS VPC Flow Logs delivered to a CloudWatch Logs group, surfacing REJECT (denied) flows for an investigation.
Package awsvpc implements providers.NetworkProvider against AWS VPC Flow Logs delivered to a CloudWatch Logs group, surfacing REJECT (denied) flows for an investigation.
network/gcpfirewall
Package gcpfirewall implements providers.NetworkProvider against GCP Firewall Rules Logging, surfacing DENIED connections for an investigation.
Package gcpfirewall implements providers.NetworkProvider against GCP Firewall Rules Logging, surfacing DENIED connections for an investigation.
network/hubble
Package hubble implements providers.NetworkProvider against Cilium Hubble Relay (the observer gRPC API), surfacing dropped flows for an investigation.
Package hubble implements providers.NetworkProvider against Cilium Hubble Relay (the observer gRPC API), surfacing dropped flows for an investigation.
notify
Package notify delivers completed investigations to chat (Slack, Matrix).
Package notify delivers completed investigations to chat (Slack, Matrix).
notify/webhook
Package webhook is a generic outgoing-webhook notifier: it POSTs each investigation's findings as JSON to an operator-configured URL.
Package webhook is a generic outgoing-webhook notifier: it POSTs each investigation's findings as JSON to an operator-configured URL.
outcome
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.
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.
providers
Package providers defines the pluggable backend contracts RunLore is built on.
Package providers defines the pluggable backend contracts RunLore is built on.
providers/cloud/aws
Package aws implements providers.CloudProvider against AWS using aws-sdk-go-v2 and in-cluster identity (EKS Pod Identity / IRSA, resolved by the SDK's default credential chain).
Package aws implements providers.CloudProvider against AWS using aws-sdk-go-v2 and in-cluster identity (EKS Pod Identity / IRSA, resolved by the SDK's default credential chain).
providers/cluster
Package cluster reads Kubernetes pod logs for investigation (read-only) via the client-go CoreV1 GetLogs API.
Package cluster reads Kubernetes pod logs for investigation (read-only) via the client-go CoreV1 GetLogs API.
providers/gitops/argocd
Package argocd implements providers.GitOpsProvider for Argo CD: it reads Argo CD Applications from the cluster and emits engine-agnostic Changes (diffable via whatchanged.Differ) and failure events β€” the same contract as the flux package.
Package argocd implements providers.GitOpsProvider for Argo CD: it reads Argo CD Applications from the cluster and emits engine-agnostic Changes (diffable via whatchanged.Differ) and failure events β€” the same contract as the flux package.
providers/gitops/flux
Package flux implements providers.GitOpsProvider for Flux: it reads Flux Kustomizations and their GitRepository sources from the cluster and emits engine-agnostic Changes, each diffable through whatchanged.Differ.
Package flux implements providers.GitOpsProvider for Flux: it reads Flux Kustomizations and their GitRepository sources from the cluster and emits engine-agnostic Changes, each diffable through whatchanged.Differ.
ratelimit
Package ratelimit provides a sliding-window start limiter β€” the windowed timestamp pattern from internal/action/auto.go:reserve(), reusable.
Package ratelimit provides a sliding-window start limiter β€” the windowed timestamp pattern from internal/action/auto.go:reserve(), reusable.
redact
Package redact masks secret-shaped values in free text before it crosses a trust boundary β€” specifically before tool output (pod/controller logs, git diffs, status/event messages) is fed to the LLM provider, from where the model's quoted evidence would otherwise flow on into a (possibly public) KB pull request and chat.
Package redact masks secret-shaped values in free text before it crosses a trust boundary β€” specifically before tool output (pod/controller logs, git diffs, status/event messages) is fed to the LLM provider, from where the model's quoted evidence would otherwise flow on into a (possibly public) KB pull request and chat.
server
Package server exposes RunLore's HTTP endpoints (incident webhooks).
Package server exposes RunLore's HTTP endpoints (incident webhooks).
source
Package source registers event-source adapters and runs their core-owned transports.
Package source registers event-source adapters and runs their core-owned transports.
source/alertmanager
Package alertmanager is the Alertmanager/VMAlert webhook source adapter.
Package alertmanager is the Alertmanager/VMAlert webhook source adapter.
source/gitops
Package gitops is the GitOps-failure watcher source adapter (Flux/Argo CD).
Package gitops is the GitOps-failure watcher source adapter (Flux/Argo CD).
source/pagerduty
Package pagerduty is the PagerDuty V3 webhook source adapter.
Package pagerduty is the PagerDuty V3 webhook source adapter.
telemetry
Package telemetry provides RunLore's self-instrumentation: an OpenTelemetry metric set plus a Prometheus-exporter HTTP handler.
Package telemetry provides RunLore's self-instrumentation: an OpenTelemetry metric set plus a Prometheus-exporter HTTP handler.
trigger
Package trigger ingests incidents (Alertmanager/VMAlert webhooks) and decides, per the configured policy, which ones start an investigation.
Package trigger ingests incidents (Alertmanager/VMAlert webhooks) and decides, per the configured policy, which ones start an investigation.
whatchanged
Package whatchanged produces the "what changed" delta between two GitOps revisions: a path-scoped unified diff (the actual landed change).
Package whatchanged produces the "what changed" delta between two GitOps revisions: a path-scoped unified diff (the actual landed change).

Jump to

Keyboard shortcuts

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