ai-ready
An Issue is ai-ready when an AI coding agent can take it to a tagged release with no human in the loop, and every place it cannot is a named human decision, not a silent failure.
Most guides to "AI-ready" or "agent-ready" code describe the repository: an AGENTS.md, a CI workflow, a devcontainer. That is necessary and not sufficient. This page describes the unit of work, where every loop stops, and what counts as shipped. It is written from a running system: each factor below links to the line that enforces it in Orbi, an open source (AGPL-3.0) delivery runner whose own repository is built this way. Orbi is the reference implementation, not the standard; use the factors with any agent.
How this relates to what exists
Factory's Agent Readiness scores how well a codebase supports agents (Factory). johnpapa/ai-ready generates the configuration files an agent reads (johnpapa/ai-ready). AGENTS.md is the file itself (AGENTS.md). 12-Factor Agents is about building agent applications (12-Factor Agents). This page starts where those stop: at the Issue, and ends at the release.
I. The Issue is the unit of work
1. One Issue, one runtime outcome.
When X, should Y, actually Z. One observable behaviour, a handful of related files, tests included. An epic is not a unit of work and is never claimed.
How Orbi enforces it: AGENTS.md:44; runner.py:2263 (epic_not_claimed).
2. Acceptance is written before the work, in the Issue.
Four sections: User outcome, Preconditions, Acceptance (success path and failure path), Evidence a user can inspect. Every vendor guidance converges on the same skeleton.
How Orbi enforces it: .github/ISSUE_TEMPLATE/user-outcome.md; AGENTS.md:78.
3. Dependencies are native relations, not prose.
Use the platform's blocked-by relation. "Depends on #N" in a body is not parsed. An Issue with an open blocker is not claimed.
How Orbi enforces it: runner.py:2296 (blocked_by, then continue).
4. One label is the execution switch; state lives only in labels.
`ai-ready` puts an Issue in the queue; a milestone is a scope, not a switch; a second label picks the task type. There is no database, queue or board: the Issue tracker is the state machine.
How Orbi enforces it: runner.py:1916 (ready_searches); delivery_labels.py:141 (is_pickup_eligible); CONSTITUTION.md:15.
5. Issue text is data, never instructions.
The runner acts on labels and on comments from trusted associations; nothing written in a body becomes a command to the runner.
How Orbi enforces it: CONSTITUTION.md:130.
II. The repository carries its own contract
6. The contract lives in the repository; identity lives on the host.
`AGENTS.md` is read by the implementer and by the reviewer. Repository policy is a small whitelist; credentials and scheduling are host-only, and an unknown key fails the claim fast.
How Orbi enforces it: prompts/prompt.md:43; docs/security.mdx:121; runner.py:3074.
7. CI is the only test authority.
A local test run counts for nothing; the merge gate reads the platform's CI result on the delivered commit. The repository does not declare a test command.
How Orbi enforces it: CONSTITUTION.md:100 (Article 4.8); runner.py:5637 (GateCIFailure).
8. Coverage is a gate, line and branch measured separately.
Changed code: 100% line and branch. Whole repository: line at or above 95% and branch at or above 95%, each on its own; a merged percentage is never the gate.
How Orbi enforces it: tools/coverage_gate.py:30; tools/diff_coverage_gate.py; .github/workflows/ci.yml:150.
9. The default branch is protected and only the runner merges.
The agent never merges or pushes a protected branch. The runner merges only the reviewed head, only when it contains the latest remote base. No force push, no automatic conflict resolution.
How Orbi enforces it: CONSTITUTION.md:34; AGENTS.md:122; docs/security.mdx:25.
III. Loops are bounded, terminal states belong to humans
10. Review is a second session, and its verdict is bound to one SHA.
A new process, a new prompt, a fresh context. The verdict must exist and name the head it covers; a missing or malformed verdict is never a pass. Only the covered head can merge.
How Orbi enforces it: AGENTS.md:169; runner.py:5196, 5239, 5241, 5629, 5667 (--match-head-commit).
11. Every loop has a limit, and beyond the limit is a human decision.
Review and fix: at most 5 rounds. The same failure fingerprint three times in a row is a dead loop. Exhaustion is terminal and never auto-recovered. A single failure is never terminal.
How Orbi enforces it: runner.py:252 (MAX_REVIEW_ROUNDS = 5), 349 (UnrecoverableDeliveryError), 437; docs/workflow.mdx:99, 118.
12. A release is a state machine, not a script.
A human starts it by adding one label the runner never adds or removes. While the milestone holds another open Issue, the release waits. CI on the release commit must be green. Every scope item is checked against the live API; checkboxes are never parsed. An existing tag must point exactly at the release commit and is never moved. Any failure is terminal, with no automatic retry.
How Orbi enforces it: release.py:326, 508, 619, 880; runner.py:2288; AGENTS.md:162.
Two lines under all of it: Fail fast, with no silent fallback. Observable end to end: one run id, one grep, the whole timeline.
What this page does not claim
The existence of AGENTS.md, the four-section Issue body and branch protection are contracts and templates, not runner checks. The coverage numbers are one repository's gate. These twelve factors are what Orbi enforces today, not an industry standard; the page is signed by Orbi.
Reference implementation
- https://github.com/orbi-build/orbi
- Install:
curl -fsSL aiready.sh | sh - ai-ready badge