fedService Federation

Isolation

Run the same project in several places at once — your checkout plus a review worktree, or five coding agents on one laptop — without a single port collision. fed already scopes containers, volumes, and state to the directory; one command, fed isolate enable, gives a checkout its own ports too.

Ports must be parameters

Isolation can only remap ports it knows about — the ones declared as type: port parameters and interpolated with {{...}}. A literal 4321 in a command or healthcheck is invisible to fed and will collide across workspaces. Write every port the fed way:

parameters:
  APP_PORT:
    type: port
    default: 4321
  DB_PORT:
    type: port
    default: 5433

services:
  database:
    image: postgres:16-alpine
    ports: ["{{DB_PORT}}:5432"]          # never "5433:5432"
    environment:
      POSTGRES_PASSWORD: postgres

  app:
    process: npm run dev -- --port {{APP_PORT}}
    startup_message: 'http://localhost:{{APP_PORT}}'
    environment:
      DATABASE_URL: 'postgres://localhost:{{DB_PORT}}/app'
    healthcheck:
      httpGet: 'http://localhost:{{APP_PORT}}/health'

entrypoint: app

In normal (non-isolated) mode fed prefers the configured defaults; if one is occupied, it can allocate an alternative. Under isolation each workspace gets random ports from the outset — but only for ports declared this way. fed warns once at startup when it finds literal localhost:<port> references or literal host ports in the config.

Directory scoping

Everything fed tracks is scoped to the directory containing your service-federation.yaml:

Two directories are two independent stacks. There's nothing to configure, and it doesn't matter who created the directory — a worktree made by fed ws new, by hand, or by a coding agent behaves the same.

Isolation mode

Directory scoping keeps containers and state apart, but two checkouts of the same project still want the same default ports. Isolation mode fixes that — run it once in the second checkout:

fed isolate enable       # Random ports + unique container names (persisted)
fed isolate status       # Show isolation state and port allocations
fed isolate rotate       # Re-roll ports and isolation ID
fed isolate disable      # Return to the directory's normal scope

fed isolate enable prints an isolation ID and the full port table, then persists both. Every fed command you run in that directory afterwards — start, scripts, tests, psql — uses the isolated ports and containers, across restarts, until you fed isolate disable.

CLI output calls the normal namespace the shared scope. It is shared by runs in this directory, not by different worktrees: normal container names, volumes, and state are still directory-scoped.

Quick isolation

fed start --isolate      # Enable isolation + start (one command)

On a new or stopped checkout, this has the same persistent result as fed isolate enable && fed start. Use the explicit command when services may already be running: it checks and offers to stop them before changing scopes.

What isolation does

Compose-backed services are already directory-scoped through a project name derived from the Compose file path. fed isolate enable does not replace that project name with the isolation ID, and fed isolate rotate does not create fresh Compose volumes.

Port management

fed ports list            # Show current allocations
fed ports list --json     # Machine-readable output

Allocations stay put until you fed isolate disable — or re-roll them with fed isolate rotate.

Git worktrees

Each worktree is a separate directory, so each worktree is a separate stack. Enable isolation right after creating one, before you run anything else:

# Main checkout — default ports
~/project $ fed start

# Second worktree — its own ports, containers, and volumes
~/project-review $ fed isolate enable
~/project-review $ fed start

Both stacks run at the same time on the same machine — this scales past two. A docker ps on a busy laptop shows the main checkout on default ports and three isolated worktree stacks beside it, each under its own isolation ID.

Cookies and other shared namespaces

Ports isolate; localhost cookies don't — they're port-agnostic, so two stacks of the same app expire each other's sessions on every login. Scope the cookie name with the built-in FED_PROJECT_ID variable, which embeds the isolation ID, and each stack keeps its own session. The same trick namespaces anything else parallel stacks would share behind one hostname.

If you skip isolation, fed detects occupied defaults. An interactive start prompts for a response; a non-interactive start can fall back to alternative ports. Explicitly enabling isolation avoids that ambiguity and randomizes every declared port. Never use fed start --replace in a worktree: it can take the port by killing the other checkout's services.

Workspace management (beta)

fed ws (alias for fed workspace) automates git worktree creation and switching:

fed ws setup                # One-time: install shell integration (zsh or bash)
fed ws new my-feature -b    # Create branch + worktree, cd into it
fed ws list                 # Show all worktrees with service status
fed ws cd main              # Switch to another worktree
fed ws rm my-feature        # Stop services and remove worktree
fed ws prune                # Clean up worktrees for deleted branches

Worktrees are created as siblings to the repo in a <repo>-worktrees/ directory. Shell integration enables auto-cd — without it, fed ws new and fed ws cd print the path instead.

Coding agents

When your coding-agent workflow uses one git worktree per task, each worktree is its own directory and can run its own full stack — database, backend, tests — without touching yours. One rule makes it predictable: isolate first.

Don't leave that to the agent's judgment. Put it in your AGENTS.md (or CLAUDE.md) so every agent starts every worktree the same way:

## Worktrees
Run `fed isolate enable` before any other fed command in a new worktree.
It persists: every fed command after it — start, tests, scripts — gets
the worktree's own ports, containers, and volumes.

Why fed isolate enable rather than fed start --isolate? Agents rarely open with fed start — the first fed command is usually an install, a code generator, or a test run. fed isolate enable isolates the directory once, for whatever comes next; the flag only helps when the first command happens to be start.

The rule also protects the rest of your machine. An agent that skips it hits a port conflict on fed start — and an agent improvising its way out of that can reach for fed start --replace, which frees the port by killing another checkout's services. Agents follow written instructions more reliably than they recover from collisions.

No plugin or integration needed. Isolation is directory-scoped, so it works the same whether the worktree came from Cursor, fed ws new, or git worktree add.

Isolated scripts

Scripts can opt into a throwaway child context with isolated: true — fresh ports, isolated direct image-backed containers and named volumes, and automatic cleanup. Compose limitations are covered in Scripts.

Next: Scripts →