FAVA Trails

By Machine Wisdom AI

FAVA Trails · Open-source agent memory

Shared agent memory with a review step between draft and decision

FAVA Trails is open-source memory for AI agents, built by Machine Wisdom AI. Agents save thoughts as drafts, a reviewer you configure decides which drafts become shared records, and an approved correction replaces an older record while keeping its history. Agents connect through MCP, and the records are Markdown files in a Git-compatible repository you control, versioned with Jujutsu.

It suits teams whose agents reuse each other's conclusions, or whose work continues across sessions, and who want to see how a remembered decision changed. It does not verify facts, search by meaning, or isolate agents that share one endpoint.

Federated Agents Versioned Audit Trail

Why shared memory needs a review step

An agent can mistake a temporary failure for a lasting constraint. If that observation goes straight into shared memory, another agent can reuse it long after the original context has disappeared, and nobody can say who accepted it. Machine Wisdom AI built FAVA Trails around three questions: who may publish a memory, what review it receives, and how a correction reaches later readers.

In FAVA Trails a saved thought starts as a draft with a named author. A review step decides whether it becomes an approved record, and the review result is stored with the record. When a decision turns out to be wrong, an approved successor replaces it in default recall and links back to what it replaced. The two-agent case study is a dated account of that correction from February 2026, written before the current review defaults.

How a thought becomes shared memory

FAVA Trails separates saving a thought from accepting it. Four steps cover one record's life, and publication to other machines is a fifth, separate step.

  1. Save a draft

    save_thought(trail_name="team/project", content="Cache test needs a repeat run.")
    before_save after_save

    A saved thought starts in drafts/. Default recall returns approved current records only, so the draft is invisible to other readers. The authoring agent reads its own drafts through explicit authoring mode, and each authoring process runs with an identity the operator sets. The operator chooses a stable role name for it, and processes that reuse a name share its authoring view.

  2. Ask for review

    propose_truth(trail_name="team/project", thought_id="<saved-id>")
    before_propose after_propose

    The configured reviewer sees the candidate with limited context and approves or rejects it. A rejection freezes that draft, and the author revises by saving a new draft that points at the rejected one. Review is a quality-control step. A convincing false claim can still be approved, and a failed or unavailable review approves nothing.

  3. Recall approved records

    recall(trail_name="team/project", query="cache test")
    on_recall

    Recall returns approved records whose text contains every word of the query. It is lexical matching, so a paraphrase can miss.

  4. Correct by supersession

    supersede(trail_name="team/project", thought_id="<approved-id>", content="...", reason="...")

    A correction is a new draft successor. The old record stays current until the successor is approved, after which default recall returns only the successor and the lineage stays inspectable. Supersession records what replaced what; it does not establish that the replacement is true.

  5. Publish, then sync

    sync(trail_name="team/project")

    Another environment sees approved records only after they are published to the shared remote and the reader calls sync, which fetches and rebases. In manual push mode, the default that fava-trails bootstrap writes, you publish with an explicit push. With push_strategy: immediate, the server pushes after a successful write operation, and a successful sync counts as one.

    The setup instructions own the exact procedure →

Read the review-and-recall details in governed recall

Fit and limits

FAVA Trails adds structure, and structure has costs: a review step, an identity per authoring process, and a Git remote to operate if records cross machines.

It fits when

  • Several agents or sessions reuse each other's decisions, and a wrong conclusion that spreads would cost you. Drafts stay private to their author, and shared readers see approved records.
  • Work continues across sessions or machines and you need accepted decisions to survive, with a record of who wrote each one and what replaced it.
  • You want a reviewer in the loop that you choose and can run yourself, including a model served from your own infrastructure, and a repository you can read, diff and back up.
  • You can operate a Git remote if records must cross machines. Hosting, access and credential rotation for that remote are your responsibility.

It is the wrong tool when

  • One agent works in one session, or a plain notes file already serves you. A review lifecycle adds overhead that a single reader does not repay.
  • You need search by meaning. Recall matches lowercased, whitespace-separated words as substrings, and a query that uses different words than the record misses it.
  • You need claims checked against reality. The reviewer applies a rubric or a probability threshold to one candidate with limited context. It does not verify facts, and it does not compare the candidate with existing records, so approved records can still disagree with one another.
  • You need isolation between agents that share one endpoint. A shared endpoint is one identity boundary, and separate authoring identities need separate processes.
  • Review content may not leave your network and you cannot run a reviewer inside it. Under a remote reviewer the candidate has already been sent when a rejection comes back.
  • You want a store for operational working context. FAVA Trails holds decisions, observations, validation evidence and lineage; working context belongs in the caller's own system.

What to settle before you rely on it

Where review text goes is a data-egress choice that you make on purpose. The destination is set by your effective configuration, and fava-trails doctor prints the effective destination and model without secrets. Calling a reviewer local does not prove the model runs on the same host: FAVA Trails classifies an endpoint as local only when its address is localhost or a numeric loopback IP, and it cannot see through a tunnel or port forward on a loopback port. An explicit custom non-loopback API base is reported as a custom endpoint, a hosted provider used without an API base is reported as a remote provider, and choosing a provider by name alone does not keep text on your machine. A rejection never recalls text that a remote reviewer has already received. The hosted Decisions reviewer, TypeSafe Jev through OpenRouter, returns a probability and no rejection rationale, so a rejection from it tells the author nothing about what to change. Model approval is recorded as advisory (llm_advisory), which is different from an explicit operator approval and is not human review. A bounded preflight refuses a small set of obvious credential shapes before they are stored or sent, and it is not complete data-loss prevention.

Durability is also bounded. A successful tool return means the write finished, but an interrupted write can leave a recoverable working copy that an operator should inspect.

A recorded run against a local reviewer

On 24 October 2026 we ran one complete lifecycle against a reviewer model served on a local OpenAI-compatible endpoint: Unsloth's unsloth/Qwen3.6-27B-GGUF. A deliberately weak draft was saved and stayed invisible to default recall. The reviewer rejected it and explained that it was a vague assertion with no grounding. A first revision narrated a throwaway setup and was rejected again for having no lasting value. A second revision stated a decision, a reason and a cost, and was approved. The team then corrected that decision through supersession, and default recall returned only the successor with its lineage.

The walkthrough also records an error: the first save failed until the edited configuration was committed. It shows one model on one run. It is not a benchmark, it does not show that revised drafts are generally approved, and remote publication was not exercised because the disposable repository had no remote.

Follow the local review walkthrough

Earlier history: the February 2026 two-agent case study

The run was recorded on an installed 0.9.0rc1 candidate built from source commit effba472d342f74be9439f72329f96797a4acfec. That candidate is not a published release. Install the build you intend to use and confirm what loaded with fava-trails version.

Quick start

These commands set up a local evaluation. The product repository owns the full procedures, and the links under each step lead to them.

  1. Install and check what loaded

    pip install --upgrade fava-trails
    fava-trails version
    fava-trails install-jj

    FAVA Trails stores records with Jujutsu (JJ) in colocate mode beside Git, so your data repository remains an ordinary Git repository. fava-trails install-jj reuses a JJ that is already installed at version 0.28.0 or later. fava-trails version prints the product version and loaded module path, so you can see which build your client will launch. The main branch can be ahead of the package you installed, so a feature described here is available only if the release you installed includes it. Compare fava-trails version with the release history.

  2. Create a local data repository

    fava-trails bootstrap "$PWD/fava-trails-data"
    export FAVA_TRAILS_DATA_REPO="$PWD/fava-trails-data"
    fava-trails doctor

    A local repository with no remote is a valid evaluation setup. Save, review, recall and supersession work without one, and sync reports not_configured until you add a remote. fava-trails doctor and fava-trails register read the data repository from FAVA_TRAILS_DATA_REPO, which defaults to ~/.fava-trails. Without the export, both commands can inspect an unrelated repository that already exists there, so set it to the absolute path of the repository you just created before you run either one.

    Which reviewer a new repository uses depends on the release you installed. In a release that includes the local-reviewer bootstrap, bootstrap with no review options, or with only some of them, writes a policy and no complete reviewer settings. Review then fails closed only where the effective configuration is still incomplete. The release history says which release added this bootstrap. Fields that already exist in this machine's per-machine file can complete or override that policy, and a missing flag does not disable a reviewer configured there. doctor prints the effective destination and model, so check it before you propose anything. The per-machine file at $XDG_CONFIG_HOME/fava-trails/config.yaml overrides the repository's Trust Gate fields key by key, so a reviewer endpoint set there wins over the repository you just created. The setup instructions describe how to choose a local or hosted reviewer.

  3. Register the MCP server

    fava-trails register --agent-id claude-code

    Run this in the same shell, with FAVA_TRAILS_DATA_REPO still exported. It prints registration instructions for your install and your client, and only writes a client configuration if you add --write. A desktop client launches the server in its own process and may not inherit your shell exports, so its registration must carry the same absolute FAVA_TRAILS_DATA_REPO and, if you deliberately isolate per-machine overrides, the intended XDG_CONFIG_HOME. Reviewer credentials come from the process that runs the server, through a credential file or an environment variable, and never from a value typed into the registration. Set a stable FAVA_TRAILS_AGENT_ID on each authoring server process. You choose it as a role name, as in the claude-code example above, and not as a host or session name, so a new machine does not need a new value. Processes that share a value share its authoring view, so agents that need private drafts need separate values and separate endpoints. Restart the client after changing its configuration. The printed instructions and the README's quick start show the registration shape for Claude Code, Claude Desktop and other clients that take the standard JSON shape, and the README's client registration examples cover Windows with WSL and OpenAI Codex CLI. The setup instructions own the reviewer, credential and configuration procedures.

  4. Run one lifecycle

    Follow the local review walkthrough to save, reject, revise, approve and correct a record against a disposable repository. Your agents then use the MCP tools described in the usage instructions.

Optional lifecycle protocols (SECOM, ACE, RLM) are not part of a first evaluation. See /protocols/.

Choose your next step

Evaluate

Decide whether FAVA Trails fits your agents. Start with fit and limits, then read governed recall and follow the recorded walkthrough.

Operate

Run it for a team: reviewer choice, identities, publication, upgrades and tunnels.

Contribute

Change the code or the design documents.

Dated background such as the case study, local trust gate experiment, landscape analysis and protocols summary sits under "Background and history" and is labelled with its date.