repolane v0.11.0 · open source

Reference

Teams

What is machine-local and what is shareable, what happens when someone leaves, and the parts that are honestly still single-player.

On this page

“A ticket touches three repos” is an organisational problem, and Repolane is a tool that runs on one laptop. Those two facts do not cancel out, but it is worth being exact about where the line sits — so this page says what the code actually supports today, and names the parts that do not exist.

The short version: Repolane is single-player. It coordinates one person across many repos. It does not coordinate many people across one lane. Where people meet is still git — branches, remotes and pull requests — as always.

Machine state and source of truth

The split is drawn in the workspace, and lane init --git writes it into a .gitignore for you.

Machine state: deletable, rebuildable.repolane/repos/ (the base clones), lanes/ (the worktrees), .repolane/cache/, every .claude/settings.local.json
Source of truth: small, plain text, what git can trackCLAUDE.md, .claude/settings.json, .repolane/config.yml, .repolane/env.sh, .repolane/registry/ (the repo list, the lane files, your rules), .repolane/memory/, .repolane/knowledge/ and .repolane/scripts/local/
Repolane’s, refreshed on upgrade.repolane/REPOLANE.md, .repolane/LANE.md, .repolane/version: commit them, never edit them

A lane file is a few dozen lines: the goal, the repos and branches it touches, the note you left when you parked it, findings, and an appended log. Nothing in it is a secret and nothing in it is big. It is the part worth keeping.

Can two people work the same lane?

Not as one shared thing, no. There is no server, no locking, no notion of a second user anywhere in the code. Lane ids are local names; two people can each have a lane called ABC-123 on their own machines and neither will know about the other.

What they can share is what they always shared. Lane branches are named after the lane id in each repo by default, they are pushed to the normal remote, and lane gh <repo> pr create opens a pull request the usual way. So the handover is a branch and a PR, plus, if you want the context to travel too, the lane file, which is a text file you can paste into the ticket or commit somewhere.

Should the workspace be committed somewhere shared?

Your own workspace repo is the normal way to back it up and to carry it to another machine: lane init --git, commit, push to a private remote, clone it elsewhere and run lane init there (see Install). Repolane never pushes it.

Sharing one workspace repo between people is a different thing. A team that wants everyone to start from the same repo list, rules and commands can keep one workspace repo and clone it on each machine: .repolane/registry/repos.yaml, .repolane/registry/rules.yaml and .repolane/scripts/local/ are ordinary tracked files. What should stay per person (.repolane/memory/, .repolane/knowledge/, the lane files, config.yml with its owner name) is up to you: leave it out of the shared repo, or add it to .gitignore.

Two things to know before you do. .repolane/registry/old-checkouts.json and any lane file with an attached reference contain absolute paths from the machine that wrote them (/Users/you/...), and config.yml names one owner. They were written to be read by a person and by the hooks on that machine, not to be merged between machines. Sharing them as reading material (here is what I was doing and where I got to) works. Sharing them as state two machines both write to is not something the tool supports, and you would be hand-resolving conflicts in a log file.

For rules alone, lane rules pull is the lighter way: every machine pins the same commit of a separate rules repo, and nobody’s own files are touched.

What happens when someone leaves

Honestly: whatever was only on their laptop goes with the laptop. The goal, the resume note and the findings for an in-flight lane live in .repolane/registry/lanes/<id>.md on that machine. Nothing is replicated anywhere by default.

The parts that survive without any action are the parts that were already pushed: the branches, the commits, the PRs. That is the same exposure a team has today with someone’s local branches. Repolane does not make it worse, but it does not fix it either, and it collects more context worth losing than a bare checkout does.

If that context matters to you, the mitigation is the one above: keep the workspace in a private git repo of your own and push it. With lane init --git, the lane files, the repo list, memory and knowledge are all tracked; only the machine-local parts are ignored.

Rolling this out to twelve people

There is no fleet configuration, no central policy file and no server that pushes a change to everyone. Each person runs pipx install repolane and lane init in a folder of their own, and answers up to three questions (or passes flags; see Install). What that actually involves:

  • Each person gets their own copy of every repo. The base clone under .repolane/repos/<name> is a full clone, shared between that person’s lanes but not between people. Twelve people is twelve clones, as it is today.
  • .repolane/config.yml is the per-person file. It holds the owner’s name, the tracker URL and a few defaults (stale_days, delete_sessions_on_done, sync_days). Only the tracker line is likely to be the same for everybody.
  • There are two ways to share setup. lane rules pull keeps rules.yaml (and optionally scripts and notes) in a git repo that each person pulls, pinned to a commit SHA; see Extending, including what comes with it: scripts that become commands and notes that are injected into every session. Or a shared workspace repo, as above. The built-in guard itself comes with the package, so everyone on the same version has the same guard; lane upgrade moves each machine forward.
  • lane doctor is the only compliance check, and it is local. It tells the person at that machine whether their guard compiles and is still wired into every lane. Nothing reports anywhere.

Know that before you promise anyone central control: there is none.

The board’s token, and what it does and does not protect

lane board starts a Python server bound to 127.0.0.1 only, never 0.0.0.0, so nothing on your network can reach it. On top of that, each run generates a fresh token (secrets.token_urlsafe(24)). It is not printed in the terminal: it is embedded in the page the server sends your browser, and every /api call is rejected with 403 unless it carries that token in an X-Token header.

What the token is for: it stops a form post or a cross-origin fetch from another site in your browser, which cannot set a custom header, from driving the board.

What it is not:

  • It is not a login. The page that carries the token is served to anyone who can reach the port, so another local account on a shared machine can fetch it and read the token. If other people have shell accounts on the machine you run this on, do not run the board there.
  • DNS rebinding is blocked. Every request, the page at / included, must carry a Host of 127.0.0.1:<port> or localhost:<port> (and an Origin of the same when sent), or the server answers 403. A web page that makes your browser resolve a name it controls to 127.0.0.1 cannot load / and read the token. The check does nothing about another local account that connects to the port and sets the right Host. See the security model for the routes that token opens, which include discarding changes and pushing.
  • It does not protect against another process running as you. That process can already read your repos.

The board also reaches the network, so “it never leaves your machine” is not accurate. Its page makes no outbound requests (the fonts ship with it), but while it is open the server polls GitHub through gh pr view every 60 seconds to fill the pull request column. Push and Pull run git push and git pull. With gh not installed that column is empty.

Next steps