FAVA Trails ๐ซ๐ฃ โ Federated Agents Versioned Audit Trail. VCS-backed memory for AI agents via MCP.
Project description
FAVA Trails
Federated Agents Versioned Audit Trail โ Git-native, curated memory for AI agents via MCP.
Every thought, decision, and observation is stored as a markdown file with YAML frontmatter in a Git repo you control, with crash-proof persistence and a versioned audit trail. Agents interact through MCP tools โ they never see VCS commands.
Why
- Supersession tracking โ when an agent corrects a belief, the old version is hidden from default recall. No contradictory memories.
- Draft isolation โ working thoughts stay in
drafts/. Other agents only see promoted thoughts. - Trust Gate โ an LLM-based reviewer validates thoughts before they enter shared truth. Hallucinations stay contained in draft.
- Full lineage โ every thought carries who wrote it, when, and why it changed.
- Crash-proof โ every write is an atomic commit. No unsaved work.
- Engine/Fuel split โ this repo is the engine (stateless MCP server). Your data lives in a separate repo you control.
Install
Prerequisites
FAVA Trails uses Jujutsu (JJ) as its storage engine, running in colocate mode alongside Git. Your repo remains a standard Git repo (GitHub and CI/CD see normal commits; pushes go through the sync MCP tool or jj git push). One-time install:
fava-trails install-jj
From PyPI (recommended)
pip install fava-trails
From source (for development)
git clone https://github.com/MachineWisdomAI/fava-trails.git
cd fava-trails
uv sync
Quick Start
Set up your data repo
New data repo (from scratch):
# Create an empty repo on GitHub (or any git remote), then clone it
git clone https://github.com/YOUR-ORG/fava-trails-data.git
# Bootstrap it (creates config, .gitignore, initializes JJ in colocate mode)
fava-trails bootstrap fava-trails-data
Existing data repo (clone from remote):
fava-trails clone https://github.com/YOUR-ORG/fava-trails-data.git fava-trails-data
Register the MCP server
Add to your MCP client config:
- Claude Code CLI:
~/.claude.json(top-levelmcpServerskey) - Claude Desktop:
claude_desktop_config.json
If installed from PyPI:
{
"mcpServers": {
"fava-trails": {
"command": "fava-trails-server",
"env": {
"FAVA_TRAILS_DATA_REPO": "/path/to/fava-trails-data",
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
If installed from source:
{
"mcpServers": {
"fava-trails": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/path/to/fava-trails", "fava-trails-server"],
"env": {
"FAVA_TRAILS_DATA_REPO": "/path/to/fava-trails-data",
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
For Claude Desktop on Windows (accessing WSL):
{
"mcpServers": {
"fava-trails": {
"command": "wsl.exe",
"args": [
"-e", "bash", "-lc",
"FAVA_TRAILS_DATA_REPO=/path/to/fava-trails-data OPENROUTER_API_KEY=sk-or-v1-... fava-trails-server"
]
}
}
}
OpenAI Codex CLI: ~/.codex/config.toml
[mcp_servers.fava-trails]
command = "fava-trails-server"
[mcp_servers.fava-trails.env]
FAVA_TRAILS_DATA_REPO = "/path/to/fava-trails-data"
OPENROUTER_API_KEY = "sk-or-v1-..."
Other MCP clients (Crush, OpenCode, etc.): check your client's MCP config docs โ most accept this JSON format:
{
"mcpServers": {
"fava-trails": {
"type": "stdio",
"command": "fava-trails-server",
"env": {
"FAVA_TRAILS_DATA_REPO": "/path/to/fava-trails-data",
"OPENROUTER_API_KEY": "sk-or-v1-..."
}
}
}
}
The Trust Gate uses LLM verification: Thoughts are reviewed before promotion to ensure they're coherent and safe. By default, FAVA Trails uses OpenRouter to access 300โ500+ models from 60+ providers including Anthropic, OpenAI, Google, Qwen, and others. Get a free API key at openrouter.ai/keys. The default model (
google/gemini-2.5-flash) costs ~$0.001 per review. Multi-provider support via any-llm-sdk enables switching to other providers by modifyingconfig.yaml.
Use it
Agents call MCP tools. Core workflow:
save_thought(trail_name="myorg/eng/my-project", content="My finding about X", source_type="observation")
โ creates a draft in drafts/
propose_truth(trail_name="myorg/eng/my-project", thought_id=thought_id)
โ promotes to observations/ (visible to all agents)
recall(trail_name="myorg/eng/my-project", query="X")
โ finds the promoted thought
Agents interact through MCP tools โ they never see VCS commands.
Cross-Machine Sync
FAVA Trails uses git remotes for cross-machine sync. The fava-trails bootstrap command sets push_strategy: immediate which auto-pushes after every write.
Setting up a second machine
# 1. Install FAVA Trails
pip install fava-trails
# 2. Install JJ (storage engine; runs alongside Git in colocate mode)
fava-trails install-jj
# 3. Clone the SAME data repo (handles colocated mode + bookmark tracking)
fava-trails clone https://github.com/YOUR-ORG/fava-trails-data.git fava-trails-data
# 4. Register MCP (same config as above, with local paths)
Both machines push/pull through the same git remote. Use the sync MCP tool to pull latest thoughts from other machines.
Manual push (if auto-push is off)
Note: Most users never need these commands. The
syncMCP tool andpush_strategy: immediatehandle everything automatically. These are for advanced manual intervention only.
cd /path/to/fava-trails-data
jj bookmark set main -r @-
jj git push --bookmark main
NEVER use git push origin main after JJ colocates โ it misses thought commits. See AGENTS_SETUP_INSTRUCTIONS.md for the correct protocol.
Architecture
fava-trails (this repo) fava-trails-data (your repo)
โโโ src/fava_trails/ โโโ config.yaml
โ โโโ server.py โโโ MCP โโโโโโ .gitignore
โ โโโ cli.py โโโ trails/
โ โโโ trail.py โโโ myorg/eng/project/
โ โโโ config.py โโโ thoughts/
โ โโโ trust_gate.py โโโ drafts/
โ โโโ hook_manifest.py โโโ decisions/
โ โโโ protocols/ โโโ observations/
โ โ โโโ secom/ โโโ preferences/
โ โโโ vcs/
โ โโโ jj_backend.py
โโโ tests/
- Engine (
fava-trails) โ stateless MCP server, Apache-2.0. Install viapip install fava-trails. - Fuel (
fava-trails-data) โ your organization's trail data, private.
Configuration
Environment variables:
| Variable | Read by | Purpose | Default |
|---|---|---|---|
FAVA_TRAILS_DATA_REPO |
Server | Root directory for trail data (monorepo root) | ~/.fava-trails |
FAVA_TRAILS_DIR |
Server | Override trails directory location (absolute path) | $FAVA_TRAILS_DATA_REPO/trails |
FAVA_TRAILS_SCOPE_HINT |
Server | Broad scope hint baked into tool descriptions | (none) |
FAVA_TRAILS_SCOPE |
Agent | Project-specific scope from .env file |
(none) |
OPENROUTER_API_KEY |
Server | API key for Trust Gate LLM reviews via OpenRouter | (none โ required for propose_truth) |
LLM Provider: FAVA Trails uses any-llm-sdk for unified LLM access. OpenRouter is the default provider (recommended for simplicity โ single API key, 300โ500+ models from 60+ providers). Additional providers (Anthropic, OpenAI, Bedrock, etc.) can be configured in config.yaml for future versions.
The server reads $FAVA_TRAILS_DATA_REPO/config.yaml for global settings. Minimal config.yaml:
trails_dir: trails # relative to FAVA_TRAILS_DATA_REPO
remote_url: null # git remote URL (optional)
push_strategy: manual # manual | immediate
When push_strategy: immediate, the server auto-pushes after every successful write. Push failures are non-fatal.
See AGENTS_SETUP_INSTRUCTIONS.md for full config reference including trust gate and per-trail overrides.
Protocols
FAVA Trails supports optional lifecycle protocols โ hook modules that run custom logic at key points in the thought lifecycle (save, promote, recall). Protocols are registered in your data repo's config.yaml and loaded at server startup.
SECOM โ Compression at Promote Time
Extractive token-level compression via LLMLingua-2, based on the SECOM paper (Tsinghua University and Microsoft, ICLR 2025). Thoughts are compressed once at promote time (WORM pattern), reducing storage and boosting recall density. Purely extractive โ only original tokens survive, no paraphrasing or rewriting.
pip install fava-trails[secom]
Add to your data repo's config.yaml:
hooks:
- module: fava_trails.protocols.secom
points: [before_propose, before_save, on_recall]
order: 20
fail_mode: open
config:
compression_threshold_chars: 500
target_compress_rate: 0.6
compression_engine:
type: llmlingua
Structured data: SECOM's token-level compression has no notion of syntactic validity โ JSON objects, YAML blocks, and fenced code blocks may be silently destroyed at promote time. Tag thoughts with secom-skip to opt out:
save_thought(trail_name="my/scope", content='{"phases": [...]}', metadata={"tags": ["secom-skip"]})
The before_save hook warns when structured content is detected without secom-skip.
See protocols/secom/README.md for full config reference, model options, and the secom-skip opt-out. See AGENTS_SETUP_INSTRUCTIONS.md for the general hooks system.
Quick setup via CLI:
# Print default config (copy-paste into config.yaml)
fava-trails secom setup
# Write config directly + commit with jj
fava-trails secom setup --write
# Pre-download model to avoid first-use delay
fava-trails secom warmup
ACE โ Agentic Context Engineering
Playbook-driven reranking and anti-pattern detection, based on ACE (arXiv:2510.04618) (Stanford, UC Berkeley, and SambaNova, ICLR 2026). Applies multiplicative scoring using rules stored in the preferences/ namespace.
pip install fava-trails # included in base install
Add to your data repo's config.yaml:
hooks:
- module: fava_trails.protocols.ace
points: [on_startup, on_recall, before_save, after_save, after_propose, after_supersede]
order: 10
fail_mode: open
config:
playbook_namespace: preferences
telemetry_max_per_scope: 10000
Quick setup via CLI:
fava-trails ace setup # print default config
fava-trails ace setup --write # write + jj commit
RLM โ MapReduce Orchestration
Lifecycle hooks for MIT RLM (arXiv:2512.24601) MapReduce workflows. Validates mapper outputs, tracks batch progress, and sorts results deterministically for reducer consumption.
pip install fava-trails # included in base install
Add to your data repo's config.yaml:
hooks:
- module: fava_trails.protocols.rlm
points: [before_save, after_save, on_recall]
order: 15
fail_mode: closed
config:
expected_mappers: 5
min_mapper_output_chars: 20
Quick setup via CLI:
fava-trails rlm setup # print default config
fava-trails rlm setup --write # write + jj commit
Development
uv run pytest -v # run tests
uv run pytest --cov # with coverage
Docs
- AGENTS.md โ Agent-facing: MCP tools reference, scope discovery, thought lifecycle, agent conventions
- AGENTS_USAGE_INSTRUCTIONS.md โ Canonical usage: scope discovery, session protocol, agent identity
- AGENTS_SETUP_INSTRUCTIONS.md โ Data repo setup, config reference, trust gate prompts, lifecycle hooks
- protocols/secom/README.md โ SECOM compression protocol: config, models, WORM architecture
- docs/fava_trails_faq.md โ Detailed FAQ for framework authors and ML engineers
Contributing
See CONTRIBUTING.md for setup instructions, how to run tests, and PR expectations.
See CHANGELOG.md for release history.
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 fava_trails-0.5.6.tar.gz.
File metadata
- Download URL: fava_trails-0.5.6.tar.gz
- Upload date:
- Size: 102.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c46cf666d2e7551304e0187e6374bda054a24e0d29555ca5300ba060042682ac
|
|
| MD5 |
a36b6dbb341be18a5bf0e40102841756
|
|
| BLAKE2b-256 |
a8c04cafdd63dd265d593797da5d826caf313521666490cb2421c6baa8d93fd1
|
Provenance
The following attestation bundles were made for fava_trails-0.5.6.tar.gz:
Publisher:
release.yml on MachineWisdomAI/fava-trails
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fava_trails-0.5.6.tar.gz -
Subject digest:
c46cf666d2e7551304e0187e6374bda054a24e0d29555ca5300ba060042682ac - Sigstore transparency entry: 1442046180
- Sigstore integration time:
-
Permalink:
MachineWisdomAI/fava-trails@79a12ea2c1c4d509ae60137550470990b2de67a6 -
Branch / Tag:
refs/tags/v0.5.6 - Owner: https://github.com/MachineWisdomAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79a12ea2c1c4d509ae60137550470990b2de67a6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file fava_trails-0.5.6-py3-none-any.whl.
File metadata
- Download URL: fava_trails-0.5.6-py3-none-any.whl
- Upload date:
- Size: 121.9 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 |
5c40d2a4a294310afa8c6877e0a20183a69b7d29230f654b001d899217f33c93
|
|
| MD5 |
67c349b9eab8a8454b2bea092839c495
|
|
| BLAKE2b-256 |
1b8552b78cd3ce465f324e32815491be36923c85089aaf756aebe7153df2ffed
|
Provenance
The following attestation bundles were made for fava_trails-0.5.6-py3-none-any.whl:
Publisher:
release.yml on MachineWisdomAI/fava-trails
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fava_trails-0.5.6-py3-none-any.whl -
Subject digest:
5c40d2a4a294310afa8c6877e0a20183a69b7d29230f654b001d899217f33c93 - Sigstore transparency entry: 1442046246
- Sigstore integration time:
-
Permalink:
MachineWisdomAI/fava-trails@79a12ea2c1c4d509ae60137550470990b2de67a6 -
Branch / Tag:
refs/tags/v0.5.6 - Owner: https://github.com/MachineWisdomAI
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79a12ea2c1c4d509ae60137550470990b2de67a6 -
Trigger Event:
release
-
Statement type: