Skip to content

D5: Bind-mount contract for agent CLIs #10

Description

@Teagan42

Part of #2

D5 — Bind-mount contract for agent CLIs

Labels: wayfinder:grilling status:closed
Blocks: D6, D8

Resolution

Hybrid contract: image ships a curated baked-in agent set AND supports an /opt/agents bind-mount for operator extensions/overrides. Specific baked set is deferred to D9 — Curated baked-agent set; this ticket locks the shape.

Spec fragment:

  • Base image: debian:stable-slim (not alpine — musl breaks glibc-linked host binaries bind-mounted in, and rules out common precompiled tools).
  • Pre-installed runtimes & tools:
    • nodejs (current LTS via NodeSource) + npm
    • python3 + pip3
    • git
    • ca-certificates
    • coreutils (already in debian-slim)
    • su-exec or gosu (from D4)
    • tini (from D4/D6, for PID-1 reap)
    • Skip: rust, go, ruby, php, jvm — out of scope for v1.
  • Baked agent install location: /usr/local/bin (npm globals land here by default; pip --prefix=/usr/local). No dedicated directory.
  • Bind-mount extension point: /opt/agents — image creates the empty dir. Operators mount their own binaries here (-v ~/.local/bin:/opt/agents:ro or curated dir).
  • PATH order: PATH=/opt/agents:/usr/local/bin:/usr/bin:/bin (image ENV). Operator's bind-mounted binaries shadow the baked ones — this is deliberate: it's how users pin an agent to a specific host-installed version if a baked one breaks.
  • HydratePATH: image sets CHARTR_NO_PATH_PROBE=1. In-container there's no operator login-shell to inherit from; the probe would waste ~200ms on a guaranteed no-op. The existing gate (internal/env/path.go:48) already supports this — zero Go change.
  • Agent auth material: two supported patterns, both demonstrated in D8's compose example:
    1. Bind-mount host state: e.g. -v ~/.claude:/config/agents/.claude:ro (readonly if the agent only reads; writable if it needs to persist).
    2. Env passthrough via compose env_file: for API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.).
  • Known-broken shape (troubleshooting doc entry, not a code change): agent CLIs that hardcode $HOME-relative paths outside of ~/.claude, ~/.config, or their own dotfile — operator must bind-mount whatever the CLI needs. This is a documentation surface, not an image concern.

Downstream impact:

  • Destination Notes update — the "thin runtime, not batteries-included" line no longer holds; the map Notes will be reworded to "curated baked-in agent set with a bind-mount extension point."
  • D6 (Dockerfile) — install steps (nodejs LTS, python3, git); ENV PATH=/opt/agents:..., ENV CHARTR_NO_PATH_PROBE=1; RUN mkdir /opt/agents; agent install steps come from D9.
  • D7 (GHCR workflow) — image is larger; note in buildx cache strategy that node/python layer changes rarely, so cache hit rate stays high.
  • D8 (compose + docs) — show BOTH auth patterns; show optional /opt/agents bind-mount example.
  • New fog — "one image or chartr:slim + chartr:latest variants" — deferred; may graduate once D9 nails the baked set size.

Question

The image is a thin runtime; agent CLIs (Claude Code, Codex, aider, etc.) come from the host via bind-mount. Decide the contract:

  • What exactly does the operator mount? A single bin/ directory prepended to PATH? Individual binaries? The host's ~/.local/bin?
  • Does the image need any runtime dependencies pre-installed so bind-mounted CLIs actually run (node? python? glibc vs musl compatibility of a debian-slim vs. alpine base)?
  • How does chartr's agent registration inside the container find these binaries — hardcoded PATH prefix, or a CHARTR_AGENTS_DIR env pointing at the mount?
  • What breaks if a user's CLI is a shell script depending on host-side files (e.g. references ~/.config/... inside its own script)? Document known-good vs. known-broken shapes.
  • Contract for auth material the agent CLI needs (e.g. ~/.claude, API keys) — bind-mount, env passthrough, or out of scope for this ticket and lives in the compose example (D8)?

Deliverable: a short "agent bind-mount contract" spec fragment + list of pre-installed runtime deps the base image must include.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions