The Workflow
Forge is built around one canonical spec-driven development (SDD) spine. Every change flows through the same phases, and the only thing that varies is how much of the spine a given change actually traverses. This page explains the spine, the foundation phases that run once, adaptive depth, and how artifacts are produced and promoted.
This is a reference page — it goes deep, on purpose, so you can look up exactly what a phase or gate does. If you just want a first walkthrough, read Getting Started instead and come back here later.
The canonical SDD spine
There is exactly one spine, in this order:
explore → propose → specify → plan → tasks → implement → verify → archive
Every change is a subset of this spine — never a different one. Adaptive depth (below) decides where a change enters the spine, but the ordering and semantics of the phases never change.
/forge.clarify is optional, not a spine phase
/forge.clarify resolves ambiguity in the spec before plan — but it is opt-in and lives outside the dependency graph: nothing in forge.continue or the status engine requires it or tracks its output the way specify, plan, or tasks are tracked. Skip it for a well-understood change; run it by hand when the spec still has open questions worth resolving before design.
You rarely type every phase by hand
/forge.new and /forge.continue drive most of the spine for you — new starts a change and gets you to a proposal, continue resolves and runs whichever phase comes next. /forge.ff blasts through all four planning phases (propose → specify → plan → tasks) back-to-back. See Entry commands for the full command reference.
Where review sits
Bounded adversarial review is not a tenth phase either. It is the gate that stands between a finished implementation and every delivery boundary — commit, push, pull request, and release:
review start opens right after implement, not after verify: independent final verification requires an already-active review transaction, so verify stays blocked until a review has been started and reaches a final-verification-ready state. review validate --gate is then re-run at every later boundary against the same content-bound receipt.
Three commands, and only the first one opens anything:
forge review start # freeze scope, derive risk tier, lenses, budget
forge review finalize --result <file> # record lens results and evidence
forge review validate --gate <gate> # check the receipt against a boundarystart freezes the target and selects lenses deterministically by risk — zero for a docs-only diff, exactly one focus lens for an ordinary change, the full 4R set for a hot path or a diff over 400 changed lines. finalize records the lens results and produces a content-bound receipt.
Plain-language recap: lens, receipt, risk tier
- A risk tier is just how much scrutiny a change earns, decided automatically from what it touches — a typo fix earns none, a payments change earns the full sweep.
- A lens is one specific angle of review (readability, reliability, resilience, or risk/security) — like having four different specialists each look at the same diff for their one area of expertise.
- A content-bound receipt is proof that a specific, exact version of the code passed review — it is tied to the file contents themselves (via a hash), so if the code changes even slightly afterward, the receipt no longer applies and review has to run again.
validate is then run at each boundary, with one of five gates:
| Gate | Runs before |
|---|---|
post-apply | anything else — immediately after implement |
pre-commit | git commit |
pre-push | git push |
pre-pr | opening the MR/PR, including forge deliver |
release | tagging and publishing |
Gates validate — they never re-review
forge review validate re-derives live Git evidence and checks the existing receipt against it. It never starts a lens, never opens a second review, and never spends a new budget. If the tree still matches the content the receipt was issued for, the gate passes; otherwise it returns non-zero and the loop must stop.
A gate that cannot validate reports why, and each answer has exactly one correct response — none of them is "run the gate again":
| Receipt state | What it means | What to do |
|---|---|---|
| missing | review was never run for this scope | run review start |
| scope-changed | the code moved on after the receipt was issued | open a new lineage |
| unrelated / ambiguous | no single receipt covers this tree | resolve the lineage explicitly |
| invalidated / escalated | new evidence withdrew the approval | a human decides; do not reopen automatically |
Where deliver sits
forge deliver is not a tenth phase. It opens the merge or pull request on whichever host this repo lives on, and it is a terminal command rather than a spine phase — the spine describes the state of the spec and the work, not the state of a review on your git host.
It does share archive's readiness gate, though: delivery refuses while any task is not done, listing the blockers and exiting non-zero, with --allow-incomplete as the deliberate override for opening a --draft early. So the two are siblings rather than sequential — you can archive without delivering, or open a draft MR before archiving:
forge issues create sits in the same place: it exports a change's remaining tasks as issues on the same resolved host, and can run at any point once tasks.md exists.
Foundation phases (run once)
Some phases establish standing project truth rather than describing a single change. These foundation phases run once and set the ground rules the spine operates within:
constitution— the project's non-negotiable principles and constraints.security— the security posture and requirements.infra— the infrastructure baseline.brand— brand identity and voice.design— the design system and conventions.
The forge init wizard's Foundation step lets you pick which of these to scaffold right away; it prints the matching /forge.* command for each one you check as your next steps. See Foundation Phases for what each one establishes and where it writes.
Keep the constitution current
The constitution is load-bearing. Conflicts against it cap your analyze quality score, so a stale constitution quietly drags down every quality assessment. See Best Practices.
Adaptive depth
"Adaptive" runs on two independent axes, and it is worth keeping them apart:
| Axis | Question it answers | Where it is decided |
|---|---|---|
| Per change | How much ceremony does this change need? | Triage, below |
| Per repo | What is relevant in this repository at all? | forge profile |
Per change: how much spine to run
Forge triages each change to decide how much ceremony it needs. This is per-change triage, not a per-project mode you switch on — different changes in the same project take different paths.
| Depth | When it applies | Path |
|---|---|---|
| Trivial | Docs, typos — zero executable code | Fast-forward straight to implement → verify |
| Standard | A bounded feature or fix | specify → plan → tasks → implement → verify → archive |
| Substantial / Hot-path | Auth, payments, security; cross-cutting; more than 400 changed lines; or the agent is unsure | The full explore → … → archive spine |
The human is always in control
Adaptive depth only ever picks a starting point. A human can always force a deeper path when a change deserves more scrutiny than the triage suggested.
Per repo: what is relevant here at all
The other half of "adaptive" is about the repository rather than the change. Forge builds a repo profile — stack (from marker files like go.mod or Cargo.toml), the test and lint commands verify will use, the resolved git provider, related repos, and a rough size band — and uses it to decide what is relevant here:
forge profileThe visible payoff is skill pruning: guidance that requires a stack this repo does not have is reported as skipped, so the agent's context isn't padded with Terraform advice in a repo with no infrastructure.
Reports today, prunes later
forge profile is read-only and reports the relevant/skipped split; it does not yet prune what install/sync inject. See Repo Adaptivity.
Test-driven by default
Strict TDD is the default posture: tests are written before the implementation they cover. Specifications use OpenSpec Given/When/Then scenarios combined with RFC-2119 language (MUST / SHOULD / MAY) so requirements are precise and testable.
Changes flow through .forge/changes/
Every change lives in its own directory under .forge/changes/ while it is in flight. When a change passes verify and is archived, its delta specs are promoted into the canonical specs under .forge/specs/, and the change itself moves into the immutable archive.
Phase-to-artifact map
Each phase produces a specific artifact on disk:
| Phase | Artifact |
|---|---|
propose | proposal.md |
specify | specs/<domain>/spec.md (delta spec) |
plan | plan.md (plus optional data-model.md and contracts/{interface-name}.md companions when the change introduces or modifies entities/interfaces) |
tasks | tasks.md |
verify | verify-report.md |
archive | moves the change to changes/archive/YYYY-MM-DD-<name>/ and merges deltas into specs/ |
See Project Structure for the full on-disk layout of a change directory.
Cross-cutting commands
Some commands are not phases at all — they are cross-cutting, callable at any time, and non-destructive:
analyze— produces a 100-point quality score for the current state.drift— detects code-vs-spec drift, classified as Ghost (code with no spec), Phantom (spec with no code), or Mutated (code and spec disagree).reconcile— brings code and specs back into agreement.refine— improves an existing artifact in place.recall— surfaces prior specs and decisions relevant to what you are about to write. Advisory: it informs, it never blocks.
A second group is read-only by construction — these commands report what forge sees and write nothing at all:
profile— the repo profile: stack, test/lint commands, provider, size, and which skills are relevant here.provider— the resolved git host for this repo and every related repo, with the CLI each one uses.workspace— this repo plus its declared siblings, their active changes, and the changes that span more than one of them.metrics— the harness rollup across every change, active and archived: verify pass rate, breaker, budget, waivers, timeline.
Because they are non-destructive, you can run these freely at any point without disturbing an in-flight change.
Review belongs to neither group. review validate --gate <gate> is one of Forge's four enforced controls: it fails closed, and a non-zero exit means the loop stops and escalates rather than retries. See Where review sits above.
Honest task status
Task status in Forge is deliberately honest. A task moves through these states:
backlog— not started.in-progress— being worked.blocked— cannot proceed.done— and only when its acceptance scenarios pass underverify.
Archive is gated on honesty
archive is blocked while any task is blocked or not done. A change cannot be quietly archived with incomplete work — a successful archive is a real signal that the change is finished and verified.
Next steps
- Commands — every command, as CLI and slash command.
- Configuration — override defaults like
strict_tddandadaptive_depth. - Project Structure — where artifacts live on disk.
- Circuit-breaker — how verify loops are bounded.
- Git Providers & Related Repos —
deliverandissues create. - Repo Adaptivity — the per-repo half of "adaptive".
- Adversarial Review — risk tiers, refuters, and the receipt.
- Bounded Autonomous Run — driving the loop, and stopping it.