The SDD Planning Loop
SCOPE → DECIDE → SYNTHESIZE → VERIFY → GATE → ↺
The SDD Planning Loop
SCOPE → DECIDE → SYNTHESIZE → VERIFY → GATE → ↺

This document is the single reference for running the SpecForge v2 planning pipeline on any project. It contains the workflow, every prompt you run, and the outputs those prompts produce. Nothing else is required to drive a planning session from an empty folder to a complete set of implementation prompts.
The Workflow
The pipeline is a loop over a dependency-aware artifact catalogue. It starts by classifying your project, then repeatedly picks the next eligible artifact, generates it, verifies it independently, and puts it in front of you for approval. When every required artifact is approved, the catalogue is complete and the Forge implementation phase can begin.

SCOPE runs once at the start. It reads your product description and writes docs/project_shape.md — a two-line classification (size + domain complexity) that DECIDE reads to filter the catalogue. Lightweight projects skip DDD and architecture entirely. Standard and complex projects pull in those tiers.
DECIDE runs once per artifact. It reads the catalogue, the decision log, and the project shape, picks the single most valuable eligible artifact, and writes docs/next-artifact.md. It also adds a row to docs/decision-log.md marking the chosen artifact in_progress.
SYNTHESIZE generates the artifact. It reads every approved prerequisite file for context, follows the catalogue’s prompt file, and writes the artifact to disk.
VERIFY reviews the artifact independently — adversarially. It reads the same prerequisite files and produces a review document with a verdict (PASS or ISSUES FOUND) and a list of assumptions for human confirmation.
GATE presents the findings to you. You type approved, provide feedback, or resolve open assumptions. On approval, GATE updates the decision log and the pipeline loops back to DECIDE.
How to Use This Document
-
Create a folder for your project. Drop inputs/product-description.md in it.
-
Copy catalogue.yaml into the project root.
-
Copy the five prompt files (1-scope.md through 5-gate.md) to prompts/.
-
Open a Cowork session and run the prompts in order, pasting each prompt into the chat when instructed.
Each prompt below is ready to paste. The SCOPE and DECIDE sections also show the actual output those prompts produced for the Personal Reading List example project, so you can see what to expect.
Companion Repository
The artifacts and implementation code produced by running this pipeline on the Personal Reading List are available at:
**github.com/mail2mhossain/personal_reading-list**
The repository contains the complete reference output for the Personal Reading List case study — the approved planning artifacts, the full SDD planning package, and the Gherkin .feature files. The React TypeScript reference implementation is built feature by feature following the backlog, with its accompanying test suite; the repository tracks that work in progress.
Use the repository as a reference, not a shortcut. The artifacts are specific to the Personal Reading List. Copying them into your own project gives you the wrong spec, the wrong backlog, and the wrong implementation prompts. The value of this pipeline is in running the prompts against your own product description and producing artifacts that reflect your domain. The companion repository shows you what a correct output looks like — it does not replace the process that produces one.
Step 1 — SCOPE
Run this once at the start of every project. Paste the full block below.
# SCOPE — Classify the Project
Read `inputs/product-description.md`.
Use the following definitions when deciding the overall shape of the project:
**size** is the scope of planning work the project warrants before implementation begins.
There are three sizes:
LIGHTWEIGHT — a small, focused project: a tool, a CRUD app, or a single-purpose
service. The domain is simple enough that a spec and a task breakdown are
sufficient. No formal architecture phase and no Domain-Driven Design are needed.
STANDARD — a moderate project with meaningful features, integration points, or
business logic. Requires a spec, an architecture plan, and a task breakdown.
DDD applies only if genuine domain complexity is present.
COMPLEX — a large or complex product with significant domain complexity, multiple
bounded contexts, or hard non-functional requirements. Warrants full DDD
strategic design and a formal architecture plan before any task breakdown.
**domain_complexity** measures how much genuine domain modelling the product needs.
LOW — a single coherent problem space. Consistent vocabulary, no distinct
subdomains with separate rules.
MEDIUM — two or more recognisably different areas of concern, but the vocabulary
overlaps enough that a shared model is workable.
HIGH — two or more areas with clearly distinct vocabularies, rules, or ownership
boundaries. A shared model would introduce leakage or ambiguity.
Now classify the project described in `inputs/product-description.md`. Produce:
1. **size** — one of `lightweight`, `standard`, or `complex`.
2. **domain_complexity** — one of `low`, `medium`, or `high`.
3. **rationale** — one or two sentences justifying both calls, citing the specific
sections of the product description that support them.
Be decisive and proportionate. Do not inflate a small tool into a full DDD project.
For every classification decision, cite the section of `inputs/product-description.md`
that supports your reasoning. Mark anything you are inferring rather than reading
directly with `ASSUMPTION:`.
Save the classification as `docs/project_shape.md` in this format:
size: “lightweight” domain_complexity: “low” rationale: “”
Then initialise the decision log. Check whether `docs/decision-log.md` already
exists on disk.
If it does NOT exist, create it with this exact content:
# Decision Log
artifact_id title status approved_at
If it already exists, do not modify it — a prior session's log is in progress.
The decision log is the single source of truth for which artifacts have been
produced and approved. Only the GATE prompt may write `approved` into it.
Only the DECIDE prompt may add new rows. No other prompt touches it.
SCOPE output — Personal Reading List
docs/project_shape.md:
size: "lightweight"
domain_complexity: "low"
rationale: "The product description (§ opening paragraph) defines a browser-only
SPA for a single user with no backend and no login — a self-contained CRUD tool
over one entity (Book). The only business rule beyond CRUD is auto-recording a
finish date on status change (§ 'Status Updates'), which lives entirely within
that single entity; there are no distinct subdomains, no separate vocabularies,
and no integration points that would warrant an architecture plan or domain
modelling."
Step 2 — DECIDE
Run this after SCOPE, and again after every gate approval. Paste the full block below.
# DECIDE — Choose the Next Artifact
Read the following files:
- `inputs/product-description.md`
- `docs/project_shape.md`
- `catalogue.yaml`
- `docs/decision-log.md`
Use the following definitions when computing which artifact to produce next:
An ARTIFACT is a planning document listed in `catalogue.yaml`. Each artifact has:
DEPENDS_ON — a hard list of other artifact ids that must be APPROVED in
`docs/decision-log.md` before this artifact is eligible. If any id in this
list is not marked `approved` in the log, the artifact is BLOCKED.
SOFT_DEPENDS_ON — a soft list of artifact ids whose files are used as context
during synthesis if they are approved, but do not block eligibility.
NEEDED_WHEN — a condition stating which kinds of project require this artifact.
Read it against `docs/project_shape.md`.
ESSENTIAL — if true, this artifact must be produced in every project regardless
of size or domain complexity. The plan cannot end until every essential artifact
is marked `approved` in `docs/decision-log.md`.
There are three possible states for each artifact:
APPROVED — the artifact id appears in `docs/decision-log.md` with
`status = approved`. It has been produced and accepted by the human.
It must not be produced again.
IN PROGRESS — the artifact id appears in `docs/decision-log.md` with
`status = in_progress`. It is currently being synthesised or verified.
Do not pick it again — wait for the gate to approve or reject it.
ELIGIBLE — the artifact id does not appear in `docs/decision-log.md` at all,
and every id in its `depends_on` list is marked `approved` in the log.
BLOCKED — the artifact id does not appear in `docs/decision-log.md`, and
one or more ids in its `depends_on` list are not yet `approved`.
Now decide which artifact to produce next. Follow these steps:
1. Read `docs/decision-log.md`. Build the APPROVED SET — every artifact id
whose row has `status = approved`. Build the IN-PROGRESS SET — every
artifact id whose row has `status = in_progress`.
2. Check every artifact in `catalogue.yaml`. Classify each one as APPROVED,
IN PROGRESS, ELIGIBLE, or BLOCKED using the definitions above.
3. From the ELIGIBLE set, remove any artifact whose `needed_when` condition
does not apply to this project. Use `docs/project_shape.md` to judge each
condition. Never remove an artifact marked `essential: true`.
4. If the remaining eligible set is empty and every `essential` artifact is
in the APPROVED SET, the plan is complete. Write a completion notice and
do not add any row to the log.
5. Otherwise, choose the single most valuable artifact from the remaining
eligible set. Prefer essential artifacts. Among essentials, prefer the one
whose dependencies were most recently approved (furthest along the chain).
6. Add one new row to `docs/decision-log.md` for the chosen artifact with
`status = in_progress` and `approved_at = —`. Do not modify any existing row.
Produce the following output:
1. **APPROVED** — list every artifact id in the approved set.
2. **BLOCKED** — list every blocked artifact id and name the missing approved
dependency blocking it.
3. **ELIGIBLE** — list every eligible artifact id after the `needed_when`
filter, with your one-sentence judgement of whether its condition applies.
4. **CHOSEN** — the id and title of the artifact chosen next, and one sentence
explaining why.
5. **PREREQUISITES** — list every file to read before synthesising: the product
description, every approved `depends_on` artifact path, and every approved
`soft_depends_on` artifact path.
Save the result as `docs/next-artifact.md`.
Then update `docs/decision-log.md` by appending the new row for the chosen
artifact with `status = in_progress`.
Only the GATE prompt may change a row from `in_progress` to `approved`.
Do not mark anything approved here.
For every eligibility decision, cite the `depends_on` entries and the log rows
that support it. For every `needed_when` judgement, cite the field in
`docs/project_shape.md` that supports it. Mark anything you are inferring
rather than reading directly with `ASSUMPTION:`.
DECIDE output — Personal Reading List (current state)
docs/next-artifact.md (shown at the point where seven essentials are approved and the pipeline is working through sdd-feature-prompts):
# DECIDE — Next Artifact
## APPROVED
spec, tasks, sdd-feature-backlog, sdd-gherkin, sdd-testing-strategy,
sdd-shared-infra, sdd-agents-md
## BLOCKED
| id | blocking dependency |
|---|---|
| ddd-subdomain-map | needed_when not met (lightweight, no domain complexity) |
| ddd-bounded-contexts | ddd-subdomain-map not approved |
| ddd-context-map | ddd-bounded-contexts not approved |
| ddd-strategic-review | ddd-context-map not approved |
| arch-module-structure | needed_when not met (no multi-module structure) |
| arch-assessment | arch-module-structure not approved |
| arch-event-contracts | arch-module-structure not approved |
| arch-outbox | arch-event-contracts not approved |
| arch-inbox | arch-event-contracts not approved |
| arch-cqrs-decisions | arch-module-structure not approved |
| arch-cqrs-read-models | arch-cqrs-decisions not approved |
| arch-final-review | arch-assessment not approved |
| arch-handoff | arch-final-review not approved |
| sdd-product-spec | needed_when not met (lightweight path) |
| sdd-surface-assessment | sdd-product-spec not approved |
| sdd-feature-spec | sdd-surface-assessment not approved |
| sdd-domain-model | sdd-feature-spec not approved |
| sdd-architecture-plan | sdd-domain-model not approved |
| sdd-page-map | sdd-surface-assessment not approved |
| sdd-integrated-review | needed_when not met (full SDD package only) |
| sdd-prompt-review | sdd-feature-prompts not yet approved |
## ELIGIBLE
| id | title | judgement |
|---|---|---|
| sdd-feature-prompts | Feature Prompts | needed_when "Always"; essential:true; both hard deps (sdd-feature-backlog ✓, sdd-shared-infra ✓) approved. Source: project_shape.md size=lightweight. |
## CHOSEN
**id:** sdd-feature-prompts
**title:** Feature Prompts
**why:** Only eligible artifact remaining; essential:true; both hard dependencies
approved. This is a `multiple: true` artifact — one detailed implementation
prompt per backlog item (BL-01 through BL-10), produced sequentially.
## PREREQUISITES
- `inputs/product-description.md`
- `docs/sdd/07-backlog-and-milestones.md` ← depends_on (sdd-feature-backlog)
- `docs/sdd/prompts/00-shared-infrastructure.md` ← depends_on (sdd-shared-infra)
- `AGENTS.md` ← soft_depends_on (sdd-agents-md, approved)
- `docs/sdd/scenarios/all-scenarios.md` ← soft_depends_on (sdd-gherkin, approved)
## Prompt file
`sdd/Step 13 - Generate Feature Prompts One at a Time.txt`
## Note on multiple: true
This artifact produces one file per backlog item. Synthesise each BL item
separately using the Step 13 prompt, verify each one individually, and gate
each one before moving to the next. The catalogue path `docs/sdd/prompts/`
is the directory; each file should be named for its backlog item.
ASSUMPTION: Feature prompt filenames follow the pattern `BL-XX-<slug>.md`
inside `docs/sdd/prompts/`. No naming scheme is mandated by the catalogue.
Step 3 — SYNTHESIZE
Run this after each DECIDE. Paste the full block below.
# SYNTHESIZE — Generate the Artifact
Read the following files:
- `docs/next-artifact.md` — the artifact chosen by the DECIDE step.
- `inputs/product-description.md` — the product being planned.
- `docs/decision-log.md` — to confirm the chosen artifact is `in_progress`.
- Every file listed under PREREQUISITES in `docs/next-artifact.md` that exists
on disk. These are the approved dependency artifacts that provide context.
Also read `catalogue.yaml` and find the entry whose `id` matches the CHOSEN
artifact in `docs/next-artifact.md`. Note its `prompt` and `parts` fields.
Use the following definitions when producing the artifact:
A PREREQUISITE FILE is any artifact whose id appears in `depends_on` or
`soft_depends_on` for the chosen catalogue entry, and whose row in
`docs/decision-log.md` has `status = approved`. Do not read files for
artifacts that are not yet approved — their content is not reliable.
A PROMPT FILE is the `.txt` file named in the `prompt` field of the catalogue
entry. If a prompt file path is given and the file is readable, follow its
instructions exactly to produce the artifact content. If no prompt file is
available, produce a well-structured markdown document appropriate to the
artifact `title` and `needed_when` description.
An ASSUMPTION is a design choice you make without explicit information in the
product description or prerequisite files. Mark every assumption on its own line
starting with `ASSUMPTION:` so the human reviewer can confirm or correct it.
Now produce the artifact. Follow these steps:
1. Read `docs/next-artifact.md` and confirm the CHOSEN artifact: its id, title,
path, and the list of prerequisite files.
2. Confirm in `docs/decision-log.md` that the chosen artifact id has
`status = in_progress`. If it is missing or shows a different status, stop
and report the inconsistency rather than proceeding.
3. Read all approved prerequisite files listed under PREREQUISITES in
`docs/next-artifact.md`. Do not read files for unapproved artifacts.
4. If the catalogue entry has a `parts` list, produce the artifact in sequential
parts:
- Run the first part prompt and write its output to the artifact path.
- For each subsequent part, read the already-written content as additional
context, run the next part prompt, and append its output to the same file.
If the catalogue entry has a single `prompt` file, use it to produce the
artifact in one call.
If neither `parts` nor `prompt` is available, produce a comprehensive
markdown document appropriate to the artifact title and `needed_when`.
5. Write the artifact. Begin at its first `# ` heading. Output ONLY the markdown
document — no preamble, no commentary before the heading. Every assumption
must appear on its own line starting with `ASSUMPTION:`.
Save the artifact to the `path` specified for it in `catalogue.yaml`.
Create any parent directories that do not yet exist.
Do NOT update `docs/decision-log.md`. The log is only updated by DECIDE
(adding in_progress) and GATE (marking approved). SYNTHESIZE never touches it.
For every content decision, cite the section of `inputs/product-description.md`
or the prerequisite file that supports it. Mark anything you are inferring
rather than reading directly with `ASSUMPTION:`.
Step 4 — VERIFY
Run this immediately after SYNTHESIZE. Paste the full block below.
# VERIFY — Independent Review of the Artifact
Read the following files:
- `docs/next-artifact.md` — identifies the artifact that was just produced.
- The artifact file at the `path` specified for the CHOSEN artifact.
- `inputs/product-description.md` — the source of truth for what the artifact
must describe.
- `docs/decision-log.md` — to confirm the artifact is currently `in_progress`.
- Every file listed under PREREQUISITES in `docs/next-artifact.md` that exists
on disk.
Also read `catalogue.yaml` and find the entry whose `id` matches the CHOSEN
artifact. Note its `verify_prompt` field.
You are an independent reviewer. You did not write this artifact. Your role is
to find problems, not to praise the work. Approach it as an adversary: assume
errors are present until you can prove otherwise.
Use the following definitions when classifying your findings:
ISSUE — a defect that can be fixed by rewriting the artifact. This includes:
contradictions with the product description, violations of a stated rule,
missing content that the artifact is required to contain, and internal
inconsistencies. An issue blocks approval.
ASSUMPTION — an open question that cannot be resolved by rewriting the
artifact. This includes design choices that depend on information not in
the product description, and working assumptions that need human confirmation.
An assumption does not block approval but must be surfaced for the reviewer.
When in doubt between ISSUE and ASSUMPTION, prefer ASSUMPTION. Rewriting
cannot resolve a decision that needs a human answer.
Now review the artifact. Follow these steps:
1. Confirm in `docs/decision-log.md` that the artifact id has
`status = in_progress`. If not, stop and report the inconsistency.
2. Read the artifact from top to bottom against the product description and all
prerequisite files. Check for: missing required content, contradictions with
source material, internal inconsistencies, and unjustified design choices.
3. If the catalogue entry has a `verify_prompt` field pointing to a readable
`.txt` file, read that file and follow its verification instructions exactly
in addition to the steps above.
4. Produce the review document with the following sections:
**Artifact reviewed** — id, title, and file path.
**Verdict** — either `PASS` or `ISSUES FOUND`. Use `PASS` only if there are
zero issues. Assumptions alone do not block a pass.
**ISSUES FOUND** — a numbered list. For each issue:
- State the problem clearly in one sentence.
- Cite the section of the product description or prerequisite file that is
contradicted or missing.
- State what change would resolve it.
Omit this section entirely if there are no issues.
**ASSUMPTIONS FOUND** — a numbered list. For each assumption:
- Quote or paraphrase the assumption as it appears in the artifact.
- State what information from the product owner would confirm or correct it.
Omit this section entirely if there are no assumptions.
**Summary** — one paragraph. If PASS, confirm what was checked and that the
artifact is ready for the gate. If ISSUES FOUND, summarise what must be
corrected before approval.
Save the review as the artifact filename with `-review` appended before the
extension. For example, for `docs/ddd/01-subdomain-map.md` save the review
as `docs/ddd/01-subdomain-map-review.md`.
Do NOT update `docs/decision-log.md`. Only the GATE prompt marks artifacts
as approved. VERIFY only produces the review document.
Do not soften findings to be polite. Do not invent issues that are not present.
Report exactly what you find.
Step 5 — GATE
Run this after VERIFY. Paste the full block below, then respond to the findings in the same chat.
# GATE — Human Review and Approval
Read the following files:
- `docs/next-artifact.md` — the artifact currently under review.
- The artifact file at the `path` specified for the CHOSEN artifact.
- The review file produced by the VERIFY step (`<artifact-path>-review.md`
with `-review` inserted before the extension).
- `docs/decision-log.md` — to locate the row for the artifact currently
`in_progress`.
You are assisting the human reviewer. Your job is to present the findings
clearly, wait for an explicit decision, and then update `docs/decision-log.md`
accordingly. You are the ONLY prompt that may write `approved` into the log.
Use the following definitions for the three possible reviewer decisions:
APPROVED — the reviewer accepts the artifact as written. Any listed assumptions
are acknowledged. The log row is updated to `approved` with today's date.
The pipeline advances: the reviewer runs `2-decide.md` next.
FEEDBACK — the reviewer wants something changed. They provide written
instructions. The log row stays `in_progress`. The reviewer runs
`3-synthesize.md` next, with the feedback included as a correction instruction
at the top of that prompt run.
RESOLVE ASSUMPTIONS — the reviewer has answers to one or more open assumptions.
They provide the answers in writing. The log row stays `in_progress`. The
reviewer runs `3-synthesize.md` next, with the resolved assumptions injected
as confirmed facts so the artifact can be updated.
Now present the gate. Follow these steps:
1. Show the artifact under review: its id, title, and path.
2. Show the verdict from the review file: PASS or ISSUES FOUND.
3. If the verdict is ISSUES FOUND:
- List every issue clearly and state what must be fixed.
- Tell the reviewer: "Type your feedback instructions and I will prepare
the correction brief for the next SYNTHESIZE run."
4. If the verdict is PASS:
- List every assumption found in the review, if any.
- For each assumption ask: "Do you want to confirm, correct, or accept
this as-is?"
- Tell the reviewer: "Type `approved` to accept this artifact, or provide
corrections or assumption answers."
5. Wait for the reviewer's explicit response. Do not proceed until they reply.
6. When the reviewer types `approved`:
- Update `docs/decision-log.md`: find the row where `artifact_id` matches
the chosen artifact and `status = in_progress`. Change its `status` to
`approved` and set `approved_at` to today's date (YYYY-MM-DD).
- Confirm to the reviewer: "Logged as approved. Run `2-decide.md` to
pick the next artifact."
7. When the reviewer provides feedback or resolved assumptions:
- Summarise the corrections or resolved assumptions clearly in a short brief.
- Do NOT update `docs/decision-log.md` — the row stays `in_progress`.
- Tell the reviewer: "Run `3-synthesize.md` and paste this brief at the
top as additional context."
Do not approve automatically. Do not update the log until the reviewer has
explicitly typed `approved` or provided feedback. The log update and the
reviewer's decision must happen in the same response — never pre-emptively.
Notes on the Loop
After approved: Run 2-decide.md. It reads the updated decision log, picks the next eligible artifact, and writes docs/next-artifact.md. Then run 3-synthesize.md → 4-verify.md → 5-gate.md again.
After feedback or issue resolution: Re-run 3-synthesize.md with the correction brief (produced by GATE) pasted at the top. Then verify and gate again. The decision log row stays in_progress throughout.
multiple: true artifacts (e.g. sdd-feature-prompts) produce one file per backlog item, gated individually. The log row stays in_progress until all instances are gated. DECIDE is not re-run between instances — only between artifacts. After the final instance is approved, the row advances and DECIDE picks sdd-prompt-review.
Catalogue complete: When DECIDE finds the eligible set empty and all essential artifacts approved, the planning phase is done. Hand the docs/sdd/prompts/ directory to the Forge agent for implementation.
AI-Assisted Software Engineering: Spec-Driven Development with Domain-Driven Design, BDD, and Generative UI, available at Gumroad. The book includes the full catalogue, the prompt library, and the Community Equipment Library case study — all DDD artifacts, architecture decisions, SDD planning package, and feature prompts — as a worked example.
메타데이터
- post_id
- 367f2510312e
- slug
- the-sdd-planning-loop-367f2510312e
- url
- https://medium.com/@mail2mhossain/the-sdd-planning-loop-367f2510312e
- canonical_url
- https://medium.com/@mail2mhossain/the-sdd-planning-loop-367f2510312e
- author_url
- https://medium.com/@mail2mhossain
- status
- ok
- fetched_at
- 2026-09-12 15:47:29