One command — xerj brain ~/notes — and a folder of notes becomes a queryable, timestamped, evidence-carrying knowledge graph. No graph database, no ETL, no LLM, no embedding service, no config file. Two questions no note tool answers become one HTTP call each: why does this link exist — every link carries the exact text that taught it, verified byte-for-byte against the file on disk — and what did my notes believe last Tuesday — retired links are kept, never deleted, and any past moment is replayable. Be clear about what this is: XERJ does not understand your notes. It makes the structure you already wrote queryable, timestamped, and evidence-backed — deterministically. Same folder in, byte-identical brain out, which is exactly why an agent can cite it. The proof run below is real and unstaged: this repository's own docs folder — 121 files, 5.7 MB, images and config junk included — to 364 links in 0.7 s.
The terminal output below is from the verification run, verbatim — the corpus is the XERJ repository's own docs folder, junk included. Fourteen files (images, binaries, one frontmatter file the sniffer misread — documented in the sources) were skipped and said so: exit code 3 is the documented "ready with junk" state, never a silent success.
$ xerj brain /home/claude/ai/xerj/docs
brain 'docs': 121 files (5 MB) under /home/claude/ai/xerj/docs
booted xerj server (pid 339338) — data: …/brain/data
phase A: 7 datasets inferred, 14 junk/skipped files
phase B: indexing 106 files with 8 workers → http://localhost:9340
✓ your second brain is ready — 121 files, 364 links, 0.7s
→ http://localhost:9340/_xerj-console/#/second-brain?brain=docs
agents: XERJ_URL=http://localhost:9340 xerj-mcp
# run it again: attaches to the live server, converges in 0.14s, exit 0,
# zero duplicate links — determinism observed on real data, not asserted
xerj brain <folder>, nothing else to install or configure.A live link from the proof run, as the API returns it. The quote was checked byte-for-byte against the source file on disk — that exact text exists at that place in that note. This JSON is the paper trail, and it is the one surface where the raw schema shows; everywhere a human reads, the words are link, believed since, retired, what taught this.
$ curl "localhost:9340/_graph/docs/ego?node=$NODE&include_nodes=true"
{
"type": "mdlink",
"detector": "mdlink@1",
"confidence": 0.9,
"direction": "in",
"valid_at": 1785165764150, # believed since
"invalid_at": null, # never retired
"evidence": {
"quote": "Consistent with the [earlier run](wordpress-audit-with-xerj.md), and now with a",
"source": "research/wordpress-authz-agentic-audit.md",
"offset": 1568 # byte offset in the section — verified verbatim on disk
}
}
The honest fine print, which the dashboard also carries: structural links — files that sit together, sections in sequence — carry a generated rationale ("these files sit together in notes/"), labeled as one and never presented as text from your note. A manually asserted link may carry no evidence at all, and then the row says no evidence recorded — asserted, not detected. The claim is "every link shows its evidence" — not "every link has a quote".
The full loop, run live during verification — assert, retire, replay. Note the third call: when links are excluded from an answer, the response counts them instead of silently narrowing the world.
# assert a link $ curl -X POST localhost:9340/_graph/docs/link -d '{"src":"…","dst":"…","type":"manual"}' → 201 · edge_id 51a2a80c… # retire it — invalidated, not deleted $ curl -X DELETE localhost:9340/_graph/docs/link/51a2a80c… → {"invalidated": true, "invalid_at": 1785405730710} # ask NOW: gone — and the response says one link was excluded $ curl "…/ego?node=…" → 0 links · "not_shown": {"expired_excluded": 1} # replay the moment before the retirement: the link is BACK, # with its quote, and its later retirement visible $ curl "…/ego?node=…&as_of=$T_BEFORE_RETIRE"
The dashboard makes the same loop physical: a belief-time scrubber that narrates what changed — "2 appeared · 1 retired between then and this moment" — with retired links drawn struck-through, and a URL that pins a brain, a note, and a moment, so a link you share is a belief state, not just a page. Through the whole verification session the ledger stayed exact: 364 detected + 2 asserted belief intervals, 364 live / 2 retired — and the CLI, the HTTP API, and the MCP surface all reported the same numbers.
Neighborhood-plus-moment-plus-evidence is what temporal-knowledge-graph stacks for agents charge a graph-database-plus-LLM pipeline for. XERJ ships it in one static binary, over MCP: four verbs — xerj_brain_ego, xerj_brain_link, xerj_brain_unlink, xerj_brain_overview — proven live in the verification run, round-tripping real counts under contract: xerj-second-brain/1. And because detection is deterministic, the agent's citations are re-derivable: the quote in the answer traces to a file and a byte offset that will be there tomorrow.
$ XERJ_URL=http://localhost:9340 xerj-mcp
# tools/list → …, xerj_brain_ego, xerj_brain_link, xerj_brain_unlink, xerj_brain_overview
# every brain answer carries not_shown accounting — the agent knows what it wasn't shown
A use case is only worth publishing with its limits attached. These are the four that matter, stated the way the sources state them.
"embedder": "lexical-feature-hash"). What you get is
the structure you already wrote, made queryable — nothing more is claimed.
Everything above is published: the captured run, the verified API responses, the full reproduction recipe down to exit codes and the auth header, and the live contract-check harness that exercises the real dashboard code against a real brain. Setup is one build and one command.
Tell us what your notes look like — the folder shape, the link styles you actually use, the moment you wish you could replay. We'll come back with what the detectors will and won't find there, honestly.