oah helps you build an AI development workflow that fits you and keeps changing as AI improves. It is a working reference and a guide you can adapt.
A useful result needs more than generated code: the scope must be clear, the changes checked, and decisions kept for the next session. oah connects those steps so one request can carry through the work with a record of what happened.
002 / Why it keeps changing
Older rules and skills can hold a newer model back or make its results worse. Defaults should be easy to understand and change; a rule that gets in your way is a design problem to fix.
Keep the parts that help, remove what no longer helps, and revise the workflow as your tools improve. You can start with the full setup or take only the impact map, wiki, leases, evidence gates or review loop that your project needs.
003 / Why Claude builds and Codex reviews
This split comes from the author's own experience, not a measured comparison: Claude fills in details a beginner might miss in a first version; Codex checks and corrects within a fixed scope.
The current commands run Claude Code and Codex CLI. The ideas can also be adapted to another tool or harness, with one AI or several. Give each stage to the AI that suits your work.
004 / From one request to a checked change
Describe the result you want in plain language. The AI records the goal and scope, checks what the change touches, reserves its paths and chooses the tools for the task. Claude builds; Codex reviews, corrects and reviews again.
Gates record the checks and their results. The project wiki keeps the decisions and reasons beside the code. In v0.3.0, optional TypeSafe Jev can judge difficulty for model selection; rules remain the fallback when it is unavailable or uncertain.
005 / The decisions stay with you
You ask, answer when the AI needs a decision, and confirm before the change lands. If the same problem repeats or the work reaches a design choice, the loop stops to ask you.
Ask “Is the review done?” or “Did all the gates pass?” and inspect the evidence. The final confirmation belongs to you; writing code, checking it and approving its landing are separate steps.
006 / Free, open source, yours to adapt
oah is free, open-source software under the MIT license. Read the source, change it and bring the useful pieces into your own workflow. Your AI services and any optional services use their own accounts and billing.
The current v0.3.0 release supports macOS and native Windows, and expects familiarity with git and pull requests. Install it, run oah init in your project, then try the small hello-oah example. The installation and documentation sections explain each step.
A packet holds everything about one task: intent, scope, plan, acceptance gates and return format. The intent states the problem, desired outcome and checkable success conditions, must be accepted before it binds to a lease, and travels byte for byte to every stage, worker and reviewer. Every return ends with one AC line per success condition.
When you need it
When the goal lives only in a chat, each stage and reviewer works from a slightly different version of it, and “done” drifts away from what you actually asked for.
How it works
oah packet new <task> writes .oah/tasks/<task>/PACKET.md from a template and scores the stage routes into its ## Plan; oah packet check <task> says what is still missing.
The intent holds Problem, Desired outcome and Success conditions (AC1, AC2, …). Success conditions are outcomes you can check, not process steps.
Status: draft cannot be bound to a lease (OAH_INTENT_NOT_ACCEPTED). Intent-ID never changes; a changed goal raises Revision, which you accept and rebind.
oah intent show <task> prints the binding state: current, stale, missing or unbound.
Every return ends with INTENT <id>@r<n> <digest> and one AC<n>: met|unmet|deferred — <evidence> line per success condition, checked by oah finish --return and each review round.
oah preflight --task T aborts when your branch is behind or another lease holds your paths, warns about a dirty tree or new commits touching your scope, and lists what it did not prove.
Example
The intent filled in for the worked example's task.
Status: accepted
### Problem
`python hello.py` always prints `Hello, world!`; it cannot greet a person by name.
### Desired outcome
`python hello.py Ada` prints `Hello, Ada!`, and without a name it still prints `Hello, world!`.
### Success conditions
- AC1: `python hello.py Ada` prints `Hello, Ada!`.
- AC2: the unit tests pass, including a test for a name.
Requirements
A Scope with at least one path, or - repo for the whole repository; oah packet new <task> --scope <path> fills it for you.
Limits and recovery
An empty ## Scope warns OAH_SCOPE_EMPTY, and oah start --packet refuses it.
Template placeholders left in the intent refuse with OAH_PACKET_PLACEHOLDER.
Editing the packet after binding makes the binding stale (OAH_INTENT_NOT_CURRENT): restore it, or raise Revision, accept and rebind.
A return that does not match the bound intent refuses with OAH_INTENT_RETURN_INVALID.
Preflight warnings do not stop you; an ABORT verdict (exit code 2) must be fixed first.