You changed your mind. Your agents didn’t.

When a decision changes while AI agents are already working, trailstone gets the new rule to each of them at their next edit, and blocks the push of anything still built on the old one.

For anyone running more than one agent at a time: in separate worktrees, in a teammate’s clone, or across Claude Code, Codex and Cursor.

npx trailstone demo
View on GitHub

One script and one file in your repo. No server, no account, no telemetry.

You record a decision: sessions use JWT. Three files are built on it.

$ git push ✗ blocked: logout.ts is stale

Same task, two agents, one decision changed mid-work.

Each agent works in its own worktree. Halfway through, a teammate commits “timestamps are epoch ms, not ISO” on main. Real Claude Code sessions at 3× speed.

With CLAUDE.md: 0 of 3 agents switchedWith trailstone: 3 of 3 switched

A decision knows which files it governs.

So when you reverse it, trailstone knows exactly which work now rests on the old rule.

  1. 1Record it

    A line in .trailstone/decisions.yml, committed with your code.

    $ trailstone decide "Sessions use JWT" \
        --scope src/auth/
    covers 3 tracked files
  2. 2Change your mind

    Every running agent is told at its next edit, in any worktree or clone.

    $ trailstone reverse d_5913723e \
        "Signed HttpOnly cookie"
    ⚠ was “JWT” → now “cookie”
  3. 3Stale work can’t ship

    Files last committed before the reversal block the push until someone re-checks them.

    $ git push
    ⚠ STALE: 3 files
    exit 1

You might not need it. We measured.

Small samples, all run by us, and every number says how many runs it rests on.

A CLAUDE.md is enough when your rules stay put

For rules that don’t change, agents followed a plain CLAUDE.md about as well as trailstone, and it costs less.

trailstone is for rules that change where the agent isn’t looking

A change committed on main never reaches the CLAUDE.md an agent in another worktree or an unpulled clone is reading. trailstone reads the ledger on main and on origin: it reached 15 of 15 agents in separate worktrees and 9 of 9 in separate clones. A teammate’s pushed CLAUDE.md edit reached 0 of 3 clones.

What it holds to.

Derived, never stored
Nothing records that a file is stale. It is worked out from git history and the decision’s scope every time, so it can’t drift out of date.
Exact on anything that blocks
A push is blocked only on an exact scope match: a path, a directory or a glob. Never a guess, because a false alarm is worse than a missed one.
You outrank the ledger
A recorded decision lets an agent stop and ask before contradicting it. It never lets an agent overrule you.

Where it stops.

  • It flags. It doesn’t fix.

    trailstone tells agents what changed and blocks the stale push. An agent or a person still makes the change.

  • A flag means “built on”, not “broken”

    Reversing a decision flags every file in its scope. Most still comply and clear in seconds, which is why a narrow scope matters.

  • It watches the files you name

    Prose that describes an old decision in a file no decision names will drift unseen. So will a governed file you rename.

  • Any commit clears a flag

    Editing and committing a flagged file clears it, even for an unrelated change. The warning before the edit is what makes that safe.

The ledger is the product. Build on it.

Every decision lives in .trailstone/decisions.yml, plain YAML committed next to your code. The pull request that adds a line is the review. Decisions are never edited: changing your mind is a new entry that supersedes the old one.

The format is the contract, and the script is only its first implementation. Any agent can ask what governs a file through trailstone mcp. Telling an agent before it edits, unasked, works in Claude Code, Codex and Cursor today. A hook for Windsurf or Claude Desktop is the most useful thing anyone could contribute.

- id: d_6d0bf686
  by: Dana
  decision: Sessions use JWT headers, not cookies
  why: a CLI calls the API too
  scope: [src/auth/]

- id: d_259ab7a1
  by: Dana
  decision: Sessions use a signed cookie, not JWT
  why: XSS token theft; the CLI gets a PAT
  scope: [src/auth/]
  supersedes: d_6d0bf686

Install in a minute. Remove it in one command.

npm i -g trailstone
cd your-repo
trailstone install
trailstone init --goal "what this project is"

Works with Claude Code, Codex and Cursor, and as a GitHub Action in CI. A repo without a ledger stays silent, so installing once for your machine costs nothing elsewhere.

Exactly what install touches

~/.claude/settings.json
Four hook entries: session start, each prompt, before each edit, end of turn. Other hooks are kept.
~/.codex/hooks.json
The same four, only if you use Codex. Codex runs them only after you trust them in /hooks.
.git/hooks/pre-push
The guard that blocks a stale push. A pre-push hook of your own is never overwritten.
.gitignore
One line, so the private ledger is never committed.
AGENTS.md
A short block so agents without hooks know to ask. Skip it with --no-rules.
.cursor/
Hooks and a rules file, only if you use Cursor.

trailstone uninstall removes every hook and the pre-push guard. It leaves your ledger and the lines it added to AGENTS.md, .gitignore and .cursor/rules, because those are your repo’s content.

No server, no account, no telemetry. The one network call is a background git fetch of your own origin’s default branch, to read the current decisions. TRAILSTONE_FETCH=0 turns it off.

Questions people ask.

What is trailstone?

trailstone is a decision ledger that lives in your git repo. When a decision is reversed while AI coding agents are already working, it gives each agent the new rule at its next edit and blocks the push of any file still built on the old one. It is one script and one YAML file, with no server, no account and no telemetry.

How is it different from a CLAUDE.md or AGENTS.md file?

For rules that stay put, a CLAUDE.md works about as well and costs less. trailstone matters when a decision changes where an agent isn’t looking: in another worktree or in a clone that hasn’t pulled. In our runs it reached 15 of 15 agents in separate worktrees and 9 of 9 in separate clones; a teammate’s pushed CLAUDE.md edit reached 0 of 3 clones.

Which AI coding agents does it work with?

Claude Code, Codex and Cursor are told before they edit a governed file. Any MCP client can ask what governs a file through trailstone mcp, and other agents read the rules it writes into AGENTS.md. The push guard and the CI check work with any tool, because git does not care what wrote the code.

Does trailstone fix code or stop drift on its own?

No. It tells agents what changed and blocks a push that still rests on a reversed decision. An agent or a person makes the change.

Does it send any data anywhere?

No. There is no telemetry. The only network call is a background git fetch of your own origin’s default branch, to read the current decisions, and TRAILSTONE_FETCH=0 turns it off.

How do I try it?

Run npx trailstone demo. It shows three agents, one reversal and a blocked push on a throwaway repo in about ten seconds. It needs Node.js 20.17 or later.

Is trailstone free and open source?

Yes. It is open source under the Apache-2.0 license, on GitHub and npm.

A trailstone is a stack of stones a traveler leaves to mark the trail, so whoever comes after doesn’t lose the path.

npx trailstone demo