Per-branch AI coding context — delta-encoded knowledge graphs, decision tracking, and Obsidian visualization. Your codebase is one organism. Each branch is a ramet.
Project description
ramets
Per-branch AI coding context — delta-encoded knowledge graphs, decision tracking, and Obsidian visualization.
Your codebase is one organism. Each branch is a ramet.
Named after Pando (Populus tremuloides), the world's largest organism — a single aspen clone where individual trunks (ramets) share one root system (genet).
The Problem
AI coding assistants (Claude Code, Cursor, Codex) waste enormous tokens re-reading your codebase every session:
| Without ramets | With ramets | Savings |
|---|---|---|
| Read knowledge graph: 212K tokens | Session summary injection: ~400 tokens | 99.8% |
| Re-read files on branch switch: ~50K | Delta summary: ~200 tokens | 99.6% |
| "What did we decide?" — grep history: ~10K | ramets decisions: ~300 tokens |
97% |
| New session, re-explore codebase: ~30K | SessionStart hook: ~500 tokens | 98% |
LLM providers aren't incentivized to fix this — more tokens means more subscription revenue. So we fix it ourselves.
Quick Start
pip install ramets
cd your-repo
ramets init # Build genet, install hooks (~5 seconds)
ramets query "how does authentication work?" # ~300 tokens
ramets status # Show genet freshness, branch deltas
ramets summary # Session context (~400 tokens)
ramets obsidian # Generate Obsidian vault for visualization
How It Works
Genet (shared root) ──> base knowledge graph from common ancestor
├── Ramet: main ──> 0 deltas (is the base)
├── Ramet: feat/auth ──> 12 deltas (added auth module)
├── Ramet: fix/typo ──> 2 deltas (renamed function)
└── Ramet: feat/api ──> 28 deltas (new API layer)
Total storage: ~100KB for 400 nodes (ramets codebase itself)
ramets initbuilds the genet from tree-sitter AST extraction (via graphify)- Git hooks fire on every commit/checkout — zero LLM tokens, all local computation
- Claude Code hooks inject pre-computed summaries at session start (~400 tokens)
ramets querydoes keyword + BFS traversal with configurable token budgets
Git hooks do ALL computation. The LLM only consumes pre-computed results.
Features
Delta-Encoded Knowledge Graphs
- Genet: shared base graph (zlib-compressed, ~80KB)
- Ramets: per-branch deltas — only what changed (add/remove/modify nodes and edges)
- Concurrent worktree access via SQLite WAL mode
- Storage: 104KB for 408 nodes, 837 edges (real measurement on ramets codebase)
Git Hooks (Zero Token Cost)
| Hook | Trigger | What it does |
|---|---|---|
| post-commit | Every commit | Compute branch delta (AST diff vs genet) |
| post-checkout | Branch switch | Register branch, prep snapshot |
| post-merge | After pull/merge | Recompute deltas |
| post-rewrite | After rebase | Rebuild deltas for rewritten commits |
Claude Code Hooks (Token Savings)
| Hook | Trigger | Tokens saved |
|---|---|---|
| SessionStart | Session begins | ~212K (injects 400-token summary instead) |
| UserPromptSubmit | User sends prompt | ~30-50K (redirects to graph query) |
| PreToolUse | File read attempted | ~10-50K (gates expensive reads) |
Decision Tracking
Structured records of "AI suggested X, user chose Y" — not natural language summaries.
ramets decide \
-q "Which auth strategy?" \
-o "JWT:Stateless tokens" \
-o "Session cookies:Server-side sessions" \
-c 0 \
-r "Stateless fits our microservices design" \
--category architecture \
--confidence 0.85
ramets decisions # List active decisions
ramets decisions -s "auth" # Full-text search
ramets decisions --id abc123 # View decision detail
Obsidian Visualization
ramets obsidian # Generate vault
ramets obsidian --open # Generate and open in Obsidian
ramets obsidian --all-branches # Include all branch layers
Generates a navigable vault with:
- Base layer: Community-colored nodes with
[[wikilinks]] - Branch delta layers: Added/modified/removed nodes per branch
- Decision notes: Structured choices with options and rationale
- Graph settings: Community coloring for the graph view
MCP Server (15 tools)
pip install ramets[mcp]
ramets serve # stdio transport
# Or: claude mcp add ramets -- ramets serve
Tools: query_graph, get_node, diff_branches, session_summary, record_decision, list_decisions, search_decisions, generate_obsidian_vault, and more.
Architecture
.ramets/store.db (SQLite, WAL mode)
├── genet — shared root graph (compressed blob)
├── ramets — materialized per-branch snapshots
├── ramet_deltas — delta log per branch
├── decisions — structured decision records
├── decision_edges — decision relationship graph
├── sessions — AI session tracking
└── branches — branch registry
CLI Reference
ramets init Create .ramets/, build genet, install hooks
ramets build Full genet rebuild from HEAD
ramets update Compute branch delta vs genet (called by hooks)
ramets status Genet freshness, ramet count, storage
ramets query "..." BFS traversal on current branch graph
ramets diff feat/a main Graph diff between branches
ramets summary Compact summary for session injection (~400 tokens)
ramets decide Record a structured decision
ramets decisions List/search decisions for current branch
ramets obsidian Generate Obsidian vault with branch layers
ramets obsidian --open Generate and open in Obsidian
ramets serve Start MCP server (stdio)
ramets gc Prune dead ramets, compact DB
Development
git clone https://github.com/panne027/ramets.git
cd ramets
pip install -e ".[dev]"
pytest tests/ -v # 70 tests
ruff check src/ tests/ # Lint
ruff format src/ tests/ # Format
Requirements
- Python >= 3.10
- Git repository
- graphify (installed as dependency)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ramets-0.3.0.tar.gz.
File metadata
- Download URL: ramets-0.3.0.tar.gz
- Upload date:
- Size: 41.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70cd63bd52f9a96dba7aaf663f5d13f8cde4e6f98c4bbdf970e9f19c8112bfd7
|
|
| MD5 |
871c8d9e335b7c0fe94e842b951f1b41
|
|
| BLAKE2b-256 |
193dc6cbd00ad4ec0962ffc46fb543c60f3a048c652349aaa779cab59af474f4
|
Provenance
The following attestation bundles were made for ramets-0.3.0.tar.gz:
Publisher:
release.yml on panne027/ramets
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ramets-0.3.0.tar.gz -
Subject digest:
70cd63bd52f9a96dba7aaf663f5d13f8cde4e6f98c4bbdf970e9f19c8112bfd7 - Sigstore transparency entry: 1280203175
- Sigstore integration time:
-
Permalink:
panne027/ramets@eee51df5ef302a183c5b916ace0ca418745fecb4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/panne027
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@eee51df5ef302a183c5b916ace0ca418745fecb4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ramets-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ramets-0.3.0-py3-none-any.whl
- Upload date:
- Size: 38.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc4a8b7cf625fc3b179fd066f9e1bdd3278d4654934b9a72726eb0bbcd0a0bb2
|
|
| MD5 |
8cfdff39fe12044a91eb0ccb1ca26c1b
|
|
| BLAKE2b-256 |
57e8453b43b8a681aeef069aed65b3ea3ad6bf37cff657e3a73757f8c2b21161
|
Provenance
The following attestation bundles were made for ramets-0.3.0-py3-none-any.whl:
Publisher:
release.yml on panne027/ramets
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ramets-0.3.0-py3-none-any.whl -
Subject digest:
cc4a8b7cf625fc3b179fd066f9e1bdd3278d4654934b9a72726eb0bbcd0a0bb2 - Sigstore transparency entry: 1280203185
- Sigstore integration time:
-
Permalink:
panne027/ramets@eee51df5ef302a183c5b916ace0ca418745fecb4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/panne027
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@eee51df5ef302a183c5b916ace0ca418745fecb4 -
Trigger Event:
push
-
Statement type: