Open source · Rust · MIT · kybmemory.com

The shared memory your AI agent fleet keeps forgetting it needs.

KYB — Know Your Business is a git-backed, searchable knowledge base for fleets of AI agents. Which servers exist, how services are wired, what broke and how it ended, what is still open — the operational truth that survives between sessions and across machines.

licenseMIT tests321 test cases searchhybrid · ~6ms rustedition 2021 releasebrew · docker
Star on GitHub Install → Read the docs
agent@fleet — kyb — 96×26
$ kyb query "which servers run clickhouse?"orders-api-architecture  ·  score 0.867  ·  #infra #clickhouse  "orders_api on host-a is the single write path into ClickHouse (gRPC :9000)" $ kyb incident --key inc-2026-08-06-orders-api-oom --severity criticalcreated · status open · hints: add a `detection` check, link `knowledge` $ kyb task-status task-raise-log-retention --status in_progress --assignee agent-amoved · assignee=agent-a · title, body, tags and priority untouched $ kyb query "why did the order service keep restarting"   # no keyword overlapinc-2026-08-06-orders-api-oom  ·  resolved  ·  semantic hit ✓$ 
The problem

Agents forget everything between sessions. Multiple agents — Claude Code, Codex, Antigravity — on multiple machines rediscover the same infrastructure over and over, and every hard-won incident lesson evaporates the moment the context window closes.

// How it works

Six ideas, one operational truth.

No database, no namespaces, no ceremony. Just git, a disposable index, and a search that actually finds things.

Git is the canon

One markdown file per entry, one commit per change. A commit sha is a version id. There is no database — history, diff and rollback come for free, and any text editor can read the canon.

Hybrid search

BM25 fused (reciprocal rank) with vector search over every entry — e5-small, int8 ONNX, ~5 ms on CPU. Describe a problem in your own words and the right entry surfaces; exact technical terms still rank first.

Incidents & tasks built in

Not just facts: operational events and work in flight are first-class entries with real lifecycles — and every closing demands an outcome in writing.

Upserts by key

Writes are keyed and deterministic — a no-op when content did not change, so no empty commits. Flat key space plus tags; predictable key patterns are the deduplication mechanism.

Local, private, no secrets

Binds to 127.0.0.1 by default. To serve a trusted LAN, opt into one exact private interface; there is no auth, so never publish port 9310 to the internet. Writes that look like a token, key or password are rejected: store pointers, never credentials.

🦀

Rust, all the way down

axum + tantivy 0.22 + git2 + ort (ONNX Runtime). One write mutex, lock-free reads. The index is a disposable cache — lose it and it rebuilds from git on the next start.

// Architecture

Git in, ranked answers out.

01 · SOURCE OF TRUTH

Git canon

Markdown + YAML frontmatter, one commit per change.

nats-streams.md → sha 1163de8f
02 · DISPOSABLE CACHE

Tantivy index

Rebuilt from git on every start — covers head and all history.

BM25 terms + e5 int8 vectors
03 · QUERY TIME

Hybrid search

Reciprocal-rank fusion of lexical + vector, filtered by tag / kind / status.

ranked hits · ~6 ms
↺ no model on disk → the service degrades gracefully to lexical-only
// Entry kinds

Three kinds, one flat key space.

Only the closing states archive an entry — and every one of them requires an outcome in writing.

knowledge

What is true now

A fact under a stable key: architecture, topology, deploys, decisions, gotchas.

live → retracted
incident  ·  inc-…

What happened

An operational event: what broke, the impact, the runbook, the resolution.

open → mitigated → resolved
task  ·  task-…

What is in flight

Work and ideas: who holds it right now, what it waits on, what came of it.

open → in_progress → blocked → done | dropped
// Incidents

A report is a control panel, not a story.

The server teaches structure instead of gating on it — a bare report is accepted, but the reply names every missing actionable part. Two hard rules: keys start with inc-, and closing requires a resolution.

detection
An executable "is it still happening?" check, with the expected healthy result.
affected
Machine-readable poisoned windows — a backtest excludes them programmatically.
knowledge
Links to the knowledge entries the incident concerns.
resolution
How it ended — searchable, so "how did we fix this last time" has an answer.
runbook
Each step marked SAFE (an agent may act alone) or APPROVAL (human required).
follow-ups
Checkbox loose ends in the body — the server counts them and warns when you close over them.
RESOLVED severity: critical

inc-2026-08-06-orders-api-oom

orders_api OOM loop: the write buffer grows until the container restarts.

started14:02
detected14:09
mitigated14:31
resolved16:48
✓ resolution recorded · 0 open follow-ups
// Tasks

A board your agents can actually share.

A task is a short actionable note with a real lifecycle. Claim it before you start so two agents don't do the same work; block it with the reason it waits on; close it with what came of it. Every change is a git commit, so history replays who held what, in which status, at any point in time.

kyb tasks — live only, freshest on top
in_progress high assignee=agent-a
task-raise-log-retention
72h retention, 2G disk budget
blocked critical assignee=agent-b
task-swap-failing-disk
waits on: the replacement disk
open unclaimed
task-audit-log-rotation
audit.jsonl grows unbounded

Partial transitions

kyb task-status sends the status and nothing else — title, body, tags, priority and links stay exactly as stored. A transition never has to fetch and resend the task.

pick up--status in_progress --assignee agent-a
get stuck--status blocked --blocked-reason "…"
hand back--status open --assignee ""
finishkyb done <key> <<< "what came of it"

Nothing is inferred

Unranked stays unranked, unclaimed stays unclaimed. A blocked_reason is only valid while blocked — moving off blocked clears it, so a task never advertises a block it is out of. parent_task hangs child work under the task it belongs to.

// The agent skill

One command wires it into every agent on the machine.

A skill an agent never opens is a skill it never uses — so the installer drops a pointer into each agent's always-loaded global instructions. Marker-delimited and idempotent: re-running updates the section in place.

Claude Code

~/.claude/skills/kyb
+ CLAUDE.md

Codex

~/.codex/skills/kyb
+ AGENTS.md

Antigravity

~/.gemini/…/skills/kyb
+ GEMINI.md

$ KYB_SERVER=your-server:9310 bash skills/install.sh

What no database can enforce — governance

01

The loop is ask → assess → enrich: query before reasoning, write back what you learned before finishing.

02

Always query before adding. Found something close? Overwrite the same key — duplicates kill a shared base.

03

Entries are self-contained and hold verified facts only — never a guess dressed as knowledge.

04

Working a task means claiming it first, blocking it with a reason, closing it with an outcome.

05

Broke something? File an incident, close it with a real resolution, then fold the lesson back into knowledge.

06

Secrets never in bodies — pointers in refs, and the server rejects the rest.

// Search quality

Vectors earn their keep.

14 real questions against a real base, phrased the way an agent would ask rather than the way the entry was written. Top-1 / top-3 hit rate — lexical alone barely finds anything.

SETUP
TOP-1
TOP-3
LATENCY
lexical only
2 / 14
3 / 14
~2 ms
+ e5-small int8 118 MB · baked into the image
9 / 14
12 / 14
~6 ms
+ e5-base int8 266 MB
10 / 14
12 / 14
~10 ms
// HTTP API

A small, honest surface.

Every request except /healthz is appended to a JSONL audit log — timestamp, ip, method, path, status, duration.

METHOD
PATH
WHAT IT DOES
POST
/knowledge
Upsert by key → {key, sha, changed, action}. Identical content = no commit.
GET
/knowledge/{key}
Current entry; ?at=<sha> returns a version from history.
GET
/knowledge/{key}/history
Every version, newest first, with what changed.
DEL
/knowledge/{key}
Retract knowledge / archive an incident or task. History stays searchable.
POST
/incidents
Upsert a report; reply carries hints + unknown_knowledge.
GET
/incidents
Filter by status / service / follow-ups. Live first, freshest on top.
POST
/incidents/{key}/resolve
Flip status, record the outcome, stamp the timeline. Resolution required.
POST
/tasks
Upsert a task, or send a partial status / assignee / parent / blocked-reason update.
GET
/tasks
?status=&priority=&assignee=&parent_task= — live tasks, freshest on top.
POST
/tasks/{key}/resolve
done or dropped — resolution required, then archived.
GET
/search
Ranked hits with full bodies. ?q=&tag=&history=&kind=&status=&sort=
GET
/tags
Which topics the base covers, most used first.
GET
/healthz
entries · open_incidents · open_tasks · index_docs · last_commit
// Install

Up in two commands.

🍺 macOS · Apple Silicon
$ brew install alex09x/apps/kyb$ brew services start kyb
Installs both binaries, wires the skill into every agent on the machine, and keeps the server alive under launchd.
🐳 Docker
$ docker compose up -d# ghcr.io/alex09x/kyb:latest
The model is baked into the image, so the container has no network dependency at runtime.
🦀 From source
$ cargo run --release# reindexes, listens on :9310
Rust edition 2021. The index rebuilds from git on every start.

Two things to know before you expose it

There is no auth by design — keep port 9310 on a private network. And run the container as your host uid: otherwise the git canon ends up root-owned and unreadable by hand, and git-as-truth is the whole point.

Configuration — env, all optional
KYB_DATA./kyb-data
KYB_INDEX./index
KYB_ADDR127.0.0.1:9310
KYB_MODELdir · absent = lexical
KYB_AUDITaudit.jsonl
KYB_SERVERfor install.sh
CLI cheatsheet
$ kyb tags / kyb health          # the map of the base, and its pulse$ kyb query "nats streams" --tag infra --history$ kyb add --key nats-streams --title "..." --tags nats,infra <<< "body"$ kyb get nats-streams --at <sha>      # any historical version$ kyb incident --template               # the report skeleton$ kyb incidents --status open --open-followups$ kyb resolve inc-… <<< "what fixed it"  # resolution mandatory$ kyb task-status task-… --status in_progress --assignee agent-a$ kyb tasks --status blocked --priority critical$ kyb done task-… <<< "what came of it"
// Fleet deploy

One idempotent command, whole pipeline.

Refuses to run with uncommitted changes, waits for CI green, health-checks the server, then rolls the skill and CLI to every machine. Sleeping laptops don't abort the rollout — unreachable hosts are skipped and the run ends with a per-machine health table.

git push CI builds the image server pulls & restarts skill + CLI to every machine
$ scripts/deploy.sh # everything
$ scripts/deploy.sh --skills # only roll skills + CLI

Machine-specific config lives outside the repo in a gitignored fleet.local.sh. Releases are byte-reproducible: fixed member order, pinned mtimes, zeroed uid/gid, verified against a layout contract before the tag build can ship.

K

Give your agents a memory.

One command to run it, one to wire every agent on every machine into the same operational truth.

Star on GitHub Install Read the docs →