# Quality Gates

Phase transition criteria. Every gate must pass before proceeding.

## Source of truth

The machine-readable canonical gate list lives at `hooks/config/gate-requirements.json` and is consumed by `hooks/scripts/gate-enforcer.sh`. This reference is the human-readable companion: it explains the gate model, lists pass criteria, and documents enforcement.

When the two disagree, the JSON wins — it's what actually fires.

## Core model

A **gate** is a verifiable pass criterion that blocks the next phase (or slice) from starting. v6 uses three flavors:

| Flavor | Scope | How "done" is signaled |
|---|---|---|
| **Phase-lock gates** | One per SDLC phase | `artifacts.{phase}.locked_at` timestamp written to the work manifest at end-of-phase. Downstream phases read this lock to know they can start. |
| **Per-slice gates** | Phase 6 only — one set per slice in `slice_graph.slices` | `slice_graph.slices.{id}.gates.{gate-name}.gate-passed: true` per gate, then the slice's `status` advances `pending → in-progress → gated → complete`. |
| **Hook-enforced gates** | Runtime — per-slice gates only | `gate-enforcer.sh` (PreToolUse hook) intercepts manifest writes that flip `gate-passed: true` and checks `.forge/state/telemetry.jsonl` for evidence that the required skill + agent were **invoked for this work item** before allowing the write. The enforcer scans `gate-passed: true` patterns specifically — phase-lock writes (`artifacts.{phase}.locked_at: <timestamp>`) are NOT hook-enforced; their integrity comes from the locking skill (`iterate-prototype`, `harden`, `deliver-deploy`) following its own protocol. Work-item-scoped per v6.2 — stale invocations from another work item or pre-`work_id` legacy records do NOT satisfy a fresh gate. Only gate names present in `hooks/config/gate-requirements.json` are enforced; slice-internal gates like `build-tdd` and `skeleton-runs` are not in the JSON and pass without invocation evidence (their content is verified by the calling skill, not by telemetry). |

### What telemetry proves (and doesn't)

This is **invocation enforcement**, not completion enforcement. Be precise about what the hook guarantees:

| Telemetry proves | Telemetry does NOT prove |
|---|---|
| The required skill was dispatched via the Skill tool during this work item | The skill produced correct output |
| The skill name + `work_id` were recorded before the gate write | The skill ran to completion (it could have errored partway or been aborted) |
| The workflow actually ran rather than being skipped | The gate's pass criteria were actually met |
| | The user reviewed the resulting artifacts |

Content verification is the calling skill's job (per its own Step N checks) and the user's job (final reviewer). The hook is a guardrail against silent skipping, not a substitute for review.

## Phase gates (v6 canonical)

The seven phases (per `references/common/phases.md`) and their lock signals:

| # | Phase | Lock signal | Required artifacts | Primary skill / agent | Pass criteria |
|---|---|---|---|---|---|
| 1 | Concept | `artifacts.concept.{deck_path, locked_at}` | Marp slide deck | `concept-slides` / `concept-designer` | User reviews + locks the deck |
| 2 | Wireframe | `artifacts.wireframe.{html_path, locked_at}` | Single-HTML annotated wireframe | `build-wireframe` / `wireframer` | User clicks through + approves all states |
| 3 | Prototype | `artifacts.prototype.{path, scaffold_status: complete}` (`path` + `scaffold_status` only — `locked_at` is written by Phase 4) | Runnable POC at `pocs/{name}-prototype/` | `build-prototype` / `prototype-builder` | Initial scaffold smoke-tests pass (dev server starts, screens render, in-memory state loads) |
| 4 | Iterate | `artifacts.prototype.locked_at` (sole writer — closes both Phase 3 and Phase 4) | Polished prototype + captured gotchas/conventions in `aiwiki/` | `iterate-prototype` / `prototype-reviewer` | User emits "satisfied" / "LOCKED" / "done" after click-through verification |
| 5 | Codify | `artifacts.codify.locked_at` (no path — slice_graph + `aiwiki/architecture/` ARE the artifacts) | Architecture pages, ADRs (with inline adversarial review), slice graph, oracles at `aiwiki/oracles/{slug}.md` | `harden` / `prototype-codifier` | User reviews architecture + ADRs + slice graph + dream proposal; `--size major` requires explicit adversarial sign-off on every ADR |
| 6 | Production-build | `artifacts.production-build.locked_at` (no path — slice `complete` state + production code ARE the artifacts) | Per-slice production code + per-slice review reports | `build-tdd` / `builder` + per-slice review chain | All slices reach `status: complete`; `code-review-final` passes the full diff. Note: `production-build` is not a single enforcer gate — Phase 6 is slice-driven, with `code-review-final`, `test-plan`, `test-execution`, `uiux-review` as the manifest-level closeout gates. |
| 7 | Deliver | `artifacts.deliver.{pr_urls, locked_at}` | PR(s) opened; deploy verified if applicable; onboarding docs updated for major features | `build-pr-workflow` / `deliver-deploy` / `deliver-onboarding` | PR opened with summary + test plan; deploy smoke tests pass; retrospective dream consolidates session captures. Note: `deliver` is not a single enforcer gate; the PR + deploy artifacts are the proof. |

## Per-slice gates (Phase 6)

Each slice in `slice_graph.slices` must pass its gate set before its `status` advances to `complete`. The gate set depends on slice type (per `templates/manifests/v5/feature.yaml`):

| Slice type | Gate set |
|---|---|
| **Feature slice** | `build-tdd`, `code-review`, `runtime-reach`, `wiki-lint` |
| **Skeleton slice** | `skeleton-runs`, `runtime-reach`, `wiki-lint` (no `build-tdd` — wiring, not behavior) |
| **Refactor slice** | `build-tdd`, `code-review`, `runtime-reach`, `wiki-lint` (same as feature) |

### Gate definitions

| Gate | What it verifies | Skill / Agent | Enforcement |
|---|---|---|---|
| `build-tdd` | RED → GREEN → REFACTOR cycle completed with passing tests, oracle assertions satisfied | `build-tdd` / `builder` | Slice-internal — content verified by `build-tdd` itself; not in `gate-requirements.json` |
| `skeleton-runs` | Skeleton scaffold compiles and smoke-tests pass | (slice-specific runner) | Slice-internal — not in `gate-requirements.json` |
| `code-review` | Safety → craft → reachability → gotcha-hunter chain passes for the slice's diff | `quality-code-review` / `craft-reviewer` | `gate-enforcer.sh` checks telemetry |
| `runtime-reach` | Every export in the slice diff has a production caller — no orphan exports | `support-runtime-reachability` | `gate-enforcer.sh` checks telemetry |
| `wiki-lint` | Any `aiwiki/**` writes during the slice pass schema, citation freshness, and `.md → .md` link integrity | `support-wiki-lint` | PostToolUse hook on every write (always-on, not slice-bound) |

Phase 6 closes when all slices reach `status: complete` AND `code-review-final` runs across the merged diff.

## Oracle satisfaction (Phase 5 → Phase 6 contract)

`harden` Step 2.5 produces an oracle page per slice that crosses a **wiring boundary** (CLI ↔ filesystem, process exec, manifest I/O, external services). Oracles live at `aiwiki/oracles/{slug}.md` and list concrete assertions the slice must satisfy: file paths, exit codes, error codes, state transitions.

In Phase 6, the `builder` agent loads the slice's oracle before writing a RED test. Production code must satisfy every assertion listed there. If oracles are missing for a wiring slice, the builder halts and surfaces the gap — `harden` owes the artifact. Silently inventing oracles or proceeding against an empty file re-creates the wiring-blindness that mock-heavy TDD has historically caused.

## Per-command gate flows

Each top-level command picks a subset of the phase-gate model. Use the row that matches your command:

| Command | Phases active | Gate notes |
|---|---|---|
| `/feature` | 1-7 (skip per `phase_plan` for trivial scope) | Standard prototype-driven flow. Trivial fast path (`--size trivial` or matching patterns at Step 0c) skips Phases 1-5 and jumps straight to Phase 6 (production-build), with `production-build, test-plan, code-review-final, deliver: active` and `gotchas: skipped` keeping Step 13 from running without aiwiki. |
| `/greenfield` | 1-7 | Same phase set as `/feature`. The `scaffold` gate is reserved in `gate-requirements.json` and the greenfield manifest's `phase_plan` includes `scaffold`, but the command currently transitions harden → production-build without a dedicated build-scaffold step (the prototype scaffold from Phase 3 carries through). |
| `/bugfix` | Phase plan: `debug-root-cause, production-build, code-review, deliver, gotchas` (per `templates/manifests/v6/SCHEMA.md` §3.2) | No prototype phases. The `debug-root-cause` checkpoint (root cause + evidence trail) is the critical flow milestone but is not in `gate-requirements.json` — flow label, not telemetry-enforced. `code-review` IS JSON-enforced. Step 5 (gotcha) skips when Step 0b bootstrap was skipped (trivial path). |
| `/refactor` | Discover → brainstorm → task-decompose → tdd → test-execution → deliver | Keeps the v5 brainstorm + task-decompose shape because refactoring against existing code has no wireframe/prototype phase. The brainstorm + task-decompose gates from §Legacy still apply here. |
| `/hotfix` | Compressed emergency flow | See §Hotfix gate exemptions. Every hotfix MUST create a follow-up ticket that completes the skipped gates. |

## Hotfix gate exemptions

The `/hotfix` command uses a compressed gate set for production-down emergencies. These exemptions are intentional, not bugs:

| Standard Gate | Hotfix Equivalent | Deferred To |
|---|---|---|
| Phases 1-5 (concept → codify) | Skipped | Follow-up ticket |
| `test-plan` + `test-execution` | Existing tests + smoke tests + regression test for the specific bug | Follow-up ticket |
| `code-review-final` (full two-pass) | Critical pass only (safety, no craft) | Follow-up ticket |
| `runtime-reach` | Skipped (assumes the bug is in already-reachable code) | Follow-up ticket |
| Onboarding doc update | Skipped | Follow-up ticket |

A hotfix without a follow-up ticket is incomplete.

## Gate outcomes

| Result | Action |
|---|---|
| **Pass** | Proceed to next phase or next slice. Write the `gate-passed: true` (or `locked_at`) signal. |
| **Warn** | Proceed with documented concerns recorded in the manifest. Surface concerns in the PR description. |
| **Fail** | STOP. Report what is missing. Return to the phase that owes the artifact. Do not write `gate-passed: true`. |
| **Blocked** | Cannot fully verify (e.g. flaky test infrastructure, missing oracle for a wiring slice). Proceed to PR with an `INCOMPLETE` flag visible in PR description + test results. Cannot deploy to production without resolution. |

## Softening

Phases are defaults, not requirements. The work manifest's `phase_plan.{phase}` field declares per-phase status — values include `active`, `active-light`, `active-commit-only`, `skipped`, `as-discovered`, `complete-inline`. A phase marked `skipped` does not run its gate; the resume rule reads the `locked_at` lock signal (or `scaffold_status: complete` for Phase 3) to decide whether to skip on resume. See `references/common/phases.md` for the softening rule and `templates/manifests/v6/SCHEMA.md` §3 for the full phase-plan vocabulary.

---

## Legacy gate sets (v4 / v5 — fallback only)

The v6 prototype-driven pipeline collapsed the v5 "brainstorm / architecture / task-decompose" trio into Phase 5 (codify, via the `harden` skill). The checklists below remain accurate for **v5 fallback** workflows (`/refactor` keeps brainstorm + task-decompose; `/feature` and `/greenfield` only land here for v4/v5 manifests still in flight) and as historical reference. New v6 runs do NOT surface `brainstorm-approved.md` or `architecture-approved.md` — their equivalents are `aiwiki/decisions/` and `aiwiki/architecture/`.

The transition labels below (`debug → build`, `tdd → code-review`, etc.) are v5 phase-transition checkpoints, NOT keys in `hooks/config/gate-requirements.json`. v6's JSON-enforced gate names are the ones listed in the v6 sections above.

### v5: requirements → brainstorm
- [ ] Every requirement has acceptance criteria
- [ ] Every requirement has a priority (must/should/could/won't)
- [ ] No implementation details in requirements
- [ ] User has reviewed and approved requirements

### v5: brainstorm → architecture
- [ ] User explicitly approved the chosen approach
- [ ] Rejected alternatives documented with rationale
- [ ] Approach is documented in `brainstorm-approved.md` (v5) or `aiwiki/decisions/` (v6 equivalent)

### v5: architecture → task-decompose
- [ ] API contracts fully defined (endpoints, request/response shapes, error codes)
- [ ] DB schema complete (tables, columns, indexes, constraints)
- [ ] System diagram created (ASCII or Mermaid)
- [ ] ZERO TBDs remaining in architecture documents
- [ ] Architectural decisions recorded in decision log

### v5: task-decompose → tdd
- [ ] Every task has: description, affected files, inputs, expected outputs
- [ ] Task dependencies identified (which block which)
- [ ] Parallel vs. sequential tasks marked
- [ ] Tasks reviewed by `spec-reviewer`

### v5: tdd → code-review
- [ ] All unit tests pass
- [ ] No skipped tests
- [ ] Coverage meets project threshold (80%+ default)
- [ ] Implementation matches API contracts from architecture

### v5: code-review → test-execution
- [ ] All critical review items resolved
- [ ] All important review items resolved or documented as accepted risk
- [ ] Security audit passed when changes touch auth, payments, encryption, PII, user-input handling that introduces injection/XSS surfaces, or external service integrations (see `quality-security-audit`)

### v5: test-execution → deploy
- [ ] Every test plan item has a pass/fail result
- [ ] Zero test failures
- [ ] Coverage report generated and meets threshold
- [ ] Traceability: every requirement maps to a passing test

### `/refactor` gates (still active in v6)

`/refactor` keeps the v5 brainstorm + task-decompose shape because refactoring against existing code has no wireframe / prototype phase.

#### discover → brainstorm
- [ ] Codebase analysis complete and approved by user
- [ ] Refactoring scope, rationale, and constraints documented

#### brainstorm → task-decompose
- [ ] User approved refactoring approach
- [ ] Rejected alternatives documented

#### task-decompose → tdd
- [ ] Tasks reviewed and approved by user
- [ ] Dependencies and parallel/sequential execution marked
- [ ] Coverage baseline recorded

#### tdd → test-execution
- [ ] All phases complete, per-task code reviews passed
- [ ] All tests pass on merged result
- [ ] Coverage equals or exceeds baseline
- [ ] Any test breakage during refactoring was reverted — not fixed by adjusting the test to match new behavior

#### test-execution → assessment
- [ ] All tests pass
- [ ] Coverage equals or exceeds baseline from Step 0

#### assessment → deliver
- [ ] Before/after summary produced (quantitative + qualitative)
- [ ] User has reviewed the assessment
- [ ] Assessment feeds into PR description

### `/bugfix` gates (mostly unchanged in v6)

#### debug → build
- [ ] Root cause confirmed with evidence trail
- [ ] Debugging summary produced (root cause, evidence, hypotheses tested)
- [ ] User reviewed root cause analysis

#### build → code-review
- [ ] Regression test written and passes
- [ ] All existing tests still pass
- [ ] Fix is minimal — no unrelated changes

#### code-review → deliver
- [ ] All critical and important review items resolved
