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.

PhaseCommandMain outputGate
Init/guild:init.guild/wiki/, a cheap-scan CodebaseMap, an architecture-map stubteam decision
Ideate/guild:ideate.guild/spec/<slug>.mdspec approval, team decision
Plan/guild:plan.guild/team/<slug>.<phase>.yaml, .guild/plan/<slug>.md, the PRDteam decision
Build/guild:buildHandoff receipts under .guild/runs/<run-id>/handoffs/per-lane review gate, team decision
QA/guild:qaA quality report and a computed release-gate recommendationrelease / blocker gate
Ops/guild:opsRunbook evidencepre-flight dry-run; risky steps always ask
Lifecycle phases around the run record.
Open full size

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:

  1. Incident and rollback are never autonomous.
  2. The first run is always interactive.
  3. Always-ask is unconditional for risky or destructive steps.
  4. 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.

A prompt passes through typed verb, then the class flag, then the deterministic classifier. A product idea routes to product-explore and then product-define. Anything the classifier is not confident about is sent back to you as a question.
Open full size

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:

CategoryMeaningWeight
strong-ideaAn explicit idea statement: "I have an idea", "my idea is", "I want to build a …", "prototype the concept", "explore whether"1.0
openerAn ideation phrase: "what if we built", "I wish there was", "could we build"0.6
specificityA product noun (app, tool, platform) or an audience term (users, customers)0.6
vetoEngineering 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:

  1. The net score (product weights minus veto weights) is at least 1.0.
  2. Either a strong-idea signal is present, or an opener appears together with a specificity signal.

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.

ClassEntry nodeShape
productintakeexplore, define, spec, team, plan, build, qa, close, release, harvest
researchrecallrecall, research, packet, harvest
debugrecallrecall, reproduce, fix, verify, harvest
opsops.first-runfirst-run, release, incident, monitoring, maintenance, harvest
initdetectdetect, 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.

  1. A typed verb. init, ops, research and debug bind their own class. ideate, plan, build and qa bind product.
  2. --class=product|research|debug|ops|init.
  3. 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=ops

A 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:

  • assumptions
  • evidence_needs
  • comparables
  • risks
  • recommended_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_stories
  • non_goals
  • risks
  • affected_surfaces
  • test_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 QA pipeline: SignalScan, SelectMatrix, RunChecks, G-quality, ReleaseGate, ending in RELEASE-READY or BLOCK.
Open full size

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:

ClassDisposition options
e2eselected, 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 records override: 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.

KeyDefault
defaults.quality.budget.per_class_minutes10
defaults.quality.budget.total_minutes30

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:

  1. In-phase panel. Producer qa-test-strategy. Challengers are security (always present) and architect (only when the multi_component signal fired). Each finding is closed by a rerun, an added check, or a named owner-accepted risk.
  2. 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 returns rework, 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.

ConditionVerdict
A selected class is failBLOCK
inconclusive with no owner-accepted riskBLOCK
A security, privacy or reliability gap with no owner-accepted riskBLOCK
None of the aboveRELEASE-READY
not_applicable, or a non-safety gapNever 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 it

Every 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/*.md for changed_files, evidence and followups. The machine truth is the embedded guild.handoff.v2 JSON 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.

#CheckFails when
1Tests passThe spec's acceptance command is missing or exits non-zero. A spec with no verifiable command is itself a fail.
2Scope boundaryAny 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.
3Success criteria matchA criterion has no corroborating evidence in the receipts or test output, even if tests pass.
4No open blocker follow-upsA follow-up in the receipts or review.md is phrased as blocking, for example "must fix before merge". Deferred items pass and carry forward.
5Assumptions reviewedYou dispute a specific assumption. Acknowledging the log passes. A disputed assumption becomes a blocker.
6aTaskCell artifact joinMandatory when TaskCells exist. task-cell-audit.js exits non-zero. Completion is never inferred from chat transcripts.
6bDispatch integrityaudit-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:

  1. Overall status, pass or fail.
  2. 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.
  3. 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_id
  • verify_path
  • review_path, carried forward from review
  • assumptions_path, now acknowledged
  • followups, 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.