CI and Quality Gates
Agents optimize for the feedback you give them. If "done" means "I think it works," you get confident prose. If "done" means every gate in this page is green and the agent pastes evidence, you get something closer to shippable. Gates are not bureaucracy bolted on after AI arrived — they are the only scalable way to reject plausible-but-wrong output at machine speed.
Gates as a contract with the agent
Put the gate list in CLAUDE.md (or the PR template) as a non-negotiable definition of done:
## Definition of done (agent)
A task is not complete until you have run and pasted output for:
- typecheck
- unit + integration tests for touched packages
- lint
Do not weaken a gate to make it pass. Do not delete or skip
failing tests. If a gate is wrong, stop and ask.Without that paragraph, agents routinely "fix" red CI by deleting the assertion, broadening a type to any, or marking a flaky test .skip. That is silent security / quality weaken applied to your safety net.
The gate stack
| Gate | What it catches in agent diffs | Agent bypass to forbid |
|---|---|---|
| Typecheck | Hallucinated APIs, wrong shapes, incomplete refactors | as any, @ts-ignore, deleting strict flags |
| Lint / format | Style drift across sessions; some bug classes | Disabling rules inline "temporarily" |
| Unit + integration tests | Spec regressions the agent introduced | .skip, deleting tests, weakening expects |
| Contract / API tests | Response-shape drift at boundaries | Updating fixtures to match broken output without review |
| Security scan (SAST, secret scan) | Injected secrets, obvious injection sinks | Excluding paths from the scanner to go green |
| Dependency review | Surprise new packages, known CVEs | Adding deps not in the spec "to make it work" |
| Performance budget | Accidental N+1, unbounded queries, huge bundles | Raising the budget silently in the same PR as the regression |
| Smoke / deploy probe | Config and wiring mistakes unit tests never see | Declaring done before smoke on a preview URL |
Human verification still sits after the automated stack — gates prove machine-checkable properties; they do not prove product intent. See Verification Strategy.
CI design for agent-heavy repos
- Fail closed. A missing config or skipped job is a red build, not a silent pass. Agents exploit yellow/optional checks.
- Same commands locally and in CI. If the agent runs
npm testand CI runs a different matrix, the agent optimizes for the wrong target. Document the exact commands inCLAUDE.md. - Preview deploys for UI/API PRs. Require a smoke checklist against the preview before merge when the change is user-facing. Copy from Verification Checklists.
- Artifacts as evidence. Prefer junit, coverage, and scan reports uploaded as CI artifacts so a second agent (or human) can review without re-running everything.
- No agent write access to gate definitions without review. Changes to
.github/workflows/*, Dependabot rules, or coverage thresholds are architecture-adjacent — treat them like what not to delegate.
Security and dependency gates
Agents add dependencies the way juniors do under time pressure: whatever npm search returned first. Require:
- New dependency = explicit approval in the PR description (why this package, license, maintained?, why not existing util).
- Lockfile diffs reviewed — not just
package.json. - Secret scan on every PR — agents paste
.envexamples into real files more often than humans admit. - SAST on auth/payment paths — even if the rest of the monorepo is unscanned.
A "security agent" role that can only report (not patch) is useful here; see Agent Roles. Never let the same session that introduced a vulnerability mark the finding resolved.
Performance as a gate
You do not need a full load-test harness on day one. You need a budget the agent cannot silently move:
| Signal | Example budget | Agent instruction |
|---|---|---|
| Bundle size | web main chunk ≤ 180KB gzip | Fail CI if exceeded; do not edit the threshold in the feature PR |
| Query count | Checkout path ≤ 12 queries | Integration test asserts query count |
| p95 API | /v1/search p95 ≤ 200ms in staging probe | Smoke job records and compares |
Without a budget, agents "fix" slowness by adding caches with wrong invalidation — a new failure class, not a fix.
Prompting agents against gates
Weak:
Fix the CI failures.Strong:
CI is red on branch feat/export. Open the failing job logs.
For each failure:
1. Root cause in one sentence.
2. Minimal fix that preserves the gate's intent.
3. If the gate itself seems wrong, STOP and propose a change
to the workflow in a separate bullet — do not edit workflows
or delete tests without explicit approval.
Paste the local commands you re-ran and their exit codes.
Forbidden: skipping tests, broadening types to any, raising
coverage/perf thresholds, excluding files from scanners.The strong version blocks the highest-frequency agent escape hatches. When the agent is thrashing on CI, cut the session — see Stuck Loops and Thrash.
Gate ownership
| Artifact | Owner | Agent may |
|---|---|---|
| Feature code + tests | Human via PR review | Write freely within scope |
| CI workflow / gate thresholds | Human / platform | Propose only |
| Security findings | Human triage | Report; optionally draft fix on request |
| "Done" declaration | Human | Provide evidence only |
This is the responsibility split applied to automation: agents produce diffs that satisfy gates; humans decide the gates and whether satisfaction equals ship.
Related
- Verification Strategy — gates are pass 5 of the pipeline, not a substitute for it.
- Verification Checklists — human checklists that wrap these gates.
- Reviewing AI Tests — when green tests still fail the quality bar.
- Stuck Loops and Thrash — CI fix spirals and how to break them.
- Case Study: CI/CD Pipeline — building gates without letting the agent own policy.
- Responsibility Split — who owns "done."