Skip to content

02 concepts

github-actions[bot] edited this page Aug 12, 2026 · 3 revisions

2. Concepts

A short shared vocabulary. Everything in the how-to guides builds on these two ideas — the slug and the fact that up is state-driven, not flag-driven — plus the state machine below.

The workdir & config file

Forge Fleet keeps its per-project state under a workdir, ~/.forge-fleet by default. Each project gets its own ffleet.toml there, written once by ffleet init, so your settings persist and you don't re-pass CLI flags on every run. Full details: config reference.

The slug

Every environment has a slug: a short name you choose (e.g. my-feature, bugfix-login). It's how the environment is named and referenced — the worktree directory, the branch, and the container all derive from it, and every command takes the slug as its argument:

$ ffleet up my-feature      # start / resume it
$ ffleet status my-feature  # inspect it
$ ffleet tail my-feature    # read its transcript
$ ffleet remove my-feature  # tear it down

List the slugs you already have with ffleet ls. Pick something short and descriptive; it's the handle you'll type all day.

Naming rules. Forge Fleet normalizes the slug (and the project name) so it's safe to use in branch, worktree, and container names:

  • trims surrounding spaces
  • trims leading/trailing - and _
  • allows only lowercase letters, digits, -, and _
  • must start and end with an alphanumeric character

If you type something that doesn't fit (e.g. mixed case or a trailing dash), it's normalized to the nearest valid form.

up is state-driven, not flag-driven

This is the core mental model. The same command — ffleet up SLUG — does whatever the current state needs, rather than you choosing a different verb for each situation:

  • No environment yet → it creates one (worktree, branch, container, agent).
  • A live agent session → it attaches you to it.
  • A stopped container or a dead/exited agent → it rebuilds from the current config and resumes the session — without losing your work.

You don't have to remember "did I stop this? did it crash?" — you just run ffleet up SLUG and Forge Fleet reconciles reality to "running and attached". --no-attach starts it in the background; --peek is the strict, side-effect- free variant that attaches only if the agent is already live and never relaunches anything.

One consequence worth internalizing: on a rebuild, config-derived settings (image, mounts, hosts, env-file, auth, credential dirs, agent command/args) refresh from your current config, while identity/continuity settings (branch, worktree, git-mode, which agent, the session) stay fixed at create time. That's why some things only change after a remove — see config precedence.

The container state machine

An environment moves between a handful of states. Note especially that stopped (container gone, but worktree + branch + metadata kept — revivable) is distinct from removed (worktree deleted — gone for good).

stateDiagram-v2
    [*] --> Absent
    Absent: Absent (nothing created yet — also where ffleet remove lands)
    Running: Running (container up, agent live)
    Stopped: Stopped (container removed on purpose; worktree+branch+metadata kept)
    Interrupted: Interrupted (agent exited, setup failed, or container vanished — worktree kept)

    Absent --> Running: ffleet up SLUG
    Running --> Running: ffleet up (re-attach) · detach Ctrl-B D
    Running --> Stopped: ffleet stop
    Running --> Interrupted: agent exits · setup fails · host reboot · docker rm
    Stopped --> Running: ffleet up (revive)
    Interrupted --> Running: ffleet up (rebuild & resume)
    Running --> Absent: ffleet remove (worktree deleted — back to start)
    Stopped --> Absent: ffleet remove
    Interrupted --> Absent: ffleet remove
Loading

In prose:

  • Absent — nothing exists yet. ffleet up SLUG creates the environment. It's also where you land again after ffleet remove.
  • Running — the container is up and the agent session is live. You're either attached to it or detached (it keeps running either way).
  • Stopped — you ran ffleet stop. Because containers run with --rm, "stop" means the container is removed, but the worktree, branch, and metadata are deliberately kept. ffleet up revives it with no data loss. This is the state to leave things in when you want a container out of the way without discarding work.
  • Interrupted — the environment isn't running but its worktree is intact, whether because the agent process exited, setup failed, or the container vanished unexpectedly (host reboot, a stray docker rm, a crash). Recovery is the same in every case: ffleet up rebuilds the agent from saved metadata and resumes — no work lost.
  • ffleet remove — deletes the worktree (and the branch, if Forge Fleet created it). Nothing is left to revive, so the environment is back to Absent: a later ffleet up SLUG starts fresh.

The single takeaway: stop is reversible, remove is not. When in doubt, stop.

Lifecycle at a glance

The everyday actions across an environment's life:

flowchart LR
    start([no environment]) -->|ffleet up SLUG -p '...'| attached[attached to agent]
    attached -->|detach: Ctrl-B D| detached[running, detached]
    detached -->|re-attach: ffleet up SLUG| attached
    start -->|background: ffleet up SLUG --no-attach| detached
    attached -->|ffleet remove SLUG| gone([removed])
    detached -->|ffleet remove SLUG| gone
Loading
  • Start: ffleet up SLUG (optionally -p to seed a prompt) — creates and attaches.
  • Detach: tmux Ctrl-B then D — leaves the agent running.
  • Re-attach: ffleet up SLUG again — same command.
  • Background start: ffleet up SLUG --no-attach — start without attaching.
  • Tear down: ffleet remove SLUG.

From here the how-to guides zoom into each stage: Starting · Working · Completing.

Clone this wiki locally