## Project **claudebox** A Nix derivation that produces a `claudebox` wrapper script for Claude Code. It runs Claude inside a bubblewrap sandbox with an allowlisted environment, explicit filesystem mounts, and a minimal PATH — keeping SSH keys, GPG/age secrets, cloud tokens, and Tailscale state completely invisible to the AI agent. **Core Value:** Secrets never enter the Claude Code environment. If a secret is accessible inside the sandbox, it's a bug. ### Constraints - **Stack**: Nix derivation + shell script — no Docker, no systemd, no external dependencies beyond nixpkgs - **Sandbox**: Own bwrap call — not delegating to Claude Code's `--sandbox` or Nix's build sandbox - **Env model**: Allowlist, not denylist — start empty, add explicitly ## Technology Stack ## Recommended Stack ### Core: Nix Derivation via `writeShellApplication` | Technology | Version | Purpose | Why | Confidence | |------------|---------|---------|-----|------------| | `writeShellApplication` | nixpkgs stable | Produce the `claudebox` wrapper script | Generates a shellcheck-validated bash script in the Nix store with runtime PATH wired to declared `runtimeInputs`. Superior to `writeShellScriptBin` because it runs shellcheck at build time and sets `set -euo pipefail` automatically. | HIGH | | `bubblewrap` (bwrap) | 0.9.x+ | Sandbox runtime | Unprivileged user-namespace sandbox. In nixpkgs as `bubblewrap`. No setuid needed on NixOS (user namespaces enabled by default). | HIGH | | `claude-code` | CLI | The wrapped tool | Provided by Anthropic's npm/standalone installer. Assumed pre-installed or passed as input. | HIGH | ### Runtime Dependencies (runtimeInputs) | Package | Purpose | Why This One | Confidence | |---------|---------|--------------|------------| | `bubblewrap` | Sandbox | The whole point | HIGH | | `coreutils` | Basic shell utils | `env`, `cat`, `echo`, `mkdir`, etc. | HIGH | | `git` | Version control | Claude Code requires git for repo operations | HIGH | | `curl` | HTTP requests | Claude Code's MCP and tool use | HIGH | | `jq` | JSON processing | Env audit display, config manipulation | HIGH | | `ripgrep` | Search | Claude Code's preferred grep | HIGH | | `fd` | File finding | Claude Code's preferred find | HIGH | | `nix` | Package manager | Required for `nix shell` inside sandbox | HIGH | | `comma` | On-demand packages | Runs `nix shell nixpkgs# -c ` via `, ` syntax | HIGH | | `nix-index` | Package database | Required by comma to resolve command -> package mapping | HIGH | | `bash` | Shell | bwrap needs a shell to exec into | HIGH | | `nodejs` | Runtime | Claude Code is a Node.js application | HIGH | ### NOT in runtimeInputs (Important) | Package | Why Excluded | |---------|-------------| | `gnupg` | Secret material -- explicitly hidden | | `openssh` | Secret material -- explicitly hidden | | `age` / `agenix` | Secret material -- explicitly hidden | | `tailscale` | Infrastructure access -- explicitly hidden | ## Key Nix Functions ### `writeShellApplication` -- Use This ### Why NOT These Alternatives | Alternative | Why Not | |-------------|---------| | `writeShellScriptBin` | No shellcheck, no automatic `set -euo pipefail`, no `runtimeInputs` wiring. You'd have to manually construct PATH. | | `makeWrapper` / `wrapProgram` | Designed for wrapping existing binaries with env vars/flags. Overkill and wrong abstraction -- we're writing a new script, not patching an existing binary. | | `symlinkJoin` + `makeWrapper` | Pattern for combining multiple derivations. Not needed -- we have one script. | | `stdenv.mkDerivation` | Too heavy. `writeShellApplication` is a specialized shortcut for exactly this use case. | | `runCommand` / `writeScript` | Lower-level, no shellcheck, no runtimeInputs. | ## Bubblewrap Flags ### Namespace Isolation ### Filesystem Mounts ### Mount Ordering Matters ### Environment Handling ### Process Execution ## Comma and nix-index ### How Comma Works ### Packaging in nixpkgs - `pkgs.comma` -- the comma binary itself - `pkgs.nix-index` -- the indexer that builds/queries the database - Database: comma needs a pre-built index. Two options: ### For claudebox - Mount `~/.cache/nix-index` read-only into the sandbox (if using nix-index-database on the host) - Or use the `nix-index-database` flake's `comma-with-db` package which bundles the database ## Flake Structure ### Why `builtins.readFile` for the Script Body - Shell syntax highlighting in editors - Shellcheck can run independently - Easier to iterate on the script without touching Nix expressions - `writeShellApplication` still runs shellcheck on it at build time ## PATH Construction Inside Sandbox ## Nix Store Access Inside Sandbox ## Testing Strategy ## Sources - Training data knowledge of nixpkgs `writeShellApplication` (stable API since 2022) - Training data knowledge of bubblewrap (stable API, project is mature) - Training data knowledge of comma/nix-index-database (nix-community project) - **All versions should be verified against current nixpkgs before implementation** ## Verification Checklist (for implementation phase) - [ ] Confirm `bubblewrap` version in current nixpkgs channel - [ ] Confirm `comma` and `nix-index-database` flake are current and compatible - [ ] Test Nix daemon socket access through bwrap bind mount - [ ] Test mount ordering with CWD under $HOME - [ ] Confirm `--clearenv` + `--setenv` pattern works with Claude Code (it may need vars we haven't listed) - [ ] Check if Claude Code needs `~/.local` or `~/.config` beyond `~/.claude` ## Conventions Conventions not yet established. Will populate as patterns emerge during development. ## Architecture Architecture not yet mapped. Follow existing patterns found in the codebase. ## Project Skills No project skills found. Add skills to any of: `.claude/skills/`, `.agents/skills/`, `.cursor/skills/`, or `.github/skills/` with a `SKILL.md` index file. ## GSD Workflow Enforcement Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync. Use these entry points: - `/gsd-quick` for small fixes, doc updates, and ad-hoc tasks - `/gsd-debug` for investigation and bug fixing - `/gsd-execute-phase` for planned phase work Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it. ## Developer Profile > Profile not yet configured. Run `/gsd-profile-user` to generate your developer profile. > This section is managed by `generate-claude-profile` -- do not edit manually.