22 May 2025 / Coding agents

Writing work orders for coding agents

Coding agents can now take an issue and hand back a pull request, so the issue is doing a lot more work than it used to. I want it to say what should change, where to look, what's in scope and how we'll know it works.

A designer drawing a building by hand at a desk.
Photo: Ryan Ancill (opens in a new tab)

This month OpenAI released Codex as a cloud software-engineering agent, and GitHub put its Copilot coding agent into public preview. Both work in a repository, make changes and give you something to review, and GitHub's version starts from an assigned issue and opens a draft pull request. That means a vague ticket can turn into a plausible patch before anyone notices the misunderstanding, because the agent just goes ahead with whatever it thought "improve the checkout" meant.

So I'd write the objective as behaviour someone can observe. Something like: "When the payment provider returns a timeout, keep the order pending and show the existing retry message. Do not mark the order paid or failed." That gives the agent a state transition, a visible result and two outcomes it mustn't produce, and it still leaves the implementation up to the agent. Keep each issue to one coherent change. If you're listing unrelated verbs across different subsystems, split it.

The agent can search the code, but it can't tell which conventions are deliberate and which are accidents. Point it at the likely entry points, the existing test file, any schema or interface that has to stay compatible, and the build and lint commands. It's fine to be honest about what you don't know, too: "The handler appears to start here, but confirm all callers before changing the signature." Leave production data, credentials and customer examples out and use a synthetic fixture instead. Then say what it's allowed to touch, whether dependency changes or migrations are expected, and whether network access or secrets are needed at all. OpenAI says Codex runs tasks in isolated cloud sandboxes, and GitHub says its agent uses an environment backed by GitHub Actions, so most changes should get by with mocks and local fixtures. "Do not rename public API fields" is far more useful than "avoid breaking changes", because the agent can actually check it.

For the timeout example, I'd want acceptance criteria that read almost like tests:

  • given a timed-out provider call, the order stays pending
  • a retry uses the existing order identifier instead of creating another order
  • the user sees the current retry message
  • the existing success and explicit-decline tests still pass

Phrases like "handles edge cases" or "works correctly" don't help anyone. Name the edge case and the test level that proves it. Give commands that work from a clean checkout, focused tests first and then the broader suite, plus lint, type checks or a build where they apply. If part of the suite already fails on the base branch, write down the exact failure before the work starts, or the agent might waste time on it.

The handoff should be a draft pull request with a short summary, the linked issue, the commands it ran with their results, and anything it didn't run. It shouldn't merge, deploy or change repository settings. Both tools give you logs or session records, but you still need to read the diff yourself and run the important checks in normal CI. Now that an assigned issue can come back as a pull request, the issue is the work order, so it has to say what should change, where to look, what's in scope and how we'll know it works, or the agent will fill the gaps itself the way it might with "improve the checkout". I'd try all of this on one bounded issue that already has a failing test, and if the pull request needs a long back-and-forth to work out what the ticket meant, fix the work order before handing over anything bigger.

Got a take on this?

Share it on X. I read the replies.

All blogs