pipx install codevira # ~66 MB pipx venv, no ML deps, no vectors
cd ~/Projects/my-project
codevira init # opt this project in
codevira setup # wire it into the AI tools on this machine
Why Codevira
AI agents write a large share of your code now. They're fast and capable, but each one is stateless across sessions and blind to the others — so you quietly became the memory.
The root cause under all four: your decisions live in your head, not anywhere the AI can be held to them.
Codevira is not a knowledge base. A knowledge base answers "what is true?" and hopes the agent reads it. Codevira answers "what did we decide, and why?" — then blocks the edit that would break it.
See it in action: record, block, recall
1. You (or the AI) record a decision — one MCP call, ~50 tokens.
record_decision(
decision="Use bcrypt for password hashing",
context="md5 considered and rejected — rainbow-table risk. Re-examine only if NIST guidance changes.",
tags=["auth", "security"],
do_not_revert=true,
)
→ D000412 recorded and locked.
It lands in <repo>/.codevira/decisions.jsonl — plain text, human-readable, and diffable (and
git-tracked as soon as you run codevira init --shared). Codevira regenerates a slim AGENTS.md
contract from it — that file is always committed.
2. Weeks later, a fresh Claude Code session tries to swap bcrypt for md5.
The Edit goes through Claude Code's PreToolUse hook first. Because the diff touches the
locked decision's subject, the hook denies the tool call and hands the agent the original
reasoning:
✗ Edit blocked — decision_lock (do_not_revert)
D000412: "Use bcrypt for password hashing"
context: md5 rejected — rainbow-table risk.
The file was not modified. Surface this to the human and re-decide deliberately.
The regression never reaches disk. An orthogonal edit to the same file — one whose diff doesn't touch the decision's subject — is allowed through and downgraded to a warn. Precision, not paranoia.
3. You switch to Cursor the next morning — and it already knows.
You never re-explained anything. Cursor reads the same repo AGENTS.md and, over MCP, can call
search_decisions("auth") — D000412 comes back with its full context. A decision recorded in
one tool is visible to every tool.
Where the block is physical. Edit-time in Claude Code; commit-time in every editor via
codevira engine install-git-hook— because they all commit with git. Overrides, kill-switches and the precise boundary: Enforcement engine (expand).
What you get
Latest: 4.2.0. Upgrade if you use codevira in more than one project: a stray registration at $HOME could make register-all discover exactly one project and discard every real one as “nested” (measured on a real machine: 1 found, 11 excluded). 4.2.0 also stops background work writing false entries to the crash log — 39 of 45 entries on that machine were one harmless line — and adds codevira reconcile to report duplicate and contradicting decisions. Upgrading is automatic, but a registration that was already wrong is not repaired for you: run codevira register-all once after upgrading to recover projects that went missing. Full release notes →
Quick Start
# 1. Install (production install: ~66 MB pipx venv, no ML deps)
pipx install codevira
# 2. Opt this project in (writes .codevira/, AGENTS.md, .gitignore)
cd ~/Projects/my-project
codevira init
# 3. Wire codevira into every AI tool detected on this machine
codevira setup
# 4. Install the universal commit-time backstop (enforces do_not_revert in ANY editor)
codevira engine install-git-hook
Step 4 is what makes enforcement universal. codevira init installs only a post-commit
reindex hook; the enforcing pre-commit hook is this separate, explicit opt-in.
Open any IDE — codevira's MCP server is ready. Then, in your AI tool, ask:
"Use get_session_context to brief me on this project." You get a ~500-token structured
project state in one tool call instead of the AI re-reading docs.
Verify the install:
codevira doctor # health checks: ✓/⚠/✗ + a fix command for each
codevira replay # browse the decisions timeline
codevira sync # regenerate AGENTS.md from current decisions.jsonl
Team sharing. By default codevira keeps decision memory per-machine (not committed), so
unrelated projects never bleed into each other; AGENTS.md and .gitignore are still committed.
To share memory with teammates on the same GitHub repo, run codevira init --shared — it keeps
.codevira/ git-tracked, and a built-in git merge driver reconciles concurrent edits.
Opt-in tracking.
codevira initis the explicit opt-in. Codevira tracks only projects you'veinit-ed; a project you merely open stays inert (its tools return a "runcodevira init" hint and nothing is written), so~/.codevira/projects/never fills with projects you didn't choose. SetCODEVIRA_AUTO_ADOPT=1to track every project you open instead.
How it works
A local MCP server. Decisions live in <repo>/.codevira/*.jsonl — plain text, human-readable,
diffable, and git-tracked once you opt in with init --shared. A slim AGENTS.md is generated
from them for every IDE to read, and Claude Code lifecycle hooks — plus the opt-in git
pre-commit hook — enforce the ones you locked.
Built to be trusted
Codevira holds a team's architectural decisions and can refuse your AI's edits. Every guarantee below is checked by the build, not asserted in this file.
What's solid, what's not
Reference
Everything below is depth for when you need it. Each section is collapsed — open the one you came for. Browser find-in-page does not search inside a closed section, so expand before Ctrl+F. What's in them:
CLI init setup doctor status projects untrack index sync repair-ids observe-git
replay search graph memory export import engine prune reset uninstall serve
working induce-skills eval register-all merge-driver
Env CODEVIRA_ENGINE CODEVIRA_TOOL_PROFILE CODEVIRA_DECISION_LOCK_MODE
CODEVIRA_ANTI_REGRESSION_MODE CODEVIRA_BLAST_RADIUS_MODE CODEVIRA_GIT_HOOK_MODE
CODEVIRA_DECISION_LOCK_CONTENT_AWARE CODEVIRA_SESSION_LOG_ENFORCER_MODE
CODEVIRA_AUTO_ADOPT CODEVIRA_IDE
MCP tool surface
36 tools are advertised to AI clients via tools/list (37 are defined — a 37th,
refresh_graph, is registered but hidden; humans invoke it via codevira sync). Every tool
carries MCP ToolAnnotations (readOnlyHint / destructiveHint=false / idempotentHint): most
are read-only and can run without a confirmation prompt, and no MCP tool is destructive — the
only destructive ops (reset / uninstall) are CLI-only, never exposed over MCP. Good to know
for anyone wiring codevira into an autonomous agent.
The lean 12 (CODEVIRA_TOOL_PROFILE=lean) are the ones you keep — set that in the MCP
server's env block to cut tools/list from 36 tools to 12, roughly a two-thirds smaller
payload (~8.9K → ~3.5K tokens of fixed per-session cost). Hidden tools still work when called
explicitly.
get_session_context · get_impact · get_node · get_roadmap · search_decisions
list_decisions · expand · record_decision · update_phase_status
complete_phase · update_next_action · write_session_log
Reads — the memory surface
Writes — capturing decisions
Roadmap — get_roadmap · get_phase · add_phase · update_phase_status ·
update_next_action · complete_phase · defer_phase · bulk_import_phases.
Code graph — get_node (file metadata) · get_impact (blast radius) · query_graph
(function-level callers/callees/tests/dependents/symbols) · get_playbook (curated rules for
add_tool / add_service / add_schema / debug_pipeline / commit / write_test). Plus the
hidden refresh_graph.
Memory subsystems
Workflow prompt — onboard_session: full project catch-up for new sessions; wraps
get_session_context().
Removed in 4.0 (52 tools → 37 defined; 36 advertised). Cut on measured usage across 4,203
transcripts, not taste — the data they wrote is untouched, and codevira export still includes
everything. See MIGRATING.md.
Enforcement engine
Codevira ships 7 default engine policies ("heroes"), each hooked to Claude Code lifecycle
events: SessionStart, PreToolUse, PostToolUse, UserPromptSubmit, Stop.
How verdicts combine. The three edit guards compose into a single verdict — first block wins by priority (Decision Lock 100 > Anti-Regression 80 > Blast-Radius 50). The highest-priority block's message is what you see; the rest are recorded as telemetry.
Fail-open and opt-in. The dispatcher never raises: each policy is wrapped in try/except and
returns allow on failure. CODEVIRA_ENGINE=0 disables all policies; each edit guard also has a
per-policy off|warn|block env override (CODEVIRA_DECISION_LOCK_MODE,
CODEVIRA_ANTI_REGRESSION_MODE, CODEVIRA_BLAST_RADIUS_MODE). Enforcement is not global
across all Claude Code projects — in any project you never ran codevira init on, the hooks stay
fully inert.
The universal backstop (4.0). codevira engine install-git-hook installs a pre-commit hook
that runs locked decisions against staged changes through the same engine — so a do_not_revert
decision is enforced in any editor, because they all commit with git. git commit --no-verify
overrides a single commit; CODEVIRA_GIT_HOOK_MODE=warn (or off) changes it globally; merge
commits are never blocked.
Why edit-time blocking is Claude Code only. The hard-block path is Claude Code's real
PreToolUse hook. Edits from Cursor / Codex / Copilot go straight to the filesystem — they never
reach codevira's PreToolUse engine — so those IDEs get decisions as advisory AGENTS.md
context, with the git pre-commit hook as the universal backstop. Verified: Claude Code returns
permissionDecision: deny (exit 2) with the decision's reasoning, rejected alternatives and
re-examination trigger attached; the git hook refuses the commit with the same reasoning. Other
IDEs are supported but verified one at a time rather than inferred.
CLI commands
26 subcommands. Two are internal (merge-driver, invoked by git's merge driver, and
register-all, a setup helper); three more are advanced (working, induce-skills, eval).
The daily-use ones are below — run codevira <cmd> --help for full flags:
To fully remove codevira: run the uninstall command above, then pipx uninstall codevira.
Language support
Decisions / AGENTS.md / roadmap are language-agnostic — they work for any language.
Code-graph and symbol tools cover exactly Python (stdlib ast) plus TS / TSX / JS / JSX / Go
/ Rust (bundled tree-sitter grammars). For any other language the AI Reads the file directly.
The legacy 17-grammar [all-languages] pack was removed in v2.2.0 to keep the install lean.
Concurrency & safety
Every on-disk write goes through mcp_server/storage/atomic.py: a crash-safe atomic write
(mkstemp + fsync + os.replace) behind a Posix fcntl.flock (with an in-process
threading.Lock first, and a Windows O_EXCL sentinel fallback). Appends to the JSONL logs are
line-atomic — concurrent appenders never interleave bytes. Result: two IDEs hitting the same
project don't race on manifest.yaml / roadmap.yaml / AGENTS.md.
This is exercised by a 50-operation stress over a 10-thread pool, a 20-subprocess cross-process
stress (spawn), and an adversarial chaos harness (scripts/chaos_smoke.py
— 8 scenarios including SIGKILL during a held lock, symlink traversal, malformed MCP payloads,
corrupt-JSONL graceful degradation, and read-only-directory hostility). See
docs/architecture.md § "Concurrent-write safety".
Upgrading & troubleshooting
Upgrading is automatic — codevira migrates your memory on the first server start after an
upgrade, and your existing decisions stay put. (After a pipx upgrade codevira, restart your IDE
so its MCP server reloads the new binary.)
One exception, if you are coming from 4.1.0 or earlier. A bug could register $HOME itself as
a project, and every genuine project below it was then discarded as a "nested sub-store". 4.2.0
stops that happening, but it does not repair a registration that is already wrong — nothing
prunes the bad row on upgrade. If projects went missing from an IDE, run this once:
codevira register-all --dry-run # read-only; shows what IS registered
If that prints one project at your home directory with your real ones listed as excluded nested, that is this bug. Before clearing it, look at what would be removed:
codevira untrack --dry-run "$HOME" # read-only; lists IDE entries AND the data dir
Read that output. untrack deletes the project's data directory, not just the registry
entry. If you were bound to $HOME by mistake, any decisions recorded during that time live in
that directory and will go with it. If the dry-run lists a data dir you might want, copy it
aside first (cp -R the path it names). Your other projects each have their own directory and
are not affected.
Then clear and re-register:
codevira untrack -y "$HOME"
codevira register-all
Restart the IDE afterwards.
(codevira doctor will not catch this one: its checks cover the current binding and whether
global.db opens, not what is registered inside it.)
If an IDE then shows the wrong project, doesn't show codevira at all, or memory looks missing,
it's almost always a stale IDE-config entry rather than lost data. Two fixes cover most cases:
remove a stray or temporary entry with codevira untrack <path> (or sweep dead ones with
codevira prune --ghosts), then run codevira doctor — it names the bound project and ships the
exact fix for each ⚠/✗.
Full guides: IDE config hygiene · Antigravity · FAQ
Frequently asked
How do I give Claude Code persistent memory across sessions?
Install codevira and run codevira init in the project. Every new session starts with
get_session_context() — a ~500-token brief of the project's decisions, current phase and next
action — instead of you re-explaining the codebase.
Does this work with Cursor and Antigravity, or only Claude Code?
Memory works everywhere: every tool reads the same in-repo .codevira/decisions.jsonl and the
generated AGENTS.md. codevira setup writes MCP server config automatically for the tools that
support it (Claude Code, Claude Desktop, Cursor, Antigravity); Codex, Copilot and other agents are
covered by the generated AGENTS.md. Hard edit-time blocking is Claude Code only — every other
editor is covered at the commit boundary by codevira engine install-git-hook.
How is this different from a hand-written CLAUDE.md or AGENTS.md?
Those are static text you maintain by hand. Codevira generates AGENTS.md from a queryable
decision log, keeps the reasoning attached to each decision, and blocks the edit that would
break a locked one.
Does it use vectors or embeddings?
No. Decision search is SQLite FTS5/BM25 keyword search — no ChromaDB, no sentence-transformers,
no torch. An AST scan in CI fails the build if any module but egress.py imports a network
client.
Is my code or my memory sent anywhere?
No. Everything lives in <repo>/.codevira/ and ~/.codevira/ on your machine. MIT-licensed, no
account, no API key, no cloud.
What does it cost in tokens?
Tools return summaries by default, get_session_context() is one ~500-token call, and the
lean-12 tool profile cuts tools/list from 36 tools to 12 (~8.9K → ~3.5K tokens per session).
Longer answers: FAQ.md.
How Codevira compares
Most memory tools for AI agents retrieve. Codevira also enforces, and it is per-project across many tools rather than per-session inside one. If you need cross-machine cloud memory, a temporal knowledge graph at enterprise scale, or the top LongMemEval score, other tools are the better pick — that comparison is written out honestly, including where codevira loses: Codevira vs other AI memory tools (Mem0, claude-mem, Zep, MemPalace and others).
Deeper reading: Architecture · Wire protocol · How we dogfood it · Roadmap · Changelog · Migrating to 4.0 · How I built persistent memory for AI coding agents
Contributing
Contributions are genuinely welcome, and the backlog is open — see CONTRIBUTING.md for the dev setup and PR checklist.
Start here before your first PR. One caveat it makes loud: 82% of codevira's internal imports sit inside function bodies, so a static import graph draws this codebase as disconnected leaves — the arrows below are runtime call edges. The diagram also marks the boundaries that don't hold, rather than pretending the layering is clean.
Good places to start:
- Run it in an IDE you use and report what happened. That's how the support matrix grows.
- Windows. The sentinel-lock fallback is unit-tested but never load-tested on real hardware.
- Docs. Anything wrong or slow to find in this README or the FAQ is a bug — file it.
Channels:
- Bug? Open a bug report
- Feature or idea? Open a feature request
- Security issue? Read SECURITY.md — please don't use public issues for vulnerabilities.
- Conduct: CODE_OF_CONDUCT.md
If Codevira saves you tokens or sanity, a ⭐ helps other developers find it.
License
MIT — free to use, modify, and distribute. See LICENSE.