Organizational

Sandbox Environments

Pattern for isolated, developer-owned sandbox environments for local development and testing.

Production

Definition

A sandbox is an isolated, non-production environment designed for:

  • Local development
  • Experimentation
  • Testing
  • Debugging

Sandboxes are developer-owned and MUST NOT affect production systems, data, or resources.

Core Principles

Isolation

Sandboxes MUST be completely isolated from production:

  • No access to production databases
  • No access to production APIs (unless explicitly read-only and safe)
  • No ability to trigger production events or side effects
  • No shared state with production systems

Developer Ownership

Each developer MUST be able to:

  • Start their own sandbox independently
  • Tear down their sandbox without coordination
  • Modify sandbox configuration without affecting others
  • Run multiple sandboxes simultaneously if needed

Reproducibility

Sandboxes MUST be:

  • Quickly recreatable from scratch
  • Consistent across different developer machines
  • Documented in the repository's operational instructions

Sandbox Architectures

Sandboxes may take different forms depending on the repository:

Local-Only Sandbox

All components run on the developer's machine:

  • Databases: Docker Compose or local instances
  • Services: Running natively or in containers
  • External dependencies: Mocked or stubbed

When to use: Simple services with minimal external dependencies

Hybrid Sandbox

Mix of local and remote resources:

  • Frontend: Running locally for fast iteration
  • Backend: Running locally or against a shared dev environment
  • Databases: Local or remote development instances
  • External APIs: Mocked locally or pointing to dev endpoints

When to use: Complex systems with heavy infrastructure requirements

Remote Sandbox

Ephemeral cloud resources:

  • Infrastructure: Deployed to a dedicated sandbox namespace
  • Databases: Isolated sandbox instances
  • Services: Deployed to sandbox environment
  • Cleanup: Automated teardown after session

When to use: Services requiring production-like infrastructure

Requirements

Task Exposure

If a repository CAN reasonably run in sandbox mode, it MUST provide Taskfile tasks:

  • sandbox:start — Start the sandbox environment
  • sandbox:stop — Stop and clean up the sandbox
  • sandbox:restart — Restart the sandbox environment
  • sandbox:seed — Seed the sandbox environment with sample data
  • sandbox:reset — Reset sandbox to clean state (optional)

If a repository CANNOT run in sandbox mode (e.g., infrastructure-only repos), this MUST be documented in AGENTS.md.

No Production Leakage

Sandboxes MUST implement safeguards:

  • Environment variables clearly distinguish sandbox from production
  • Configuration defaults to sandbox mode
  • Accidental production access is prevented by design

Example environment variable naming:

# Clear distinction
SANDBOX_MODE=true
ENVIRONMENT=sandbox

# Avoid ambiguous naming
ENV=dev  # Unclear if this is sandbox or shared dev

Easy Teardown

Developers MUST be able to:

  • Tear down sandboxes without manual cleanup
  • Remove all sandbox resources with a single command
  • Avoid orphaned resources (containers, volumes, cloud resources)

Sandbox vs. Other Environments

EnvironmentPurposeIsolationLongevityData
SandboxDev/experimentationCompleteEphemeralDisposable
DevelopmentIntegration testingSharedPersistentRealistic but not real
StagingPre-production validationProduction-likePersistentProduction snapshot
ProductionReal usersCompletePermanentReal data

Anti-Patterns

❌ Shared "Dev" Databases

Multiple developers sharing a single development database:

  • Causes state conflicts between developers
  • Makes debugging harder
  • Slows down development

Instead: Each developer runs their own isolated database in their sandbox.

❌ Manual Setup Steps

Requiring developers to manually provision resources:

  • Increases friction and setup time
  • Leads to inconsistent environments
  • Makes onboarding painful

Instead: Automate sandbox startup with sandbox:start.

❌ Stateful Sandboxes

Sandboxes that accumulate state over time:

  • Become unreproducible
  • Drift from clean state
  • Hide bugs that only appear in fresh environments

Instead: Design sandboxes to be easily reset to a known good state.

❌ Production Credentials in Sandbox

Using production API keys or credentials in sandbox:

  • Risks accidental production modifications
  • Violates least privilege principle
  • Creates security exposure

Instead: Use sandbox-specific credentials or mocks.

Examples

Simple Sandbox (Local Docker)

# Taskfile.yaml
sandbox:start:
  desc: Start local sandbox environment
  cmds:
    - docker compose -f docker-compose.sandbox.yml up -d
    - task: dev:migrate
    - echo "Sandbox running at http://localhost:8080"

sandbox:stop:
  desc: Stop and clean up sandbox
  cmds:
    - docker compose -f docker-compose.sandbox.yml down -v

Hybrid Sandbox (Local Frontend + Remote Backend)

# Taskfile.yaml
sandbox:start:
  desc: Start hybrid sandbox (local frontend + dev backend)
  cmds:
    - echo "Starting frontend locally..."
    - npm run dev &
    - echo "Frontend: http://localhost:3000"
    - echo "Backend: https://api-dev.ontopix.internal"

sandbox:stop:
  desc: Stop local frontend
  cmds:
    - pkill -f "npm run dev"

Remote Sandbox (Ephemeral Cloud)

# Taskfile.yaml
sandbox:start:
  desc: Deploy ephemeral sandbox to cloud
  vars:
    SANDBOX_ID:
      sh: echo "sandbox-$(whoami)-$(date +%s)"
  cmds:
    - terraform -chdir=.infra/sandbox apply -var="sandbox_id={{.SANDBOX_ID}}"
    - echo "Sandbox deployed: {{.SANDBOX_ID}}"

sandbox:stop:
  desc: Destroy ephemeral sandbox
  cmds:
    - terraform -chdir=.infra/sandbox destroy -auto-approve

Sandbox-Specific Configuration

Configuration SHOULD default to sandbox mode:

# config.py
import os

ENVIRONMENT = os.getenv("ENVIRONMENT", "sandbox")  # Default to sandbox
DATABASE_URL = os.getenv(
    "DATABASE_URL",
    "postgresql://localhost:5432/myapp_sandbox"  # Sandbox default
)

if ENVIRONMENT == "production":
    # Production overrides
    DATABASE_URL = os.getenv("PROD_DATABASE_URL")  # No default for production

Documentation Requirements

Every repository with sandbox capability MUST document in AGENTS.md:

  • How to start the sandbox
  • What the sandbox includes (databases, services, etc.)
  • How to verify the sandbox is working
  • How to tear down the sandbox
  • Any prerequisites (Docker, cloud CLI, etc.)

Example:

## Sandbox Mode

This repository supports local sandbox mode using Docker Compose.

**Start sandbox:**

task sandbox:start


**Sandbox includes:**
- PostgreSQL database (port 5432)
- Redis cache (port 6379)
- API service (port 8080)

**Verify sandbox:**

curl http://localhost:8080/health


**Stop sandbox:**

task sandbox:stop


**Prerequisites:**
- Docker and Docker Compose installed
- Ports 5432, 6379, 8080 available

Rationale

Sandboxes exist to:

  • Enable fearless experimentation
  • Reduce developer setup time
  • Prevent accidental production impact
  • Make development environments reproducible

Isolated, developer-owned sandboxes are a prerequisite for productive development at Ontopix.