Skip to content

D3: Persistence & volume strategy #8

Description

@Teagan42

Part of #2

D3 — Persistence & volume strategy

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

Resolution

chartr already has a two-root model in internal/server/server.go: DataDir (runtime, per-session payload archives) and ConfigDir (operator config — agent registry, sources, prompt contract). ConfigRoot (server.go:298-309) resolves XDG_CONFIG_HOME first, then falls back to $fallback/config. The Docker spec mirrors this split.

State map:

Kind In-container path Volume? Notes
Runtime / session payload archives (DataDir) /data Yes Set via CHARTR_DATA_DIR=/data env (per D1). Declared as VOLUME /data in the Dockerfile.
Operator config, agent registry, sources, prompt contract (ConfigDir) /config Yes Set via XDG_CONFIG_HOME=/config in image ENV — no new Go env needed (ConfigRoot already honors it). Declared as VOLUME /config.
/tmp — spawned PTY child scratch container-local (default) No Explicit non-goal: do NOT VOLUME /tmp and do NOT document a /tmp bind-mount. Left to the container's own writable layer or an operator-supplied tmpfs.
Repo working trees operator-chosen (/workspace, etc.) No — not chartr's volume Comes from the operator's bind-mounts per D5's contract. Chartr's own volumes hold zero repo bytes.
Ephemeral caches (Go module, npm, etc.) build-time only n/a Live in build stages only; final image ships no cache dirs to volume.

Env/config surface the operator can relocate with:

  • CHARTR_DATA_DIR — overrides -data-dir default (per D1).
  • XDG_CONFIG_HOME — overrides ConfigDir derivation. Chartr's existing behavior; no new env.

Rationale for two volumes over one:

  • Backup semantics: /config alone is a small, meaningful snapshot; /data is regenerable-ish runtime.
  • Symmetric with the codebase's own split — no in-container path convention that fights the existing model.

Downstream impact:

  • D6 (Dockerfile) — declare VOLUME ["/data", "/config"]; add ENV XDG_CONFIG_HOME=/config alongside D1's other envs.
  • D8 (compose + docs) — the compose example maps both volumes; docs note /tmp is intentionally not a mount and repo trees come from D5's bind-mounts.

Question

Enumerate every piece of state chartr writes today (config, registered spaces, maps under repo working trees, agent registration, logs, caches) and decide, for the container:

  • Which paths need to survive container recreation → declared VOLUMEs or documented bind-mount targets.
  • Canonical in-container paths (e.g. /config, /state) and how they map to chartr's usual XDG dirs. Do we override XDG_CONFIG_HOME/XDG_STATE_HOME, or teach chartr an in-container path convention?
  • Which paths are ephemeral (caches, tmp) and must NOT be volumes.
  • Compose-example implication: what volume declarations the getting-started example needs.

Deliverable: a table of state kind → in-container path → volume? → notes, plus the env/config surface (if any) that lets an operator relocate them.

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