Gapless

Environments and CI/CD

The environments an AI assistant needs, what data and models each one uses, and the pipeline stages that take a change from pull request to production.

Environments let you test changes before users see them. For an AI system, an environment is not just code and infrastructure: it is also data (the index), model access, and configuration. A staging environment with an empty index tells you nothing about retrieval quality.

Environments

EnvironmentPurposeDataModelsWho uses it
LocalDevelopmentSmall fixture corpus, seeded test users and ACLsReal APIs with a dev key, or a mock model for offline workDevelopers
Preview (per pull request)Review a change running end to endFixture corpusReal APIs, dev keyReviewers
StagingPre-production validationRealistic synthetic or approved test corpus, with permission fixtures and canary documentsSame model routes as productionQA, AI team, automated checks
ProductionReal usersReal dataProduction routes and keysUsers
EvalRunning evaluations at scaleEval datasets and their indexesProduction routes, separate keys and quotaCI, AI team

Data in non-production environments

Do not copy production data into staging or development. Production conversations and indexes contain confidential data, and lower environments have weaker access controls.

Instead:

  • Build a synthetic corpus that resembles your real documents: similar formats, lengths, tables, languages, and permission structures.
  • Include permission fixtures: test users and groups with known access, and canary strings in restricted documents. See Access control.
  • For tenants who want to test with their own data, offer a sandbox tenant in production, inside production's controls, rather than moving their data into staging.

Model access per environment

  • Separate API keys or projects per environment, so a runaway test cannot exhaust production quota, and costs are attributable.
  • Lower quotas in non-production environments.
  • A mock model for unit tests and local offline work: returns canned responses, tool calls, and streams with configurable delays. Fast, free, and deterministic.

Pipeline stages

StageChecksBlocks merge or deploy?
Lint, format, type checkCode style and typesYes
Unit testsLogic, with the mock modelYes
Integration testsServices with real database, index, and mock modelYes
Prompt rendering testsTemplates render, variables filled, within token budgetYes
Security scansDependencies, secrets in code, container images, infrastructure configYes, for high and critical
Eval gatesSelected eval sets against thresholds. See CI gatesYes
Permission testsCanary-based access testsYes
Build and sign imagesReproducible builds, signed artifactsYes
Staging deploy and smoke testsDeploy, then end-to-end checks and the smoke eval set against stagingYes
Production deployRolling or blue-green deployAutomatic or approved
Post-deploy verificationSmoke set against production, error rate and TTFT watchTriggers rollback

Pull request checks versus main branch checks

Fast checks run on every pull request. Slower and more expensive checks run when they are relevant, and nightly on main. Do not make every pull request wait 40 minutes for the full eval suite when it only changed a button.

Deploy strategy

  • Rolling deploys for stateless services, with readiness checks that include connectivity to the database, index, and model gateway.
  • Graceful shutdown matters more than usual: chat streams last tens of seconds. When an instance is draining, stop accepting new streams and let active ones finish, with a drain timeout longer than your longest expected answer, such as 2 to 3 minutes.
  • Database migrations run as a separate, backward-compatible step before the code that needs them. Old and new code must both work during a rolling deploy.
  • Workers drain their current job before stopping, or rely on idempotent retries.

Configuration management

Runtime configuration, including model routes, prompt versions per environment, guardrail settings, feature flags, and kill switches, is:

  • Stored in git as the source of truth, reviewed in pull requests.
  • Delivered to running services through a config service or feature flag system, so changes apply without redeploying.
  • Validated before applying: unknown model names, missing prompt versions, or out-of-region providers are rejected.
  • Audited: every change records who, when, and the pull request.

Emergency changes (opening a circuit breaker, flipping a kill switch) can be made directly by on-call, and are reconciled into git afterward.

Secrets per environment

  • Each environment has its own secrets in the secret manager. No shared provider keys between staging and production.
  • CI uses short-lived credentials from workload identity federation where possible, not long-lived keys stored in the CI system.
  • Preview environments get minimal secrets, scoped to fixture data.

Checklist

  • Staging has a realistic synthetic corpus with permission fixtures and canary documents.
  • Production data is never copied into lower environments.
  • Each environment has separate model API keys and quotas.
  • A mock model supports fast, deterministic unit and integration tests.
  • The pipeline includes prompt rendering tests, eval gates, and permission tests.
  • Deploys drain long-lived streams gracefully.
  • Runtime config is in git, validated, delivered without redeploys, and audited.
  • CI uses short-lived credentials.

On this page