CI as the Default Shape for Engineering
CI tests on every PR. The norm.
CI is the default shape
CI as the default is the discipline of running every change through automated checks before merge. Without it, code quality drifts and trust in main erodes; with it, the merge gate is the contract rather than the engineer's vigilance.
- Every change through CI. The automated check gate runs on every PR. Local pre-commit hooks help; they do not replace the CI gate that runs against the merge target.
- CI catches predictable issues. Test failures, type errors, lint, security scan findings, and secret leaks surface in CI rather than in production. Standard catches.
- Without CI default, quality drifts. Unchecked-change tax. Trust in main branch erodes once a few "small" changes ship without CI; the next reviewer reasons "they did it, why should I block?".
- Published no-bypass rule. Org-level "no merge without CI" policy. Catches "I will fix it in a follow-up" PRs that, in practice, never get the follow-up.
Standard pipeline shape
The standard pipeline shape is five stages: lint, tests, integration, build, security. The order is cost-ascending and dependency-driven; cheap stages fail fast, expensive ones gate on prior pass.
- Lint and format check. Syntactic gate. Catches the cheap-to-fix mistakes first so reviewers do not spend time on style during code review.
- Unit tests with coverage. Test-suite run plus coverage report. Drives the test-quality conversation when coverage moves and forces explicit thinking when it drops.
- Integration tests. Ephemeral-environment integration run. Catches cross-component failures that unit tests cannot see; expensive to run, so gated on prior pass.
- Build artifact, tag, and security scan. Artifact produced, tagged, and ready for deployment. SCA (Snyk, Dependabot), SAST (CodeQL, Semgrep), and secret scan (Gitleaks) run before the artifact is considered shippable.
CI speed targets
Speed is its own discipline. Lint plus unit under five minutes; full pipeline under fifteen. Above that, devs context-switch and the feedback loop dies; the metric matters because the engineering culture depends on it.
- Lint plus unit under five minutes. Fast-feedback target. Devs stay in flow and react to the failure rather than coming back to it after lunch.
- Full pipeline under fifteen minutes. End-to-end target. Beyond this, context-switch cost dominates and the engineer is not the one reading the failure when it lands.
- Above fifteen minutes the loop dies. Disengagement signal. Devs stop watching the build and start multitasking; the immediate-feedback discipline is gone.
- Per-stage timing dashboard. Published durations per stage of the pipeline. Catches creeping slowdown before it crosses the fifteen-minute line.
Flake handling
Flaky tests destroy CI trust faster than anything. Quarantine fast, track flake rate, do not auto-retry; each retry trains the team to dismiss real failures as flakes.
- Quarantine within 24 hours. Fast-isolation rule. Hidden flakes train devs to ignore failures; the cure is moving them to a non-blocking suite the same day they are identified.
- Track per-test flake rate. Flake-rate metric per test. Above one percent, fix or delete; chronic flakers earn a kill switch.
- Do not auto-retry. No-retry rule. Retries hide flakes from the metric and from the team; the test passes deterministically or gets fixed.
- Team flake budget. Bounded flaky-test count. Catches accumulating debt before the budget itself becomes the conversation rather than the fix.
How to install the discipline
Installation needs three pieces: branch protection, visibility, and parallel PR/main runs. Without all three, the discipline depends on individual conscientiousness and erodes under schedule pressure.
- Branch protection. Require CI pass before merge per repository. No exceptions; an exception once is an exception twice.
- Make pipeline visible. Slack notification on main-branch failure. Surfaces problems fast so the fix happens in minutes rather than the next morning.
- Run on PRs and on main. Dual trigger per pipeline. Catches "works on PR, fails on main" rebase issues that the PR run alone misses.
- Named CI owner. One maintaining team per repository. Catches the "everyone's-and-no-one's" CI hygiene gap that shows up after reorgs.