Lesson 20 of 36

OpenAI: The Ticket Board Is the Control Plane

ReadFree to read · saving needs Core22 min · Slice → Gate → Run → Wrap → Prove · Updated 2026-10-28
You end this lesson with: factory/adopt/openai.md — ticket states, workpad and land-step rules adapted to your tracker
view

A small OpenAI team set out to build a product with no hand-written code, and for the first stretch the agents were not the problem. Progress was slow because the environment was underspecified: the app could not be started per change, the rules lived in people's heads, and one giant instruction file crowded the context and rotted (OpenAI, harness engineering post, self-reported, observed 2026-10-28). Once the agents did write code, the cost moved to the humans. The team spent every Friday, a fifth of the working week, cleaning up what it called AI slop, and human QA capacity became the next bottleneck (same post). Separately, OpenAI observes that most people can supervise only three to five interactive agent sessions before switching between them starts to hurt (OpenAI, Symphony announcement, self-reported, observed 2026-10-28). Watching sessions does not scale, and cleaning up after them by hand does not either. Decide now: when agents can open pull requests faster than anyone can watch a terminal, what is the one place the humans look, and what makes an agent stop there?

This lesson gives you factory/adopt/openai.md - ticket states, workpad and land-step rules adapted to your tracker. It serves the Prove stage of the loop: you study a published line, separate what is shown from what is claimed, and decide which parts your charter adopts.

What is actually going on

OpenAI has described its factory in three layers, each resting on different evidence.

The first layer is the board loop. It comes from Symphony, a specification and reference implementation that OpenAI open-sourced in April 2026. A human moves a ticket from Backlog to Todo; Backlog is explicitly off limits to agents. A daemon polls the tracker, gives each ticket its own workspace, and starts a Codex session whose instructions come from a workflow file kept in the repo. The agent moves the ticket to In Progress, opens one persistent comment called the workpad, reproduces the problem before touching code, and runs any validation plan the ticket's author wrote, treating it as mandatory. Anything it finds outside the ticket becomes a new Backlog ticket instead of scope creep. When checks are green and review feedback is answered, it attaches proof of work (CI status, a walkthrough video) and moves the ticket to Human Review. A human approves by moving the ticket to Merging. Only then does the agent run a land procedure, and it is told never to call the raw merge command. A reviewer who wants changes sends the ticket to Rework, which loops back to Human Review. Done is terminal. The project's own README calls it a low-key engineering preview for trusted environments, so treat it as a pattern to adapt, not a product to install.

The second layer is the repo the agent works in, described in the harness engineering post. A short instruction file acts as a table of contents into a docs directory that is the system of record. The app boots once per git worktree, so each change gets its own instance and its own throwaway logs, metrics and traces. Custom linters enforce a fixed layer order, and their error messages tell the agent how to fix the violation. Scheduled background agents scan for drift and open small cleanup pull requests. Harness Engineering lectures 03 and 04 teach this in general form.

The third layer is secondhand. Gergely Orosz of The Pragmatic Engineer visited OpenAI and wrote up a longer pipeline: specialist reviewer agents, risk-classified review, a per-change deploy agent, a production-watching loop and an incident agent that proposes but never acts (The Pragmatic Engineer, secondhand and paywalled, observed 2026-10-28). Only the free excerpt was readable for this course, so every claim in this layer carries that label.

The diagram shows layer one only: the tracker states and who may move a ticket between them.

diagram
drawing
Every human gate in the Symphony loop is a ticket state, and the only route to Done runs through Human Review and Merging.

Read it left to right: the agent can only advance a ticket into Human Review, and only a person can move it out. The agent never has a path to Merging on its own.

The rule and its condition

Copy the ticket-state pattern when your tracker can enforce who moves a ticket into each state and your repo already carries its own rules. Otherwise fix the repo and the tracker permissions first, because states the agent can edit are not gates.

DimensionOpenAIProvenance and source
TriggerA human moves a ticket from Backlog to Todo and a daemon polls for it; the harness team starts from a prompt; scheduled background agents run cleanup.Reference spec and OpenAI Symphony post; harness post
Where the agent worksOne isolated workspace per ticket; in the harness repo, one bootable app instance per git worktree with its own throwaway observability.First-party, self-reported (harness post)
Gates before mergeTicket-supplied validation plan must run; checks green and review feedback answered before Human Review; linters with remediation text; flaky tests re-run instead of blocking. Secondhand: specialist reviewers and risk classes.First-party for the first part; secondhand for the rest (Pragmatic Engineer)
Who approves the mergeSymphony: a human moves the ticket to Merging. Harness repo: agents often merge their own PRs and humans may review but are not required. Secondhand: high risk needs more review or a human, low-risk areas may opt into auto-approval.Both first-party and differing; third row secondhand
After merge (staging, rollback)Symphony ends at Done. Secondhand: after a human approves a production release, a per-change deploy agent watches the rollout; the incident agent proposes mitigations and an engineer applies them.Secondhand, paywalled (Pragmatic Engineer)
Scale claimAbout a million lines and about 1,500 merged PRs over about five months, three engineers growing to seven (OpenAI, self-reported, observed 2026-10-28); landed PRs up 500% on some teams, baseline and period unstated (OpenAI, self-reported, observed 2026-10-28).Self-reported by OpenAI; one team's greenfield repo for the first
What the company has not publishedMerge rate with a denominator; revert or defect rate of the generated code; cost per merged change; incident counts; the baseline for the 500% figure; named adopters of Symphony; the written risk classes and the eligibility rule for auto-approval.Absent from every source read

What it does well: the human gate is a state the tracker can enforce, so approval needs no chat message and leaves a record. The workpad makes every run resumable and reviewable. The repo carries its own rules, so the agent reads a map instead of a manual. What it costs: you need a tracker whose transitions you control, a repo that boots per change, and a policy file someone owns. OpenAI itself says Symphony works best in repos that already adopted harness engineering, so the board is the last thing you build, not the first.

Worked case

Illustrative composite. A ten-person team keeps its work in a tracker with three statuses: Open, In Progress, Done. Admins can add statuses and restrict transitions by role. The team has a Codex-style agent that can open pull requests from tickets. Last month it merged a change after a teammate wrote "looks good" in chat. Nothing broke, but nobody could say who had approved what.

Decide now: which statuses do you add first, who may move a ticket into each, and what can the agent never do?

Add Human Review and Merging first, and leave Rework for the second week. Those two are the gates; Rework is only a loop-back. Human Review is entered by the agent identity and left only by a person. Merging is entered only by a named human role. That is Lesson 01 applied to a tracker: queues between stages, a gate at each queue, and an approver you can name. It is also Lesson 04: the author of the change does not hold the key that merges it.

Take the tracker token out of the agent's hands. In Symphony's spec the agent reaches the tracker through a provider tool the host supplies, and the token is stripped from the child process environment. That is Agent Fleets lesson 07 and Lesson 12 of this course: the agent acts through a scoped tool, so every ticket write traces to a named sponsor.

Turn the loose chat into one workpad comment per ticket. The agent writes its plan, acceptance checks, validation steps and notes there and updates it as it goes. The reviewer reads it first. If the daemon restarts, the next run reads the workpad and resumes. For you this is also the evidence source for Lesson 14: if you ever want to count rework, the data sits in the comment history.

Replace "merge it" with a land step. Merging triggers a fixed procedure: re-run checks at the head commit, confirm the base branch is green, confirm an approval from someone other than the requester, merge, and move the ticket to Done. If a step fails, the ticket returns to Rework. This is Lesson 08: a deterministic node that code runs, not a judgment the agent makes, with the explicit input and output contract that Graph Engineering lecture 03 teaches for nodes. Enforce "no direct merge" in branch protection, not in the prompt.

Keep the whole policy in one file in the repo, versioned with the code and listed as a protected path (Lesson 06), because the agent must not be able to rewrite its own gate.

The rejected option is the one the team already used: let the agent merge whenever it believes it is done. OpenAI's harness team does that, and it works for a team with an unusually strong harness and a scheduled cleanup crew. A ten-person team without those pays for the speed in review debt it cannot see. The rule that survives the move is a short one: If the agent can reach merge without the board saying so, the board is decoration.

Fill the file below for your own tracker. The validator fails on any empty cell or missing section.

markdown

factory/adopt/openai.md

FieldYour value
Tracker and project
Repo this file governs
Named owner of this file
Policy file (versioned in the repo)
Max concurrent agent runs
Max turns per run

Ticket states

StateEntered byAgent may work here?Leaves whenEnforced by
Backlog
Todo
In Progress
Human Review
Merging
Rework
Done

Workpad

RuleYour setting
Where the one workpad lives
Who may edit it
Required sections
When the agent must update it
What the reviewer reads first

Land step

RuleYour setting
Command the agent may never run directly
Name of the land procedure
Checks the land procedure repeats
Who moves the ticket to Merging
What happens when the land procedure fails
Setting that blocks a direct merge

Tokens

CredentialHeld byAgent sees it?
Tracker token
Merge permission
bash
awk -F'|' '/^\|/ && !/^\|[-| :]+\|$/ { for (i=2;i<NF;i++) { c=$i; gsub(/^[ \t]+|[ \t]+$/,"",c); if (c=="") { printf "line %d: empty cell\n", NR; bad=1 } } } END { exit bad }' factory/adopt/openai.md && for h in "## Ticket states" "## Workpad" "## Land step" "## Tokens"; do grep -q "^$h" factory/adopt/openai.md || { echo "missing $h"; exit 1; }; done && echo OK

Faded case

Skip to the open case if this is familiar. The table puts the OpenAI pattern next to three published setups, using only what each source states.

DimensionOpenAIStripeRampLabel-driven open-source queue
TriggerTicket moved to Todo; prompt; scheduleTag in a Slack thread, or a ticketing buttonSlack, GitHub, Linear, webNew issue routed by an intake step, then a build queue
Where the agent worksWorkspace per ticket; app per worktreePre-warmed devbox with no internet egress and no production dataSandbox VM built from a per-repo imageA git worktree per run
GatesValidation plan, green checks, remediation lintsLint on push, then CI capped at two roundsNormal PR review; a review agent, secondhandTest command ends the loop; review verdict; CI at head commit; base not red
Who approvesA person moves the ticket to MergingThe launching engineer asks another engineer; humans review every PRPR opened with the requester's own token so nobody approves their own agentA merge queue after its gate; humans answer batched questions
Scale claimAbout 1,500 PRs, one teamOver 1,300 PRs a week74% of merged PRsMajority of its own repo's PRs, per its README, not repeated here

Sources, all self-reported: Stripe, observed 2026-10-28 for the weekly count, the two CI rounds and the review rule; Ramp, observed 2026-10-28 for the share; Ramp's build post for the requester token; OpenAI harness post for the OpenAI row. Ramp's own January figures conflict across its sources, which Lesson 20 covers. The open-source queue is a code-hosted README, so no number from it is used here.

The patterns differ most at the approver row. Stripe puts a person at every pull request, and Ramp's token rule makes self-approval impossible, though no Ramp page states outright that review is mandatory. OpenAI's board puts a person at a state, and the harness team puts none at all. Your line probably wants different answers in different lanes.

Decide: a team wants "a human reviews every PR" from Stripe and "the agent runs the land step" from OpenAI. The agent's service account opens the PR, and the requesting engineer is the only reviewer anyone has time for. Who should be allowed to move the ticket to Merging?

Open case

Course judgment, not OpenAI's advice. Each paragraph says what to copy, what to skip and the first week's action.

Solo developer. Copy the workpad and the land step; skip concurrency and the daemon. Week one: one workpad per issue and a branch rule that blocks your own direct merges, so you approve in a separate step.

Small team. Copy all six states and the transition permissions. Skip scheduled cleanup agents until the states hold. Week one: add Human Review and Merging, restrict who can enter them, and run five tickets through.

Enterprise. Copy the policy file in the repo and the token rule. Skip the idea that the board is complete: the post-merge stages are secondhand. Week one: name the owner of the policy file and protect its path.

Regulated shop. Copy the workpad as an audit record. Skip auto-approval and agent merges. Week one: map each state to an approver the auditor can name.

Scenario: your tracker lets any user, including the agent's service account, set any status. The agent holds a token that can merge. It opened a pull request, a teammate typed "lgtm" in a chat thread, and the agent merged and set Done. A security reviewer asks what would have stopped it on a protected path. What do you change first?

Where this breaks

Start with what is missing. None of these sources gives a merge rate with a denominator, a revert or defect rate, a cost per merged change, or incident counts. The Codex usage study reports that almost all of OpenAI engineers' output tokens are generated by Codex, and it measures usage, not accepted work (OpenAI Economic Research, internal telemetry, observed 2026-10-28). Token counts tell you the tool is used, not that the code is good.

The headline, zero hand-written code and about a million lines, is one team's greenfield repo. OpenAI's own post says the end-to-end loop depends on that repo's tooling and should not be assumed to generalize, and the team's estimate of a tenfold speed-up is a counterfactual, not a measurement (OpenAI, self-reported, observed 2026-10-28). The 500% landed-PR figure has no stated baseline (OpenAI, self-reported, observed 2026-10-28).

Symphony is a preview. Its README recommends writing your own hardened implementation from the spec, the spec leaves sandbox and approval posture to the implementer, and the reference configuration lets agents run with network access and no approval prompts. Its blocked-ticket list lives in memory, so a restart can make blocked work look eligible again.

The two OpenAI documents disagree on human review, and Lesson 04 sides with the human state for any lane where a bad merge costs more than a slow one. Published numbers on cost, revert rate and incidents would change this verdict; a statement that the harness team's no-review merges held up over years would change it most. Nothing here shows either.

Key Takeaways

  • Treat the tracker as the control surface: manage tickets and their states, not individual agent sessions.
  • Restrict who can enter Human Review and Merging, or the states are labels, not gates.
  • If the agent can reach merge without the board saying so, the board is decoration.
  • Replace "merge it" with a scripted land step that rechecks head CI and the approver.
  • Keep one workpad comment per ticket so reviewers and restarted runs read the same record.
  • Label each OpenAI claim by layer: first-party, self-reported, or secondhand and paywalled.

What You Have Now

factory/adopt/openai.md - ticket states, workpad and land-step rules adapted to your tracker. It lives in your factory/adopt/ directory beside the line map from Lesson 01 and the blueprint from Lesson 08, and its state table becomes the approval routing in your charter. It serves the Prove stage: it records which parts of a published factory you adopt and which you refuse, and the validator command lets you check the file stays complete whenever someone edits it. Re-run the validator in CI, and review the file whenever your tracker's permissions change.

Further Reading

Exercises

  1. Fill factory/adopt/openai.md for a tracker you use, run the validator, and fix every empty cell it reports.
  2. List who can change status in your tracker today. Mark each state the agent identity could set, and name the permission change that closes it.
  3. Pick one OpenAI claim in the table and trace it to its source line. Classify it as first-party, self-reported or secondhand, then write what it would take to turn it into a measured outcome.

Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in

Check your understanding


Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in