Back to blog
  • Agents
  • Infrastructure

How We Built a Landing System for Agent-Written Code

One reasoning owner, compatible batches, and mechanical authority checks moved 17 agent-written PRs through two integrations in about two hours.

At 5:45 PM, a notification reported that ten pull requests had reached master in one integration. Fifty-nine minutes later, a second integration landed seven more. By 7:02 PM, deploy and production-smoke evidence for both exact merges was green.

From the first integration’s assembly at 4:59 PM to the final smoke result, 17 agent-written pull requests reached production in about two hours. We did not make the authoring agents slower, and we did not remove a required release gate.

We changed the shape of landing.

Q
Amazon Q APP 5:45 PM
Ottto master merge completed
Status: merged to master
Branch: batch-land/integration-20260705-133544
Pull request: #2115 batch-land: 10 PRs (#1674 #1717 #1721 #1752 #1787 #2086 #2092 #2094 #2102 #2104)
Merge commit: a3c37bc7680ea8ae67f8a4abdda23f2a31f51cef
Agent: Claude Code (from PR metadata)
Agent session name: Landing Owner Agent
Agent session source: claude-code-headless
Observed evidence from the first batch in that July run. The identifiers are preserved so the event can be traced.

We call the system the landing lander. It is an internal release workflow built from an agent skill, deterministic policy tools, a server-side landing queue, and durable evidence. A sanitized version of the skills is open source.

This is not a story about an agent receiving unlimited merge authority. It is a story about narrowing that authority until the agent can operate continuously without weakening the boundary around master.

The bottleneck moved downstream

Once many coding agents can work in parallel, writing code stops being the only constraint. Review, integration, validation, deployment, and production verification become the shared serial path.

Our original queue landed one pull request at a time. Each source could be healthy in isolation and still wait behind a complete CI-and-release cycle for every source ahead of it. Adding more author agents increased arrival rate, but did nothing for departure rate.

The obvious shortcuts were unacceptable:

  • Do not trust a green source branch as proof that it composes with current master.
  • Do not let every author race to merge its own work.
  • Do not turn a red batch into an unbounded debugging session.
  • Do not call an integration complete until deploy and smoke evidence exist for the exact merge.

The useful question became: how can several compatible changes pay for one guarded landing round while failures remain attributable?

Before and after: pull requests pass through validation one at a time, then travel in compatible groups through the same guarded path.
The gates stay in place. Compatible pull requests share the integration and release round.

What this run proves—and what it does not

This July run is a concrete event, not a universal benchmark. Integration #2115 carried ten source pull requests and merged as a3c37bc7680e; integration #2119 carried seven and merged as ce1c3f7293cd. Both completed their applicable deploy paths and production checks by 7:02 PM local time.

That proves those 17 sources could share two guarded integration rounds under those conditions. It does not prove that every queue will see the same throughput, that every source avoids its own CI, or that batching cuts the total engineering bill by the batch width. Compatibility, changed paths, cache state, baseline health, deploy topology, and arrival timing all affect the result.

The durable result was architectural: a batch could fail without making the whole queue opaque, and a successful batch could carry several source changes through one integration boundary.

The contract: reason broadly, mutate narrowly

The current implementation has evolved since that first run, but its contract remains simple: the owner may plan and route; trusted mechanisms decide whether a mutation is allowed.

Pull requests move through review, combined validation, merge, deploy, smoke checks, and production evidence.
One guarded path from source changes to evidence that the exact merge is live.

Every landing must preserve these boundaries:

  1. Source review and checks. Each source arrives with its author-side review disposition and the checks required for its changed paths.
  2. Current-tree composition. Candidate sources are composed on the authoritative current master, not on a remembered local ref.
  3. Combined validation. The integration runs the validators selected for the combined change. Exact-head check reuse is allowed only behind fail-closed identity and tree-equivalence proofs; uncertainty falls back to validation.
  4. Baseline classification. A failed candidate is not automatically a bad source. The same focused failure is compared with clean current master before blame moves to a PR.
  5. Freshness before mutation. The system re-reads remote state before publishing or moving master. A moved source, changed approval, stale base, or lost lease stops the mutation.
  6. Deploy and smoke closeout. Merge is an intermediate state. The owner records the applicable deploy and production-check evidence back on every carried source.

The owner cannot reinterpret a failed gate as success. It decides what evidence to collect and where work should go next; trusted mechanisms decide whether mutation is allowed.

One reasoning owner, several mechanical locks

The landing owner is a headless reasoning session with one queue-wide view. It sees source PRs, existing integrations, repair work, approval boundaries, deploy debt, and current remote state. That global view matters: independent author agents cannot safely optimize the shared queue from their individual branches.

Ownership is enforced below the prompt. The shipped system combines a host-level owner lease, a per-process mutation lock, exact host assignment, and a repository-global lease backed by atomic Git references. Remote mutation has its own short lease after validation. If identity, host assignment, ancestry, or lease proof is unreadable, the operation fails closed.

The owner is therefore not “an agent with admin access.” It is a planner operating through commands that independently recheck its authority.

The runtime also separates reasoning from bounded work. The owner may delegate immutable inspection or exact-head repair tasks, but workers never inherit queue authority. Batch selection, policy decisions, labels, integrations, deploy state, and every shared mutation remain with the sole owner.

Batch the widest compatible set

The owner gathers the complete eligible intake, orders it according to policy, and tries to fill an integration with up to ten successfully combined sources. Ten is a target batch size, not a limit on how many candidates it may inspect.

Architecture diagram: source pull requests enter owner intake, compatible changes form an integration, the queue validates against current master, and merge, deploy, smoke, and evidence follow. Failures route to repair or a human decision.
The owner reasons over the queue; deterministic gates protect the mutation boundary.

When a candidate group fails, diagnosis narrows the failing set instead of condemning every source. Clean subsets keep moving. Source-specific problems carry exact evidence into repair. The same focused failure on clean master is baseline debt, not source blame.

Singleton integrations are supported, but they are recorded exceptions. A lone source waits through a bounded coalescing window so a compatible peer can arrive. Priority means “serve this source at the next safe boundary,” not “give it a private lane.” Isolation requires an explicit operator decision.

Those details sound procedural because they are. Throughput came from making the desired geometry—wide compatible batches—the default, then requiring evidence for every narrower path.

State must survive the agent

A headless agent will eventually exit, lose connectivity, hit a provider limit, or get replaced. The queue cannot rely on its chat history.

Durable state lives in places a successor can reconcile:

  • GitHub records source heads, checks, labels, integration PRs, approvals, and merge state.
  • The owner ledger records the current phase, batch membership, repair reservations, and deploy debt.
  • Leases and heartbeats distinguish an active owner from an abandoned session.
  • Handoff packets explain what moved, what failed, and what evidence remains.

On restart, the next owner reconciles remote truth before creating anything. It resumes or retires existing integrations, restores deploy closeout, and avoids opening a duplicate batch for the same sources.

This was one of our most important lessons: a running process is not an observable automation. An observable automation has a named owner, a current unit of work, last evidence, a next boundary, and a safe recovery path.

Failure routing is throughput work

Early versions treated every red state as a reason to stop. That made one ambiguous source the queue’s problem. The current system separates several outcomes:

  • A source-specific, repairable failure moves to supervised exact-head repair.
  • A clean-master failure becomes baseline work and keeps source attribution open.
  • A sensitive change without current approval waits for an operator.
  • An unreadable authority or identity check stops mutation without inventing a verdict.
  • A healthy compatible subset can proceed while excluded failures retain their evidence.

Fixers are bounded and supervised. They receive one PR, one exact head, and one repair question. A moved head cancels the reservation. A failed first attempt may escalate once under the configured policy; repeated no-progress attempts do not fan out forever.

That is less cinematic than “the system heals itself,” and more useful. Recovery is a governed state transition with a finite budget and an audit trail.

The economics without a magic multiplier

Batching changes the number of integration-level rounds. In the observed run, 17 sources rode two integrations instead of a hypothetical 17 singleton integrations. That is 8.5 sources per integration for that run.

It would be misleading to translate that directly into “8× cheaper.” Source CI still exists. Different batches trigger different validators and deploys. Failed compositions consume work. Some checks can be reused only when exact identity and tree proofs hold. Cloud pricing and cache behavior also matter.

The defensible model is:

  1. Measure fixed cost per integration round.
  2. Measure source checks separately from combined-tree checks.
  3. Record batch width, exclusions, retries, and baseline failures.
  4. Attribute deploy work to the services the combined tree actually changed.
  5. Compare observed totals over a representative window, not one unusually full afternoon.

Batch width is therefore an operational metric, not a savings claim. It tells us whether the queue is using shared release work efficiently and where incompatibility or policy is forcing singletons.

Review the workflow, not the prose

During bring-up, a separate review pass examined real owner shifts: batch widths, deferred sources, abandoned worktrees, incorrect blame, repeated repairs, premature queue cancellation, and missing handoffs. When it found a recurring failure, we moved the lesson into a test, a state transition, or a mutation-time guard.

A reviewer otter with a checklist watches an operator otter at a landing console.
Review the workflow from durable events: what it attempted, why it changed state, and what happened next.

The distinction matters. Recommendations can begin as prose. Critical rules must eventually run where the decision happens. A long-lived session may hold stale instructions; a pre-push or server-side gate evaluates the current rule at mutation time.

We now treat the landing workflow like any other production system: instrument it, inspect incidents, repair the narrow control, and verify the next natural run. The reviewer recommends and verifies; it does not bypass the owner or grant itself release authority.

Keeping these categories separate makes the system easier to trust.

Shipped architecture: one reasoning owner; mechanical authority checks; widest-compatible batching; explicit isolation; current-master validation; baseline comparison; bounded repair; deploy and smoke closeout; durable handoff evidence.

Observed evidence: the 17-source July run; its batch widths of ten and seven; exact integration and merge identifiers; and later incidents recorded in the repository’s failure history.

Operational policy: target wide batches, fail closed on unreadable authority, never infer source blame from a red integration alone, and keep human approval distinct from machine repair.

Recommendations for another repository: start with a smaller state machine and your own CI policy. Adopt thresholds only after measuring your arrival rate, validator cost, failure modes, and human approval needs.

A practical starting point

You do not need our entire control plane on day one. A useful first version has six parts:

  1. One intake. Give ready source PRs a canonical state and bind it to the exact head that was reviewed.
  2. One owner. Elect one queue-wide planner. Put its authority in a lease that mutation tools verify independently.
  3. One integration builder. Compose several sources on current main, validate the combined tree, and preserve the exact membership manifest.
  4. One failure funnel. Compare focused failures with clean main, keep clean subsets moving, and route repairable versus human decisions separately.
  5. One freshness boundary. Re-read source heads, approvals, and main immediately before remote mutation.
  6. One evidence trail. Close each source only with the integration, merge, deploy, and smoke facts that apply to it.

Then measure. Look at batch width, time in each state, baseline-red rate, repeated repair attempts, stale ownership, integration retries, and deploy closeout lag. These metrics tell you whether the automation is reducing work or merely moving it somewhere harder to see.

The sanitized landing-lander skill and batch-land engine are available under Apache-2.0. They include the rulebook, runner, lease guard, batch tools, prompts, and tests. You still supply the repository-specific server-side queue, validation commands, path policy, and approval model.

Operations starts after the pull request

Agentic engineering does not end when an agent opens a pull request. The costly, failure-prone work continues through queues, retries, validations, deploys, smoke tests, and forgotten state.

The same pattern can appear in long-running AI workflows: schedules that outlive their purpose, overlapping loops, silent context growth, and work whose owner has disappeared. Cost without operational state is unexplained; operational state without cost hides waste.

Our landing lander became reliable when every run could answer five questions: What is running? Who owns it? What shared work did it consume? What evidence moved it forward? What safely stops or recovers it?

Those are not just release-engineering questions. They are the foundation for operating fleets of coding agents without losing control of the work—or the bill.