secure_agent_envs/CLAUDE.md
guessthepw cbc379c0cc Add project memory system with versioning guidelines
Establishes CLAUDE.md, CHANGELOG.md, and README.md as persistent
project memory. Adds documentation update triggers and semantic
versioning rules to ensure context is maintained across sessions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:29:37 -05:00

6.3 KiB

CLAUDE.md

Project Memory

This project uses three documentation files as persistent memory. You must keep these files up to date when making changes:

File Purpose Update When
CLAUDE.md Technical context for Claude Code sessions Adding new patterns, conventions, or implementation details
CHANGELOG.md Version history following Keep a Changelog format Every commit (add entry, bump version)
README.md User-facing documentation Changing user-visible behavior, adding features, or modifying usage

Versioning Rules

  • Use semantic versioning (MAJOR.MINOR.PATCH)
  • Increment PATCH for bug fixes and minor updates
  • Increment MINOR for new features and enhancements
  • Increment MAJOR for breaking changes
  • Tag every commit with its version: git tag -a vX.Y.Z -m "Description"

Project Overview

This repository contains a dual-mode setup script for creating OrbStack-based development sandboxes tailored for Claude Code with Elixir/Erlang, browser automation, and PostgreSQL.

Repository Structure

setup_env.sh        - Main script (macOS host mode + Linux VM provisioning mode)
config.env.example  - Example credentials file
config.env          - User credentials (gitignored, created on first run)
.gitignore          - Ignores config.env
README.md           - User-facing documentation
CHANGELOG.md        - Version history (Keep a Changelog format)
CLAUDE.md           - This file (context for Claude Code sessions)

How the Script Works

The script has two modes, detected via uname -s:

  • Darwin (macOS): Orchestrator mode. Checks for OrbStack, reads/creates config.env, creates a VM, copies itself in, runs itself inside the VM with --non-interactive.
  • Linux (VM): Provisioning mode. Installs all tools, configures PostgreSQL, sets up VNC, installs Claude Code plugins.

This means ./setup_env.sh my-vm on macOS does everything end-to-end.

Key Technical Details

  • Target environment: OrbStack Ubuntu VM on macOS Apple Silicon (ARM64)
  • Version manager: mise (manages Node.js, Erlang, Elixir)
  • Versions: All tools use latest by default. Erlang/Elixir versions can be configured at the top of setup_env.sh (ERLANG_VERSION, ELIXIR_VERSION) - set to "latest" or pin to specific versions
  • PostgreSQL auth: Peer for local socket, scram-sha-256 for all TCP connections (localhost and network)
  • Browser: Chromium (no Chrome ARM64 Linux builds exist), symlinked to google-chrome
  • VNC: TigerVNC + XFCE on display :1 (port 5901), controlled via vnc-start/vnc-stop helpers in ~/bin
  • Shared credentials: config.env stores git name/email only; VNC password is prompted each time (never stored)

Working on This Project

Editing setup_env.sh

  • The macOS host-mode block is at the top (inside the if [[ "$(uname -s)" == "Darwin" ]] block)
  • The Linux VM-mode block is everything after that conditional
  • Version numbers are defined as variables at the top (ERLANG_VERSION, ELIXIR_VERSION)
  • All installation steps must be idempotent (safe to run multiple times)
  • Use log_info, log_warn, log_error helpers for output
  • New apt packages go in the base dependencies section
  • New Claude plugins go in the appropriate array (ANTHROPIC_PLUGINS or SUPERPOWERS_PLUGINS)
  • Redirect verbose output to $LOG_FILE, show only meaningful progress to the user
  • The LOG_FILE variable is only set in VM mode (not available in macOS host mode)
  • Each optional component is wrapped in prompt_install "Name" "Description" — this handles both interactive prompts and --yes/--non-interactive auto-accept
  • Track dependency flags (INSTALLED_NODE, INSTALLED_CHROMIUM) to skip dependent components gracefully

Script Conventions

  • set -euo pipefail is enforced - handle potential failures with || true or explicit checks
  • Use command_exists to check for already-installed tools
  • Use apt-get (not apt) for scripting reliability
  • Quote all variable expansions
  • Use find for PostgreSQL config paths (version-agnostic)
  • The --non-interactive flag is for VM mode (implies --yes); macOS mode always uses config.env
  • --yes/-y accepts all components without prompting but still allows interactive credential entry
  • MISE_GLOBAL_CONFIG_FILE and MISE_CONFIG_DIR are set to prevent OrbStack host-mount config pollution

Security Patterns

  • Input validation: Use validate_vm_name(), validate_vnc_password(), validate_safe_input() for all user inputs
  • Safe config loading: Use load_config_safely() which parses key=value pairs without shell execution (never source)
  • Credential passing: Base64-encode values before passing to VM via orb run to prevent shell injection
  • Download helper: Use download_verified_binary() for binary downloads (supports optional checksum verification)
  • Temp files: Always use mktemp with restrictive permissions (chmod 600/700)
  • Symlinks: Check with [ ! -e path ] (not [ ! -L path ]) to avoid overwriting existing files
  • Architecture detection: Use detect_architecture() for portable binary downloads

Testing

There are no automated tests. To test changes:

  1. Remove an existing test VM: orb delete test-sandbox
  2. Run: ./setup_env.sh test-sandbox
  3. Verify provisioning completes
  4. Run again to verify idempotency: ssh test-sandbox@orb -- bash /tmp/setup_env.sh --non-interactive (will need env vars)
  5. Test VNC: ssh test-sandbox@orb -- vnc-start, then open vnc://test-sandbox.orb.local:5901
  6. Clean up: orb delete test-sandbox

Security Considerations

  • config.env is chmod 600 and gitignored (stores git name/email only, never VNC password)
  • PostgreSQL uses scram-sha-256 for all TCP connections (peer auth for local socket)
  • The script refuses to run as root inside the VM
  • VNC password is required (min 6 chars), validated to block shell metacharacters, never stored
  • VNC binds to all interfaces (-localhost no) to allow connections from the macOS host — this is intentional for the OrbStack use case and documented in the vnc-start script
  • All user inputs are validated before use to prevent command injection
  • External scripts (mise, ollama) are downloaded to temp files and validated before execution
  • Host filesystem access is disabled inside the VM for isolation