Skip to content

Rekal

Rekal is the memory your team is missing — the why behind your code, captured at every commit and shared in git, not someone else's cloud. Your AI agent starts every session blank; Rekal gives it your team's reasoning, dead-ends and all.

Website Release CI arXiv License Discord Stars

Quick start · How it works · Benchmarks · Docs · Paper · Discord

📄 Research published: "Why Git Is the Memory Solution for the Agentic Development Lifecycle" on arXiv (2607.14390)

Memory that lives in git — shared by your team, personally adaptive as you recall. Works with Claude Code, Cursor, Copilot, Codex, Gemini, Kiro, and OpenCode.

Every AI session settles decisions — why this approach, what got tried and thrown away. Then the session ends and that reasoning is gone. Rekal captures it at every commit, stores it raw in git, indexes and embeds it locally in the background, and shares it across your team when the work merges. No memory SaaS, no external memory service — embedding is local, and the store is just two files in .rekal/. Your agent recalls the conversation behind any change: the reasoning, the dead-ends already ruled out, the exact decision — in ~7.5K context tokens, in a few seconds, from git.

  • Know why, not just what — the conversation behind every change, not just the diff.
  • Stop re-deciding — dead-ends already ruled out stay ruled out; nobody re-proposes them.
  • Team memory in git — merged work travels with the repo over plain push/fetch. No server.
  • Personalised & adaptive — as you recall, load-bearing memories get a local usage hint and a gentle ranking nudge — on your machine only, never synced.

Quick start

Requirements: Git, macOS or Linux.

From Claude Code

/plugin marketplace add rekal-dev/rekal-cli
/plugin install rekal@rekal-dev

Then /rekal:install once per machine, and /rekal:init in each repo you want memory in. Both confirm before touching anything. That's the whole setup — skip to step 3 below.

From a shell

# 1. Install (default: ~/.local/bin — override with --target <dir>)
curl -fsSL https://raw.githubusercontent.com/rekal-dev/rekal-cli/main/scripts/install.sh | bash

# 2. Turn it on in your repo
cd your-project
rekal init

# 3. Work as normal — commit, and your AI session is captured automatically
git commit -m ""

# 4. In any later session, ask
rekal "why did we drop batching?"

rekal init sets up .rekal/ (the store), a post-commit/pre-push git hook, the agent skill under .claude/skills/rekal/, an orphan branch rekal/<your-email> for transport, and one marker-tagged line in CLAUDE.md pointing your agent at the skill — plus the equivalent line in the rules file of any other agent it detects (AGENTS.md for Codex/Cursor/OpenCode, GEMINI.md, .github/copilot-instructions.md, or .kiro/steering/rekal.md for Kiro). Your own content is never touched. That line is the whole developer experience for most users: init, then commit and push as normal — your agent routes its own memory from there.

After you upgrade the binary, the next recall that sees a pinned skill-version mismatch refreshes .claude/skills/ in place (hooks and agent instruction files are left alone). Re-run rekal init to also refresh hooks, the CLAUDE.md marker line, and other detected-agent rules — data stays untouched. To remove everything Rekal created, run rekal clean (no residue). Full setup, teardown, and verification detail: docs/usage.md.

The Claude Code plugin above is setup only — /rekal:install and /rekal:init, plus the installer it ships. The recall skill itself comes from the binary, so it always matches the version answering your commands.

See it in action

Last week, one engineer and their agent settled how webhook retries should work. This week, a different agent is about to re-propose the approach that was already rejected — until it asks Rekal first:

$ rekal "should webhook retries use a fixed delay?"
INJECT top=0.81 gap=0.28 2 seeds
  01JNQX8F2K9M conf=0.81 t14 [reached 3×· "webhook retry policy"] "no, a fixed 5s delay stampedes the downstream on recovery. Use exponential backoff with jitter…"
  01JNR2A7YQ4P conf=0.53 t9 "we capped retries at 5 attempts then dead-letter — anything past that never lands…"

Compact text by default — the whole answer in two lines. Line one is the verdict: INJECT (surface this memory now); the alternatives are KNOWLEDGE (read a HEAD-prose pointer instead) and SILENCE (memory isn't the tool — stay quiet). Each seed is a session id, its absolute confidence, the turn to drill (t14), and the snippet. [reached 3×· …] is your personal recall graph: you have used this memory three times before, last for "webhook retry policy" — a load-bearing decision on your machine (local-only, never pushed), and a good first drill.

The agent gets the decision and the reason the alternative was rejected — sourced from the human's own mid-course correction — before it wastes a round re-proposing it. It drills in for the full reasoning with one more call:

$ rekal query --session 01JNQX8F2K9M --role human_steering

Everything defaults to text an agent can act on directly; add --json when a program needs to parse it — the same result carries score (rank within the set, max-normalized), absolute confidence, and raw BM25 mass, so a silence gate can reject a query that is merely the best of a weak set:

$ rekal --json "should webhook retries use a fixed delay?"
{
  "query": "should webhook retries use a fixed delay?",
  "results": [
    {
      "session_id": "01JNQX8F2K9M",
      "score": 0.87, "confidence": 0.81, "mass": 5.4,
      "snippet": "no, a fixed 5s delay stampedes the downstream on recovery. Use exponential backoff with jitter…",
      "snippet_role": "human_steering",
      "session": { "author": "dev@team.dev", "branch": "feat/webhooks", "commit": "a1b2c3d" }
    }
  ]
}

Why not just…?

Instead of The gap Rekal
a MEMORY.md / notes file rots, hand-maintained, tied to one branch captured automatically at every commit, immutable, branch-aware
a RAG / memory SaaS a service to run + external servers + privacy risk local-only, nothing to operate, memory that travels with the repo
editor rules (Cursor/Copilot) per-user, per-editor, ephemeral, no team history team-wide persistent memory, travels with repo, shared decision ledger
git log / git blame tell you what changed, never why the conversation and reasoning behind the change

What makes Rekal different

Rekal is built on beliefs. Those beliefs guide every decision. When a choice conflicts with a belief, the choice loses. That is the difference.

  • Data and index, separated. Your sessions land in an append-only data.db raw — no LLM pre-summarization, no lossy "memory" distillation. The derived index.db (full-text + embeddings) is built and rebuilt locally from that data, and can be thrown away and regenerated at any time.
  • Local embedding, no external memory service. Embeddings are computed by an on-device model; retrieval — lexical + graph + deep semantic — runs on your machine. No memory SaaS, no vector-DB tier, no session text leaving the box (unless you explicitly point embeddings at a remote endpoint).
  • One immutable source of truth — fresh, no stall. Raw sessions are an append-only, immutable ledger in git — the truth; the index (embeddings and all) is a disposable derivative, a pure function of that truth. So it can never drift or go stale the way a separate memory store does — a rebuild always reconciles it — and because it's disposable, the heavy passes run in the background, hard-timeboxed, so your commit never waits. Thin on the wire, rich on the machine.
  • Personalised, adaptive recall graph. Every recall links a session to the query that reached it — on your machine only (never pushed or synced). Well-trodden memories surface with a [reached N×] hint and, by default, rank a little higher (reach_boost). Self-activating; inert until you accumulate edges. See docs/design/recall-graph.md.
  • Intent in git. Not in a separate system, not behind someone else's service. Orphan branches, full history, travels with the repo. No servers, no APIs, no telemetry.
  • Single binary. Everything embedded — database, embeddings, inference engine, compression. Zero setup. Just rekal init and commit.
  • Provenance. Every answer traces back: the turn, the session, the commit it produced, the reasoning it captured. Full graph.
  • Agent-first output. A compact text digest built for an agent to act on — verdict, per-seed confidence, drill pointers — with structured JSON one --json away. Silence gates and confidence thresholds, not prose.

The full version: SOUL.md.

Team memory

This is the payoff: your team's reasoning, shared without a server. Rekal data rides plain git on orphan branches named rekal/<email> — no common ancestor with your code, so it never touches your history, merges, or working tree.

  • rekal sync fetches teammates' branches and folds their sessions into your local index — team context before you start working.
  • Merged work only. Your local store keeps every branch at full fidelity, but only work that landed on the default branch reaches the wire (ancestor of main, or a squash-merge detected by patch-equivalence — no heuristics). Unmerged spikes stay local; a dead-end never leaks to the team, and merged work ships automatically on the next push.
  • Cross-repo recall (optional) can span every local session on your machine, index-only so it's structurally unshareable.

Team memory is the shared session ledger. The recall graph is separate: personal and local — it adapts to your access patterns and never rides the wire. Full workflow: docs/usage.md.

Knowledge layer

Recall isn't only past sessions. Rekal also chunks your repo's prose at HEAD (README, docs/, design notes) into a knowledge substrate, so a question about a current convention returns a pointer to the authoritative file and lines rather than an old conversation — the KNOWLEDGE verdict in the digest above. Design: docs/design/knowledge-layer.md.

The research

The design is argued and measured in our paper — "Why Git Is the Memory Solution for the Agentic Development Lifecycle" (arXiv:2607.14390, PDF): memory bound to git inherits its hard guarantees instead of rebuilding them; retrieval is closed as a seed-supply problem (honest grep floors, a mechanism study, the facet term); and a gated router answers each question kind — structure, episode, or rationale — at a few hundred tokens per question. The benchmark labels itself from your own commit–session links, so every result is replicable on your own history at zero annotation cost. See docs/research/ for details.

Benchmarks

On two public long-term-memory benchmarks, Rekal reaches strong answer quality with no memory layers and no external memory service — retrieval runs locally over git. The answering agent is GPT-5 Sol; Rekal supplies the memory, the model supplies the answer:

Benchmark Accuracy Recall@20 Context tokens/query Agent turns/query Time/query (agent)
LoCoMo 90.57% 98.61% ~7.5K 5.9 a few seconds
LongMemEval 86.60% 99% ~10.5K 6.6 a few seconds
Additional metric (LoCoMo) Result
Recall@10 93.60%
Recall@5 86.44%
Official F1 63.0
Typical answer output ~78–80 tokens
L1 / L2 memory layers None
External memory service None

That is 90.6% LoCoMo accuracy, 86.6% LongMemEval accuracy, and Top-20 recall of 98.6% (LoCoMo) / 99% (LongMemEval) — at roughly six agent turns per question, with no memory tier behind it. And these are the shipped skill in the loop, not a hand-tuned harness: as the answering agent gets stronger, so does the skill — accuracy climbs toward the ~98.6% / 99% Top-20 recall ceiling as the right seeds are surfaced.

Local store, wire & recall latency (Rekal's own coding sessions, Apple M4 — 6 Claude transcripts / 14 sessions, 473 turns; pure rekal, no answering model):

Metric Result
Raw JSONL 8.5 MB
Wire 54 KB (~158×)
data.db 5.8 MB
index.db 10.8 MB
Local store (data + index) 16.5 MB
Recall latency median ~150 ms (p95 ~210 ms)
LoCoMo synthetic recall median ~350 ms (p95 ~400 ms)
In-process search ~76 ms

Time/query in the accuracy table is end-to-end agent answering; these rows are retrieval and footprint alone. Wire reduction is vs the raw agent transcript (strip tool outputs / file bodies / JSONL chrome, then zstd) — see SOUL.md. Local DBs stay rich on the machine; only the wire is thin.

The trade we make on purpose: one immutable source of truth — no summaries, no upkeep, real reasoning on demand. Rekal keeps your raw sessions as an append-only, immutable ledger in git — the single source of truth — and never distills them into lossy "memories." There is nothing to summarize, nothing to maintain, nothing that drifts: the index (embeddings and all) is just a disposable accelerator over the ledger, reconciled to truth by a one-command rebuild, with raw sessions drillable the instant you commit. The intelligence isn't pre-baked into stored summaries — the heavy reasoning (retrieval, ranking, routing, the agent's own judgment) runs at query time, over the real record, when you actually ask. It's lazy evaluation — the oldest trick in the engineering book, compute on demand instead of eagerly up front — applied to memory: lazy inference, so nothing is derived until a question needs it, and nothing derived can rot in the meantime. And when you do pay for ask-time reasoning, that ask becomes another session — distilled, reasoned, riding git with the team — so the cost of the inference is implicitly cached for the next recall. The one expensive write-time step, building that index, runs in the background and hard-timeboxed, so your commit never waits. Fresh memory, no upkeep, real reasoning on demand.

Token estimates are the visible context produced during the enhanced hard-question runs. Reproduce them on your own history: the benchmark labels itself from your commit–session links at zero annotation cost (see docs/research/).

How it works

flowchart LR
    subgraph capture ["Capture"]
        A["AI Session"] -->|"rekal checkpoint<br/>(post-commit)"| B[("data.db<br/>append-only")]
    end

    subgraph transport ["Transport"]
        B -->|"rekal push"| C["Wire Format<br/>zstd + varint interning"]
        C -->|"git push<br/>rekal/&lt;email&gt;"| D[("Remote<br/>orphan branch")]
    end

    subgraph index ["Index"]
        B -->|"rekal index"| E[("index.db<br/>local-only")]
        D -->|"rekal sync"| E
        E --- F["BM25 FTS"]
        E --- G["LSA Embeddings"]
        E --- N["Deep Embeddings"]
        E --- H["Co-occurrence"]
        E --- I["Facets"]
        E --- KN["Knowledge chunks"]
    end

    subgraph query ["Query"]
        J["rekal 'keyword'"] -->|"hybrid + knowledge"| E
        E -->|"seed digest (text)<br/>conf · mass · --json"| K["Agent"]
        K -->|"rekal query<br/>--session &lt;id&gt;"| B
        B -->|"full conversation"| K
    end

    style capture fill:#fff5f5,stroke:#e94560,color:#333
    style transport fill:#f0fdf4,stroke:#22c55e,color:#333
    style index fill:#f0f4ff,stroke:#3b82f6,color:#333
    style query fill:#faf5ff,stroke:#a855f7,color:#333
Loading

The flow: commit → capture → push → sync → recall.

Developer touchpoints

You do Rekal does
rekal init (once per repo) Creates .rekal/, installs git hooks, writes the agent skill (tip + scripts + references)
git commit Hook runs rekal checkpoint — snapshots your active AI session into data.db (append-only)
git push Hook runs rekal push — encodes only your unexported data into compact wire format (zstd + string interning) and pushes to your orphan branch rekal/<email>
rekal sync (manual, when you want team context) Fetches teammates' orphan branches, imports their sessions into your local DB and rebuilds the search index
rekal clean (if needed) Removes .rekal/ and hooks from the repo

Day-to-day: commit and push as normal. Everything else is automatic.

What your agent does

Your agent recalls with rekal "<query>" — the compact seed digest it acts on directly — and drills into any session with rekal query --session <id>, controlling how much context it loads: search first, drill progressively, full sessions only when needed. The complete command surface and the progressive-loading pattern are in docs/usage.md.

The agent skill

rekal init installs one Claude Code skill under .claude/skills/rekal/. It is a thin route: the agent classifies each question and sends it to one substrate — tree (grep, now), knowledge (prose at HEAD), ledger (past reasoning), or map (structure). For a ledger question, a second step classifies the answer type and loads exactly one specialist workflow, so "how long", "how many", and "when" each get concentrated, non-overlapping guidance. Retrieval and navigation are commands in the binary; the skill is judgment, not scripts.

flowchart TB
    tip["SKILL.md route<br/>always loaded, thin"]
    tip --> triage{"Which substrate?"}
    triage -->|Tree now| grep["grep / read HEAD"]
    triage -->|Knowledge| readk["rekal '&lt;q&gt;' → Read HEAD prose"]
    triage -->|Map| mapf["map.sh fresh → map.md"]
    triage -->|Ledger / past reasoning| gate{"Answer type?"}
    gate -->|duration| w1["workflows/duration.md"]
    gate -->|count / set| w2["workflows/complete-set.md"]
    gate -->|event time| w3["workflows/event-time.md"]
    gate -->|inference| w4["workflows/inference.md"]
    gate -->|fact / why| w5["workflows/point-fact.md"]
Loading

Full skill reference: docs/usage.md#the-agent-skill · every command and flag: docs/commands.md · design: docs/design/skill-router.md.

Under the hood

Two local DuckDB databases keep the split clean: data.db (append-only truth, the only thing pushed) and index.db (rebuildable local intelligence — FTS, embeddings, the recall graph, knowledge chunks). Linked git worktrees share one store. The databases, transport, and cross-repo recall are covered in docs/usage.md.

Configuration

Rekal is zero-config by default. To tune ranking weights — the hybrid layer mix, the facet layer, and the recency / recall-graph reach boosts — or point deep embeddings at an OpenAI-compatible endpoint (vLLM, Ollama, LM Studio, TEI), there is exactly one file — .rekal/config.json, gitignored and local-only, never committed. See docs/configuration.md.

Commands reference

Command Description
rekal init Initialize Rekal in the current git repository
rekal clean Remove Rekal setup from this repository
rekal version Print the CLI version
rekal checkpoint Capture the current session after a commit
rekal push [--rebuild] Push Rekal data to the remote branch (merged work only; append-only — no force)
rekal sync [--self] Sync team context from remote rekal branches
rekal index [--include-all|--include <repo>|--no-local] Rebuild the index DB (atomic temp→rename); optionally fold in cross-repo local sessions
rekal embed Fill missing semantic embeddings (resumable; also started after index/sync)
rekal log [--limit N] Show recent checkpoints
rekal find "<term>" [role] Enumerate every ledger mention of a term (complete, time order)
rekal [--file <re>] [--commit <sha>] [--author <email>] [--actor human|agent] [-n N] [--explain] [--json] [query] Hybrid search → seed digest by default; --json for raw structured results; --explain adds per-layer scores
rekal query --session <id> [--role <r>] [--offset N] [--limit N] [--full] [--json] Drill into a session — readable turns by default; --json for one object
rekal query --sql "<sql>" [--index] [--json] Raw SQL → TSV by default; --json for NDJSON

Full details: docs/spec/command/.

Documentation

Guide What's in it
docs/usage.md The two databases, orphan branches & merged-work-only sharing, worktrees, the full agent command surface, the skill, cross-repo recall
docs/configuration.md .rekal/config.json — ranking weights, embedding backends, API-key handling
docs/spec/command/ Per-command reference specs
docs/research/ The paper, benchmark harness, and evaluation strategy
docs/DEVELOPMENT.md Building, testing, and releasing
CONTRIBUTING.md What a contribution has to satisfy, and what will be declined
SECURITY.md The security model, what's in scope, how to report a vulnerability
SOUL.md The beliefs behind every design decision

Development

git clone https://github.com/rekal-dev/rekal-cli.git rekal-cli
cd rekal-cli
mise install

See docs/DEVELOPMENT.md for the full development guide.

Contributing

Read SOUL.md first — it is the review bar, not a mission statement. Then CONTRIBUTING.md for the checks, the doc-sync rule, and the list of changes that will be declined before you spend a weekend on them.

Everyone participating is expected to follow the Code of Conduct.

Security vulnerabilities go through SECURITY.md, never a public issue.

Getting help

rekal --help
rekal <command> --help

Issues: github.com/rekal-dev/rekal-cli/issues

Citation

If you use Rekal or build on the research, please cite the paper:

@misc{guo2026rekal,
  title         = {Why Git Is the Memory Solution for the Agentic Development Lifecycle},
  author        = {Guo, Frank},
  year          = {2026},
  eprint        = {2607.14390},
  archivePrefix = {arXiv},
  primaryClass  = {cs.SE},
  url           = {https://arxiv.org/abs/2607.14390}
}

License

Apache-2.0 — see LICENSE.

About

Your coding agent starts every session blank. Rekal is the memory your team is missing

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages