Skip to content

Environments and deployment framework

Four environments serve distinct purposes. Every system domain maintains all four before any code ships to production. No environment is optional and none may be bypassed in the promotion path.

Environment topology

Environment Purpose Deployment trigger Infrastructure
local Developer iteration and rapid feedback Manual — framework emulator (e.g. sam local, serverless offline, LocalStack) Cloud provider emulators; external services mocked or pointed at dev sandboxes
dev Continuous integration baseline Every merge to main Full IaC, scaled to minimum, shared team instance
uat Pre-release verification Release candidate tag on main Full IaC, prod-equivalent config, reduced capacity
prod Live service Release tag + named approval gate Full IaC, production capacity, multi-region

Promotion flow

Code is never rebuilt between environments. The function artefact that passes UAT is the artefact deployed to prod — same content hash, no recompilation.

commit
  → PR → merge to main
  → dev pipeline: lint → unit tests → build artefact (content hash) → integration tests → deploy to dev → smoke tests
  → release candidate tag (vX.Y.Z-rc.N)
  → UAT pipeline: pull artefact → deploy to UAT → UAT/BDD suite → performance tests → security scan → promote artefact
  → release tag (vX.Y.Z) + approval
  → prod pipeline: pull promoted artefact → deploy to prod → smoke tests → live
                                                              ↑ auto-rollback if smoke tests fail within 5 min

Manual deployments to dev, UAT, or prod are prohibited. A failed gate blocks promotion — no bypass without a documented exception approved under DT-007.

Pipeline stages

dev pipeline (trigger: merge to main)

Stage Requirement On failure
Lint & static analysis Zero errors Block
Unit tests ≥ 80% line coverage Block
Build artefact Packaged with content hash; stored in artefact registry Block
Integration tests All API contracts + key error paths pass Block
Deploy to dev IaC apply — idempotent Block
Smoke tests Key function invocations respond correctly Rollback dev deploy

UAT pipeline (trigger: release candidate tag vX.Y.Z-rc.N)

Stage Requirement On failure
Pull artefact Same hash as passed dev Block
Deploy to UAT IaC apply Block
UAT / BDD test suite All acceptance criteria in docs/systems/ pass Block
Performance tests p99 latency within NFR thresholds Block
Security scan No critical dependency CVEs; SAST clean Block
Promote artefact Tag as release candidate in artefact registry

prod pipeline (trigger: release tag vX.Y.Z + approval gate)

Stage Requirement On failure
Approval gate Named approver confirms deployment Block
Pull promoted artefact Same hash as passed UAT Block
Deploy to prod IaC apply Block
Smoke tests Pass within 5 minutes Auto-rollback to previous version

Infrastructure as code

All cloud resources are defined in code. Nothing is created or modified through a cloud console or direct API call outside of IaC. IaC tooling is not mandated here — see ADR-022 for options and selection criteria.

Concern Approach
Cloud infrastructure SST v3 (Ion) with Pulumi as the infrastructure engine — resolved by ADR-025. State in S3 backend with DynamoDB locking.
Serverless configuration Function definitions, event sources, IAM bindings, and concurrency limits defined in IaC — not set manually.
Environment differences Variable overrides or stack parameters per environment applied to a shared IaC definition. No separate IaC codebases per environment.
Secrets Injected at runtime from secrets manager. Never in source code, artefacts, or pipeline logs.
Pipeline-to-cloud auth Short-lived OIDC tokens. No static credentials.
DNS, TLS, networking IaC-managed. No manual console edits.

Testing requirements by module

Each module must ship all of the following before build_status can progress to Built:

Type Scope Blocks
Unit tests Business logic, calculations, state machines dev deploy
Integration tests API contracts, event publishing, data round-trips dev deploy
Contract tests Consumer-driven contracts for inter-service calls dev deploy
UAT / BDD tests Acceptance criteria from module's docs/systems/ page UAT promotion
Performance tests p99 latency for any path with an NFR threshold UAT promotion
Security scans SAST, dependency vulnerability scan UAT promotion
Smoke tests Liveness check, one key function invocation Post-deploy

Test definitions live in the code repository for each system domain, not in this wiki. The wiki documents the acceptance criteria that tests must cover.

Branch and release strategy

Pattern Convention
Development Trunk-based. Short-lived feature branches (≤ 2 days), merge to main frequently.
Feature isolation Feature flags for partial work committed to main. No long-lived feature branches.
Release candidate Tag vX.Y.Z-rc.N on main to trigger UAT pipeline. Multiple RCs expected per release.
Release Tag vX.Y.Z on main after UAT passes. Triggers prod pipeline.
Hotfix Branch from latest release tag. Fast-track through the same pipeline gates — no gates skipped.
Versioning Semantic versioning. MAJOR for breaking API changes, MINOR for new capabilities, PATCH for fixes.

Environment isolation

  • Dev, UAT, and prod run in separate cloud accounts (or equivalent hard-boundary isolation).
  • No cross-environment network paths. UAT cannot call dev services; prod cannot call UAT.
  • Prod data never flows to dev or UAT. Test data is synthetic.
  • Prod access requires just-in-time elevation with full audit trail. No standing access.