AgentRail’s Phase 0–5 feature list looked complete on paper. Then I started running it every day, across parallel repos, and every real-world friction point produced a new command. This post is a tour of what daily use teaches you that planning doesn’t.

The Plan-Bending Problem

A saga is a linear sequence of steps: plan it, walk it, finish it. That model works when the plan survives contact with reality. Two things tend to ruin it:

  • A dependent repo breaks halfway through step 5. You need to bounce over, fix it, and come back — without abandoning the saga you were in.
  • A step reveals a flaw in a later step. Step 3 uncovers something that means step 7 has to change, or needs to happen before step 4, or needs to be re-done after you thought it was done.

With only begin / complete, the options are bad: abandon the saga and re-plan, or pretend the detour didn’t happen and let the plan drift out of sync with what you actually did. Neither preserves the thing sagas are for: a faithful, auditable record of what was done.

The April features exist because this kept happening, every day, across multiple repos.

insert / reorder / reopen: Mid-Saga Flexibility

Three commands, each mapped to a real pattern:

CommandScenario
agentrail insert --after N A surprise lands (blocker, bug in dependent repo, unplanned dependency). Slot a new pending step at N+1; later pending/in-progress steps shift up by one.
agentrail reorder N --to M Priorities change. Move a pending or in-progress step; intervening steps shift the other way.
agentrail reopen N A completed or blocked step turns out to be wrong. Transition it back to in-progress, clear completed_at, re-focus the cursor.

The invariant that makes this safe:

Completed steps never renumber. They are anchored to git history via their commits array. Any operation that would renumber a completed step is rejected. Reopen preserves the step’s commits so the git-history linkage stays intact.

This is why insert and reorder only move pending and in-progress steps. The past is immutable; the future is negotiable.

Cursor Preemption

A small but important follow-up. When insert drops a blocker at slot N+1, the cursor used to stay attached to its original step by identity — the new step was there, but agentrail next still surfaced the old focus. Same story for reorder pulling a later step forward.

Both now apply a preemption rule: if the new or moved step lands at or ahead of the cursor’s slot, focus follows it. Steps placed behind the cursor are still queued without disturbing focus. The result: agentrail next shows you the thing you just said was more urgent, instead of making you re-focus manually.

Maintenance Mode: add + Ad-Hoc Tasks

Not every session is a planned saga. Sometimes the shape of the work is a todo stream, not a roadmap:

  • User types a task.
  • Agent calls agentrail add to create a step.
  • Agent runs begin / work / complete.
  • Repeat.

agentrail add --slug <slug> --prompt <text> records the step without going through the plan-first flow. Combined with a CLAUDE.md maintenance protocol, this turns AgentRail into a daily driver for ad-hoc work, not just a tool for staged roadmaps. Agents can also use add mid-session to enqueue related work they discovered but shouldn’t pursue right now.

When Things Go Wrong: audit + snapshot

These two were motivated by a real incident: an agent deleted untracked .agentrail/ files. Nothing in the reflog. No recovery path. That one hurt enough to build infrastructure for.

agentrail snapshot writes a git commit of .agentrail/ (and .agentrail-archive/ when present) under refs/agentrail/snapshots/<timestamp>. Implementation detail that matters: it uses GIT_INDEX_FILE pointed at a throwaway temp file, so the user’s real index is never touched — no staged-file surprises, git status is unchanged before and after, and pre-commit hooks don’t race. Because a named ref holds the commit, blobs survive git gc. Restore is left to the user via plain git: git restore --source=<ref> -- .agentrail .agentrail-archive. AgentRail never writes to the working tree on your behalf.

agentrail audit compares git history against saga history and reports three categories: matched commits, orphan commits (in git but not claimed by any step), and orphan steps (claimed commits that don’t exist). With --emit-commands, it prints a shell script of agentrail add lines seeded from commit subjects — a reconstruction scaffold you review before running.

Two schema changes make audit exact instead of heuristic:

  • StepConfig.commits: Vec<String> is populated by complete from HEAD, so step <-> commit linkage is recorded at the moment of truth.
  • SagaConfig.retroactive: bool lets you mark a saga as reconstructed-after-the-fact, so audits treat its commits as claimed.

One related bug worth calling out. agentrail add --commit <ref> used to record whatever string you passed — short hashes, tags, HEAD~N. Audit compares against full 40-char SHAs from git log %H, so non-canonical entries never matched and every short-hash commit was flagged as an orphan. A retroactive saga in sw-cor24-snobol4 produced 8 phantom orphans this way. Fixed by routing every --commit value through git rev-parse --verify <ref>^{commit} and storing only the full SHA. Unresolvable refs now fail at add time with a clear error, instead of silently producing orphans at audit time.

archive: Closing One Saga, Opening the Next

agentrail archive moves .agentrail/ into .agentrail-archive/<name>-<timestamp>/ and clears the way for a new init. Optional --reason writes archive-reason.txt alongside. Collisions get a -2, -3 suffix. It sounds small; in practice it’s what makes AgentRail work across many small sagas in the same repo instead of one ever-growing one.

gen-agents-doc: Portable Rules

Dogfooding across N repos only works if the safety rules travel. agentrail gen-agents-doc writes AGENTS.example.md — a self-contained template covering the session protocol, .agentrail/ handling rules, and audit recovery guidance. Drop it in any project, rename to AGENTS.md, CLAUDE.md, .cursorrules, whatever your agent reads. The template is embedded via include_str!, so the binary is self-sufficient.

What Dogfooding Teaches

Three patterns keep recurring in the April commit log:

Pattern Example
Surprises need a slot, not a restart insert / reorder / reopen
Recovery tools must exist before you need them audit / snapshot — built after an incident, not during one
Bootstrapping friction kills adoption across repos setup / gen-agents-doc / archive

The meta-lesson: the only way to find these problems is to use the tool on real work, every day, across the kind of messy, parallel, interrupt-driven development that real projects actually look like. A plan-first feature list will never surface the cursor-preemption bug, the short-hash audit false-positives, or the “I need a todo stream, not a roadmap” mode. Only use does.

Next up: porting these conventions into a couple of the other sw-vibe-coding repos so more of the saga history is recoverable by default.


AgentRail is one command at a time. Follow for more AI Tools posts on the small tools that keep agents honest.