*magenta-docker.txt*     Docker sub-agents and containerized development

==============================================================================
CONTENTS                                             *magenta-docker-contents*

    1. Overview ................................ |magenta-docker-overview|
    2. Requirements ............................ |magenta-docker-requirements|
    3. Configuration ........................... |magenta-docker-config|
    4. Writing a Dockerfile ................... |magenta-docker-dockerfile|
    5. Lifecycle ............................... |magenta-docker-lifecycle|
    6. Unsupervised Mode ....................... |magenta-docker-supervision|
    7. File Synchronization ................... |magenta-docker-sync|

==============================================================================
OVERVIEW                                             *magenta-docker-overview*

Docker sub-agents run in isolated containers to safely execute unsupervised
work without affecting the local filesystem. The agent has full read/write
access within the container but cannot change local files until it yields
back to the parent agent.

Key benefits:~
  - Safe unsupervised execution (container is ephemeral)
  - Reproducible environments (same image every time)
  - No local side effects until explicitly synced via yield
  - Built-in auto-restart capability for supervision mode

How it works:~
  1. Project files are copied to a temporary container context
  2. Docker image is built using the specified Dockerfile
  3. Container is started and agent executes via `docker exec`
  4. Agent can make changes, run tests, commit to git within the container
  5. On yield: modified files are synced back via rsync
  6. On abort: container is cleaned up without syncing changes

==============================================================================
REQUIREMENTS                                         *magenta-docker-requirements*

To use Docker sub-agents, you need:

  - Docker installed and running on the host machine
  - A Dockerfile in the project (typically at `docker/Dockerfile`)
  - Sufficient disk space for temporary container contexts and images
  - rsync installed on the host (used for file synchronization)

Verify Docker setup:~
>bash
    docker --version
    docker run hello-world
<

==============================================================================
CONFIGURATION                                        *magenta-docker-config*

Docker sub-agents are configured inline when spawning, not in a separate
config file. Required fields:~

  `dockerfile`      Path relative to the working directory to the
                    Dockerfile (e.g., `"docker/Dockerfile"`). The parent
                    directory is used as the Docker build context.

  `workspacePath`   Where the project lives inside the container
                    (e.g., `"/workspace"`). Should match the WORKDIR
                    directive in the Dockerfile.

Optional fields:~

  `directory`       Host directory to build from (defaults to cwd)

Example spawn call:~
>lua
    spawn_subagents({
      agents = [{
        prompt = "Run tests and fix failures",
        agentType = "tests-in-docker",
        environment = "docker_unsupervised",
        dockerfile = "docker/Dockerfile",
        workspacePath = "/workspace"
      }]
    })
<

==============================================================================
WRITING A DOCKERFILE                                 *magenta-docker-dockerfile*

A well-structured Dockerfile uses layer caching to speed up rebuilds.
Here's the recommended pattern:~

>dockerfile
    FROM node:24-bookworm

    # Install system dependencies once
    RUN apt-get update && apt-get install -y \
        git \
        curl \
        # ... other tools
        && rm -rf /var/lib/apt/lists/*

    WORKDIR /workspace

    # Copy only package files first (stable layer)
    COPY package.json package-lock.json ./
    COPY node/package.json node/package-lock.json ./node/

    # Install dependencies (cached unless package.json changes)
    RUN npm ci
    RUN cd node && npm ci

    # Copy everything else (changes frequently)
    COPY . .

    # Configure git for the agent
    RUN git config --global user.email "agent@example.com" && \
        git config --global user.name "Agent"

    # Keep container alive (agent will use docker exec)
    CMD tail -f /dev/null
<

Key practices:~

  - Place stable content (package files) early for layer caching
  - Install dependencies before copying rest of code
  - Put frequently-changing content last
  - Use `RUN rm -rf /var/lib/apt/lists/*` to minimize layers
  - Set `workspacePath` to match the WORKDIR
  - Configure git with user.email and user.name
  - Use `CMD tail -f /dev/null` to keep container running

==============================================================================
LIFECYCLE                                            *magenta-docker-lifecycle*

Understanding the container lifecycle helps you debug issues and optimize
builds.

1. Working directory copy~

   The host's working directory is copied to a temporary location. This
   becomes the Docker build context.

2. Docker image build~

   The image is built from the specified Dockerfile. Layer cache is reused
   across builds, so unchanged layers are skipped.

3. Container startup~

   A container is started from the image. The agent works inside this
   container via `docker exec` commands.

4. Agent execution~

   The agent can:
     - Edit files
     - Run tests
     - Make git commits
     - Install packages
     - Run any command available in the image

5. Teardown~

   On successful yield:
     - Modified files are synced back via rsync (respecting .dockerignore)
     - Container and temporary context are deleted
   
   On abort:
     - Container and context are cleaned up without syncing

==============================================================================
UNSUPERVISED MODE                                    *magenta-docker-supervision*

Unsupervised Docker mode (`docker_unsupervised`) allows agents to run
autonomously without requesting user approval for tool use.

Auto-restart behavior~

If the agent stops before yielding (e.g., due to an error), the supervisor
automatically restarts the agent up to 5 times. Each restart:
  - Preserves file changes in the container
  - Maintains git history
  - Allows the agent to recover and try again

This is useful for:
  - Long-running test suites that may timeout
  - Agents that encounter transient errors
  - Complex tasks requiring multiple attempts

When auto-restart is exhausted~

After 5 restarts, the agent is considered failed. The container is cleaned
up and no files are synced back to the host.

==============================================================================
FILE SYNCHRONIZATION                                 *magenta-docker-sync*

Files are synchronized between the host and container using rsync. This
happens only on successful yield, not during execution.

Sync behavior~

  - Uses `rsync` with `--delete` to ensure deletions are propagated
  - Respects `.dockerignore` (similar to `.gitignore`)
  - One-way sync: container → host (after agent yields)
  - Files modified by the agent in `/workspace` are synced to the
    corresponding directory on the host

Example .dockerignore:~

>
    node_modules
    .git
    .env
    __pycache__
    *.log
<

Performance considerations~

  - Large node_modules directories can be slow to sync; exclude them if
    they're installed fresh each build
  - Use .dockerignore to exclude build artifacts and cache directories
  - Binary files sync faster than text files

See Also~

  - |magenta-subagents| - Sub-agent spawning and communication
  - |magenta-tools| - Available tools including spawn_subagents
vim:tw=78:ts=8:noet:ft=help:norl:
