Repo Contracts for ChatGPT–Codex Handoffs
A practical ChatGPT→Codex workflow: store briefs in .ai/, generate plans, and enforce acceptance criteria via CI so multi-agent code changes stay safe, auditable and shippable.
Faisal Karkoh · 30 Aug 2026 · 21 min read
What a reliable ChatGPT → Codex workflow actually looks like
If you want ChatGPT to design features and Codex (or a similar coding agent) to implement them reliably, treat their interaction as a contract in your repository, not a conversation in your browser. The concrete pattern:
- ChatGPT turns a product brief into two artefacts committed to the repo:
.ai/brief.md and .ai/plan.yaml.
.ai/plan.yaml encodes tasks, file paths, operations and machine-enforceable acceptance criteria.
- Codex reads those artefacts and edits the repo task-by-task; CI enforces the contract via tests and checks.
- Humans review a PR that explicitly references
.ai/brief.md and .ai/plan.yaml, not a screenshot of a chat.
This article shows how to set up that contract, defines a minimal schema, and walks through a worked Next.js + Supabase feature. The goal is to remove the human as the synchronisation layer between ChatGPT, Codex and the repo, and plug this into a broader AI development workflow from prompt to production.
Why split ChatGPT and Codex at the hand-off?
Practitioner discussions around ChatGPT and Codex consistently converge on a division of labour: ChatGPT for reasoning and architecture; Codex or similar agents for repository-aware edits across real projects. Community threads explicitly note that the human currently ends up as the “synchronisation layer” between ChatGPT, Codex and the project context, copy-pasting plans and diffs between tools. A repo-backed contract is a way to reduce that manual synchronisation and push more of the workflow into a repeatable, multi-agent AI coding stack for 2026.
Roles: planner vs executor
- ChatGPT (planner): translates business goals into a product brief, then into a repository-aware plan. It is optimised for global reasoning, trade-offs and decomposition.
- Codex (executor): applies that plan at the file level in a real repository: adding modules, updating components, writing migrations and tests.
This mirrors a common human workflow: PRD → design doc → implementation. The brief and plan are the PRD and design; the Codex session and PR are implementation.
Where Copilot, Cursor, Claude Code and others fit
OpenAI’s own guides and research describe ChatGPT Work and Codex as being used across many functions for planning, analysis and execution in complex workflows, including planning and design(ChatGPT Work overview), but they do not publish a precise share of internal teams using these tools. Codex and other code-focused agents then operate closer to the repository. GitHub describes Copilot as an “AI pair programmer” that works across supported IDEs and in GitHub.com’s code browsing and pull-request experience, with additional integrations such as GitHub Copilot in the CLI documented separately(GitHub Copilot overview). Tools like Cursor and Claude Code add repo-native or terminal-first execution, and are covered in more depth in the best AI coding stack for 2026 guide. For the rest of this article, “Codex” stands for any execution agent that can read files, make edits and open PRs.
The key idea: the value comes from a planner → executor contract. Codex can later be swapped for Cursor or Claude Code while keeping the same contract.
Cost lens: why separate reasoning from execution
OpenAI’s GPT‑4o‑mini is positioned in the official docs as a fast, affordable small model for focused tasks. As of August 29, 2026, the OpenAI API pricing page lists GPT‑4o‑mini at USD $0.15 per 1M input tokens and $0.60 per 1M output tokens(GPT‑4o‑mini pricing). By constraining ChatGPT’s work to a small number of planning sessions per feature, planning costs can be bounded tightly.
Coding assistance via Copilot or Codex tends to be continuous. GitHub’s official billing docs list Copilot Business at $19 USD per user per month and state that each Business seat includes 1,900 AI credits per month before usage‑based overages apply(Copilot Business billing). That works out arithmetically to 100 included AI credits per $1 of monthly seat price, based solely on the published price and credit allotment. That flat per-seat price can cover the bulk of implementation work, while planning stays on a per-token model.
Pricing primitives (official headline prices, as of 2026‑08‑29, per the linked vendor documentation; all are subject to change).
| Tool |
Unit |
Headline price |
Notes |
| GPT‑4o‑mini (ChatGPT/API) |
Per 1M input tokens |
$0.15 |
Per-token billing; used for planning and decomposition(GPT‑4o‑mini). |
| GPT‑4o‑mini (ChatGPT/API) |
Per 1M output tokens |
$0.60 |
Per-token billing for responses. |
| GitHub Copilot Business |
Per user / month |
$19 incl. 1,900 credits |
Organisation plan, usage metered in AI credits(Copilot billing). |
Define the product brief: from idea to contract-ready spec
The workflow starts with a concise, opinionated product brief. The brief must be structured enough that ChatGPT can turn it into a plan, but readable enough that stakeholders can review it.
Minimal brief schema
Use ChatGPT to populate this structure and save it as .ai/brief.md in your repo:
# Feature: <clear, user-facing name>
## Problem
- What user problem are we solving?
- Why now? Link to ticket/OKR if relevant.
## Target users
- Primary user(s)
- Secondary/affected personas
## Scope
- In scope: bullet list of behaviours, screens, APIs
- Out of scope (non-goals): things we explicitly will not do
## Constraints
- Technical constraints (stack, performance budgets, data residency)
- UX constraints (brand, accessibility level)
- Operational constraints (rollout, flags, migrations)
## Success metrics
- Quantitative (e.g. activation rate, error rate)
- Qualitative (e.g. support tickets, UX feedback)
## Edge cases & failure modes
- Known edge cases
- Degradation behaviour (what we prefer if something fails)
## Acceptance criteria (user-level)
- <AC-1> When a <user> does <behaviour>, they see <outcome>
- ...
Driving ChatGPT to this brief
In ChatGPT, a prompt along these lines can be used:
You are acting as a product lead for a Next.js + Supabase SaaS.
I will describe a feature. Produce a product brief in the following schema, suitable to be saved as `.ai/brief.md` in the repo:
[PASTE SCHEMA ABOVE]
Feature description: <your rough idea or ticket text>.
The important constraint is: ChatGPT must output a single Markdown document with the exact headings, because later automation (and Codex) will assume that structure.
Example: email-based signup with rate limiting
For a Next.js + Supabase app, a shortened .ai/brief.md might look like:
# Feature: Email signup with rate limiting
## Problem
Anonymous visitors can hit the dashboard without creating an account. We want to introduce email-based signup while preventing abuse from repeated signup attempts.
## Target users
- Primary: new visitors signing up via email
- Secondary: support team handling signup issues
## Scope
- In scope:
- Email signup form on `/signup`
- Supabase email+password auth
- Rate limiting per IP and per email (max 5 attempts / hour)
- Basic error messages and resend logic
- Out of scope (non-goals):
- SSO providers
- Magic links
## Constraints
- Stack: Next.js App Router, Supabase client
- Data: store rate-limit counters in Supabase
- Rollout: behind `ENABLE_EMAIL_SIGNUP` feature flag
## Success metrics
- 90% of new signups go through email flow within 2 weeks of launch
- Signup error rate < 1% of attempts
## Edge cases & failure modes
- Email provider outage: show generic error and log incident
- Repeated attempts from bots: hard cap + captcha integration (future)
## Acceptance criteria (user-level)
- AC-1: Users can create an account with email+password and receive a confirmation email.
- AC-2: More than 5 failed attempts in one hour from the same IP or email results in a clear error message.
- AC-3: Feature can be turned off via `ENABLE_EMAIL_SIGNUP=false` without breaking existing login.
Screenshot 1: .ai folder in the repo
Screenshot suggestion: IDE file tree showing a .ai folder at the root, containing brief.md and plan.yaml. The content can be partially redacted; the key is the location and filenames.
Turn the brief into a repository-ready implementation plan
Once the product brief is in the repo, ChatGPT’s job shifts to turning it into a precise plan that Codex can execute.
What the plan must contain
Unlike the brief, the plan is written for tools. Each task must specify:
- Target file paths and operations (create, modify, delete).
- Dependencies between tasks.
- Technical acceptance criteria that can map to tests or checks.
YAML works well because it is readable and parseable.
Minimal .ai/plan.yaml schema
feature: "Email signup with rate limiting"
brief_path: ".ai/brief.md"
owner: "@team-auth"
status: "draft" # draft | in_progress | complete
context:
repo:
framework: "nextjs"
backend: "supabase"
branch: "feature/email-signup"
acceptance_criteria:
functional:
- id: "F-1"
description: "User can sign up with email+password and receive confirmation email."
checked_by: "test"
test_files:
- "tests/auth/signup.test.ts"
- id: "F-2"
description: "Rate limiting of 5 failed attempts per hour per IP/email."
checked_by: "test"
test_files:
- "tests/auth/rate-limit.test.ts"
operational:
- id: "O-1"
description: "Feature can be disabled via ENABLE_EMAIL_SIGNUP without breaking existing login."
checked_by: "test"
test_files:
- "tests/auth/feature-flag.test.ts"
plan:
- id: "T-1"
description: "Add Supabase auth client util."
operations:
- type: "create"
path: "lib/supabaseClient.ts"
depends_on: []
- id: "T-2"
description: "Implement /signup page with email+password form."
operations:
- type: "create"
path: "app/signup/page.tsx"
- type: "modify"
path: "app/layout.tsx"
note: "Add nav link to /signup"
depends_on: ["T-1"]
- id: "T-3"
description: "Implement Supabase-based rate limiting."
operations:
- type: "create"
path: "app/api/auth/rate-limit.ts"
- type: "modify"
path: "app/api/auth/signup/route.ts"
note: "Enforce rate limit before signup"
depends_on: ["T-1"]
- id: "T-4"
description: "Wire feature flag and tests."
operations:
- type: "modify"
path: "app/api/auth/signup/route.ts"
note: "Gate main logic behind ENABLE_EMAIL_SIGNUP"
- type: "create"
path: "tests/auth/signup.test.ts"
- type: "create"
path: "tests/auth/rate-limit.test.ts"
- type: "create"
path: "tests/auth/feature-flag.test.ts"
depends_on: ["T-2", "T-3"]
Screenshot 3: plan.yaml snippet
Screenshot suggestion: code editor showing the middle of .ai/plan.yaml, including acceptance_criteria and at least one plan task with operations and depends_on.
Prompting ChatGPT to produce plan.yaml
Once .ai/brief.md is committed, create a new ChatGPT session:
You are a senior tech lead for a Next.js + Supabase application.
You will read the following product brief (Markdown) and produce a concrete implementation plan as YAML, to be saved as `.ai/plan.yaml`.
Requirements:
- Follow this exact schema: [PASTE YAML SCHEMA WITHOUT EXAMPLE VALUES].
- All file paths must be relative to the repo root.
- Every acceptance criterion must either map to a test file or be marked `checked_by: manual`.
Here is the brief:
[PASTE .ai/brief.md CONTENT]
This is still a human-driven copy-paste step, but the output now lives in the repo and can be reused by Codex or other agents without further manual synchronisation.
Encoding the handoff contract between ChatGPT and Codex
With .ai/brief.md and .ai/plan.yaml in place, the contract is a first-class part of the codebase. The next step is to standardise how Codex consumes it.
Where the contract lives
.ai/brief.md: product intent and user-level acceptance criteria.
.ai/plan.yaml: implementation tasks, file operations, technical acceptance criteria.
- Optional:
.ai/context.json for machine-updated metadata (e.g. task statuses, links to PRs).
// .ai/context.json (optional)
{
"feature": "Email signup with rate limiting",
"branch": "feature/email-signup",
"codex_runs": [
{ "id": "run-001", "tasks": ["T-1", "T-2"], "status": "complete" },
{ "id": "run-002", "tasks": ["T-3", "T-4"], "status": "in_progress" }
]
}
Standard handoff prompt for Codex
Whenever a Codex session is started for this feature, a fixed prompt template can be used:
You are an AI coding agent working on branch `feature/email-signup` of a Next.js + Supabase repo.
Your contract is defined by two files in the repository:
- `.ai/brief.md` (product intent, user-level acceptance criteria)
- `.ai/plan.yaml` (implementation tasks, file operations, technical acceptance criteria)
Rules:
- Work only on tasks in `.ai/plan.yaml` with `status` not equal to `complete`.
- For each task:
- Read the referenced files.
- Apply the specified operations.
- Create or update tests listed under `acceptance_criteria` that relate to this task.
- Keep diffs minimal and scoped.
- Do not modify files outside the paths listed in `plan.yaml` without explicit instruction.
- Do not merge branches or deploy.
Report back after each task with:
- Task ID
- Files changed
- How acceptance criteria were addressed
If the Codex environment can directly read .ai/brief.md and .ai/plan.yaml from the repo, the prompt can be shorter and refer to them by path.
Update rules and governance
- Who edits
brief.md? Typically product owners or tech leads. Changes require human review.
- Who edits
plan.yaml? Primarily ChatGPT and tech leads; Codex should not modify it.
- How is status tracked? Option A: update
status fields in .ai/plan.yaml manually during review. Option B: a small script that updates .ai/context.json from PR labels or CI results.
Running Codex: from plan to shippable code in the repo
At this point the executor takes over.
Step 1: prepare the branch and environment
- Create a dedicated branch:
feature/email-signup.
- Commit
.ai/brief.md and .ai/plan.yaml as the first changes.
- Ensure Codex (or a chosen agent) has repo access on this branch.
For guidance on making an existing production repo safe and cheap for Codex-driven edits before adopting the full contract, see the separate piece on how to set up an existing repository for Codex.
Step 2: execute tasks incrementally
Codex should work task-by-task:
- Choose the next
plan entry with unmet dependencies (e.g. T-1).
- Apply file operations (
create lib/supabaseClient.ts, etc.).
- Run the relevant tests locally if the setup allows.
- Commit with a message referencing the task ID (
feat(auth): T-1 add Supabase client).
Keeping each commit small and bounded to a plan task makes review and rollback manageable.
Step 3: enforce operational guardrails
In the Codex prompt or configuration, encode guardrails such as:
- Surface area limits: no changing more than N files per run; no cross-cutting refactors unless listed in the plan.
- Tests are mandatory: if a plan task references acceptance criteria with
checked_by: test, Codex must touch or create the named test files.
- No config drift: environment variables and deployment config (e.g.
vercel.json) can only be changed when explicit tasks exist.
Example edits for the email signup feature
Following the plan, Codex might:
- T-1: Create
lib/supabaseClient.ts initialising the Supabase client with environment variables.
- T-2: Create
app/signup/page.tsx with a form posting to /api/auth/signup; update app/layout.tsx to add a signup link.
- T-3: Implement
app/api/auth/rate-limit.ts storing attempts in a Supabase table and enforcing the “5 attempts / hour” rule; update app/api/auth/signup/route.ts to call this before creating a user.
- T-4: Add a feature flag check in
app/api/auth/signup/route.ts and create three test files under tests/auth/ that assert behaviour for normal signup, rate-limited signup and disabled feature flag.
Review and acceptance: closing the loop in GitHub
The contract becomes enforceable when it flows into PR descriptions, CI checks and review checklists.
PR template referencing the contract
Create a GitHub pull request template .github/pull_request_template.md:
# Summary
- Feature: <copy from `.ai/brief.md` title>
- Plan: `.ai/plan.yaml`
## Completed plan tasks
- [ ] T-1 Add Supabase auth client
- [ ] T-2 Implement /signup page
- [ ] T-3 Implement rate limiting
- [ ] T-4 Wire feature flag and tests
## Acceptance criteria mapping
Link each AC and criterion from `.ai/brief.md` / `.ai/plan.yaml` to evidence:
- AC-1 / F-1: <link to test file / describe manual validation>
- AC-2 / F-2: ...
- AC-3 / O-1: ...
## Notes
- Known limitations
- Follow-ups
CI enforcing acceptance criteria
Translate as many criteria as possible into CI checks. For example, a GitHub Actions workflow:
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm test -- tests/auth
If tests corresponding to F-1, F-2 and O-1 fail, the PR cannot be merged. This makes the contract partially self-enforcing.
Screenshot 2: PR view with checks and contract references
Screenshot suggestion: GitHub PR showing a description section that links to .ai/brief.md and .ai/plan.yaml, a checklist of tasks (T-1 … T-4), and CI status checks for tests and linting marked as required.
Human review checklist
Automated checks rarely cover everything. Reviewers should:
- Open
.ai/brief.md and verify that the implementation matches user stories and non-goals.
- Cross-check
.ai/plan.yaml against the actual file diffs to ensure Codex did not touch files outside the plan.
- Confirm that new tests genuinely cover the acceptance criteria, not just happy paths.
- Verify operational constraints: feature flag behaviour, rate limits, logging, failure modes.
Cost and utilisation: structuring ChatGPT, Codex and Copilot
The core cost question is not “Which tool is cheapest?” but “Where should the expensive reasoning happen, and how often?” Using the documented prices, it is possible to reason about different scenarios. For a deeper breakdown of ChatGPT tiers and when API or paid plans make sense for planning-heavy workflows, see the separate breakdown on ChatGPT pricing for real work.
Scenario 1: solo builder, light usage
Assume three medium features per month. Each feature uses one substantial ChatGPT planning session on GPT‑4o‑mini and several Codex runs for implementation.
- Planning tokens: suppose a planning session uses 50k input tokens and 10k output tokens. At $0.15 per 1M input tokens and $0.60 per 1M output tokens(GPT‑4o‑mini pricing):
- Input cost per feature ≈ 50,000 / 1,000,000 × $0.15 = $0.0075.
- Output cost per feature ≈ 10,000 / 1,000,000 × $0.60 = $0.006.
- Total planning ≈ $0.0135 per feature, or ≈ $0.0405 for three features.
- Execution: Codex or Copilot credits will dominate here; the exact cost depends on usage.
Even if actual token counts are an order of magnitude higher, GPT‑4o‑mini planning remains cheap relative to a fixed $19/month Copilot Business seat, which includes 1,900 credits according to GitHub’s billing docs.
Scenario 2: small team with Copilot or Cursor
A team of 4 developers on Copilot Business pays 4 × $19 = $76/month, gaining 7,600 credits. They can adopt this contract as:
- ChatGPT (API or ChatGPT Work) for a handful of planning sessions per sprint; costs stay in the low single-digit dollars on GPT‑4o‑mini given the pricing above.
- Copilot or Cursor as the primary day-to-day coding assistant, burning credits while implementing tasks from
.ai/plan.yaml. Cursor’s limits and seat economics are covered in the dedicated Cursor pricing and real cost guide.
This avoids running every coding action on a high-end general model, while keeping reasoning on a model dedicated to occasional planning.
Scenario 3: heavier multi-agent usage
On a larger repo with frequent features, both planning and execution tokens grow. The cost benefit of this structured contract comes less from reducing total token use and more from:
- Lower rework: fewer failed or incomplete implementations, because Codex follows a precise plan.
- Less repeated context: ChatGPT can refer to and update
.ai/brief.md and .ai/plan.yaml instead of re-consuming the entire repo in every session.
- Reduced human review time: reviewers focus on plan compliance and acceptance criteria, not reconstructing intent.
ChatGPT-only vs Codex-only vs split stack
Qualitative comparison of coding stacks
| Stack |
Planning vs execution |
Repo awareness |
Cost control |
Human coordination |
| ChatGPT-only |
Everything in one chat |
Limited; relies on pasted snippets |
OK for small projects; planning and coding share tokens |
High; users copy context and diffs manually |
| Codex-only / IDE agents |
Inline coding help only |
Strong within open files / repo |
Per-seat (Copilot) or per-execution |
Medium; humans still define and track scope manually |
| ChatGPT → Codex contract |
ChatGPT plans; Codex executes |
Strong; plan encodes file paths & operations |
Reasoning isolated to planning tokens |
Low; contract is stored in .ai/* instead of chats |
If a team primarily wants inline suggestions while typing rather than feature-level planning and branch-wide edits, a Copilot- or Cursor-first workflow may be better; see the comparison of GitHub Copilot vs Cursor for detail.
Failure modes and how to design for them
A contract does not eliminate failure; it makes it visible and contained. The main failure modes and mitigations:
Spec drift between brief and plan
Problem: .ai/brief.md is updated (e.g. new non-goal added), but .ai/plan.yaml is not synchronised.
Mitigation:
- Require any change to
brief.md to be accompanied by a regenerated or manually updated plan.yaml.
- Enforce this via PR review: no merging
.ai/brief.md changes without a diff in .ai/plan.yaml or an explicit note why not.
Partial implementation
Problem: Codex stops after T‑2; tests or acceptance criteria for later tasks never land.
Mitigation:
- Use the PR template’s “Completed plan tasks” checklist to signal which tasks are done.
- Refuse to merge if tasks linked to critical acceptance criteria remain unchecked.
- Optionally, add a CI job that parses
.ai/plan.yaml and fails if any plan entries marked as required lack corresponding code changes or tests.
Over-broad refactors
Problem: Codex updates hundreds of files, renames components or changes APIs not mentioned in plan.yaml.
Mitigation:
- Guardrail in the Codex prompt: do not modify files not listed in
plan.yaml.
- Reviewer checklist: reject PRs that change out-of-scope areas.
- Smaller runs: limit each Codex session to one or two tasks.
Flaky or missing tests
Problem: Acceptance criteria reference tests, but the tests are brittle or incomplete.
Mitigation:
- Prefer simple, deterministic tests for AI-authored code.
- Reserve complex property-based or integration tests for human authors or a higher-touch workflow.
- Schedule a human review sprint focusing only on test quality if flakiness appears.
Rollback and containment
- Isolate all agent work on feature branches; avoid allowing Codex to push directly to
main.
- If a branch goes wrong, revert or delete it; the contract in
.ai/* remains as a record and can drive a clean re-implementation.
- Pin prompts and model choices via configuration so changes in model behaviour do not silently alter the contract.
For teams adding AI features to an existing SaaS, this structured contract pairs well with incremental rollout guidance in the separate piece on adding AI features to an existing SaaS.
Putting it together: a worked Next.js + Supabase example
This section walks through the full flow for the email signup feature in a Next.js + Supabase app.
1. Create the brief
- Open ChatGPT with GPT‑4o‑mini or equivalent.
- Paste the brief schema and a rough idea (for example, “Add email-based signup with rate limiting to the dashboard”).
- Guide ChatGPT to fill in problem, users, scope, constraints, success metrics and user-level acceptance criteria.
- Save the output as
.ai/brief.md and commit on feature/email-signup.
2. Generate the plan
- In a new ChatGPT session, paste
.ai/brief.md and the .ai/plan.yaml schema.
- Ask ChatGPT to output only YAML, including file paths, operations, dependencies and technical acceptance criteria.
- Review the plan: check file paths, ensure tests are listed, confirm no cross-cutting refactors slipped in.
- Save as
.ai/plan.yaml and commit.
3. Run Codex to implement
- Open Codex or an equivalent coding agent on the
feature/email-signup branch.
- Provide the handoff prompt pointing to
.ai/brief.md and .ai/plan.yaml.
- Ask Codex to execute
T-1 and T-2 only, then stop and summarise.
- Review diffs for these tasks; if acceptable, run tests (if any) and commit.
- Repeat for
T-3 and T-4, ensuring corresponding tests are created.
4. Wire into CI and deploy
- Ensure the GitHub Actions (or other CI) workflow runs tests under
tests/auth/ on every PR.
- Open a PR from
feature/email-signup to main, using the PR template so tasks and criteria are clearly listed.
- Wait for CI to pass: tests for signup, rate limiting and the feature flag must succeed.
- Reviewers validate the implementation against
.ai/brief.md and .ai/plan.yaml.
- Once merged, deploy to the appropriate environment. For a Next.js + Supabase app on Vercel, see the deployment guidance in the separate how-to on deploying a Next.js project to Vercel.
5. Governance and scaling
As this pattern is adopted across multiple features:
- Standardise the
.ai/brief.md and .ai/plan.yaml schemas across services.
- Use labels in the issue tracker to mark “contracted” features vs ad-hoc ones.
- For teams that prefer terminal-first agents, this contract can be executed by Claude Code or similar; see the detailed review of Claude Code as a terminal-first coding agent.
- For a broader view on how multi-agent workflows fit into the overall engineering stack by team size and maturity, see the overview of the best AI development stack in 2026.
What changes the decision
The structured ChatGPT → Codex contract is not the right default for every team or project. It becomes the right choice when feature-level control, auditability and multi-file changes matter. The decision flips in several conditions:
- The primary need is inline suggestions while typing. In that case, the overhead of maintaining
.ai/brief.md and .ai/plan.yaml is rarely justified. Use GitHub Copilot or Cursor as the primary tool, with ChatGPT planning reserved for occasional big features.
- There is no CI. Acceptance criteria cannot be automatically enforced without tests and checks running on every PR. The contract degenerates into documentation. Setting up at least a minimal CI pipeline first is advisable.
- The repo is tiny or the work is throwaway. If all relevant code fits comfortably in a single chat and manual review is trivial, running the entire loop inside ChatGPT or a single coding agent is faster.
- Governance and auditability are critical. In regulated domains or multi-engineer teams, versioned briefs, plans and CI-enforced acceptance criteria provide a paper trail that ad-hoc AI use cannot match. In this case, leaning harder into the contract pattern is beneficial.
- OpenAI tools cannot be used. The underlying idea is planner → executor with a repo-backed contract. Another strong reasoning model can substitute for ChatGPT and Codex can be replaced with Cursor, Claude Code or other repo-aware agents while keeping the same
.ai/* schema.
FAQ
Why not just use ChatGPT for everything instead of adding Codex?
ChatGPT is strong at reasoning, decomposition and explanation, but repo-aware tools like Codex, Cursor and Claude Code are better at making precise edits across large codebases. Splitting responsibilities lets more capable planning models be reserved for occasional, high-leverage reasoning, while repetitive file edits are offloaded to cheaper or per-seat agents. A formal handoff contract stored in .ai/* also reduces context-switching and copy-paste between tools and makes the workflow reproducible in version control.
GitHub’s official billing documentation shows Copilot Business priced at $19 per user per month with 1,900 AI credits included, grounding the article’s cost comparison between per-seat Copilot usage and per-token OpenAI planning.
How do I structure the handoff contract between ChatGPT and Codex?
Use a small, fixed schema:
.ai/brief.md for product intent and user-level acceptance criteria.
.ai/plan.yaml for implementation tasks, file paths, operations, dependencies and technical acceptance criteria.
Require ChatGPT to output the plan in that schema, then feed those files directly into Codex as part of its session context. Each plan entry should spell out which files Codex may touch and which tests or checks must be updated.
How do acceptance criteria actually get enforced in this workflow?
Translate criteria into automated checks wherever possible: tests, linters, type checks, basic performance budgets or contract tests. Wire CI status checks into the Git hosting provider so that PRs cannot merge until those checks pass. For criteria that cannot be automated (e.g. UX copy, visual layout), create a review checklist that explicitly compares the code changes with the acceptance criteria in .ai/brief.md and .ai/plan.yaml.
What does this workflow cost compared with just paying for GitHub Copilot?
GitHub Copilot Business is priced per user per month, with 1,900 AI credits included at $19/user according to GitHub’s billing docs. It is optimised for continuous inline assistance rather than infrequent planning. OpenAI’s GPT‑4o‑mini is billed per token, at $0.15 per 1M input tokens and $0.60 per 1M output tokens, which supports very low-cost planning sessions(GPT‑4o‑mini pricing). By keeping heavy reasoning in a small number of ChatGPT sessions and letting Codex, Copilot or similar tools execute most file edits, it is possible to gain more predictable and often lower total spend than if all reasoning and coding run on an expensive, general-purpose model.
Can tools like Cursor or Claude Code replace Codex in this workflow?
Yes. The core pattern is planner → executor with a repo-backed contract. Cursor can read .ai/plan.yaml and apply changes in an editor; Claude Code can consume the same artefacts in a terminal-first environment. The schemas in .ai/brief.md and .ai/plan.yaml remain unchanged; only the executor changes. For Cursor-specific execution patterns and costs, see the Cursor pricing and limits guide, and for Claude Code’s ergonomics, see the review of Claude Code for terminal-first workflows.