Skip to content

Workflow transformation for AI coding agents is the redesign of a team’s ticket-to-merge loop so that agents draft the plan, the code and the tests, while people own intent, acceptance criteria and risk decisions. Each stage ends in a gate: an approved plan, acceptance tests written before the code, an evidence bundle, and a review sized to the risk.

Your team has Claude Code, Codex and Cursor seats, and everyone uses them. Yet the ticket still waits two days for someone to pick it up, the pull request still waits two days for review, and nobody can name one step the agents removed. The tools sped up typing, and typing was never the constraint. This guide is for the tech lead who has to change the loop itself, not the editor.

Before you start, make sure the repository is agent-ready: see the project conversion playbook.

  • An audit prompt that reads your last 30 merged pull requests and shows where the time actually goes.
  • A stage map that says, for each stage, what the agent drafts, what a person decides, and what evidence closes the gate.
  • The plan-gate and implementation commands for Claude Code, Codex and Cursor, plus a Claude Code hook that sends the agent back when tests are red.
  • Two CI review jobs (Claude Code and Codex) with least-privilege permissions, and a risk-lane table that says which pull requests a human still reads line by line.
  • A two-week pilot with four measures and an expand, hold or roll back rule.

Where does your team’s delivery time go today?

Section titled “Where does your team’s delivery time go today?”

Do not rebuild everything at once. Pick the loop that costs the most, usually feature delivery from ticket to merged pull request, and measure it before you change it: the bottleneck is rarely where people guess. Run the prompt below in any of the three tools from the repository root, with the GitHub CLI (gh) signed in.

If your team already has the GitHub MCP server configured, it can replace gh for this audit and for the review steps later on. The server works in all three tools; for example claude mcp add --scope project --transport http github https://api.githubcopilot.com/mcp/ -H 'Authorization: Bearer ${GITHUB_PAT}' in Claude Code or codex mcp add github --url https://api.githubcopilot.com/mcp/ --bearer-token-env-var GITHUB_PAT in Codex (flags checked against Claude Code 2.1.283 and Codex CLI 0.157.1). --scope project writes the entry to .mcp.json, where Claude Code expands ${GITHUB_PAT}, so the team shares the config without committing the token. Keep the prompt the same and ask for the equivalent MCP tools instead of the gh commands.

Read the output critically: the agent estimates stage boundaries from timestamps, so treat the numbers as a ranking, not a measurement. If your audit looks like most, waiting time (for clarification and review) is larger than writing time, so the redesign has to cover the stages around the code, not only the code.

Which decisions stay with people and which work moves to the agent?

Section titled “Which decisions stay with people and which work moves to the agent?”

The rebuilt loop keeps six stages. What changes is who produces each artifact and what closes each gate. The rule behind the table: a person decides anything that is expensive to get wrong or hard to reverse, and the agent drafts everything that a test, a type check or a reviewer can check afterwards.

StageThe agent draftsA person decidesEvidence that closes the gate
IntentQuestions about ambiguity in the ticketWhat the change is for, and what is out of scopeTicket with acceptance criteria the author signs
AcceptanceGiven/When/Then scenarios and failing testsWhether the tests encode the requirementFailing tests committed before any production code
PlanFiles to touch, approach, test list, open questionsApproach, trade-offs, answers to the open questionsPlan approved in the session or in the ticket
ImplementCode, and more tests where the plan asks for themNothing, unless the agent stops on an open questionDiff scoped to the approved plan
VerifyFixes until the suite is greenNothing, unless a gate cannot go greenTests, types, lint and build green in CI
ReviewA first review pass in CIApprove, return or escalate, by risk laneEvidence bundle plus the review the lane requires

Two of these rows carry most of the value. The acceptance row moves human judgment to before the code exists, where it is cheap; see executable acceptance criteria for the full technique. The review row stops every pull request from receiving the same line-by-line reading, which is the queue your audit almost certainly found. Google’s DORA team makes the same point about batch size: “AI can easily generate massive blocks of code, which are hard to review and test. Enforcing the discipline of small batches counteracts this risk” (Google Cloud blog, 2025-12-10).

Walk one real ticket through the loop with the team watching before you write any policy. The steps are the same in every tool; the mechanics differ.

  1. Write acceptance criteria as failing tests. Ask the agent to turn the ticket’s criteria into tests, read the tests (not the code), and commit them while they fail. From here on, the tests are the specification the agent must meet, and the agent may not edit them without asking.

  2. Get a plan and approve it. The agent reads the ticket and the tests and proposes files, approach and open questions without writing code. Correcting a plan costs one sentence; correcting a finished implementation costs an afternoon.

  3. Implement against the plan with the gates on. The agent writes the code and runs the suite after each logical step. If it tries to finish while the suite is red, a hook sends it back once to fix it, and CI blocks the merge if it is still red.

  4. Assemble the evidence. The pull request states the acceptance results, the checks that ran, and what changed outside the plan. See the evidence bundle for the full contract and the CI check that enforces it.

  5. Review by risk lane. A CI reviewer does the first pass. A person then reviews what the lane requires, which for most changes is the evidence and the tests, not every line.

Plan and implementation commands in each tool

Section titled “Plan and implementation commands in each tool”

Start on each tool’s default model and raise effort before you switch model; the models hub has the current defaults and prices.

Plan interactively with plan mode (/plan, or Shift+Tab to cycle modes), or headless for a scripted pipeline. In a terminal:

Terminal window
# Stage 2: plan only; plan mode cannot edit files
claude -p "Read docs/tickets/TICKET-482.md and the failing tests in tests/acceptance/. \
Produce an implementation plan: files, approach, extra tests, open questions. No code." \
--permission-mode plan
# Stage 3: implement the approved plan; claude -p starts in Manual mode
# (auto mode on third-party providers or with telemetry off, v2.1.285+),
# so allow exactly the commands the loop needs
claude -p "Implement the approved plan in docs/plans/TICKET-482.md. Run npm test after \
each logical step and fix failures before continuing. Do not edit tests/acceptance/." \
--permission-mode acceptEdits \
--allowedTools "Bash(npm test:*),Bash(npm run lint:*),Bash(npm run typecheck:*)"

Make the “do not finish red” rule mechanical with a Stop hook. Exit code 2 from a Stop hook prevents Claude from stopping and shows your message to it. Save this as .claude/hooks/tests-green.sh and make it executable (it needs jq on the PATH):

#!/usr/bin/env bash
# Stop hook: send Claude back once if the suite is red.
input=$(cat)
# CI jobs (such as the review job below) have their own gates; skip there.
[ -n "$GITHUB_ACTIONS" ] && exit 0
# Plan-mode sessions write no code, and the acceptance tests are red by design.
[ "$(printf '%s' "$input" | jq -r '.permission_mode // ""')" = "plan" ] && exit 0
# stop_hook_active is true when this hook already forced a continuation;
# let the session end then, and rely on CI to block the merge.
if [ "$(printf '%s' "$input" | jq -r '.stop_hook_active // false')" = "true" ]; then
exit 0
fi
# Nothing changed since the last commit; skip.
[ -z "$(git status --porcelain)" ] && exit 0
log=$(mktemp)
trap 'rm -f "$log"' EXIT
if ! npm test --silent > "$log" 2>&1; then
echo "Tests are failing. Fix them before you finish. Last lines:" >&2
tail -n 40 "$log" >&2
exit 2
fi

The git status --porcelain guard means a question asked after a commit does not rerun the suite. If your full suite is slow, point the hook at the unit tests only and leave the rest to CI. Register it in .claude/settings.json, which is committed, so the whole team gets it:

{
"hooks": {
"Stop": [
{ "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/tests-green.sh" } ] }
]
}
}

The first two guards (the GITHUB_ACTIONS check and the plan-mode check) keep the hook out of sessions where red is correct. Plan mode (step 2) writes no code, and the CI review job has no installed dependencies to test with, so the two guards make the hook exit early in both. In step 1 the committed acceptance tests are red by design, so either run the test-writing session without the hook (a personal session, or --setting-sources user) or point the hook at the suite without the acceptance tests, for example npm test -- --exclude 'tests/acceptance/**' with Vitest, whose --exclude takes a file glob (quoted so the shell leaves it alone) rather than a bare directory name.

A Stop hook fits better than a PostToolUse hook on every edit: a full suite after each file edit is slow, and it cannot undo an edit that has already run. Claude Code hooks covers fixture tests for hooks like this one.

How do you verify the output without reading every line?

Section titled “How do you verify the output without reading every line?”

Line-by-line reading does not scale when agents open most pull requests, and the review queue becomes the new bottleneck. Replace it with layered evidence, where each layer catches a different class of defect:

  1. Acceptance tests written before the code prove the behaviour the ticket asked for. Lock them: a change to tests/acceptance/ in the same pull request as the implementation needs a separate approval. See protecting the oracle.
  2. Mechanical gates (tests, types, lint, build) run in CI on every push, and a red gate blocks the merge.
  3. A CI reviewer sweeps for unhandled errors, missing edge cases and security smells, so a person does not have to.
  4. A person reviews by risk lane, using the table below.

Both jobs below trigger on pull_request, so on pull requests from forks the secret is empty and the job fails rather than exposing it; review fork pull requests by hand or with a maintainer-triggered workflow that checks out the fork read-only. Do not switch them to pull_request_target to get secrets onto forked code. On pull requests from branches in your own repository the key is present, and the job runs that branch’s workflow file, its .claude/settings.json hooks, .mcp.json and AGENTS.md. So put /.github/, .claude/, .codex/, .mcp.json and AGENTS.md under CODEOWNERS with required code-owner review, or a pull request (including one an agent wrote) can change what runs next to the key. The review is advisory evidence, not a merge gate.

Adapted from the automatic review example in anthropics/claude-code-action:

name: AI PR review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 1
persist-credentials: false
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
Review this pull request. Report only unhandled errors, missing edge cases,
security issues, and changes to tests/acceptance/. Skip style.
Use `gh pr comment` for a summary and inline comments for specific lines.
claude_args: |
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"

Which pull requests does a person still read line by line?

Section titled “Which pull requests does a person still read line by line?”

Write the lanes into AGENTS.md and the pull request template once, and let the paths decide. The reviewer signs off on the lane’s evidence; the tech lead owns the lane policy and changes it only on evidence from escaped defects.

LaneTypical pathsHuman review
Evidence onlyUI copy, internal tools, tests, docs, feature-flagged codeRead the evidence bundle and the acceptance tests; approve if green
SampledOrdinary product codeEvidence, plus a line-by-line read of the riskiest file or of every fifth pull request
Full readAuth, payments, data migrations, public API contracts, infrastructureLine-by-line review by a code owner, whatever the evidence says

Moving a loop from full read towards evidence only is a staged change of its own; trust transfer covers shadow review, sampling and the rollback rule.

A worked example: a rate-limited export endpoint

Section titled “A worked example: a rate-limited export endpoint”

Here is the loop on one ticket: add POST /api/exports to an Express service, limited to five requests per user per minute.

  1. Acceptance. The agent writes three failing tests: an export succeeds, an invalid body returns 400, and a sixth request inside a minute returns 429. The reviewer reads the tests and adds one: the limit is per user, not global. The tests are committed red.
  2. Plan. The agent proposes a route in src/routes/exports.ts, a Zod schema, and an in-memory rate limiter. The reviewer rejects the in-memory limiter, because the service runs on several instances, and points to the existing Redis client. Cost: one sentence.
  3. Implement and verify. The agent writes the route, schema and Redis limiter. The 429 test is still red when the agent tries to finish (the middleware returns 503), so the Stop hook sends it back once and it fixes the status code; had it stayed red, CI would have blocked the merge.
  4. Review. The Claude Code CI reviewer flags that the limiter fails closed when Redis is down, so a Redis outage blocks every export. That is a product decision, so the human reviewer escalates it; the product owner chooses fail-open for exports and the choice goes in the pull request. The path is in the sampled lane, so the reviewer reads the limiter file line by line and the rest through the evidence.

A person made every judgment call (per-user limits, Redis over memory, fail-open), and none required reading the generated route handler.

Codify the loop so every engineer runs the same one

Section titled “Codify the loop so every engineer runs the same one”

A workflow that lives in one tech lead’s head runs differently for each engineer, so put it in the repository: the stage rules in AGENTS.md (Claude Code reads CLAUDE.md, and reads AGENTS.md when there is no CLAUDE.md from v2.1.277; Cursor reads AGENTS.md and CLAUDE.md too, and uses Rules), the Stop hook in .claude/settings.json, the evidence checklist in .github/pull_request_template.md, and the lanes in CODEOWNERS plus the template. Shared agent rules covers one core file with thin per-tool adapters.

Review the generated section the way you review code: every command must exist, every path must resolve. A wrong test command in AGENTS.md is worse than none, because every agent session will run it with confidence.

Pilot the new workflow for two weeks, then decide

Section titled “Pilot the new workflow for two weeks, then decide”

Run the loop on one team and one repository for two weeks, with all feature tickets going through it. Compare these four measures against the audit baseline:

MeasureHow to compute itWhat good looks like
Ticket-to-merge lead timeMedian, from ticket “ready” to mergeFalls, mainly through less waiting for review
Review rounds per pull requestChange-request reviews per merged pull requestFalls, because plans are corrected before code
Evidence completenessShare of pull requests whose template sections are all filledNear every pull request by the second week
Escaped defectsBugs traced to pilot pull requests after mergeNot higher than the baseline

Full metric definitions are in metrics frameworks.

Then decide. Expand to the next team when lead time or review rounds fell and escaped defects did not rise. Hold and fix the weakest gate when the numbers are flat. Roll back the lanes to full read when escaped defects rose, and find which gate let the defect through before you try again. The adoption roadmap sequences the next loops, and team adoption rate defines how to measure effective use across the team.

DORA’s 2025 report is a useful warning here: “AI doesn’t fix a team; it amplifies what’s already there” (Google Cloud blog, 2025-09-23). A pilot on a team with flaky tests and unclear tickets will amplify those first, so fix the gates before you blame the agents.

When the new delivery workflow breaks down

Section titled “When the new delivery workflow breaks down”