Prompting coding agents has quickly become normal. It feels so natural: just tell the agent what you want! The problem is that the prompt is not the unit of work.
You see, a prompt isn’t just instructions. It’s a compressed representation of everything you know about the work: the goal, the state, and what should happen next. The problem is that most of that knowledge never actually makes it into the prompt. It stays in your head.
Let’s imagine you want to add a “dry-run” feature to your shell script. You fire up Claude Code, and tell it to write a spec for the dry-run feature. After a minute, Claude prompts with a write permission request to docs/dry-run-feature.md, which you approve. You keep watching the screen and a few seconds later Claude says he’s done. You read the spec, it looks good and you reply to Claude telling him to implement the spec. Note that nothing about the work itself changed, rather the stage of development progressed. Yet you’re forced to write another prompt. Claude starts beavering away, and then stops to ask you a question about the dry-run behavior …
Each time you reply to Claude you’re reconstructing the context from the current state of the work.
What if instead of starting with a prompt, you opened a ticket (or GitHub issue) which briefly described the feature, and you set the ticket status to “spec-needed”. Then the prompt for “spec-needed” tickets could be a template: ‘Read the description of ticket #{ticket_number} and write a detailed spec … When you’re done, run bin/submit #{ticket_number}".’
See that by running bin/submit, the agent is no longer asking a human what to do next, it’s telling the system what changed. Once the work has explicit state, software development starts to look less like a chat and more like a state machine:
| Ticket Status | Agent Role Needed | Transition action |
|---|---|---|
| spec-needed | Spec writer | Submit |
| spec-in-review | Spec reviewer | Reject, submit |
| code-needed | Implementer | Reject, submit |
| code-in-review | Code reviewer | Reject, merge |
Once the workflow is explicit, orchestration becomes possible. Each state has a well-defined goal, a corresponding prompt template, and a known set of valid transitions. And in fact, that’s exactly how Greenlight autopilot works.
When each stage has an explicit purpose, several things become possible. Agents receive the permissions appropriate for their role, reducing unnecessary requests. Separate agents can write and review specifications, reducing ambiguities before a human gets involved. And because the workflow is tracked in a ticket and not in a conversation, any coding agent can pick up the work where it was left off.
Work lives in tickets and code lives in Git. Agent conversations are just a way of transforming one into the other.