# Workflow

End-to-end walkthroughs plus recovery scenarios. The native-primitives routing table and CLI surface live in `SKILL.md` — this doc is the operational manual.

There are two ways work enters the fleet: **native spawn** (preferred — agent teams or background agents do the parallel work) and **manual spawn** (`fleet init` creates lanes you point sessions at). Landing is identical for both.

## Path A — native spawn, fleet landing

### 1. Spawn the parallel work natively

Use whichever native primitive fits ([agent teams](https://code.claude.com/docs/en/agent-teams) for collaborating teammates, [background agents](https://code.claude.com/docs/en/agent-view) for independent fire-and-forget sessions):

```bash
claude --bg "Add JWT middleware. Work on branch auth-mw. <lane brief>"
claude --bg "Add rate limiting. Work on branch rate-limiter. <lane brief>"
```

Background sessions automatically isolate into worktrees under `.claude/worktrees/`. Embed the lane brief from `references/session-prompt.md` so each session commits to a named branch, respects its scope, and signals when green.

### 2. Track the branches

Once branches exist with commits:

```bash
fleet track auth-mw rate-limiter
```

Registers each existing branch as a lane (`RUNNING`), deploys `signal.sh`, touches no worktrees. **Never delete or relocate a native session's `.claude/worktrees/` entry** — worktree cleanup belongs to agent view / `claude rm`, after the branch has landed.

### 3. Land

Either manually, in the order you choose:

```bash
fleet land auth-mw        # scrub → clean-base check → merge --no-ff → test gate → rebase others
fleet land rate-limiter
```

Or via the daemon + `signal.sh READY` gates (see Path B steps 3–4) if sessions signal their own readiness.

## Path B — manual spawn (`fleet init`)

### 1. Init

```bash
fleet init auth-mw rate-limiter cache-layer
```

Creates: a branch per name (off `main`), a worktree at `.fleet-worktrees/<name>/` (top-level so headless lane sessions can write — see "Headless agent compatibility" in `SKILL.md`), a status file at `.claude/fleet/lanes/<name>` (state: `RUNNING`), and deploys `signal.sh` to `.claude/fleet/signal.sh`.

`fleet init` also appends `.claude/fleet/` and `.fleet-worktrees/` to `.gitignore` and auto-commits that change (`chore: gitignore fleet-ops runtime state`) when the tree is otherwise clean and you're on `main`. If it can't auto-commit safely, you'll see an `ACTION REQUIRED` notice — commit `.gitignore` yourself before `fleet start` or the daemon will refuse to land with `uncommitted tracked changes`.

Force branch-only mode: `mode=branch` in `.claude/fleet/config`. Use this when each session is in a separate clone or remote machine — no worktrees needed.

### 2. Launch sessions

For each lane, open a Claude session pointing at that worktree (or that clone). Use `references/session-prompt.md` as the template — fill in `LANE`, `SCOPE`, `TASK`, `TESTS`.

Each session works in isolation, commits atomically, runs tests, and signals when ready:

```bash
bash .claude/fleet/signal.sh READY tests/test_auth.log
```

`signal.sh` will refuse if the lane has uncommitted changes or if the test log shows failures.

### 3. Run the daemon

```bash
fleet start
```

Polls `.claude/fleet/lanes/` every 5 seconds. When a lane shows `READY`:

1. Pre-land scrub — refuses if forbidden patterns found in the diff
2. Refuses if `main` is dirty
3. Merges the branch with `--no-ff`
4. Runs `test_cmd` if set; otherwise trusts `signal.sh`'s log gate
5. On pass: marks lane `LANDED`, deletes branch, rebases all other active lanes
6. On fail: hard-resets `main`, marks lane `FAILED`

### 4. Watch

```bash
fleet status
```

One panel: every lane grouped by state (`RUNNING / READY / CONFLICT / FAILED / LANDED`) with age and commits-ahead. `fleet status --verbose` adds worktree paths and notes.

### 5. Cleanup

When all lanes are terminal (`LANDED` or `FAILED`), the daemon exits. To tear down:

```bash
fleet stop                                              # if daemon still running
git worktree remove .fleet-worktrees/<name>             # for each fleet-created worktree lane
rm -rf .claude/fleet                                    # nuke fleet state
```

Only remove worktrees that `fleet init` created. Native sessions' worktrees under `.claude/worktrees/` are cleaned up through agent view (`Ctrl+X`) or `claude rm` — not by hand.

`fleet init` is idempotent — keep `.claude/fleet/` for the next round if you want.

If a previous daemon was killed without cleanup, `fleet start` auto-detects the stale `daemon.pid` and clears it.

## Recovery

### `CONFLICT` lane (rebase or merge failed)

Pop into that session (for background agents: open it from `claude agents` and reply). Tell Claude:

> "Rebase conflict on `<file>`. Lane that landed modified `<symbol>`. Resolve and re-signal READY."

Or resolve manually:

```bash
git checkout <lane-branch>
# fix conflicts
git rebase --continue
bash .claude/fleet/signal.sh READY <test-log>
```

### `FAILED` lane (tests broke `main` post-merge)

Daemon already reverted the merge. Branch still exists:

```bash
git checkout <lane-branch>
# fix the test
bash .claude/fleet/signal.sh READY <test-log>
```

Daemon picks it up on next poll (or `fleet land` it manually).

### Bad land that snuck through scrub + tests

```bash
fleet revert <branch>
```

Finds the merge commit on `main` (by message `merge: <branch>`), runs `git revert -m 1`, logs the action. No git surgery while you're panicking.

## Common patterns

### Agent team built a feature across three branches

Lead reports teammates done. `fleet track <b1> <b2> <b3>`, then `fleet land` in dependency order. Each landing rebases the rest, so the second and third merges are tested against a `main` that already contains the first.

### Five small refactors, no shared scope

Path B default. Each lane is independent. Cleanest case — daemon handles everything.

### Lanes with shared dependencies

Land the foundational lane first via `fleet land <branch>`, others rebase against it automatically. Daemon will pick them up after.

### Long-running session + several quick fixes

Land the quick fixes first. The long-running lane rebases against each landing. By the time it's done, `main` has all the small wins.

### Hackathon pace, multiple lanes ready at once

Currently the daemon lands them strictly one at a time — that sequencing is the point. If batch mode becomes a real need, the next iteration adds `--batch`.
