Skip to main content
← /writing
  • #agentic-sdlc
  • #spec-driven-development
  • #engineering-leadership

Two Gates and a Night Shift

My personal delivery pipeline runs on three Claude agents, three nested loops, and two explicit human approval gates. The gates sit where judgment is cheapest and most consequential, and the real bottleneck moved upstream to the clarity of the ask.

Vinny Carpenter12 min read2.3k words

Two explicit approval gates. That is my entire footprint in my personal delivery pipeline now. I approve the plan before any meaningful code exists, and I approve the release after I have tested the running preview. Both approvals arrive on my phone. Everything in between belongs to Claude agents and a CI pipeline that treats my laptop as an untrusted actor, which is exactly how I want it treated.

This essay documents how the pipeline works, why the two gates sit where they do, and what running it has taught me about where engineering judgment actually lives. Fair warning: the interesting part is not the automation. The interesting part is what the automation exposed.

The pipeline, end to end

Every change starts as a GitHub issue created from a template that mirrors the agents' planning spec. The template requires acceptance criteria, constraints, out-of-scope notes, rollback considerations, and a risk label: docs, chore, feature, or risky. The issue is the contract, and the template keeps me honest about writing it like a spec rather than a sticky note. A vague issue produces a plausible plan for the wrong problem, so the template raises the floor before an agent ever sees the work.

A Claude agent runs on my local machine and scans the repository for open issues. When it finds one, it claims the issue and produces an implementation plan against a standard spec. Plan depth follows the risk label. A docs change or dependency bump gets a lightweight plan that is auto-approved and logged for later audit. A feature or risky change gets the full treatment: approach, files touched, test strategy, and open questions. Then the agent stops and waits for me.

Flowchart of the plan and build phase. A templated GitHub issue with a risk label flows to the builder agent, which drafts a risk-scaled plan. Feature work waits at gate 1 for plan approval via Roci, low-risk changes take a dashed fast lane past the gate, and approved work builds to coding standards.

That pause is the first gate, and it travels with me. Roci, my Telegram-connected agent, pushes the plan summary to my phone, and I approve, revise, or reject from wherever I am. Approval latency used to be the pipeline's largest hidden cost. An agent that plans in minutes and then waits hours for a human at a desk is not automated in any way that matters. Now the queue moves at the speed of a glance.

On approval, the agent builds the change under my versioned coding standards, which set test coverage thresholds, style rules, and documentation requirements. The standards define done, not the agent's confidence in its own work.

When the build meets the standards, the agent commits, pushes to origin, and opens a pull request. CI deploys the branch to an ephemeral preview environment that lives as long as the PR does. Nothing lands on main directly. A separate reviewer agent then evaluates the pull request alongside CI, and if either finds issues, the work goes back to the builder for fixes.

When CI is green and the review is clean, the PR moves to release-ready. It does not merge itself. Roci sends me the preview link, the review summary, and the rollback command. I test the running software, approve the release from my phone, and only then does CI merge and deploy to production.

Flowchart of the review and ship phase. A pull request deploys a preview environment, a reviewer agent checks the code alongside CI, clean work becomes release-ready, gate 2 approves the deploy after testing the preview, production ships with a pre-staged rollback, and a verify-and-measure step feeds telemetry and audits back into the standards.

That notification is the second gate, and it is not a rubber stamp on a green checkmark. No rollback path means no approval. Once I approve, CI merges, deploys to production, then runs smoke tests and health checks against the live release. The pipeline proves the deploy worked instead of assuming it did.

One honesty note before I go further. The gates, the agents, and the night shift below have been running for a while. The risk tiers, preview environments, and telemetry are this month's additions, and the numbers they produce will get their own essay once they have something to say.

Two gates, one pipeline, two human decisions. The gate count is complete, but the cast is not. There is a third agent, and it works nights.

The night shift

Pull requests fail for boring reasons: formatting drift, a lint error, a stale lockfile, a merge conflict with main. Left alone, those failures pile up and steal attention from real work. So at 8 p.m. every night, a scheduled Claude Code routine clocks in and triages them, unattended, with no human approving its steps.

The routine scans open pull requests, reproduces each failing check, and sorts it into one of three buckets. Safe classes get repaired on a fresh claude/ branch, verified locally, and submitted as a fix PR targeting the failing branch. Anything requiring judgment about intent gets a needs-human label and a written reason instead of a guess. Everything else gets skipped and logged. I review the escalation queue with my morning coffee, which is the correct pairing.

Flowchart of the nightly maintenance loop. A scheduled Claude Code run checks a soft-stop label, triages failing checks on open pull requests, and routes each into a fix PR on a claude branch, a needs-human escalation, or a skip. Every run ends with a triage report, and fix PRs re-enter the standard review.

The constraints define the role more than the goal does. The routine never merges, never force-pushes, never touches a branch it did not create, and never edits CI, deploy, or security configuration. A failing security scan gets escalated, never patched around. It opens at most three fix PRs per run. Its fixes re-enter the same review the daytime work does, so nothing the night shift produces can reach main on its own.

Two details in the routine do outsized work. Before acting, it reads a designated triage issue, and a triage:paused label makes it post one line and exit. That gives me a kill switch that requires no code change and no SSH session. After acting, it posts a triage report comparing what it did against its written goal and flags any anomaly itself. An unattended agent that files its own incident report is an agent I can leave alone at night.

Why the gates sit where they do

The placement is not arbitrary. It follows the cost curve of catching a mistake.

A bad plan caught at gate one costs minutes. The same bad plan caught after implementation costs hours of agent work, a review cycle, and the awkward realization that the tests faithfully verify the wrong behavior. Plan review is the cheapest quality control in the entire pipeline, so meaningful changes get a mandatory human stop there, and the risk tiers protect that stop from drowning in dependency bumps. A gate that fires on everything eventually gets swiped through on autopilot, and a gate on autopilot is not a gate.

Gate two works differently. By the time a change reaches production approval, the pipeline has already proven most of what I need to know. I approved the plan, the standards held, an independent reviewer signed off, and CI passed. The preview environment upgrades my final check from trust to evidence, because I approve software I watched run, not a diff I skimmed. I will happily delegate typing. I will not delegate accountability.

Everything between the gates is automated, and everything at the gates is judgment. That single sentence is the whole design.

Separation of duties, but for agents

The control I care most about is one I borrowed from decades of enterprise thinking: the agent that writes the code never approves the code.

For a solo developer, separation of duties cannot mean separate people. It has to mean separate powers. The builder cannot merge its own work. The reviewer cannot deploy. The night shift can do neither, and it cannot even push to a branch it did not create. Roci routes my approvals but can never grant one. CI cannot ship without my sign-off, and I cannot bypass the pipeline, because main and production are only reachable through it. Each actor in the system holds exactly one kind of power, which means no single failure, human or agent, can push a change from idea to production alone.

This is the same pipeline-first principle I push at work, applied to a fleet of personal projects. The scale is smaller and the stakes are lower, but the discipline is identical. If anything, personal projects need the discipline more, because nobody is watching and the temptation to hot-fix at 11 p.m. is real. I have met that temptation. The pipeline wins the argument every time now, mostly because I removed my ability to lose it.

The standards are the interface

The quiet workhorse of the pipeline is the coding standards document. It is versioned, it is explicit, and it is the actual interface between my judgment and the agents' execution.

When an agent makes a category of mistake, I do not fix the code and move on. I fix the standards, and every future build inherits the correction. Each failure gets paid down once instead of rediscovered forever. Over dozens of revisions, the document has accumulated coverage thresholds, a deviations ledger, and rules born from specific mistakes I never want to review twice.

The telemetry keeps this loop honest. Every run records cycle time from issue to production, plan revision rate, review findings per PR, and tokens per merged PR. The metrics tell me where the pipeline drags, and audit findings flow back into the standards the same way mistakes do. The point is not to admire the dashboard. The point is to find the next weak gate before it becomes the next escaped defect.

This changed how I think about my own output. My durable artifacts are no longer the code the agents produce. They are the issues, the spec, and the standards. The code is downstream of all three, and its quality is a lagging indicator of theirs.

The skeptic's objection

The fair pushback goes like this: agents wrote the code, an agent from the same model family reviewed it, an agent patched the failures overnight, and the human approved from a phone. Is this a delivery pipeline or a rubber stamp with extra steps? I made the general argument in Trust the Gate, Not the Actor, and this essay is what that principle looks like as running machinery.

I have two honest answers. First, what I review changed rather than disappeared. I no longer read every diff, but I read every meaningful plan, and a plan review catches the errors that matter most: wrong problem, wrong approach, missing edge case, unstated assumption. Diffs hide those errors well. Plans expose them. And gate two now includes hands-on time with the running artifact, which catches the category of problem no diff review ever could.

Second, the shared-blind-spot risk is real, and I do not pretend otherwise. The builder, the reviewer, and the night shift share a model family, so a mistake one makes can be a mistake the others miss. My defense is a standing audit. I spot-check roughly one in ten merged pull requests by hand, including the fast-lane merges and the night shift's fixes. A "chore" that touches auth is not a chore.

The audit has teeth. Each agent keeps its privileges only while my spot checks stay clean. If audits start surfacing defects the reviewer missed at any meaningful rate, its release-ready call stops counting and human code review returns. The pipeline earns its autonomy continuously, and it can lose it the same way.

What the pipeline exposed

I built this to move faster, and it does. But the speed is not the lesson.

The first surprise is structural. The pipeline turned out not to be a line at all. It is three nested loops running at different cadences. The delivery loop moves an issue to production and runs per change. The maintenance loop runs nightly and keeps the delivery loop unclogged, clearing mechanical failures before they cost me attention. The learning loop runs continuously, feeding telemetry, audit findings, and every escalated mistake back into the standards. Each loop protects the ones it wraps, and the standards sit at the center of all three.

The second surprise is personal. Once agents handled planning, building, reviewing, triaging, and verifying, my throughput stopped depending on how fast I could type and started depending entirely on how clearly I could ask. A crisp issue flows through the pipeline in one pass. A fuzzy issue generates a plan revision, a rebuild, and sometimes a quiet conversation with myself about what I actually wanted. The agents did not remove the hard work. They relocated it upstream, to the part that was always hardest.

The bottleneck was never the stack. It was the clarity of the ask.

That is the operating-model story hiding inside a tooling story. The pipeline is three agents and some YAML, and any developer could assemble a version of it in a weekend. The advantage does not come from the assembly. It comes from writing issues like specs, maintaining standards like a product, and knowing which two decisions should never leave human hands.

// found this useful? share it

Post on X Share to LinkedIn
Vinny Carpenter

Written by Vinny Carpenter

VP Engineering · 30+ years building software

I lead engineering teams building cloud-native platforms at a Fortune 100 company. I write about engineering leadership, AI-assisted development, platform strategy, and the hard lessons that come from shipping at scale.

keep reading