From 527ed51e6ad7d098a37494a52ae6ba950a09805b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 9 Apr 2026 10:46:40 +0200 Subject: [PATCH] docs(01): capture phase context --- .../01-minimal-viable-sandbox/01-CONTEXT.md | 88 +++++++++++++++++++ .../01-DISCUSSION-LOG.md | 73 +++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 .planning/phases/01-minimal-viable-sandbox/01-CONTEXT.md create mode 100644 .planning/phases/01-minimal-viable-sandbox/01-DISCUSSION-LOG.md diff --git a/.planning/phases/01-minimal-viable-sandbox/01-CONTEXT.md b/.planning/phases/01-minimal-viable-sandbox/01-CONTEXT.md new file mode 100644 index 0000000..eaa7f7d --- /dev/null +++ b/.planning/phases/01-minimal-viable-sandbox/01-CONTEXT.md @@ -0,0 +1,88 @@ +# Phase 1: Minimal Viable Sandbox - Context + +**Gathered:** 2026-04-09 +**Status:** Ready for planning + + +## Phase Boundary + +Produce a working `claudebox` command via Nix flake that launches Claude Code inside a bubblewrap sandbox with environment allowlisting, filesystem isolation, secret path hiding, and on-demand tool provisioning via comma/nix. User runs `claudebox` in any project directory and gets a fully functional Claude session with secrets invisible. + + + + +## Implementation Decisions + +### Argument Passthrough +- **D-01:** Forward all unknown flags to `claude`. claudebox claims only its own flags (`--yes`, `--dry-run`, `--check`) and passes everything else through. No `--` separator required. `--dangerously-skip-permissions` is always injected. + +### nix-index Database +- **D-02:** Use `comma-with-db` from the `nix-community/nix-index-database` flake. Self-contained — bundles the package index, no host dependency, no extra bind mount needed. DB updates when the flake input is bumped. + +### Environment Variables +- **D-03:** Strict allowlist per SAND-03, plus a `CLAUDEBOX_EXTRA_ENV` escape hatch. Core allowlist always passes (HOME, PATH, TERM, EDITOR, LANG, LC_ALL, NIX_SSL_CERT_FILE, SSL_CERT_FILE, ANTHROPIC_API_KEY, USER, SHELL, XDG_RUNTIME_DIR). User can add extras at launch via `CLAUDEBOX_EXTRA_ENV="COLORTERM,NODE_OPTIONS"` — their responsibility to not leak secrets. +- **D-04:** Sandbox-generated vars (TMPDIR=/tmp, etc.) are set via `--setenv`, never read from host. + +### Git Identity +- **D-05:** Generate a minimal `.gitconfig` inside the sandbox at launch time. Reads `user.name` and `user.email` from the host's git config, writes them plus `safe.directory = *` into the sandbox's `~/.gitconfig`. No host `.gitconfig` mounted — avoids credential helper, pager, and alias breakage from missing binaries. + +### Claude's Discretion +- Mount ordering strategy for CWD-under-HOME (bwrap specifics) +- Exact tmpfs layout and /dev, /proc, /tmp setup +- How `--clearenv` + `--setenv` are sequenced in the bwrap invocation +- DNS resolution mount strategy (resolv.conf and its symlink targets) +- SSL cert bundle path detection + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Project Docs +- `.planning/PROJECT.md` — Core value, constraints, key decisions +- `.planning/REQUIREMENTS.md` — Full requirement list with IDs (SAND-*, TOOL-*, GIT-*, NIX-*, UX-*) +- `.planning/ROADMAP.md` — Phase 1 success criteria and requirement mapping + +### Stack Research +- `CLAUDE.md` §Technology Stack — writeShellApplication, bwrap flags, comma/nix-index, flake structure, PATH construction, testing strategy + + + + +## Existing Code Insights + +### Reusable Assets +- None — greenfield project, only CLAUDE.md exists in the repo + +### Established Patterns +- None yet — Phase 1 establishes all patterns + +### Integration Points +- Nix flake as entry point (`nix run`, `nix profile install`) +- `writeShellApplication` produces the claudebox script +- bwrap is the sole runtime dependency for sandboxing + + + + +## Specific Ideas + +- `CLAUDEBOX_EXTRA_ENV` is comma-separated, not space-separated +- Git identity is read from host at launch time (not build time) so it works across machines +- `comma-with-db` as flake input, not a nixpkgs package + + + + +## Deferred Ideas + +None — discussion stayed within phase scope + + + +--- + +*Phase: 01-minimal-viable-sandbox* +*Context gathered: 2026-04-09* diff --git a/.planning/phases/01-minimal-viable-sandbox/01-DISCUSSION-LOG.md b/.planning/phases/01-minimal-viable-sandbox/01-DISCUSSION-LOG.md new file mode 100644 index 0000000..04776bd --- /dev/null +++ b/.planning/phases/01-minimal-viable-sandbox/01-DISCUSSION-LOG.md @@ -0,0 +1,73 @@ +# Phase 1: Minimal Viable Sandbox - Discussion Log + +> **Audit trail only.** Do not use as input to planning, research, or execution agents. +> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered. + +**Date:** 2026-04-09 +**Phase:** 01-minimal-viable-sandbox +**Areas discussed:** Argument passthrough, nix-index database, Env edge cases, Git identity + +--- + +## Argument Passthrough + +| Option | Description | Selected | +|--------|-------------|----------| +| Forward all unknown | claudebox claims --yes, --dry-run, --check; everything else passes through to claude | ✓ | +| Explicit -- separator | claudebox args before --, claude args after -- | | +| Pass everything through | claudebox has no flags, controlled via env vars | | + +**User's choice:** Forward all unknown +**Notes:** No -- separator needed. Simple and intuitive. + +--- + +## nix-index Database + +| Option | Description | Selected | +|--------|-------------|----------| +| comma-with-db | Use nix-community/nix-index-database flake, bundles the DB | ✓ | +| Mount host ~/.cache/nix-index | Bind-mount host's nix-index DB read-only | | +| Both — prefer host, fallback to bundled | Mount host DB if exists, otherwise comma-with-db | | + +**User's choice:** comma-with-db +**Notes:** Self-contained, no host dependency. + +--- + +## Env Edge Cases + +| Option | Description | Selected | +|--------|-------------|----------| +| Strict allowlist | Only SAND-03 vars, rebuild to add more | | +| Allowlist + CLAUDEBOX_EXTRA_ENV | Core allowlist + user-specified extras via comma-separated env var | ✓ | +| Strict + computed vars | Allowlist from host + claudebox generates its own TMPDIR, COLORTERM, etc. | | + +**User's choice:** Allowlist + CLAUDEBOX_EXTRA_ENV +**Notes:** Pragmatic escape hatch for power users, user takes responsibility for not leaking secrets. + +--- + +## Git Identity + +| Option | Description | Selected | +|--------|-------------|----------| +| Generate minimal .gitconfig | Create sandbox-only .gitconfig with user.name, user.email, safe.directory | ✓ | +| Mount host .gitconfig read-only | Bind-mount host config, carries over everything including broken credential helpers | | +| Mount + override dangerous keys | Mount host config but neutralize credential.helper and core.pager via env vars | | + +**User's choice:** Generate minimal .gitconfig +**Notes:** User asked whether custom git settings matter for Claude. Conclusion: Claude uses git programmatically, doesn't need aliases/pagers/merge tools. Mounting host config risks breakage from credential helpers and pagers referencing binaries not in sandbox PATH. + +--- + +## Claude's Discretion + +- Mount ordering, tmpfs layout, /dev /proc /tmp setup +- --clearenv + --setenv sequencing +- DNS resolution mount strategy +- SSL cert bundle path detection + +## Deferred Ideas + +None