Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
inside-out `paths.layers` map) into `CLAUDE.md` and `project-config.json`, with a single batch
confirmation gate. Facts only - constitution rules are never auto-filled. Adds `paths.layers` to
`templates/project-config.template.json`.
- `/sd:adr` command (11th) + `sd-docs-writer` agent (6th) - drafts a numbered, MADR-style Architecture
Decision Record under `.specs/_adr/` from a spec's `03-decisions.md` (or an ad-hoc decision), behind one
hard approval gate. The agent (model `sonnet`, tools Read/Write/Glob/Grep, skill `sd-evidence-citation`)
writes only the ADR file and never invents decisions; the command owns numbering and supersession links.
Bumps command count 10 -> 11 and agent count 5 -> 6 across docs and the validators.

---

Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Note: `templates/CLAUDE.template.md` is the template `/sd:setup` scaffolds into

# Sandbox install test (run before any PR touching install/hooks/commands/agents)
.\install\install.ps1 -BasePath C:\temp\sd-test
Get-ChildItem C:\temp\sd-test\commands\sd\ # expect 10 .md files
Get-ChildItem C:\temp\sd-test\commands\sd\ # expect 11 .md files
.\install\uninstall.ps1 -BasePath C:\temp\sd-test -Force # round-trip: removes the 5 sd\ dirs
Remove-Item -Recurse -Force C:\temp\sd-test # cleanup
```
Expand All @@ -44,8 +44,8 @@ Every PR adds a line under `## [Unreleased]` in `CHANGELOG.md` (Keep a Changelog

| Source | Installs to | Contents |
|---|---|---|
| `commands/` | `~/.claude/commands/sd/` | 10 slash commands (`/sd:feature`, `/sd:bug`, `/sd:rca`, `/sd:refactor`, `/sd:perf`, `/sd:spec`, `/sd:explore`, `/sd:review`, `/sd:setup`, `/sd:release`) |
| `agents/` | `~/.claude/agents/sd/` | 5 subagents (`sd-spec-architect`, `sd-code-explorer`, `sd-debugger`, `sd-implementer`, `sd-reviewer`) |
| `commands/` | `~/.claude/commands/sd/` | 11 slash commands (`/sd:feature`, `/sd:bug`, `/sd:rca`, `/sd:refactor`, `/sd:perf`, `/sd:spec`, `/sd:explore`, `/sd:review`, `/sd:setup`, `/sd:release`, `/sd:adr`) |
| `agents/` | `~/.claude/agents/sd/` | 6 subagents (`sd-spec-architect`, `sd-code-explorer`, `sd-debugger`, `sd-implementer`, `sd-reviewer`, `sd-docs-writer`) |
| `hooks/powershell/` + `hooks/bash/` | `~/.claude/hooks/sd/` | 3 hooks × 2 platforms (`prompt-router`, `spec-gate`, `subagent-retro`) |
| `templates/` | `~/.claude/templates/sd/` | 4 setup templates + 5 spec templates in `specs/` |
| `skills/` | `~/.claude/skills/sd/` | 6 rule packs, one folder per skill with `SKILL.md` |
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ per-file-type guidelines, and how to test changes locally.

```
specwright/
commands/ # 10 slash commands (markdown with frontmatter)
agents/ # 5 subagent definitions (markdown with frontmatter)
commands/ # 11 slash commands (markdown with frontmatter)
agents/ # 6 subagent definitions (markdown with frontmatter)
hooks/
powershell/ # 3 PowerShell hooks
bash/ # 3 bash hooks (parity with PowerShell)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ The system is **stack-agnostic**. Agents read `CLAUDE.md` and `constitution.md`

| Capability | What you get |
|---|---|
| **10 slash commands** | `/sd:feature`, `/sd:bug`, `/sd:rca`, `/sd:refactor`, `/sd:perf`, `/sd:spec`, `/sd:explore`, `/sd:review`, `/sd:setup`, `/sd:release` |
| **5 specialized subagents** | `sd-spec-architect`, `sd-code-explorer`, `sd-debugger`, `sd-implementer`, `sd-reviewer` |
| **11 slash commands** | `/sd:feature`, `/sd:bug`, `/sd:rca`, `/sd:refactor`, `/sd:perf`, `/sd:spec`, `/sd:explore`, `/sd:review`, `/sd:setup`, `/sd:release`, `/sd:adr` |
| **6 specialized subagents** | `sd-spec-architect`, `sd-code-explorer`, `sd-debugger`, `sd-implementer`, `sd-reviewer`, `sd-docs-writer` |
| **3 cross-platform hooks** | `prompt-router`, `spec-gate`, `subagent-retro` (PowerShell + bash) |
| **9 templates** | 4 setup templates + 5 spec templates (feature / bug / refactor / perf / rca) |
| **6 reusable skills** | `sd-severity-taxonomy`, `sd-hypothesis-tree`, `sd-atomic-task-format`, `sd-evidence-citation`, `sd-spec-templates`, `sd-pattern-discipline` |
Expand Down
67 changes: 67 additions & 0 deletions agents/docs-writer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: sd-docs-writer
color: cyan
description: Authors a single Architecture Decision Record (ADR) from a spec's decision artifacts. Reads 03-decisions.md plus spec context and drafts a MADR-style ADR under .specs/_adr/. Never edits the constitution, never modifies code, never invents decisions.
model: sonnet
tools: Read, Write, Glob, Grep
skills:
- sd-evidence-citation
---

You are the docs-writer for specwright. You turn durable decisions captured in spec artifacts into a single human-facing Architecture Decision Record (ADR). You synthesize only what the source says: you never invent a decision, never edit the constitution, and never modify code.

---

## Always do first

1. Read the `DECISION_SOURCE` the command provides (`03-decisions.md` for a spec, or the inline decision text for ad-hoc mode).
2. Read `CLAUDE.md` and `.specs/constitution.md` for naming and convention context (read-only; never edit them).
3. Use the `ADR_NUMBER` and `ADR_PATH` the command assigns. Never pick or change the number.

---

## Input contract

The command passes:
- `ADR_NUMBER` - zero-padded 4-digit sequence (e.g. `0007`).
- `ADR_PATH` - exact target file (e.g. `.specs/_adr/0007-cqrs-read-path.md`).
- `SPEC_REF` - source spec ID (e.g. `FEAT-012`) or `ad-hoc`.
- `DECISION_SOURCE` - path to `03-decisions.md` or the inline decision text.
- `SUPERSEDES` - ADR number this one supersedes, or `none`.
- `DATE` - today's date (`YYYY-MM-DD`); never invent a date.

## Output: one ADR file (MADR-style)

Write exactly one file at `ADR_PATH` with this structure:

# ADR <ADR_NUMBER>: <Title>

- Status: proposed
- Date: <DATE>
- Source spec: <SPEC_REF>
- Supersedes: <ADR number or "none">

## Context

<Why the decision was needed. Cite the driving spec artifact and any code the decision concerns, using file:line per the sd-evidence-citation skill.>

## Decision

<What was decided, stated as one clear position.>

## Consequences

<Positive, negative, and follow-up consequences. Honest about trade-offs.>

Rules:
- Status is always `proposed` on a fresh draft - a human accepts it later.
- Every claim about the codebase cites `file:line` (sd-evidence-citation skill).
- Never fabricate a decision, date, or consequence not supported by the source.
- If `DECISION_SOURCE` is empty or absent, STOP and report `no decision content found in <DECISION_SOURCE>` - do not invent an ADR.
- If `SUPERSEDES` is not `none`, state the reciprocal link in your returned summary so the command can update the superseded ADR.

## Hard limits

- You write ONLY the one `ADR_PATH` file. You never touch the constitution, code, or other ADRs.
- You never assign or change the ADR number (the command owns numbering).
- You return the drafted ADR content as your final output.
68 changes: 68 additions & 0 deletions commands/adr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
description: Author an Architecture Decision Record (ADR) from a spec's decisions via sd-docs-writer. One hard gate before keeping the file.
argument-hint: <spec-ID | "decision title">
---

# /sd:adr

Promotes a durable decision into a numbered ADR under `.specs/_adr/`. Drives the `sd-docs-writer` agent.

**Argument:** a spec ID (e.g. `FEAT-012`) whose `03-decisions.md` holds the decision, OR a free-text
decision title for an ad-hoc ADR with no spec.

---

## Phase 0 - Bootstrap

Read, in order: `CLAUDE.md`, `.specs/constitution.md`, `.claude/project-config.json`, `.specs/index.md`.
If `.specs/` does not exist, abort: "No `.specs/` found - run `/sd:setup` first."

## Phase 1 - Resolve the decision source

1. If the argument matches a spec ID in `.specs/index.md`:
- Locate `.specs/<ID>/03-decisions.md`. If it is missing or has no decision content, STOP and ask the
user to supply the decision inline or pick another spec. Never invent decisions.
- Set `SPEC_REF = <ID>` and `DECISION_SOURCE = .specs/<ID>/03-decisions.md`.
2. Otherwise treat the argument as a free-text decision title:
- Set `SPEC_REF = ad-hoc`. If the title alone is insufficient, ask the user once for the Context,
Decision, and Consequences. `DECISION_SOURCE` = the gathered text.

## Phase 2 - Assign number and slug

1. Glob `.specs/_adr/` for files matching `^[0-9]{4}-`. Take the highest 4-digit prefix; `ADR_NUMBER` =
that value + 1, zero-padded to 4 digits. If none exist, `ADR_NUMBER = 0001`.
2. Derive `<slug>` = kebab-case of the decision title (lowercase, alphanumerics and hyphens, <= 60 chars).
3. `ADR_PATH = .specs/_adr/<ADR_NUMBER>-<slug>.md`.
4. If the user names an existing ADR this decision replaces, set `SUPERSEDES` to its number; else `none`.
5. Idempotency: if an ADR whose title clearly matches this decision already exists, ask whether to update
it in place or create a new number. Never silently clobber.

## Phase 3 - Draft via sd-docs-writer

Invoke the `sd-docs-writer` agent with `ADR_NUMBER`, `ADR_PATH`, `SPEC_REF`, `DECISION_SOURCE`,
`SUPERSEDES`, and today's date as `DATE`. The agent drafts and writes the file, then returns its content.

## Gate (HARD) - approve before keeping

Display the drafted ADR in full. STOP and ask: "Keep this ADR at `<ADR_PATH>`? (yes / edit / abort)".
Silence is not approval.
- `yes` -> keep the file. If `SUPERSEDES` is not `none`, edit that ADR's `Status` line to
`superseded by <ADR_NUMBER>` and add a reciprocal "Superseded by" link.
- `edit` -> apply the requested changes (re-invoke the agent or edit directly) and re-display.
- `abort` -> delete the drafted file and report that no ADR was created.

## Phase 4 - Report

Print the ADR path, number, status (`proposed`), source spec, and any supersession link. Remind the user
the ADR stays `proposed` until they change its status to `accepted`.

---

## Rules (hard constraints)

- **Decisions come from the source, never invented.** Empty or absent decision content aborts the command.
- **One hard gate.** Nothing is kept on disk without explicit approval.
- **ADRs are not specs.** No `.specs/index.md` lifecycle entry; ADRs live under `.specs/_adr/` with their
own numbering.
- **The constitution is never edited here.** Amending a rule is a separate `/sd:refactor` or a manual ADR
acceptance step.
4 changes: 2 additions & 2 deletions commands/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ Setup complete. Generated:
- .claude/settings.json (hooks: prompt-router, spec-gate, subagent-retro)

Installed engine paths:
- ~/.claude/commands/sd/ (10 workflow commands)
- ~/.claude/agents/sd/ (5 specialist agents)
- ~/.claude/commands/sd/ (11 workflow commands)
- ~/.claude/agents/sd/ (6 specialist agents)
- ~/.claude/hooks/sd/ (3 hooks)
- ~/.claude/templates/sd/ (templates)
- ~/.claude/skills/sd/ (6 skills: severity-taxonomy, hypothesis-tree, atomic-task-format, evidence-citation, spec-templates, pattern-discipline)
Expand Down
14 changes: 8 additions & 6 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ specwright is a thin layer on top of Claude Code that enforces spec-driven devel
+--------------------------------------------------------------------+
| Layer 1 - USER scope (~/.claude/, installed once) |
| |
| commands/sd/ 10 workflow definitions |
| agents/sd/ 5 subagent prompt files |
| commands/sd/ 11 workflow definitions |
| agents/sd/ 6 subagent prompt files |
| hooks/sd/ 3 cross-platform hook scripts |
| templates/sd/ 4 setup + 5 spec templates |
| skills/sd/ 6 reusable rule packs (referenced by agents) |
Expand Down Expand Up @@ -92,6 +92,7 @@ Each subagent has a focused role, a minimal tool allowlist, and a model assignme
| `sd-debugger` | sonnet | Read/Grep/Glob/Bash + sequential-thinking + GitNexus + MSSQL (SELECT only) + Tavily + Context7 | Hypothesis-tree investigation. Distinguishes proximate vs root cause. |
| `sd-implementer` | haiku | Read/Write/Edit/MultiEdit/Grep/Glob/Bash + Context7 | Executes ONE atomic task with scope discipline. |
| `sd-reviewer` | sonnet | Read/Grep/Glob + sequential-thinking + GitNexus | Severity-tagged review (🔴 BLOCK / 🟠 WARN / 🟡 SUGGEST / 🟢 PASS). Cannot write. |
| `sd-docs-writer` | sonnet | Read/Write/Glob/Grep + sd-evidence-citation | Authors one MADR-style ADR from a spec's decisions. Writes only the ADR file. |

**Tool allowlists are minimal by design.** The reviewer cannot fix code because it has no write tools. The explorer cannot suggest fixes for the same reason. This is enforced by the engine, not by prose discipline alone.

Expand All @@ -112,6 +113,7 @@ fan-out each command performs (left to right = invocation order; `(xN)` = once p
/sd:rca -> spec-architect -> debugger (enumerate / verify) [no code change - output IS the spec]
/sd:explore -> code-explorer
/sd:review -> reviewer
/sd:adr -> docs-writer
/sd:spec -> (none - pure file ops on .specs/)
/sd:setup -> (none - scaffolds CLAUDE.md / .specs/ / .claude/)
/sd:release -> (none - pure file ops; mirrors /sd:spec)
Expand All @@ -131,16 +133,16 @@ Skills are markdown rule packs that agents reference from their frontmatter. The

The split exists for three reasons:

1. **De-duplication.** `sd-evidence-citation` is used by `sd-code-explorer`, `sd-debugger`, and `sd-reviewer`. Without skills, the same `file:line` citation rule would be copy-pasted into three agent files and drift over time. With skills, it lives in one place.
1. **De-duplication.** `sd-evidence-citation` is used by `sd-code-explorer`, `sd-debugger`, `sd-reviewer`, and `sd-docs-writer`. Without skills, the same `file:line` citation rule would be copy-pasted into four agent files and drift over time. With skills, it lives in one place.
2. **Smaller agent bodies.** The reviewer prompt no longer carries the full severity taxonomy inline; it points at `sd-severity-taxonomy`. Body size goes down; lookup discipline stays the same.
3. **Auditability.** A reader can open one `SKILL.md` and see exactly what rules every agent follows for that concern — without grepping across 5 agent files.
3. **Auditability.** A reader can open one `SKILL.md` and see exactly what rules every agent follows for that concern — without grepping across 6 agent files.

| Skill | Used by | Purpose |
|---|---|---|
| `sd-severity-taxonomy` | `sd-reviewer` | Severity levels + per-severity rules + mandatory output markdown. |
| `sd-hypothesis-tree` | `sd-debugger` | Enumerate / verify protocol, the 5 mental models, score formula `(L × I) / C`, proximate-vs-root ladder. |
| `sd-atomic-task-format` | `sd-spec-architect`, `sd-implementer` | The task block (9 required fields + `Pattern refs`) + canonical enums (`Step type`, `Complexity`, `Reversibility`). |
| `sd-evidence-citation` | `sd-code-explorer`, `sd-debugger`, `sd-reviewer` | `file:line` discipline, snippet length, evidence taxonomy, grouping. |
| `sd-evidence-citation` | `sd-code-explorer`, `sd-debugger`, `sd-reviewer`, `sd-docs-writer` | `file:line` discipline, snippet length, evidence taxonomy, grouping. |
| `sd-spec-templates` | `sd-spec-architect` | Per-template authoring rules; which cross-phase fields to leave empty. |
| `sd-pattern-discipline` | `sd-spec-architect`, `sd-implementer`, `sd-reviewer` | Pattern discovery and adherence: precedent sampling, `Pattern refs` authoring/following, conformance review. |

Expand Down Expand Up @@ -320,7 +322,7 @@ Every command, agent, and (conceptually) namespaced asset uses the `sd:` prefix:
The prefix exists for three reasons:

1. **Collision avoidance.** A project may have its own `/feature` or `/review` slash command. `sd:` carves out a namespace.
2. **Discoverability.** Typing `/sd:` in Claude Code lists all 10 commands. The namespace is its own table of contents.
2. **Discoverability.** Typing `/sd:` in Claude Code lists all 11 commands. The namespace is its own table of contents.
3. **Removability.** Uninstalling the engine removes everything under `sd/` subfolders, leaving the rest of `~/.claude/` intact.

---
Expand Down
Loading
Loading