Putting AI Coding Agents on the Night Shift: Four Handoff Points

    An AI coding agent can watch your pull requests overnight, but unattended runs fail for predictable reasons: vague acceptance criteria, no definition of done, duplicate work, and unchecked authority. This article breaks night-shift automation into four handoff points — verification, stopping, waiting, and authority — and shows how to encode each one as a versioned checklist, a verifiable definition of done with forbidden actions and budgets, event-driven triggers with task keys and leases, and a per-action permission matrix with human checkpoints. The payoff does not come from running more agent rounds; it comes from deciding exactly where the human steps back and what the machine must be able to judge on its own.

    1. Ask the Right Question First: What Exactly Are You Handing to the Machine Overnight?

    It is almost the end of the day and a PR still isn’t merged. CI is queued, review comments may not arrive until the middle of the night, and the deployment state isn’t fully stable. The natural impulse is to let your coding agent watch it for one night.

    The danger of that impulse isn’t that it’s too aggressive — it’s that it’s too abbreviated. If all you say is “check the PR every 15 minutes, fix the failing CI, and handle new review comments,” you’ll get one of two outcomes in the morning. Either the mechanical work is quietly cleared away, or the agent has added a pile of commits: tests bypassed, assertions loosened, and failure paths buried inside a well-worded summary — all to make the pipeline go green.

    The difference between those two outcomes has nothing to do with model capability and everything to do with how engineering-grade the handoff instructions are. The vaguer the handoff, the more latitude the agent has, and it will naturally prefer the action that turns the metric green fastest. That is the optimal solution to the objective it was given — which is not necessarily ours.

    So the core argument of this article is: the value of unattended operation does not come from letting the agent run more rounds. It comes from deciding where the human steps back. Every step back requires the system to add a more explicit, machine-decidable boundary.

    2. Overview: Four Handoff Points and the Engineering Question Each One Must Answer

    Map the common agent loop patterns — an inner loop within a single task, a goal as the termination condition, time-based triggering, and autonomous dispatch and convergence — onto the night-shift scenario, and you get exactly four handoff points. They are not a list of commands. They are four engineering questions that must be answered:

    Handoff point The question it must answer Corresponding engineering action Typical incident when missing
    1. Verification How do we know it actually tested anything? Fixed acceptance checklist plus machine-decidable assertions “Looks like it works after the change”
    2. Stopping When is it actually done? Definition of done + forbidden-action list + budget caps Endless commits, or bypassing tests for green
    3. Waiting When should it look again? Polling/event triggers, backoff, idempotency and deduplication Repeated work, concurrent write conflicts, burned quotas
    4. Authority What may it decide on its own? Permission matrix, human checkpoints, audit trail and escalation path Unauthorized merge, weakened protection rules, incident nobody knows about

    Each one is expanded below.

    3. Handoff Point 1: Hand Over “Verification” — Turn Ad-Hoc Acceptance Into an Executable Checklist

    3.1 Ad-hoc checks vs. codified checks

    The moment people hear “automatic loop,” their first instinct is “just let it keep working on its own.” That is usually too fast a step. When a PR is still open, the easiest and most valuable thing to hand over first is the set of checks a human normally performs by hand.

    Take a frontend change as an example. A passing unit test suite usually isn’t enough. We also open the page, click a button, watch whether the state changes, capture a screenshot as evidence, scan the console for errors, and confirm that first-screen time and bundle size haven’t regressed noticeably. These actions are ordinary, yet they decide whether the agent ends up “actually verified it” or “changed it and it looks usable.”

    The problem is that once this kind of check is handed over verbally in natural language, it is ad hoc: the model reads the code, edits the code, runs one check, and then decides on its own whether to continue. Its judgment tends to rest on the signal being optimized (tests pass, type checks pass) rather than on the few things we actually care about.

    The more reliable first step is to write the checks down — into the repository.

    3.2 Concrete form: an acceptance checklist file committed to the repo

    Most coding agent tools support using in-repo specification files as context. This article refers to them collectively as the “acceptance checklist.” What matters isn’t where the file lives but three properties: versioned, executable by tooling, and producing machine-readable conclusions.

    1. # PR Acceptance Checklist (unattended mode: every item must be executed)
    2. ## 1. Static and logic layer (command + exit-code evidence required)
    3. - Type check / Lint: record the command and its exit code
    4. - Unit tests: record total cases, passed, skipped
    5. - Coverage: must not fall below baseline (baseline is read from ci/baseline.json; manual edits forbidden)
    6. ## 2. UI and interaction layer (smoke scenarios, evidence required)
    7. - Scenario A: main flow click-through -> assert key DOM text / state fields
    8. - Scenario B: error branches (API 500, empty data, timeout) -> assert a visible error message and no blank page
    9. - Output per scenario: screenshot path + number of console errors (must be 0)
    10. ## 3. Non-functional layer (thresholds come from config files, no on-the-fly adjustment)
    11. - Upper limits for time-to-interactive on first screen, JS bundle size, P95 of key endpoints
    12. - No new accessibility violations
    13. ## 4. Evidence requirement (missing any one item means incomplete)
    14. - Every conclusion is accompanied by the path to its raw output file
    15. - Conclusions must be PASS / FAIL / BLOCKED — "mostly passing" is not allowed

    Two details in the checklist make the biggest difference. First, move the thresholds into a config file, so “acceptable” is defined by data rather than by the model’s in-the-moment feeling. Second, introduce a BLOCKED state. With only pass/fail available, a model facing an environment it cannot obtain will tend to force a pass. With BLOCKED available, it must stop and report “the environment isn’t available” — which is exactly what we want.

    3.3 Layer the checks: the lower the layer, the more it should be machine-decided

    • Fully machine-decidable layer: types, lint, unit tests, API contracts. This is where handing work to the agent yields the highest benefit and the lowest risk, so it should be handed over first.
    • Semi-automatic layer: UI smoke tests, console errors, screenshot evidence. These require a runnable local or preview environment. If you don’t have one, don’t force it — otherwise the model will pass off “reading the code and inferring” as “running the verification.”
    • Non-functional layer: performance and size regressions. Without baseline numbers, this amounts to no check at all.

    4. Handoff Point 2: Define “Done” — Definition of Done, Forbidden Actions, and Budget

    4.1 Replace “fix the CI” with a verifiable definition of done

    “Fix the failing CI” is not a definition of done; it is a wish. A verifiable definition of done needs at least three kinds of evidence:

    1. Functional evidence: the relevant cases pass, and new changes are covered by targeted new cases — not just a rerun of the existing suite.
    2. Regression evidence: the full check suite for every touched module passes, and baseline metrics have not regressed.
    3. Rollback evidence: changes are confined to an identifiable scope, and it is possible to state clearly “if something goes wrong, revert these commits / this feature flag.”

    Written as a template, it looks roughly like this:

    1. # Definition of Done (DoD) and Forbidden Actions
    2. The task may be marked complete only if all of the following hold:
    3. - [ ] All layers 1–4 of the acceptance checklist are PASS, with BLOCKED items reported separately
    4. - [ ] Each commit explains: what changed, why, and how it was verified
    5. - [ ] A diff summary and a file-level change list are provided
    6. - [ ] No forbidden item below has been touched
    7. ## Absolutely forbidden (abort immediately and report on any hit)
    8. - Using flags such as --no-verify or -f to skip hooks and validation
    9. - Deleting, skipping, or commenting out test cases, or evading them with markers like t.skip / xit
    10. - Loosening assertions, lowering thresholds, or editing coverage and performance baseline files
    11. - "Waiting out" a flaky check via sleep, retry amplification, or longer timeouts
    12. - Downgrade changes to CI configuration, branch protection rules, or dependency lockfiles
    13. - Disabling or weakening lint / type-check rules
    14. - Writing a failing conclusion as "expected behavior," "pre-existing issue," or "future improvement"
    15. ## Budget caps
    16. - At most N iterations per task; if M consecutive iterations fail to turn checks green, stop and report
    17. - At most K commits per night shift; beyond that, stop and wait for human triage

    4.2 Why the forbidden actions must be listed explicitly

    The model’s optimization direction is “make the given signal green.” Unless the shortcuts are closed off, the fastest path to green tests is often to weaken the tests themselves. Writing these actions into a list is not a matter of distrusting the model; it converts implicit evaluation criteria into explicit constraints. It is the cheapest insurance available in an automated job.

    The matching review method matters just as much: evidence and diff must be cross-checked. Require every report to include “conclusion + path to raw output + file-level change list.” The morning shift then only needs to spot-check two things — whether the conclusion matches the raw log, and whether the change list touches test cases or configuration baseline files. This blocks most “beautiful-summary failures” before they reach a merge.

    5. Handoff Point 3: Decide “When to Look Again” — Cadence, Idempotency, and Deduplication

    5.1 If events can drive it, don’t use fixed polling

    “Check every 15 minutes” is the most intuitive way to write it and often the most wasteful. A more sensible combination is:

    • Event-driven: webhooks from the code hosting platform (new review, check status change, merge event) trigger a handling pass directly — low latency, no idle spinning.
    • Fixed polling as a fallback: enable it only when the event pipeline is unavailable, to pick up missed status changes.
    • Backoff: when you find “queued / environment not ready,” use exponential backoff (for example 1min → 2min → 5min → 15min) with random jitter, so multiple instances don’t wake up at the same time and overwhelm downstream services.

    5.2 Idempotency and deduplication: the real difficulty of unattended work

    Nightly jobs rarely fail because the model can’t edit code. They mostly fail because the same task gets processed three times: two instances pull the same failing check at the same time, both commit, and they overwrite each other. Three mechanisms are mandatory:

    1. task key = repo + PR number + head commit sha + check identifier
    2. lease = a TTL lock written when the task is claimed, released automatically on expiry
    3. progress = handling records are persisted; on restart, read progress before deciding whether to continue
    1. {
    2. "ts": "2026-08-26T02:15:00Z",
    3. "task_key": "repoA#412@9f3c1ab/ci-unit",
    4. "event": "task_claimed",
    5. "lease_ttl_sec": 900,
    6. "round": 2,
    7. "checks": { "lint": "PASS", "unit": "FAIL", "e2e": "BLOCKED" },
    8. "changed_files": ["src/api/client.ts", "src/api/client.test.ts"],
    9. "decision": "continue",
    10. "token_cost_estimate": 0.31
    11. }

    An easily overlooked point: the head commit sha must be part of the task key. The PR number never changes across the PR’s lifecycle, so if you deduplicate by PR number alone, newly pushed commits get masked by the old task’s state.

    6. Handoff Point 4: Draw the Authority Boundary — What May It Decide on Its Own?

    This is the only one of the four handoff points that carries “overreach” risk, and the one most often skipped. Recommended approach: authorize by action tier.

    Action Recommended authorization Reason
    Read code, logs, check status Allowed by default No side effects
    Run verification in a local/preview environment Allowed by default Isolatable and cleanable
    Commit on a dedicated work branch Allowed Main branch unaffected, easy to revert
    Push a dedicated branch / open a PR Allowed Still pending review
    Merge to main Forbidden, done by a human Once merged it spreads; rollback is costly
    Modify CI config, branch protection, dependency baselines Forbidden These change the “rules” themselves and weaken every subsequent check
    Trigger a production release, change production config, delete data Forbidden Irreversible; requires a human in the loop

    Three hard constraints go with it:

    • Human-in-the-loop checkpoints: merging and releasing must be done by a person. The agent’s responsibility boundary ends at “prepare the PR and its evidence into a reviewable state.”
    • Escalation and circuit breaking: on consecutive failures, when a budget cap is hit, or when a BLOCKED item has no viable workaround, stop immediately and output a pending-decisions list instead of continuing to trial-and-error. Stopping is a normal outcome, not an anomaly.
    • Handoff report: produce one structured handoff artifact at the end of every night shift, covering completed items, evidence paths, blocked items with recommended decisions, unhandled items, and consumption stats. The quality of this report decides whether the morning shift picks up in ten minutes or spends two hours doing archaeology.

    7. Pre-Shift Checklist

    1. Codify checks as a versioned acceptance checklist in the repo, with thresholds externalized to config.
    2. Write the definition of done and forbidden actions into the checklist, and set caps on iterations and commit count.
    3. Prefer event triggers, with polling only as a fallback; implement task key + lease + persisted progress.
    4. Authorize by action tier, keeping merge-to-main and release behind human checkpoints.
    5. Standardize the structured log and handoff report format, and make the stop-on-failure and escalation paths explicit.
    6. Prepare the isolated environment and dependency cache — an unstable environment is the number one cause of nightly job failures, and it has nothing to do with model capability.

    8. Closing

    The maturity of night-shift automation is not measured by how many rounds the agent ran. It is measured by whether these four questions can be answered clearly: what makes you confident it verified anything, when is it done, when should it look again, and which decisions it is not allowed to make on its own.

    Write those four things down clearly and the agent’s autonomy means something. Leave them vague and more rounds only postpone the rework to the next morning. Verification, stopping, waiting, authority — the four handoff points are also the four steps of a team’s trust in automation.