ent merges that exceed the threshold.
Implementation: Create a pre-merge check that analyzes the diff statistics.
// pr-size-gate.ts
// GitHub Action or pre-merge hook to enforce PR size limits
import { context, getOctokit } from "@actions/github";
const MAX_LINES_CHANGED = 200;
const EXEMPT_PATTERNS = [/^vendor\//, /\.lock$/, /package\.json$/];
async function run() {
const octokit = getOctokit(process.env.GITHUB_TOKEN!);
const { owner, repo } = context.repo;
const prNumber = context.issue.number;
const { data: files } = await octokit.rest.pulls.listFiles({
owner,
repo,
pull_number: prNumber,
});
let totalChanges = 0;
const violations: string[] = [];
for (const file of files) {
if (EXEMPT_PATTERNS.some((p) => p.test(file.filename))) continue;
const changes = file.additions + file.deletions;
totalChanges += changes;
if (changes > MAX_LINES_CHANGED) {
violations.push(`${file.filename} (${changes} lines)`);
}
}
if (totalChanges > MAX_LINES_CHANGED) {
core.setFailed(
`PR exceeds size limit. Total changes: ${totalChanges}. ` +
`Limit: ${MAX_LINES_CHANGED}. Split this PR or request exemption.`
);
}
}
Rationale: This enforces atomic changes. Smaller PRs are reviewed faster, merged with fewer conflicts, and easier to rollback. AI tools should be used to generate the code, but developers must manually split the output into multiple PRs before submission.
2. Optimize CI Pipeline Architecture
CI duration acts as a tax on every iteration. A 40-minute pipeline that fails intermittently destroys developer flow. Optimization requires parallelism, impact analysis, and flake quarantine.
Implementation: Configure the CI pipeline to run only relevant tests and parallelize independent jobs.
# .github/workflows/ci-optimized.yml
name: Optimized CI Pipeline
on:
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
jobs:
lint-and-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm run typecheck
test-impacted:
needs: lint-and-typecheck
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Run Impacted Tests
run: |
# Use a tool like nx or custom script to run only tests
# related to changed files
npm run test:shard -- --shard=${{ matrix.shard }}/4
Rationale: paths-ignore prevents unnecessary runs for documentation changes. Sharding distributes test load across runners, reducing wall-clock time. Impact analysis ensures only relevant tests execute, cutting duration from minutes to seconds for small changes.
3. Enforce Review Service Level Agreements (SLAs)
Review latency is often unmeasured. Implement automated monitoring to track time-to-first-review and time-to-merge.
Implementation: A bot that posts reminders when PRs exceed the SLA.
// review-sla-bot.ts
// Monitors open PRs and alerts when SLA is breached
import { schedule } from "node-cron";
import { getOctokit } from "@actions/github";
const SLA_HOURS = 4;
const ALERT_CHANNEL = "#engineering-reviews";
async function checkSLAs() {
const octokit = getOctokit(process.env.GITHUB_TOKEN!);
const { data: prs } = await octokit.rest.pulls.list({
owner: "org",
repo: "repo",
state: "open",
sort: "created",
direction: "asc",
});
const now = new Date();
const breachedPRs = prs.filter((pr) => {
const created = new Date(pr.created_at);
const diffHours = (now.getTime() - created.getTime()) / (1000 * 60 * 60);
return diffHours > SLA_HOURS && !pr.labels.some(l => l.name === 'blocked');
});
if (breachedPRs.length > 0) {
const message = breachedPRs
.map(pr => `β’ ${pr.title} (${pr.html_url}) - Open for ${Math.floor((now.getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60))}h`)
.join("\n");
// Send to Slack/Teams
await notifyChannel(ALERT_CHANNEL, `β οΈ Review SLA Breach:\n${message}`);
}
}
// Run every 30 minutes during business hours
schedule("*/30 9-17 * * 1-5", checkSLAs);
Rationale: Visibility drives behavior. Automated alerts create social pressure to clear the review queue. A 4-hour SLA during business hours is achievable for most teams and significantly reduces cycle time.
4. Strategic AI Integration
Deploy AI tools only where they compress the actual bottleneck.
- Use AI for: Boilerplate generation, test fixture creation, in-editor codebase exploration, and first-pass debugging hypotheses.
- Avoid AI for: Bulk feature generation without splitting, or replacing specification work.
- Workflow: Generate code β Split into atomic units β Submit small PRs β Review β Merge.
Pitfall Guide
-
The "Free Lines" Fallacy
- Explanation: Developers treat AI-generated code as cost-free, leading to massive PRs that overwhelm reviewers.
- Fix: Enforce PR size limits strictly. Train developers to split AI output into multiple commits/PRs.
-
Review Latency Blindness
- Explanation: Teams assume reviews happen quickly but lack data. Latency creeps up unnoticed.
- Fix: Implement SLA monitoring and daily review rituals. Make review capacity a managed resource.
-
CI Flakiness Tolerance
- Explanation: Intermittent failures are accepted as "normal," causing wasted time on retries.
- Fix: Quarantine flaky tests immediately. Investigate root causes. Use retry logic only for known transient infrastructure errors.
-
WIP Accumulation
- Explanation: Developers start new work before existing PRs are merged, increasing context switching and merge conflicts.
- Fix: Implement WIP limits. Enforce a "stop starting, start finishing" policy.
-
Sync-Driven Development
- Explanation: Relying on meetings for decisions that could be async, blocking progress.
- Fix: Default to async communication. Use PR comments and design docs. Reserve meetings for complex alignment only.
-
Spec Neglect
- Explanation: Using AI to generate code without clear requirements, resulting in rework.
- Fix: Mandate a lightweight spec or acceptance criteria before coding begins. AI cannot compensate for ambiguous requirements.
-
Metric Gaming
- Explanation: Optimizing for lines of code or PR count rather than cycle time or value delivery.
- Fix: Track outcome metrics like DORA metrics (Deployment Frequency, Lead Time for Changes). Ignore vanity metrics.
Production Bundle
Action Checklist
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|
| Startup / High Growth | AI + Async + Small PRs | Maximizes iteration speed with minimal overhead. | Low |
| Enterprise / Compliance | Strict Review + CI Gating + AI for Boilerplate | Risk mitigation requires rigorous controls; AI aids efficiency within bounds. | High |
| Legacy Codebase | CI Stabilization + Test Coverage + AI for Exploration | Unstable CI blocks progress; AI helps navigate complexity. | Medium |
| High Churn / Onboarding | AI + Automated Docs + SLA Monitoring | Reduces ramp-up time; SLAs ensure new PRs get attention. | Medium |
| Regulated Industry | Manual Review + Audit Trails + AI for Drafting | Compliance mandates human oversight; AI assists drafting only. | High |
Configuration Template
GitHub Actions: Comprehensive CI & PR Gate
# .github/workflows/velocity-gate.yml
name: Velocity & Quality Gate
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
pr-size-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check PR Size
run: |
# Custom script or action to enforce size limit
# Fails if diff > 200 lines
npm run check:pr-size
ci-optimization:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Environment
run: npm ci
- name: Run Parallel Tests
run: npm run test:parallel
env:
CI_SHARD_COUNT: 4
- name: Upload Coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
review-sla-monitor:
if: github.event.action == 'opened'
runs-on: ubuntu-latest
steps:
- name: Schedule SLA Check
run: |
# Trigger SLA bot to monitor this PR
curl -X POST $SLA_BOT_WEBHOOK \
-d '{"pr_number": ${{ github.event.pull_request.number }}, "repo": "${{ github.repository }}" }'
Quick Start Guide
- Measure Baseline: Run a script to collect average PR size, review latency, and CI duration for the last 30 days.
- Enforce PR Limit: Add the PR size check to your CI pipeline. Set the limit to 200 lines.
- Speed Up CI: Identify the slowest job in your pipeline. Parallelize it or add impact analysis. Aim for <10 minute duration.
- Deploy Review Bot: Install the SLA monitoring bot. Configure alerts for PRs open >4 hours.
- Iterate: Review metrics weekly. Adjust limits and SLAs based on team feedback and data.
By treating engineering velocity as a systems problem rather than a tooling problem, teams can achieve sustainable improvements in cycle time. AI tools are valuable accelerators, but they amplify existing processes. Optimize the queue, enforce discipline, and apply AI strategically to realize genuine velocity gains.