Concepts
Concepts
The six words the whole system is built from: workspace, repo, lane, worktree, reference, memory.
Six words carry the whole system.
Workspace
The folder your work lives in: any folder where lane init ran. Repolane itself is an installed
package (pipx install repolane); the workspace is yours, and the package never ships it and never
overwrites what you wrote in it. lane finds the workspace by looking up from the current folder, so
every command works from anywhere inside.
~/work/
CLAUDE.md yours; imports Repolane's rules with @.repolane/REPOLANE.md
.claude/ Claude Code's settings, with Repolane's `lane hook …` commands, slash commands and agents
lanes/ the work: one folder per lane
.repolane/ everything else Repolane keeps: the registry, memory, knowledge, the base clones, config
The registry (.repolane/registry/) is the source of truth: repos.yaml lists the repos, and
registry/lanes/<id>.md is one file per lane. The base clones and the worktrees are machine state
that the registry can rebuild, so the parts worth keeping are small text files, and the workspace can
be a git repo of your own (lane init --git). Install lists
every file and says which are yours to commit.
Paths on these pages are written from the workspace root: .repolane/repos/<name>, lanes/<id>/<repo>.
Repo
A repo you work on. It lives once, at .repolane/repos/<name>, as a base clone (the guard’s and the scripts’
word for the same thing is a mirror; this site says “base clone” so it is not mistaken for
git clone --mirror): a normal working clone, not a bare one, kept on its default branch,
never edited, never switched. It exists so every piece of work can share one object store.
Add one with lane add <git-url> or lane add <path-to-a-checkout-you-already-have>.
Lane
One piece of work, which may span several repos. It has an id (a ticket key or a short name), a
branch of that name in each repo it touches, and a folder at lanes/<id>/ holding a worktree of each.
lanes/ABC-123/
web/ a worktree of .repolane/repos/web on branch ABC-123
api/ a worktree of .repolane/repos/api on branch ABC-123
refs/ anything you attached for reference
You run Claude from lanes/<id>/, not from inside a repo. No repo is the main one. Reach any of them
with git -C <repo>, lane run <repo> <cmd>, or by editing <repo>/path/to/file directly.
~/work $ lane start SHOP-412 api web
worktree /Users/john.mercer/work/lanes/SHOP-412/api on new branch SHOP-412 (from origin/main
)
worktree /Users/john.mercer/work/lanes/SHOP-412/web on new branch SHOP-412 (from origin/main
)
next: cd /Users/john.mercer/work/lanes/SHOP-412 && claude
~/work $ lane status
guard: 11/11 probes answered as they should, 4/4 places point at guard.py: 1 lane(s), 2 work
tree(s), the root — lane doctor for the evidence
== workspace (its own git repo, if you made one: docs/install.md)
not a git repo — memory/, knowledge/, CLAUDE.md are not tracked anywhere
== repos (primary mirrors)
api: main, behind origin by 0, worktrees=1
mobile: main, behind origin by 0, worktrees=0
web: main, behind origin by 0, worktrees=1
== lanes
SHOP-412 [active] updated 2026-10-22 ticket=
web/SHOP-412: 0 dirty, 0 unpushed
api/SHOP-412: 0 dirty, 0 unpushed
== drift: checkouts outside the workspace (should be none; work happens here)
~/work $ exit
The last screen of a real asciinema recording, as text. With
JavaScript the player replays the whole session from the start.
lane start creating the branch and a worktree of each repo, then lane status showing the new lane. Recorded 2026-10-22. Output can differ from what you see today; run it to see the current text.Worktree
Git’s own feature: a second working directory sharing one repository. It is why a lane costs a checkout of files rather than a full clone, and why switching work is instant.
Reference
Code or documents that are not one of your repos but matter to the work. lane ref <id> add <path>
attaches it to the lane as a symlink at lanes/<id>/refs/<name>, read-only unless you add --rw. Nothing is
copied, and detaching it with lane ref <id> rm never touches the original.
Memory
What Claude has learned, kept in four scopes chosen by how long it stays true:
| scope | means | lives in |
|---|---|---|
pref | how to work with you, always | .repolane/knowledge/preferences.md |
cross | true in every repo | .repolane/memory/ |
repo | true for one repo after this work ships | .repolane/memory/<repo>/ |
lane | only while this lane is live | the lane file’s ## Findings |
Memory is not written directly into its folders: lane note drafts it, and a session is told to ask
you which scope it belongs in. The guard blocks the direct write; the question to you is an
instruction, not something a hook can force. A session inside a lane drafts memory with
lane-memory draft and sets the lane’s Goal with lane-memory goal, because Claude Code refuses Edit
and Write outside the lane folder (see Working with Claude).
Where it lives and what survives is on Where state lives.
What this is, and isn’t
“Why not just git worktree myself?” Largely, you can — worktrees are the right primitive and
Repolane is built on them, not around them. What worktrees alone don’t give you: nothing ties the
worktrees of one ticket together across repos, no goal or resume note survives a week off, no
cross-repo view of what’s dirty or unpushed, and nothing stops a session in one worktree from
reading your other work, your other repos, or your .env. The first of those you could write
yourself in a weekend; the last is why Repolane also puts guardrails around what a Claude session
reads and writes: the hook refuses reads of other lanes and of recognised secret files, among other
things. It is a guardrail against mistakes, not a sandbox, and its limits are on
Security model. See also Architecture and Rules.
“Isn’t this just another worktree-per-task tool?” That category exists and Repolane doesn’t
claim the worktree-per-task idea as novel. Two things are different here: the unit is a ticket,
not a repo — one lane holds a worktree of every repo the ticket touches, one branch name across all
of them, one goal and one resume note, with the session opened at the lane root above all of them.
And most of the boundary is enforced by hooks that inspect the tool call itself, not only suggested
by a prompt the model can drift past. You can check with lane doctor that it is in force. It
covers the tools in its matcher, and it reads commands rather than running a shell, so it is a strong
default rather than a guarantee.
If your work genuinely lives in one repo, a worktree tool — or a shell alias — is very likely enough, and you should use that instead.