skills/mav-bp-environment-management/SKILL.md
Environment management conventions for all projects. Covers reproducible local development, environment parity, .env patterns, developer onboarding, and containerised development. Applied when setting up or reviewing development environments.
npx skillsauth add thermiteau/maverick mav-bp-environment-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Ensure every project can be set up, run, and developed against reliably across machines and team members. Reproducible environments reduce onboarding time, eliminate "works on my machine" defects, and keep development aligned with production.
Before applying these standards, load the project-specific environment management implementation:
digraph lookup {
"docs/maverick/skills/environment-management/SKILL.md exists?" [shape=diamond];
"Read and use alongside these standards" [shape=box];
"Invoke upskill" [shape=box];
"Read generated skill" [shape=box];
"docs/maverick/skills/environment-management/SKILL.md exists?" -> "Read and use alongside these standards" [label="yes"];
"docs/maverick/skills/environment-management/SKILL.md exists?" -> "Invoke upskill" [label="no"];
"Invoke upskill" -> "Read generated skill";
"Read generated skill" -> "Read and use alongside these standards";
}
docs/maverick/skills/environment-management/SKILL.mddo-upskill skill with:
devcontainer\.json|docker-compose|Vagrantfile|flake\.nix|\.envrc|\.tool-versions|\.node-version|\.python-version.devcontainer/**, docker-compose*.yml, docker-compose*.yaml, Vagrantfile, flake.nix, .envrc, .tool-versions, .env.example, DockerfileEvery project must have a documented, automated path from fresh clone to running application. Choose the approach that best fits the project's complexity:
| Approach | When to use | Example tooling |
| -------- | ----------- | --------------- |
| Devcontainers | Multi-service projects, complex dependencies, team standardisation | VS Code devcontainers, GitHub Codespaces |
| Docker Compose | Projects with external service dependencies (databases, caches, queues) | docker-compose.yml with app + services |
| Language version managers | Single-language projects with minimal external deps | nvm, pyenv, rbenv, asdf, mise, rustup |
| Nix / Nix flakes | Maximum reproducibility across OS and architecture | flake.nix, shell.nix |
| Vagrant | Projects requiring a full VM (OS-level dependencies, kernel modules) | Vagrantfile |
.node-version, .python-version, .tool-versions, rust-toolchain.toml, or equivalent. Never rely on "whatever is installed on the developer's machine."make setup, ./scripts/setup.sh, docker compose up) should install all dependencies, seed databases, and start services.Environment variables are the correct mechanism for injecting environment-specific configuration. The .env file pattern provides a convenient local interface to this mechanism.
| File | Purpose | Committed to git? |
| ---- | ------- | ------------------ |
| .env.example | Template listing all required env vars with descriptions, no real values | Yes |
| .env | Developer's local values, populated from .env.example | No — must be in .gitignore |
| .env.test | Values for test runs, if distinct from development | Depends on whether values are sensitive |
| .env.production | Never exists locally — production config comes from the deployment platform | N/A |
# Database
DATABASE_URL= # PostgreSQL connection string (e.g., postgres://user:pass@localhost:5432/mydb)
DATABASE_POOL_SIZE=10 # Connection pool size (default: 10)
# External services
STRIPE_API_KEY= # Stripe secret key (starts with sk_test_ or sk_live_)
REDIS_URL= # Redis connection string (e.g., redis://localhost:6379)
# Application
LOG_LEVEL=debug # error | warn | debug
PORT=3000 # HTTP server port
.env.example — no undocumented environment variables.env.example, not in .env, not anywhere in the repositoryDifferences between development and production environments cause defects that only appear after deployment. Minimise divergence:
| Dimension | Parity approach | | --------- | --------------- | | Language version | Pin the same version in dev (version manager), CI (workflow config), and production (Dockerfile / runtime config) | | Dependency versions | Use lock files everywhere — same resolved versions in dev, CI, and production | | Database engine | Use the same engine and major version locally (via Docker) as in production. Never substitute SQLite for PostgreSQL in dev. | | External services | Run real service instances locally via Docker Compose where feasible. Use emulators (LocalStack, Azurite) when the real service is not available locally. Mock only as a last resort. | | OS and architecture | Devcontainers or Docker minimise OS differences. Be aware of ARM vs x86 differences when developing on Apple Silicon targeting x86 production. |
Configuration that varies between environments must be supplied through environment variables or a configuration service — never through code branches.
// BAD: Code branch per environment
if (process.env.NODE_ENV === "production") {
db = connectTo("prod-db.internal:5432");
} else if (process.env.NODE_ENV === "staging") {
db = connectTo("staging-db.internal:5432");
} else {
db = connectTo("localhost:5432");
}
// GOOD: Single code path, configuration injected
db = connectTo(process.env.DATABASE_URL);
if (env === "production") is a code smell. The behaviour should be controlled by a feature flag or configuration value, not an environment name.For projects with external dependencies (databases, caches, message queues, search engines), container-based development ensures every developer runs identical service versions.
docker-compose.ymlpostgres:16.2, not postgres:latest127.0.0.1:5432:5432) to avoid conflicts and security exposuremake up or docker compose up command that starts everything.devcontainer/devcontainer.jsonpostCreateCommand or postStartCommand to run setup steps automaticallyEvery project must have setup instructions that a new developer can follow without tribal knowledge.
| Section | Contents | | ------- | -------- | | Prerequisites | Required tools and versions (Docker, language runtime, etc.) with install instructions or links | | Setup steps | Numbered, copy-pasteable commands from clone to running application | | Verification | How to confirm the setup worked (e.g., "visit http://localhost:3000 and see the login page") | | Common issues | Known setup problems and their solutions | | Seed data | How to populate the local database with test data |
make setup target.This skill covers local and development environments — the developer's machine, CI runners, and local service dependencies.
The mav-bp-infrastructure-as-code skill covers deployed environments — cloud resources, servers, networking, and production infrastructure.
The boundary:
When both skills apply (e.g., a Docker Compose file used in both local dev and CI), follow the conventions from both.
| Pattern | Issue | Fix |
| ------- | ----- | --- |
| Hard-coded URLs, ports, or credentials in source code | Environment coupling | Extract to environment variables |
| if (env === "production") logic scattered in code | Environment branching | Use configuration values, not environment names |
| No .env.example but application reads env vars | Undocumented configuration | Create .env.example with all required vars |
| .env file committed to repository | Credential exposure risk | Add to .gitignore, remove from history |
| No version pinning for language runtime | Non-reproducible builds | Add .node-version, .python-version, or equivalent |
| docker-compose.yml using latest tags | Non-deterministic services | Pin to specific image versions |
| Setup instructions that require asking a team member | Tribal knowledge dependency | Document all steps in README or CONTRIBUTING.md |
| Database engine differs between dev and production | Environment parity violation | Use the same engine locally via Docker |
| No health checks in Docker Compose services | Startup race conditions | Add health checks and depends_on with condition |
development
--- name: do-test description: Write or update tests for a code change. Operates in two modes: `unit` (module-scoped, fast, deterministic) and `integration` (crosses module / service / database boundaries). Intended to be invoked once per testable change from inside a do-issue-* or do-epic phase. Mode is required. argument-hint: mode: unit or integration user-invocable: true disable-model-invocation: false --- **Depends on:** mav-bp-unit-testing, mav-bp-integration-testing, mav-local-verificati
development
Implement a focused code change. Use this skill as the wrapper for any implementation work so the Maverick workflow report captures what was done and so the agent applies the project's coding standards before editing. Intended to be invoked once per task from inside a do-issue-* or do-epic phase, not standalone.
testing
How to stack a PR on top of an unmerged sibling branch, and how to retarget it to the repo's default branch once the sibling merges. Prevents orphan-merge incidents when a dependent story is ready before its parent.
development
Claim, lease, heartbeat, and release protocols for when multiple Claude Code instances may act on the same issue or epic concurrently. GitHub labels and marker comments are the coordination surface; local state is a cache.