Lifecycle
Guild Stack does not jump straight to code. Work moves through six phases:
init → ideate → plan → build → qa → ops. Each phase has one command, one
main output, and a gate where you stay in control. You can run them one at a
time, or let /guild:guild [brief] propose where to start:
/guild:guild add a --version flag that prints the version from package.json
The Power layer below covers each phase and the intake routing in depth. The Architect layer shows the final done-gate that decides whether a run may close.
The six phases
Guild Stack work moves through six phases: init → ideate → plan → build → qa →
ops. Each phase has one command and one assembler skill. You can enter at any
phase. /guild:guild [brief] detects the phase for you and asks you to confirm.
| Phase | Command | Main output | Gate |
|---|---|---|---|
| Init | /guild:init | .guild/wiki/, a cheap-scan CodebaseMap, an architecture-map stub | team decision |
| Ideate | /guild:ideate | .guild/spec/<slug>.md | spec approval, team decision |
| Plan | /guild:plan | .guild/team/<slug>.<phase>.yaml, .guild/plan/<slug>.md, the PRD | team decision |
| Build | /guild:build | Handoff receipts under .guild/runs/<run-id>/handoffs/ | per-lane review gate, team decision |
| QA | /guild:qa | A quality report and a computed release-gate recommendation | release / blocker gate |
| Ops | /guild:ops | Runbook evidence | pre-flight dry-run; risky steps always ask |
Init
Init is cheap by default. It builds the wiki and, for an existing repo, a
cheap-scan CodebaseMap (an inventory of the repo) plus a confidence-tagged
architecture-map stub. The deep knowledge graph and the guided tour are not
built at Init. Add --learn (or set defaults.auto_learn) to run the full
learn pipeline.
Ideate
guild-brainstorm asks clustered questions until the spec covers seven
planning-contract fields: goal, audience, success criteria, non-goals,
constraints, autonomy policy, and known risks and rollback. It also rolls up
assumptions against blocking unknowns. The clarify loop runs when the resolved
loops include spec: by default at --rigor=standard and deep; quick
skips it.
Plan
guild-plan runs team composition first (see
Teams and specialists). Then it writes one
lane per approved worker. (Approved advisors, challengers, and reviewers are
not lanes; they act at their own gates.) A lane carries task-id, owner, depends-on:,
scope, success-criteria, autonomy-policy, and a seed complexity_score
and tier. The tier is re-scored at dispatch. The execution backend is resolved
once at intake, not per phase.
Build
guild-execute-plan runs each lane as an ephemeral cell: spawn at its resolved
tier, work, emit a guild.handoff.v2 receipt, dismiss. depends-on: decides
which lanes run in parallel. Before dispatch it assembles the lane's context
bundle and scores its tier (Cost and tiering).
After the lanes, guild-review checks the receipts in two stages: spec
compliance, then quality. It writes .guild/runs/<run-id>/review.md.
QA
QA runs only after a passing .guild/runs/<run-id>/verify.md. With no passing
verify, Guild Stack routes you back to Build; going on anyway is your decision, and the
quality report records it. guild-quality scans signals, shows you the
selected checks, runs them under the run sandbox and budget, and computes the
release gate. QA is opt-in: it is never auto-entered and never silently skipped.
A BLOCK override stays human-gated even under --auto-approve=all.
Ops
/guild:ops [runbook] picks one of five runbook classes: release, monitoring,
incident, rollback, maintenance. Four safety rails always hold:
- Incident and rollback are never autonomous.
- The first run is always interactive.
- Always-ask is unconditional for risky or destructive steps.
- The pre-flight dry-run is mandatory.
Auto-approve and rigor
--auto-approve[=spec,plan,build,qa,all] skips the named approval gates. It
never skips the team decision gate, and it never overrides a QA BLOCK.
--rigor=quick|standard|deep selects which loops run. For example, quick
skips the spec clarify loop.
The product loop and intake routing
When you describe work, Guild Stack first decides what kind of work it is. A vague product idea ("I have an idea for an app that tracks plants") enters the product loop. A bug fix, a review or a deploy does not.
Try it
Run the classifier on a prompt to see its verdict and the signals behind it:
echo "I have an idea for a budgeting app" | node "${GUILD_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$HOME/.local/share/guild/dist/claude-code}}/runtime/scripts/classify-intake.js"The output is JSON with intake (product_loop or other), a score, and every matched signals[] entry. Routing reads intake only, never the raw score.
The intake classifier
The classifier is deterministic. The same prompt always gives the same result. It uses signals and a threshold, not model judgment. It does no I/O and never throws. An empty or non-string prompt returns other.
It is tuned for precision over recall. A missed product idea costs you one question. A hijacked engineering prompt sends a run down the wrong path. The code states a design target of precision at or above 0.9 and recall at or above 0.8 over its fixture.
Signals fall in four categories:
| Category | Meaning | Weight |
|---|---|---|
strong-idea | An explicit idea statement: "I have an idea", "my idea is", "I want to build a …", "prototype the concept", "explore whether" | 1.0 |
opener | An ideation phrase: "what if we built", "I wish there was", "could we build" | 0.6 |
specificity | A product noun (app, tool, platform) or an audience term (users, customers) | 0.6 |
veto | Engineering or maintenance language: fix, bug, error, refactor, implement, deploy, migrate, test, endpoint, script, "/guild" | 1.5 (softer cues 0.75) |
The verdict is product_loop only when both conditions hold:
- The net score (product weights minus veto weights) is at least 1.0.
- Either a
strong-ideasignal is present, or anopenerappears together with aspecificitysignal.
A bare opener scores 0.6 and can never route on its own. A single veto weighs 1.5 and sinks even a strong idea. "I have an idea to refactor the auth module" routes to other.
When the verdict is product_loop, the next skill is guild:product-explore. Otherwise the normal lifecycle continues.
Workflow classes
Bare /guild:guild widens the product check to a six-way verdict: product, research, debug, ops, init, or other. Each class has one authored workflow graph under src/surfaces/graphs/. other means the classifier is not confident, and Guild Stack asks you instead of guessing.
| Class | Entry node | Shape |
|---|---|---|
product | intake | explore, define, spec, team, plan, build, qa, close, release, harvest |
research | recall | recall, research, packet, harvest |
debug | recall | recall, reproduce, fix, verify, harvest |
ops | ops.first-run | first-run, release, incident, monitoring, maintenance, harvest |
init | detect | detect, greenfield, brownfield, workspace, learn, harvest |
How the class is bound
The class is chosen in this order. The first match wins, and the classifier only fills silence.
- A typed verb.
init,ops,researchanddebugbind their own class.ideate,plan,buildandqabindproduct. --class=product|research|debug|ops|init.- The classifier. It scores each class. A class needs a score of at least 1.0, and a tie resolves to
other.
An unknown verb or an unknown --class= value is not downgraded to the classifier. Guild Stack asks you. research and debug are sub-verbs of /guild:guild, not separate command files.
/guild:guild debug
/guild:guild --class=opsA graph can hand off to another class mid-run with a change_class edge. For example, a debug run can move to product when "this is a feature, not a bug".
Product path: explore, then define
In the product graph, intake leads to product.explore, then product.define, then the spec.
product-explore turns the idea into .guild/explore/<slug>.json, schema guild.explore.v1. It has five required, non-empty fields:
assumptionsevidence_needscomparablesrisksrecommended_next_step
It validates with validateExploreV1, which fails closed on a missing field, an empty field or an unknown key. If the idea is too thin, it asks one to three clarifying questions rather than inventing content.
product-define takes a validated explore artifact and writes .guild/define/<slug>.json, schema guild.define.v1. This is the PRD nucleus. Its fields are:
acceptance_criteria, a list of{id, text}user_storiesnon_goalsrisksaffected_surfacestest_implications
Every acceptance criterion gets a stable, unique id (AC-1, AC-2). Those ids are the traceability tokens. A plan lane, a build receipt, a QA check and a release gate all resolve to them. validateDefineV1 fails closed on a duplicate or empty id. If the explore artifact is missing or invalid, define sends you back to explore.
The PRD and the approval gate
The plan always includes a PRD. By default it is an inline ## PRD section in .guild/plan/<slug>.md. It becomes a standalone .guild/prd/<slug>.md when any trigger fires:
- The plan covers more than one feature.
- The run is attached to an initiative.
- The spec has more than five success criteria.
On promotion, the plan keeps a one-line pointer to the standalone file.
There is no separate G-prd gate. The PRD is approved at the existing plan and PRD approval gate. The user-facing gates remain spec, team and plan.
The product graph
src/surfaces/graphs/product.yaml is the plugin default (guild.workflow_graph.v1, graph id product.default). A project overlay at .guild/graphs/product.yaml may reorder nodes or omit nodes marked required: false. It cannot drop a node marked required: true.
Three nodes are required: d5 (team compose), product.qa and d8 (initiative close). ideate and product.release can be skipped by the operator.
Edges include replan (plan back to spec, build back to plan, qa back to build) and escalate (build to d5). In the product graph, product.qa is the one review gate.
QA in depth
/guild:qa is the quality phase. On the engineering lifecycle it is opt-in: it
is never entered on its own and never skipped silently. On the product class
graph it is required: product.qa must pass before the product release step. It picks which checks apply, runs the ones your repo
already has, and computes a release recommendation. For the six-phase overview
see Lifecycle in depth.
The flow has five stages: SignalScan, SelectMatrix, RunChecks, G-quality, ReleaseGate.
Try it
/guild:qa # or /guild:qa <run-id>Requires a passing verify
QA runs after a passing .guild/runs/<run-id>/verify.md, never instead of it.
If verify.md is missing or failing, Guild Stack routes you back to Development and
says so. You may proceed anyway, but that is an operator decision. Your name and
reason are recorded in the quality report.
Team gate first
Before any participant is dispatched, the qa team is composed and approved. No
dispatch happens without a current approve decision. A stale or missing
decision fails closed. --auto-approve does not cover team approval.
Selection and the check run itself happen in the orchestrator session, so they
can proceed while the gate is pending.
Selection: SignalScan and the matrix
SignalScan reads signals on disk. It does not guess with a model. It decides each of five classes:
| Class | Disposition options |
|---|---|
e2e | selected, not_applicable: <reason>, or gap (the class applies but no harness was found) |
smoke | |
a11y | |
perf | |
integration |
No class is skipped silently. Guild Stack then shows the matrix and the estimated budget, and asks:
[proceed]runs the matrix as shown.[edit-selection]lets you change it. The report recordsoverride: user.[explain-signals]shows which signals led to each choice.
There is no --classes= flag. Selection is derived from signals, then you can
override it.
Running the checks
QA runs only harnesses it discovers. It never writes or installs a test
framework. Authoring a harness belongs to the qa-* specialists.
Sandbox. Checks run inside the run's task_run permission envelope. On top
of that, an always-ask hard set fires prompts inline, even under
--auto-approve. The set is release, security, ops and destructive.
Budget. Time per class and in total comes from defaults.quality.budget.
| Key | Default |
|---|---|
defaults.quality.budget.per_class_minutes | 10 |
defaults.quality.budget.total_minutes | 30 |
When a class runs out of budget, its result is inconclusive: budget exhausted.
It is never a silent pass.
G-quality: the advisory panel
G-quality is advisory. It never blocks on its own. It has two parts:
- In-phase panel. Producer
qa-test-strategy. Challengers aresecurity(always present) andarchitect(only when themulti_componentsignal fired). Each finding is closed by a rerun, an added check, or a named owner-accepted risk. - Cross-host review. A different host family critiques the report through
the review broker. It fires only on
risk >= high,review: cross/--review=cross, or when config requires it. Otherwise it is skipped. If it returnsrework, resolve the findings before the release gate. See Adversarial review.
ReleaseGate: computed, not asked
The recommendation is computed from the results. Each class ends as pass,
fail, inconclusive, not_applicable or gap.
| Condition | Verdict |
|---|---|
A selected class is fail | BLOCK |
inconclusive with no owner-accepted risk | BLOCK |
A security, privacy or reliability gap with no owner-accepted risk | BLOCK |
| None of the above | RELEASE-READY |
not_applicable, or a non-safety gap | Never blocks; shown in the gate summary |
You choose [release], [block] or [abort]. Choosing [release] on a BLOCK
is a human-only force-pass. Your name and rationale are recorded.
--auto-approve accepts spec, plan, build, qa and all. There is no
ops token. qa and all auto-pass a RELEASE-READY verdict only. A BLOCK
override is never auto-passed under any token, and Guild Stack prints that asymmetry.
What it writes
The report is .guild/runs/<run-id>/quality/<run-id>.md. It holds four blocks:
selection, results, challenger_trail and release_decision.
Ops runbooks read this report. A release or
rollback refuses to run on a BLOCK unless a human force-pass is recorded.
Verification and done
guild:verify-done is the last gate before a run may close. It reads files and says pass or fail. It does not redo specialist work, and it does not fix anything.
It runs after guild:review has written review.md with no open blockers. If any lane failed review, verify-done should not run. Control goes back to review.
The rule: evidence over claims
No completion or success language is allowed before an independent VCS diff confirms the change exists on disk. A claim of "done" is a hypothesis until the diff proves it.
The rule applies at two scopes:
- Per claim, in every lane. Before a specialist writes "done", "complete", "ready to hand off" or "tests pass", it takes a diff. It does not trust its own account of what it changed.
- Per run, in verify-done. The checks below apply the same rule across all lanes.
The per-claim diff uses plain git:
git status --porcelain # every modified, added, untracked path
git diff --stat HEAD # scope of the change
git diff HEAD -- <expected-paths> # the change is where the lane scoped itEvery scoped file needs a diff hunk. Every hunk must trace to the lane's scope. An out-of-scope edit is a finding, not a pass. The lane also runs the spec's checks and records the real exit status, never "it should pass". If any of this fails, the lane reports the gap with the diff output and keeps working. It does not claim completion.
What verify-done reads
.guild/runs/<run-id>/review.md, the per-lane table from review.- The spec's
success_criteria, from.guild/spec/<slug>.md. .guild/runs/<run-id>/assumptions.md, the assumption log collected from lane receipts. A missing or empty file means no assumptions to review. The gate hard-fails only if the file has unresolved disputed entries..guild/runs/<run-id>/handoffs/*.mdforchanged_files,evidenceandfollowups. The machine truth is the embeddedguild.handoff.v2JSON block. A receipt with only YAML frontmatter is not a valid machine receipt.- When present,
diff-learn.json(guild.diff_understanding.v1), for the brownfield scope cross-check.
The checks
The skill description names five checks. The skill body adds two more, for runs with TaskCells and for dispatch integrity. It stops at the first failure and records which check failed.
| # | Check | Fails when |
|---|---|---|
| 1 | Tests pass | The spec's acceptance command is missing or exits non-zero. A spec with no verifiable command is itself a fail. |
| 2 | Scope boundary | Any file in the union of lane changed_files is outside the scope of the lane that produced it. With diff-learn.json present, a changed file flagged as untraced that no lane scope covers also fails. |
| 3 | Success criteria match | A criterion has no corroborating evidence in the receipts or test output, even if tests pass. |
| 4 | No open blocker follow-ups | A follow-up in the receipts or review.md is phrased as blocking, for example "must fix before merge". Deferred items pass and carry forward. |
| 5 | Assumptions reviewed | You dispute a specific assumption. Acknowledging the log passes. A disputed assumption becomes a blocker. |
| 6a | TaskCell artifact join | Mandatory when TaskCells exist. task-cell-audit.js exits non-zero. Completion is never inferred from chat transcripts. |
| 6b | Dispatch integrity | audit-run-sinks.js exits 1: a lane ran on a downgraded backend, or a dispatch violated the tier contract. |
The skill body numbers both additional checks "6" and says "all six must pass". This page labels them 6a and 6b to tell them apart.
For 6b, a dirty run can pass only if you accept each named degradation or violation as an entry in the assumption log (check 5). An unreviewed degradation is a hard fail.
verify.md
Verify-done writes one artifact: .guild/runs/<run-id>/verify.md. It contains, in order:
- Overall status,
passorfail. - Per-check result, each with a mark and an evidence line: test command and exit code, scope-creep file list, criterion-to-evidence mapping, blocker follow-ups, assumption outcome, and the sink-audit block.
- Run summary: changed files grouped by lane, acknowledged assumptions, and open non-blocking follow-ups for the next plan.
The file is kept terse and grep-friendly. Reflect reads this file, not the specialist transcripts.
When it fails
On failure, verify-done annotates verify.md with the failing check and its evidence. It does not roll back, re-dispatch specialists, or amend receipts. It returns the path to verify.md and a one-line summary. You decide where to go next:
- Check 1, 3 or 4 failed: loop back to
guild:execute-plan. - Check 2 failed in a way that implies the plan was wrong: go to
guild:plan. - Check 5 failed: resolve the assumption dispute, or accept it.
Handoff to reflect
On pass, verify-done hands off to guild:reflect with:
run_idverify_pathreview_path, carried forward from reviewassumptions_path, now acknowledgedfollowups, the non-blocking list for the next task's plan
Reflect consumes the run summary, the handoff receipts and verify.md. It fires only after verify-done passes. See Lifecycle in depth for where verify sits in the six phases and QA in depth for the quality side.