Container-based agents

tl;dr

Container execution gives your agents the same workflow with stronger sandboxing. Agents run inside Docker or Podman containers instead of local tmux sessions – they cannot access your host filesystem outside the worktree, and crosslink hooks still enforce all policy automatically.

 

Why containers?

  • Isolation – agents cannot access your host filesystem outside the worktree
  • Reproducibility – consistent environment regardless of host OS
  • Security--dangerously-skip-permissions becomes safe inside a container because crosslink hooks still enforce policy (no push, no merge, gated commits)
  • Cross-platform – works on Windows, Linux, and macOS anywhere Docker runs

 


Quick start

You say / do:

“Run this feature agent in a container so it’s fully sandboxed.”

You want stronger isolation than a local tmux session. The container approach is a single flag change.

Agent executes:

crosslink kickoff run "add batch retry logic" \
  --container docker

Creates branch, worktree, builds the image (if needed), starts a container, and launches the agent inside it.

 


Managing container lifecycle

Building the image

You say / do:

“Set up the container image for this project.”

The image is built once and reused for all subsequent agent launches. It includes the full toolchain for your project.

Agent executes:

crosslink container build

The default image includes: Rust toolchain (matches project’s rust-version), Python 3, Git, Claude Code CLI, and crosslink binary.

Monitoring containers

You say / do:

“What are my container agents doing?”

You can list running containers, stream logs, and open interactive shells for debugging.

Agent executes:

crosslink container ps
crosslink container logs my-feature -f

Lists all running agent containers and streams live output from a specific agent.

Manual control

# Start a container manually for an existing worktree
crosslink container start .worktrees/my-feature \
  --issue 42 \
  --prompt .worktrees/my-feature/KICKOFF.md

# Graceful stop
crosslink container stop my-feature

# Stop and remove
crosslink container kill my-feature

# Remove a stopped container
crosslink container rm my-feature

 


Hook enforcement inside containers

The same crosslink hooks that enforce policy in local sessions also run inside containers – automatically, with zero additional configuration:

  • Git mutations blockedgit push, git merge, git rebase are blocked by hooks
  • Commits gatedgit commit requires an active crosslink issue
  • Stub detection – post-edit hooks catch TODOs and incomplete code
  • Language rules – project-specific best practices are injected

This means you can use --dangerously-skip-permissions for the Claude Code CLI inside the container (to avoid interactive trust prompts) while still maintaining policy enforcement through hooks.

 


Integration with kickoff

The --container flag on crosslink kickoff run handles the full workflow:

  1. Creates a feature branch and worktree
  2. Builds the container image (if not already built)
  3. Starts a container with the worktree mounted
  4. Launches the agent inside the container
  5. The agent works autonomously: explore, implement, test, commit
# Local tmux (default)
crosslink kickoff run "my feature"

# Docker container
crosslink kickoff run "my feature" --container docker

# Podman container
crosslink kickoff run "my feature" --container podman