Forge takes each change from an approved plan to a merged pull request. Whenever you
are unsure, run forge next: it says where things stand and gives the exact next command.
If Forge started you with a brief, as a worker or a cold reader, that brief is your job: follow it and the Rules below, and leave the flow and the approval steps to the agent coordinating the work.
- Every idea starts with
forge start "<idea>". Forge picks a fix, a plan, discovery or the idea list. Never ask the human whether it is a story or a fix. - A plan gets rounds of cold read (
forge read <KEY>) until no notes block building, then one approval from the human. - Each task runs in its own branch and worktree:
forge task start <KEY>/<TASK>, thenforge work <KEY>/<TASK>. forge close <item>closes it when the tests pass and the review finds no serious problem.- The human merges unless the default branch's
forge.tomlhasmerge = "agent". Then, once close says Ready, the agent runsforge merge <item>. The story's last task merge records it done, using--outcome "<outcome>"or its title. Useforge story doneon an existing work branch only to change that outcome later; it opens no separate pull request.
Send every idea through forge start "<idea>". Forge picks the lane.
- Story: anything that changes an interface or needs more than five code files.
- Fix: a small change with at most five code files and no interface change. Specs, decisions, the roadmap and discovery notes ship as fixes.
- Discovery: one question when Forge cannot guess the problem.
- Idea list: only when the owner says later. Forge keeps the idea in
plans/ideas.md.
| The human says | Run |
|---|---|
| "Make it a story" (a fix) | Add the key to the fix's roadmap and commit it, then forge story new <KEY> --from-fix <fix> |
| "Make it a fix" or "Just fix it" (a plan in planning) | forge fix start "<its Problem>" --done "<its first Done-when>", then forge story drop <KEY> --because "Moved to the fix <fix>" |
| "Do it later" (a fix) | forge fix drop <fix> --because "The owner wants it later", then forge start "Do this later: <its why> (kept on fix <fix>)". fix drop --undo brings it back |
| "Do it now" (an idea-list entry) | forge start "<the owner's new words>: <the entry's idea without its deferral words>", for example forge start "Do it now: add dark mode". Then remove the entry from the main checkout's file while it is waiting, or else in the new item's branch |
forge.toml's workers picks who builds; forge work and forge next name the worker for
each item:
codex: every task and fix on Codex, user-facing ones with the design model's codex entry.claude: every task and fix on Claude.split: user-facing story tasks on Claude, everything else on Codex.
- Before adding complexity for a speculative or vanishingly unlikely race or security edge case, explain the concrete failure mode, likelihood, and complexity cost to the user and get their buy-in. Do not silently expand scope for theoretical robustness.
Mainline Deploy is available to install through the organization's plugin catalog. Do not assume that the plugin and MCP are installed or that the user is signed in. Use Mainline Deploy only when the user explicitly requests deployment. First check whether it is installed in the current host. If it is missing, use the organization's plugin catalog and the host's installation flow. Do not invent an installation command or marketplace address. Then follow the Mainline Deploy skill. Check OAuth sign-in and have the user complete it if needed. Wait for successful authentication before deployment. Installation alone does not mean the user is signed in. Deploy only the requested app to the requested environment. A build, fix, merge, ship/land request, successful test or review, demo preparation, or Forge next step does not by itself authorize deployment. Do not install Mainline or start OAuth sign-in for those requests. An explicit request such as "deploy this to staging" or "publish this on Mainline" needs no separate routine deployment approval.
- Never commit to the default branch. Work happens on a story, task or fix branch, and the git hooks refuse anything else.
- Never run
gh pr mergeor use--no-verify. The agent merges only throughforge merge <item>when the default branch allows it;merge = "human"is the default. - Ask the human only to approve a story, to choose between options, or to merge when the repo keeps the human merge setting.
- No running commentary. Speak only when something merges, when a failure or finding needs the human, or when a decision is theirs, in a line or two.
- Write every reply, summary and question for a human in plain English that a non-native speaker understands on the first read. Use everyday words, not agent slang: important, not load-bearing; merge, not land; what it affects, not blast radius; easy mistake, not footgun; start, not spin up. Explain each technical term the first time it comes up. Use no IDs, hashes or jargon in questions, pull request summaries or the board, except story keys shown small beside titles on the board. Notes and prompts for other agents are exempt.
- Report progress in plain sentences: what changed, what failed, what comes next. Start with three lines, and add detail only when it changes the next action. Use no emoji checkmarks, no "Successfully", no "Perfect" and no wall of bullets.
- Never make anything sound more certain or more finished than it is. Keep numbers, uncertainty and status (planned, in progress, done) exact. A correlation stays a correlation, and a plan stays a plan.
- A story is approved through Plan Mode: exit Plan Mode with the text of the story doc that
forge nextnames, unchanged, as the plan: from its title down to## For the builders, or the whole doc when it has no such heading. The approval matches its "What changes for you" and "Done when" sections exactly, so a summary or a rewrite records nothing, and an edit below## For the buildersneeds no new approval. There is no other approval step. - Run long
forge workruns in the background and keep watching them. - When Forge itself misbehaves (a wrong or confusing message, a refusal that shouldn't happen, a crash, a command that reports success but did nothing, generated files that contradict each other), file a bug on Forge's GitHub with the Forge bug template's sections, fill every one, and leave out the repo's code, names, paths and secrets: describe what Forge did. The forge guide has the sections and the command.
- Put the rules every review of this repo must follow under
## Review rules, outside the forge:begin and forge:end lines. Forge's review reads them from the default branch.
Forge is a product for client repos, and this repo builds it with Forge's own process: every change is dogfooded on Forge itself before clients get it.
- A rule, step or tool that makes planning, building, testing, reviewing, merging or releasing
better belongs in what Forge ships to every repo (
src/forge/templates,forge sync,forge init). Only what is about Forge's own code lives in this repo's files. Ask first: would a client repo want this too? - Every change says what a new client repo and an existing client repo each get.
- Forge's own principles and its own test policies (such as the real-Codex tests) live here, not in the shared standards.
- Report as P1 any screen, page, route table or app shell that a change adds under
src/forge/templates/starterorsrc/forge/templates/starter-python. - A change to Forge says what a new client repo (init or adoption) and an existing client repo (on upgrade to the new release) each get. Each rule keeps its full cases on a new repo plus at least one case on an existing repo adopted on an earlier release. Keep more existing-repo cases only where Forge takes a different path for it. Report a change that covers only one side, or only Forge's own repo, as P1. Report extra existing-repo cases that repeat the new-repo path as a deletion candidate, not a gap. A release's version bump changes no behaviour and needs no new upgrade test.
- A change to what a coordinator or worker should do or can use (a command, an option, a setting,
a step in the flow) updates
src/forge/templates/skill.mdor the worker brief (src/forge/templates/brief.md) in the same change. Report a missing update as P1.
These govern every change to Forge, as they govern every app that Forge builds.
- Is it needed at all? Deleting beats fixing.
- Add work only when F x H >= 2 x C: how often the problem happens (F) times how bad it is (H) is at least two times the cost (C). Score each from 1 to 3. F, for the first 1,000 users: 1 rare, 2 weekly, 3 daily. H: 1 cosmetic or the person's own data, 2 wrong information or a broken step, 3 a P0. C: 1 for 20 lines or fewer with no model call or user step, 2 for up to about 150 lines or one model call or user step, 3 for more, or a new table, job, workflow or flag.
- Choose the simplest option.
- Forge does the right thing by default where it can. It refuses only when a mistake costs a lot or is hard to undo. It states a rule only when a mistake is cheap and something later catches it. People should not need to know how to use agents well for Forge to work.
These govern Forge itself. Each has a check: an acceptance criterion, a CI check or a review instruction.
- Every artifact serves a client-visible change or is cut. Check: every story doc starts with "What changes for you".
- One home per fact: history in git, review and tests in the PR, current state in
.factory. Check: no command writes a fact git or GitHub already holds. - Gates check outcomes, never rituals: refuse only on real problems — a red test, a P0/P1 finding, a missing approval, or input Forge cannot act on (a malformed doc, the wrong version, a branch outside the lanes). Check: every refusal names the real problem and the next action.
- Fail loud, early, once: enforce at the command or commit, never silently. Check: a behaviour test for every refusal message.
- No rule without a test; no test without a rule. Check: the suite maps one test to one rule and tests no internal record format.
- Forge shrinks over time: every story removes at least as much process as it adds. Check: no module over 1,200 lines, a fixed ceiling on
forgecommands, refactor ratchet in CI. - Adapt to third parties, never mirror them (Autoreview, Codex, Claude, GitHub): read only used fields, tolerate new ones, pin versions. Check: one boundary contract test per external tool.
- The agent does the work; the human decides (approve a story, choose between options, merge). Check: human touches per story are counted; target three or fewer.
- Same result from any agent: logic in
forgecommands and git, thin host adapters. Check: the same behaviour tests run through both adapters. - Slow is a bug: close in minutes, CI under 5 minutes. Check: time per step is recorded and shown on the board; over-budget steps get fixes.
- Plain English wherever a human looks: no IDs, hashes or jargon on the board, in PR summaries or in questions; the one exception is a story's own key, shown small beside its title on the board so similar titles can be told apart. Check: reviewed on board and PR text.
- Reversible by default: every change and every migration is one PR; rollback is a revert. Check: no command changes a client repo outside a branch and PR.
- Measure the factory: task cycle time, human touches per story, share of PRs fixing Forge instead of the product. Check: these three are the rebuild's success measure.
- Before each builder round ends, run the cheap repo checks with
uv run --frozen --python 3.11 pytest -q tests/test_rules.py::test_4_one_test_per_rule tests/test_rules.py::test_5_forge_stays_small. This step also applies in CI test mode. Fix failures in the same round, rerun the failed checks, and commit the repairs. These existing checks cover duplicate rule labels, tests with no rule, and files over 1,200 lines. - Each rule keeps its full cases on a new repo plus at least one earlier-adopted repo case. Keep more adopted-repo cases only where Forge takes a different path for it. In a test audit, report extra adopted-repo cases that repeat the new-repo path as deletion candidates, not gaps.
- Tests run the forge command and never import forge.
- A test that calls a real Codex model runs only when FORGE_LIVE_CODEX=1 (the codex-smoke workflow sets it); don't set it in local runs.
- A general process rule (how to plan, build, test, review, merge or release) added only to this
repo's files instead of what Forge ships is P1: it belongs in
src/forge/templatesor a command.