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-permissionsbecomes 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 dockerCreates 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 buildThe 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 -fLists 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 blocked –
git push,git merge,git rebaseare blocked by hooks - Commits gated –
git commitrequires 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:
- Creates a feature branch and worktree
- Builds the container image (if not already built)
- Starts a container with the worktree mounted
- Launches the agent inside the container
- 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