SDD Workflow Guide

SDD Workflow Implementation Process SDD Workflow Implementation Process SDD (spec-driven development) is one chain that takes a rough idea to a merged PR. It joins two systems that already existed in this repo but did not talk to each other: OpenSpec (OPSX), which produces the written spec and task list, and Superpowers, which does the actual implementation work. The rule is simple:
OpenSpec owns what to build. Superpowers owns how it gets built.
The workflow covers four independent OpenSpec roots: Mobile roots are outside this workflow.

Why This Exists

Before this, both systems were installed and both wanted to be in charge. That caused three concrete problems. Two plans competed. /opsx:propose writes tasks.md. superpowers:writing-plans writes its own plan file. Nothing said which one was authoritative, so an agent could implement from one while the other quietly went stale — and reviewers would read the stale one. Agents had to guess which code review to run. Saying “review this” could mean any of five things: code-review-to-github, code-review-workflow:respond, review-fix-loop, pr-workflow, or the built-in /code-review. Two of those are deliberately partial — code-review-to-github reviews but cannot post to GitHub, code-review-workflow:respond posts but needs threads to already exist — so picking the wrong one fails silently and looks like it worked. The chain had no PR step. The review skills operate on an open GitHub pull request, but nothing in the workflow created one, so review had nothing to attach to.

What’s Good About It

The Chain

Every arrow is a manual gate. No step auto-chains into the next. PR creation, merge, and archive are outward-facing or hard to undo, so a human decides when they happen.

Step-by-Step Guide

Run everything from the root that owns the change — backend/go, backend/bun, frontend/astro, or frontend/solidstart. Each has its own openspec/ directory; they are separate OpenSpec roots, not one shared one.

Step 1 — Brainstorm

Explore the requirement, the alternatives, and the direction before any spec exists. This is the only step where the shape of the work is still open. Once brainstorming has run, skip /opsx:explore — it covers the same ground.

Step 2 — Propose the change

This generates the OpenSpec artifacts in openspec/changes/<change-name>/: The schema is picked up automatically from openspec/config.yaml, which is set to spec-driven-superpowers in both backend roots and spec-driven-superpowers-fe in both frontend roots. You do not need to pass --schema.

Step 3 — Check the task shape

This is the one artifact that differs from stock OpenSpec, so it is worth a look before executing. Backend tasks use a **TDD:** line:
Frontend tasks use **Verify:** instead:
Choose exactly one verification method per frontend task: If a task needs two methods, split it into two tasks — for example, logic under TDD and presentation under render-test or browser. The WHEN/THEN scenarios in specs/ already provide the BDD layer; do not duplicate them in Cucumber, .feature files, or a Gherkin runner. Rules both schemas enforce:
  • The checkbox line is the task. Never add a bare - [ ] Complete at the end of a task block. The parser captures the checkbox text as the task name, so every task would end up named “Complete” and openspec status becomes unreadable.
  • One task = one meaningful, independently-shippable outcome. No micro-steps. If a task cannot be verified on its own, fold it into its parent.
  • **Depends on:** names other task numbers, or none.
Verify the parse before moving on:
Task descriptions should read as real sentences (2.1 Add PostgreSQL reservation repository), and schemaName should be spec-driven-superpowers for backends or spec-driven-superpowers-fe for frontends.

Step 4 — Execute

Or just /sdd:execute — it infers the change from context, auto-selects when only one is active, and asks when ambiguous. This is the only step with automation inside it. The skill:
  1. Resolves the change and loads openspec instructions apply --json, reading every file in contextFiles.
  2. Checks schemaName (see legacy changes below).
  3. Picks the next unticked task, verifying its Depends on: prerequisites are already [x].
  4. Dispatches that one task to superpowers:subagent-driven-development. Backend tasks follow superpowers:test-driven-development; frontend tasks follow their stated **Verify:** method. On an unexplained failure it uses superpowers:systematic-debugging before any fix.
  5. Ticks - [ ]- [x] once the task’s verification passes and its acceptance criteria hold: green tests for TDD, render-test, and e2e, or a reported browser check for browser.
  6. Loops until no unticked tasks remain.
  7. Runs openspec validate "<name>" --strict and superpowers:verification-before-completion.
  8. Prints Next: /pr-workflow:create and stops.
Tasks run one at a time. superpowers:subagent-driven-development states it directly: “Never dispatch multiple implementation subagents in parallel (conflicts).” Since that skill owns the dispatch, /sdd:execute obeys it rather than inventing its own merge path. Depends on: is a correctness check — it refuses to start a task whose prerequisites are unticked — not a parallel scheduler.
Two more things the skill will not do: sub-agents never edit tasks.md (only the orchestrator writes it, so progress stays trustworthy after a failure), and the skill never touches GitHub — no git push, no gh, no PR, no archive.

Step 5 — Open the PR

Commits, pushes, opens a structured PR, assigns you, applies labels, and requests review from @alvincheah88.
Put the change’s proposal path in the PR body’s Related Spec section (backend/go/openspec/changes/<name>/proposal.md or, for example, frontend/solidstart/openspec/changes/<name>/proposal.md). The reviewer’s Spec axis anchors to it instead of guessing.

Step 6 — Review until clean

Runs review → fix → review again until a round returns zero findings. Details in the Review-Fix Loop Guide. Do not substitute the built-in /code-review, and do not call the sub-skills yourself. They stay available when you name them explicitly: If you name one, that one runs and nothing else.

Step 7 — Merge

Normal GitHub merge. Nothing special here — but it must happen before the next step.

Step 8 — Archive

openspec archive folds the change’s delta specs into the root openspec/specs/ — the record of what the system does now.
Never archive before merge. Doing so makes openspec/specs/ claim behaviour that is still sitting in an open PR, and it blocks editing specs/ if review finds a requirement wrong.
Commit the archive result as its own small bookkeeping commit. Keep it out of the feature PR.

Legacy Changes

A change created before this workflow pins its own schema in <change>/.openspec.yaml, and that overrides the root config.yaml. Changing the root default does not migrate existing changes:
Such a change still resolves to spec-driven, and its tasks carry no Depends on: or acceptance-criteria metadata. /sdd:execute detects this from schemaName, announces it, and runs the tasks strictly in listed order. It will not rewrite a live change’s tasks.md into the new shape.

Reference

Files

Useful commands

openspec validate --strict with no target fails outside an interactive terminal. Always name the change.

Schema copies, kept in sync by hand

Each schema exists as two real directories: spec-driven-superpowers in the two backend roots and spec-driven-superpowers-fe in the two frontend roots. Keep copies of the same schema in sync; the backend **TDD:** and frontend **Verify:** task formats intentionally differ. Symlinking does not work: the OpenSpec runtime enumerates the schemas directory and skips symlinks, because isDirectory() is false for one. The failure is confusing — openspec schema which reports success (it checks the path directly and bypasses enumeration), then openspec status fails with Unknown schema 'spec-driven-superpowers'. Available: spec-driven.
schema which passing is not proof a schema works. Verify with openspec instructions apply --change <name> --json and check schemaName.
If you edit one copy, edit the other copy of that schema. Only the tasks artifact is customised, so drift has a small surface — but it is real.
  • Review-Fix Loop Guide — the review step in detail
  • Code Review Process — how findings are triaged and answered
  • backend/go/AGENTS.md, backend/bun/AGENTS.md, frontend/astro/AGENTS.md, and frontend/solidstart/AGENTS.md — the routing rules agents read