Repository navigation
Knowledge store
A small store of facts agents learned (decisions, patterns, blockers, environment notes), kept by the daemon in its own
database know.db. A fact is one line with a scope, a kind, a source and, optionally, the code it holds for. Search
returns at most a handful of compact lines with ids; a fact whose anchored code changed since it was verified comes back
marked STALE. It is written for the files agent teams keep by hand (facts.md with one fact per line) and replaces
their weak points: no search, repeated lines, and notes about files that no longer exist.
Nothing is added to the MCP tool list: the store is used through the CLI and the daemon's HTTP routes. An MCP tool for it is a later step, behind an option.
| Field | Meaning |
|---|---|
id |
k17, stable; the number alone works too |
| scope | what it is about: repo, area:docker, file:src/Foo.kt, symbol:Foo.bar, task:TER-12
|
| kind |
decision, pattern, blocker, environment, other
|
| text | one line (white space folded, at most 2000 characters) |
| source | the task and the run that wrote it |
| anchors | the code it holds for (below) |
| verified at | the commit of the checkout when the anchors were last fingerprinted |
supersedes, related
|
ids of the facts it replaces (those leave the search) and of related ones |
| status |
active, stale, superseded, with the reason for a stale one |
codeloupe know put "retries back off exponentially, capped at a minute" --scope area:webhooks --kind decision --task CL-86
codeloupe know put "Foo.parse accepts only UTC" --scope symbol:src/Foo.kt#Foo.parse --kind pattern
codeloupe know put "the new rule" --scope area:webhooks --supersedes k41A fact of the same scope whose words are near-identical to an older one (stems with Jaccard similarity of at least
0.85, and the same numbers) updates the older fact instead of adding a line: the text and source are replaced, links
and anchors are added up, the id and creation time stay. TER-167 and TER-168 are two facts however alike the rest is.
An anchor ties a fact to a file, to a declaration, or to both: --anchor src/Foo.kt, --anchor src/Foo.kt#Foo.parse,
--anchor Foo.parse (the text is a path when it has a directory or a known extension). A file: or symbol: scope anchors
itself. --root names the checkout the paths belong to (default: the current directory); an anchor may name another one.
When a fact with anchors is written or verified, the daemon fingerprints them through the code index: a digest of the signature and one of the code of the declaration (of all declarations of the file for a file anchor), and the commit of the checkout. Whenever a fact is shown, its anchors are read again, with the worktree's overlay, so an edit that is not committed yet counts:
| What happened | Flag |
|---|---|
| the signature of the declaration changed | STALE: signature changed: path#Foo.parse |
| the code changed, the signature did not | STALE: body changed: … |
| the declaration or the file is gone |
STALE: declaration gone: … / STALE: file gone: …
|
A file or class the text names without a directory is anchored as well, when the index of the checkout resolves it: a file name
(PaymentGateway.kt) held by exactly one file becomes that file's path, a CamelCase name of two or more words (PaymentGateway)
declared in the checkout becomes a symbol anchor. Names the index does not know, a file name held by two files, and plain words
(Docker, UTC) anchor nothing; at most six of each kind per fact. These anchors are not fingerprinted, so they only make the fact
stale when the file or declaration is gone; know verify fingerprints them like any other. Facts written before this keep the anchors they
have: write or import them again (a repeat is merged into the older fact) to add the new ones. An import resolves bare names in its first --root.
A fact that was never fingerprinted (an import) is only checked for existence of its target. A file the index does not
hold (Markdown, YAML, SQL) is looked up on disk, in a folder without a git repository too. A checkout that cannot be read
leaves the status as it was. If the code returns to the verified state the flag goes away; know verify <id> records
that the fact holds now (a new fingerprint and commit), and refuses with the reason when the anchor is gone. A type's
digest covers its members, so a fact anchored to a class goes stale on any change in it; anchor the member instead.
codeloupe know stale # reads every anchored fact, lists the stale ones
codeloupe know verify k17
codeloupe know show k17 # text, source, anchors and whether they are fingerprintedcodeloupe know search "how are retries backed off" --scope area:webhooks --kind decision --limit 5
k41 decision area:webhooks retries use exponential backoff capped at one minute (CL-86)
k77 pattern symbol:src/Foo.kt#Foo.parse STALE: body changed: src/Foo.kt#Foo.parse Foo.parse accepts only UTC (CL-90)codeloupe know search --anchor PaymentGateway.kt # the facts anchored to a file, newest first
codeloupe know search "retries" --anchor PaymentGateway # ranked by the question, only facts anchored to the class or its members--anchor takes the text of an anchor: a file name or a path (Foo.kt, src/Foo.kt), a symbol (Foo, Foo.parse, also with its
package) or src/Foo.kt#Foo.parse. A path matches whole or as its tail; a class also finds the facts anchored to its members. The question
may be left out with --anchor; --scope, --kind, --limit and --all work as without it.
Full-text search (SQLite FTS5, BM25 ranking) over the words of the text, scope, kind and task, with the stemming the code
search uses (retries, retried and retry are one word; a longer word also matches as a prefix). --scope takes a
comma-separated list, a bare area stands for every area; --all also returns superseded facts. At most --limit lines
(default 5, at most 30), each at most about 300 characters; the line is id kind scope [STALE: reason] text (task).
codeloupe know import brain/facts/docker.md --root /work/importer --root /work/workspaceReads files in the one-fact-per-line notation (+ fact, ! blocker, ~ decision, = evidence, ? unknown, > action,
-> handoff, x; @ context and % state lines belong to one task's moment and are skipped; an indented line
continues the fact above). The scope is area:<file name> unless --scope is given; ! gives kind blocker, ~ decision,
= environment, + environment (pattern in a file named for patterns, or --plus-kind), everything else other. A trailing
<!-- 2026-09-23 13:16:09 run-name --> gives the creation time and the run, the first task id (TER-167) the source, and
every cited path (app/src/Foo.kt:88) a file anchor, looked for in the --root checkouts in order. A line that says
SUPERSEDED is stored as superseded. Repeats are merged by the same rule as a write, and the command reports lines,
facts, skipped lines, merged repeats and the facts that cite a file that is gone. --dry-run only counts.
All behind the daemon token (x-codeloupe-token), like every route that is not a read-only code query.
| Route | |
|---|---|
GET /know/search?q=&anchor=&scope=&kind=&limit=&all=1 (q or anchor is required) |
{"hits": [{"fact": …, "line": "…"}]} |
POST /know |
one fact {"scope", "text", "kind", "task", "run", "root", "anchors": [{"path", "symbol", "root"}], "supersedes", "related", "verify"} or {"facts": [...]}; answers {"action": "added" or "updated", "fact": …, "replaced": n}
|
GET /know/{id} |
one fact |
GET /know/stale |
{"checked", "unreachable", "stale": [hits]} after reading every anchored fact |
POST /know/{id}/verify |
fingerprints the anchors now; 409 with the reason when one is gone |
The numbers, and what they mean for the cost of agents, are in docs/plan.md (section 8.11). How the store did inside a real agent flow (the nightly summary agent, the judge between stages, earlier findings in the planner's and reviewer's input) is on Agent run details: no saving beyond the noise and no avoided mistake, so it was not switched on there.
Repository · Releases · Issues · Contributing · Security · PolyForm Noncommercial 1.0.0 · This wiki is generated from docs/wiki: change it there.
Use
Features
- Jobs and events
- Workspaces and Docker cleanup
- Trackers
- Environment and secrets
- Hooks and token savings
- Plugin hooks
- Metrics and savings
- Knowledge store
- Brain index
- Desktop app
How it works
Install and contribute