portfolio/agentlab/decisions/ADR-001-tool-persistence.md
AgentLab d5ef629a54 feat: initial AgentLab portfolio content
Architecture, overview, homelab build plan, agent handbook, ADRs,
and agent operating rules. All sensitive operational details sanitized
(real IPs, hostnames, client names replaced with generic placeholders).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 04:52:42 +00:00

2.2 KiB

ADR-001 — CLI Tool Persistence Pattern

Status: Accepted

Context

The AgentLab devcontainer uses Docker named volumes for config/auth persistence and bind mounts for the repo. Any tool installed manually into the container filesystem (e.g. via npm install -g) is lost on docker compose down && up because the writable container layer is discarded.

This caused Codex to fail silently after a container restart. The codex-config named volume correctly preserved ~/.codex/ (auth, config), but the binary was never added to bootstrap.sh. The result: auth survived, binary didn't, tool appeared broken.

Claude Code survived because its installer was added to bootstrap.sh at setup time. Codex was not.

Decision

Every CLI tool that must survive container rebuilds requires two things — both are mandatory, neither is sufficient alone:

Part What Where
1. Named volume Persists auth/config (~/.TOOLNAME/) compose.yml
2. Bootstrap step Installs the binary idempotently bootstrap.sh

Missing either part = tool is half-set-up and will silently break on next rebuild.

Tool manifest

Tool Binary Named volume Bootstrap step
Claude Code claude claude-config → ~/.claude
Codex CLI codex codex-config → ~/.codex
Gemini CLI gemini gemini-config → ~/.gemini

Consequences

  • bootstrap.sh is the single executable source of truth for binary installation.
  • compose.yml is the single source of truth for named volumes.
  • Any agent setting up a new CLI tool MUST update both files AND this ADR before the setup is considered complete.

What does NOT need a bootstrap step

Tools installed in the Dockerfile (RUN instruction) are baked into the image and survive all rebuilds without a bootstrap step. Only tools installed at runtime (post-container-start) need a bootstrap step.

Adding a new tool — checklist

  1. Add named volume to compose.yml (TOOLNAME-config → ~/.TOOLNAME)
  2. Add idempotent install step to bootstrap.sh
  3. Add entry to the tool manifest table above
  4. Update docs/bootstrap.md with the new tool
  5. Run bootstrap.sh to verify the install succeeds