Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hindsight

Cross-session memory for coding agents, backed by a Fangorn wiki.

Agents lose context between sessions. They fall back on reading code and comments, which record what but never why — so each session re-derives the same conclusions, re-proposes the same already-rejected approaches, and re-hits bugs whose causes weren't local.

This plugin keeps a decision graph that survives the session: rationale, rejected alternatives, non-local bug causes, and constraints learned from outside the repo. None of that is recoverable from a diff.

What's in it

Component Mechanism Role
hooks/session-recall.sh SessionStart hook Injects the memory index itself. Deterministic — the agent can't skip it.
bin/hindsight-sync shell script Mirrors the wiki into .hindsight/. Costs zero context tokens.
skills/fangorn-memory Skill Capture triggers, entry format, promote/supersede rules. Loads on demand.
commands/wiki-bootstrap.md /wiki-bootstrap [sha] Builds the wiki; refreshes it diff-driven against a newer commit.

The hook is the load-bearing part. A skill or CLAUDE.md instruction is advisory; recall has to be guaranteed or none of the rest pays off.

Recall is local

Memory is authored in the wiki and read from a local mirror. Those are different jobs and they want different mechanisms.

Reading over the MCP costs a deferred-tool lookup, a list_notes round trip, and a whole page per read_note — measured at 2.6k–5.1k tokens per session on a 10-page wiki, plus latency and a hard dependency on the network being up. None of that buys anything at read time: the content is identical.

So hindsight-sync pulls the pages down over plain HTTP from the shell, and the hook hands the agent the index inline. A session now starts knowing what exists, having spent no tool calls, and greps the mirror for the one line it needs instead of fetching a page to find it.

The wiki stays the source of truth — authoring, review, signing, sharing across machines. The mirror is a cache; never hand-edit it, and re-run the sync after any write. A stale mirror is worse than no mirror, because the agent trusts it.

Requirements

The fangornmd MCP server, configured and authenticated.

Install

/plugin marketplace add /path/to/fangorn-memory
/plugin install fangorn-memory

Use it in a repo

cd your-repo
/wiki-bootstrap

It resolves the wiki namespace, reads the repo, writes the pages, drops a .fangorn-namespace marker at the root, and syncs the mirror.

Opt-in is per repo. The hook exits silently when that marker is absent, so the plugin costs nothing in repos that don't use it.

Refresh the mirror yourself any time — after a write_note, or on a new machine:

bin/hindsight-sync            # pull every page into .hindsight/
bin/hindsight-sync --check    # what's mirrored, and when it was synced

Commit .hindsight/ unless you have a reason not to. It makes memory survive a fresh clone with no MCP, no auth and no network, and keeps it greppable by tools that respect .gitignore.

After new commits:

/wiki-bootstrap <sha>    # diffs baseline..sha, reviews only affected pages

The two layers

Layer Content Refreshed by
log.md + entries why, what was rejected, what failed never — append-only
index, invariants, gotchas, file-map, concept pages what the repo is /wiki-bootstrap <sha>, diff-driven

The stable layer is re-derivable from code. The log is not, which is why the refresh path is forbidden from touching it.

Two things that decide whether this works

Capture narrowly. An append-only log of routine work makes recall worse — the signal drowns. The triggers exclude anything git or the code already holds. If you find the log filling with "changed X to Y", tighten it.

Say why. The system can't manufacture rationale. It can record what the agent decided; it can't recover why you chose an approach or what constraint you were working around. One sentence at decision time is the highest-value input the log ever gets.

Anchor entries to commits

Put the sha in the entry, the entry slug in the commit message. That gives you:

confusing line → git blame → commit → log entry → why, and what was rejected

The graph becomes reachable from the code, without the code carrying the explanation in comments.

About

Agent memory on Fangorn

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages