CI Scenarios by Team Size
Different team sizes need different CI configurations. A solo developer
does not need the same promotion gates as a 50-person engineering org.
This tutorial shows concrete project-config.yaml excerpts
for four common scenarios, with guidance on which checks to enable,
which branch protections to set up, and what local hooks help.
Prerequisites
Read Configuring CI Pipelines first for an overview of promotion chains, presets, triggers, and concurrency groups. This tutorial builds on those concepts.
Overview
| Scenario | Preset | Environments | Code review | CI time goal |
|---|---|---|---|---|
| Solo | solo |
main only | None | < 3 min |
| Small team | small-team |
staging → prod | 1 approval | < 8 min |
| Standard | standard |
dev → staging → prod | 2 approvals | < 12 min |
| Enterprise | enterprise |
dev → staging → pre-prod → prod | 2 approvals + CODEOWNERS | < 20 min |
Solo developer
Why this setup
You are the only contributor. There is no one to review PRs, and you
deploy directly from main. You want fast feedback on
every push, with no ceremony.
Configuration
# .gaia/config/project-config.yaml
ci_cd:
platform: github-actions
preset: solo
promotion_chain:
- main
triggers:
push_to_main:
checks:
- lint
- unit-tests
- build
Branch protection
None required. You push directly to main. If you want a
safety net, enable "require status checks to pass before merging" but
skip the approval requirement.
Suggested local hooks
Set up a pre-push hook that runs lint and unit tests locally. This catches failures before the push reaches CI, keeping your feedback loop under 30 seconds.
# .husky/pre-push (or equivalent for your stack)
npm run lint
npm test
What to skip
Skip integration tests in CI if they take more than 2 minutes. Run them locally or in a nightly job instead. Skip security scans on every push -- run them weekly.
Small team (2--5 developers)
Why this setup
You have a handful of contributors who need to review each other's work. A single staging environment is enough for pre-production testing. PRs are your integration point.
Configuration
# .gaia/config/project-config.yaml
ci_cd:
platform: github-actions
preset: small-team
promotion_chain:
- staging
- production
concurrency:
group: ci-${{ github.ref }}
cancel_in_progress: true
triggers:
pull_request:
checks:
- lint
- unit-tests
- integration-tests
- security-scan
push_to_staging:
checks:
- smoke-test
push_to_production:
checks:
- smoke-test
- deploy
Branch protection
- Require 1 approval before merging to
staging. - Require status checks (
lint,unit-tests,integration-tests) to pass. - Enable "dismiss stale reviews" so approvals expire when new commits are pushed.
Suggested local hooks
# .husky/pre-commit
npm run lint --fix
# .husky/pre-push
npm test
Lint on commit so formatting issues never reach the PR. Test on push so CI failures are rare.
Key principle: test on PR, smoke on merge
The full test suite runs when the PR is opened or updated. When the
PR is merged to staging, a fast smoke test confirms the
deploy artifact is healthy. This avoids running the full suite twice.
Standard team (5--20 developers)
Why this setup
Multiple developers are landing changes daily. You need a dev environment for integration testing before staging, and stricter review requirements to catch issues before they reach production.
Configuration
# .gaia/config/project-config.yaml
ci_cd:
platform: github-actions
preset: standard
promotion_chain:
- dev
- staging
- production
concurrency:
group: ci-${{ github.ref }}
cancel_in_progress: true
triggers:
pull_request:
checks:
- lint
- unit-tests
- integration-tests
- security-scan
push_to_dev:
checks:
- smoke-test
- deploy-dev
push_to_staging:
checks:
- smoke-test
- deploy-staging
push_to_production:
checks:
- smoke-test
- deploy-production
environments:
dev:
auto_deploy: true
staging:
auto_deploy: true
requires_approval: false
production:
auto_deploy: false
requires_approval: true
Branch protection
- Require 2 approvals before merging to
dev. - Require all status checks to pass.
- Require branches to be up-to-date before merging (linear history).
- Protect
stagingandmainbranches -- merges only via automation or admin.
Suggested local hooks
# .husky/pre-commit
npx lint-staged
# .husky/pre-push
npm test -- --bail
Use lint-staged to lint only changed files on commit.
Use --bail on pre-push to fail fast on the first broken
test.
Test tiering
With a larger team, test suites grow. Split tests into tiers:
- PR tier: unit tests + fast integration tests (< 5 min).
- Merge tier: smoke tests only (< 1 min).
- Nightly tier: full E2E suite, security scans, performance tests.
See Test Strategy Configuration for details on configuring test tiers.
Enterprise (20+ developers)
Why this setup
You have compliance requirements (SOC 2, HIPAA, PCI-DSS), multiple teams contributing to the same codebase, and a pre-production environment for final validation before production rollout.
Configuration
# .gaia/config/project-config.yaml
ci_cd:
platform: github-actions
preset: enterprise
promotion_chain:
- dev
- staging
- pre-prod
- production
concurrency:
group: ci-${{ github.ref }}
cancel_in_progress: true
triggers:
pull_request:
checks:
- lint
- unit-tests
- integration-tests
- security-scan
- license-check
push_to_dev:
checks:
- smoke-test
- deploy-dev
push_to_staging:
checks:
- smoke-test
- deploy-staging
- regression-tests
push_to_pre_prod:
checks:
- smoke-test
- deploy-pre-prod
- performance-tests
- accessibility-tests
push_to_production:
checks:
- deploy-production
- post-deploy-smoke
environments:
dev:
auto_deploy: true
staging:
auto_deploy: true
pre-prod:
auto_deploy: false
requires_approval: true
production:
auto_deploy: false
requires_approval: true
compliance:
regimes:
- soc2
audit_log: true
Branch protection
- Require 2 approvals, with CODEOWNERS rules for critical paths.
- Require all status checks to pass.
- Require signed commits.
- Restrict who can merge to
stagingandmain. - Enable audit logging for all merges.
Promotion gates
The enterprise preset adds explicit gates between environments. The
pre-prod → production promotion requires a manual approval step.
Use
/gaia-deploy-checklist
to generate a pre-deployment verification checklist before approving.
Compliance considerations
Enable the compliance.regimes setting to tell GAIA
which compliance frameworks apply. This affects which checks are
required at each gate and which audit artifacts are generated. Use
/gaia-config-compliance
to configure regimes after initial setup.
Choosing the right scenario
Ask yourself these questions:
- How many people merge code weekly? Solo = 1, small = 2--5, standard = 5--20, enterprise = 20+.
- Do you need pre-production validation? If yes, standard or enterprise.
- Do you have compliance requirements? If yes, enterprise.
- Is CI time a problem? Start with the simplest preset that meets your needs and upgrade later. Overengineering CI is as costly as underengineering it.
You can change presets at any time with
/gaia-ci-edit
and regenerate your workflows with
/gaia-ci-setup --regenerate.
The layered model across team sizes
The four-class prefix contract (gaia-*.yml generated, overlays,
user-*.yml user-owned, no-prefix migration-eligible) and the four-phase
stitching order scale across all team sizes -- but you'll use them differently:
- Solo + small-team -- you'll mostly rely on the
ci_cd.template_overrides:declarative section to disable a job, bump a timeout, or pin an adapter version. Overlay files are reserved for the one or two project-specific jobs you really need (coverage upload, notification, deploy hook). - Standard -- you'll author
gaia-ci.user-jobs.ymlfor the project-specific quality gates your domain demands (PII scanner, accessibility audit, performance budget) plus agaia-ci.user-steps.ymlfor the per-job setup steps shared across runs. - Enterprise -- you'll typically have a separate
user-compliance-audit.yml(entirely user-authored, GAIA never touches) for the compliance team's evidence collection, alongside the GAIA-generatedgaia-pre-merge.ymlfor the standard gates. Thetemplate_overrides.disable:list cannot remove the five security gates (commitlint, attribution-guard, no-claude-attribution, secrets-scan, credential-audit), which is a security feature -- it prevents accidental override at scale.
On a project that predates the layered model, the auto-rename migration flow runs once on the first
/gaia-config-ci --regenerate after upgrade. You'll be prompted per-file:
rename to gaia-{base}.yml + scaffold overlays, rename to
user-{base}.yml, or skip and defer. The flow is backup-first -- a sha256-verified
copy lives at .gaia-backup/ci-regen-{timestamp}/ before any rename.
What to read next
- Configuring CI Pipelines -- the concepts behind these scenarios.
- Environments and Promotion -- deep dive on per-environment configuration.
- Test Strategy Configuration -- how to configure test tiers and execution.
- Project Shapes Overview -- how project structure affects CI configuration.