@cleepi/sdd 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,113 @@
1
+ # Changelog — @cleepi/sdd
2
+
3
+ All notable changes to this package are documented here.
4
+
5
+ Format: [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/).
6
+ Versioning: [SemVer](https://semver.org/spec/v2.0.0.html). Pre-`1.0.0`, minor
7
+ bumps may include breaking changes.
8
+
9
+ ## [Unreleased]
10
+
11
+ ## [0.2.0] — 2026-05-27
12
+
13
+ **BREAKING.** Substantial redesign of the SDD workflow per
14
+ [cleepi spec 0005](../../docs/specs/0005-sdd-redesign.md). New
15
+ artifact ontology, new folder layout, new slash commands. Migration
16
+ steps below.
17
+
18
+ ### Added
19
+
20
+ - **Journal** as a new artifact type. Per-ticket
21
+ (`docs/<ticket-id>-slug/journal.md`), append-only log of in-flight
22
+ thinking — dead ends, blockers, surprises. Stack-pointer-plus-log
23
+ shape: `## Current state` overwritten each session, `## Log`
24
+ append-only.
25
+ - **Constitution** as a new optional artifact type. `CONSTITUTION.md`
26
+ at repo or package root, for projects with real invariants worth
27
+ codifying. Invariants only — code rules live in `AGENTS.md`,
28
+ process rules live in the sdd skill, one-off design choices live
29
+ in spec Decision sections.
30
+ - `/journal <text>` slash command. Appends entry to current
31
+ ticket's journal; overwrites Current state.
32
+ - `templates/journal.md` — stack-pointer-plus-log skeleton with
33
+ inline discipline guidance.
34
+ - `templates/constitution.md` — invariants-only skeleton with
35
+ anti-examples (what does NOT belong here).
36
+ - **Voice and length discipline** in the skill: principles, six
37
+ anti-patterns, the delete test, length cues per artifact. Long
38
+ artifacts when short would do are now a defect, not a preference.
39
+ - **Discriminator test** in the skill: "what happens if violated?"
40
+ routes content to the right artifact (CONSTITUTION / AGENTS.md /
41
+ spec Decision section / sdd skill).
42
+ - **Ticket-keyed folder layout** (`docs/AC-NNN-slug/`,
43
+ `docs/LIN-NNN-slug/`, `docs/DRAFT-NNN-slug/`, etc.). Folder name
44
+ is the cross-link to the tracker; no `jira:` frontmatter to
45
+ forget. Generic format — tracker prefix is unvalidated.
46
+ - Spec frontmatter gains optional `ticket:` and `ticket-url:`
47
+ fields.
48
+ - Required `## Decision` section in specs (Alternatives considered
49
+ / Rationale / Consequences). Required before flipping to
50
+ `accepted`.
51
+
52
+ ### Changed
53
+
54
+ - **Spec body structure.** From 8 fixed sections to 3 required
55
+ (What / Why / Decision) + 5 opt-in (Concrete surface / Phased
56
+ rollout / Open questions / Non-goals / Risks). Optional sections
57
+ appear only when they add information — the delete test enforces
58
+ this.
59
+ - **Spec section names.** `Problem` → `What` (works for features,
60
+ not just bug-fix framing). `Why now` collapses into `Why`.
61
+ - **`/spec` prompt** now asks for a ticket ID interactively;
62
+ defaults to `DRAFT-NNN` if no tracker exists.
63
+ - **`/changelog` prompt** updated: spec link format is now
64
+ `[spec AC-NNN](docs/AC-NNN-slug/spec.md)`. No more ADR-link
65
+ suggestion.
66
+ - **`packages/sdd/SPEC.md`** rewritten to the purpose-and-scope
67
+ shape the new skill describes (was structured as a feature spec).
68
+ - **`packages/sdd/README.md`** rewritten for v0.2.0 conventions.
69
+
70
+ ### Removed
71
+
72
+ - **ADR as a separate artifact type.** Decision rationale moves to
73
+ the required spec `## Decision` section. Durable rules move to
74
+ the optional `CONSTITUTION.md`.
75
+ - `/adr` slash command.
76
+ - `templates/adr.md`.
77
+ - `prompts/adr.md`.
78
+
79
+ ### Migration from v0.1.x
80
+
81
+ Breaking change. Full guide in [README “Migration from v0.1.x”](./README.md#migration-from-v01x). Summary:
82
+
83
+ 1. Move existing ADR content into the relevant spec's
84
+ `## Decision` section. Mark old ADRs `superseded by spec <id>`
85
+ (preserve bodies).
86
+ 2. Old `docs/specs/NNNN-*.md` and `docs/adr/NNNN-*.md` files don't
87
+ have to move. New work uses ticket-keyed folders
88
+ (`docs/<ticket-id>-slug/`).
89
+ 3. Start writing journals for active work. Skip retroactive
90
+ journals for already-shipped specs.
91
+ 4. Add `CONSTITUTION.md` *only if* your project has real invariants.
92
+ Most don't need one.
93
+
94
+ No automated migration tooling — intentional, unhurried transition.
95
+
96
+ ## [0.1.0] — 2026-05-24
97
+
98
+ ### Added
99
+ - Initial package scaffold.
100
+ - `skills/sdd/SKILL.md` teaching the SDD workflow (spec, ADR, changelog
101
+ conventions; scope resolution; numbering; status transitions; bootstrap
102
+ exception).
103
+ - Slash command prompts: `/spec`, `/adr`, `/changelog`.
104
+ - File templates under `templates/`: `spec.md`, `adr.md`,
105
+ `changelog-section.md`.
106
+ - README documenting conventions for human readers.
107
+ - [SPEC.md](./SPEC.md) — package purpose, scope, non-goals.
108
+ - [ADR 0001](./docs/adr/0001-template-format-madr-lite.md) — chose MADR-lite
109
+ with YAML frontmatter for spec and ADR templates.
110
+
111
+ [Unreleased]: https://github.com/cleevio/cleepi/compare/sdd-v0.2.0...HEAD
112
+ [0.2.0]: https://github.com/cleevio/cleepi/releases/tag/sdd-v0.2.0
113
+ [0.1.0]: https://github.com/cleevio/cleepi/releases/tag/sdd-v0.1.0
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # @cleepi/sdd
2
+
3
+ Spec-Driven Development as a pi package. Install in any repo where
4
+ you want Spec + Journal + Changelog (and optional Constitution)
5
+ discipline. Your pi sessions will know the workflow.
6
+
7
+ ## What's in the box
8
+
9
+ - **Skill** (`skills/sdd/SKILL.md`) — the canonical SDD workflow.
10
+ Loaded automatically when you ask about specs / journals /
11
+ changelogs / constitution, or explicitly with `/skill:sdd`.
12
+ - **Prompts** — slash commands:
13
+ - `/spec <title>` — scaffold a new spec in a ticket-keyed folder.
14
+ - `/journal <text>` — append an entry to the current ticket's
15
+ journal; update Current state.
16
+ - `/changelog <type> <text>` — add an entry to the `[Unreleased]`
17
+ section of the current scope's `CHANGELOG.md`.
18
+ - **Templates** (`templates/`) — markdown skeletons the prompts fill in.
19
+
20
+ "Current scope" = the nearest package (`packages/<name>/`) you're
21
+ working in, or the repo root.
22
+
23
+ ## The 30-second version
24
+
25
+ Three artifacts + one optional declarative file. Each answers one
26
+ question:
27
+
28
+ | Artifact | Question | Lifecycle |
29
+ |---|---|---|
30
+ | **Spec** | What are we building, and why this approach? | `draft` → `accepted` → `shipped` / `superseded` |
31
+ | **Journal** | What's been tried? Where are we now? | Append-only; per-ticket |
32
+ | **Changelog** | What shipped in version N? | Append-only by SemVer / date |
33
+ | **Constitution** *(optional)* | What invariants must always be true? | Living document |
34
+
35
+ ADRs are not a separate artifact type in v0.2.0. Their "X over Y"
36
+ function lives in a required `## Decision` section inside specs.
37
+ Durable invariants live in the optional `CONSTITUTION.md`.
38
+
39
+ For the full discipline (discriminator test, voice/length rules,
40
+ invariant-vs-rule distinction, folder layout, status lifecycles),
41
+ see [`skills/sdd/SKILL.md`](skills/sdd/SKILL.md). It's the source
42
+ of truth.
43
+
44
+ ## Folder layout (in your repo)
45
+
46
+ ```
47
+ <repo>/
48
+ CHANGELOG.md ← repo-level releases
49
+ CONSTITUTION.md ← optional, when project has invariants
50
+ docs/
51
+ AC-101-pricing-page/ ← ticket-keyed; AC-NNN, LIN-NNN, gh-NN, DRAFT-NNN
52
+ spec.md
53
+ journal.md
54
+ packages/<name>/
55
+ SPEC.md ← purpose-and-scope (singular)
56
+ CHANGELOG.md ← per-package SemVer
57
+ docs/AC-NNN-slug/
58
+ spec.md
59
+ journal.md
60
+ ```
61
+
62
+ The folder name is the cross-link to the tracker — no `jira:` or
63
+ `ticket-id:` frontmatter to forget.
64
+
65
+ ## Install
66
+
67
+ Global (every pi session anywhere gets the workflow):
68
+
69
+ ```bash
70
+ pi install git:github.com/cleevio/cleepi/packages/sdd
71
+ ```
72
+
73
+ Project-local (recommended for repos that adopt SDD as their
74
+ process):
75
+
76
+ ```bash
77
+ cd <repo>
78
+ pi install -l git:github.com/cleevio/cleepi/packages/sdd
79
+ ```
80
+
81
+ ## Migration from v0.1.x
82
+
83
+ v0.2.0 is a breaking change. If you have an existing project on
84
+ v0.1.x:
85
+
86
+ - **`/adr` is gone.** Move ADR content into the relevant spec's
87
+ `## Decision` section. Mark old ADRs `status: superseded by
88
+ spec <id>` (preserve bodies as historical record).
89
+ - **Existing `docs/specs/NNNN-*.md` and `docs/adr/NNNN-*.md` files
90
+ don't have to move.** They stay in place as archive. New specs
91
+ go in ticket-keyed folders (`docs/<ticket-id>-slug/spec.md`).
92
+ - **Start writing journals** for active work
93
+ (`docs/<ticket-id>-slug/journal.md`). Skip retroactive journals
94
+ for already-shipped specs.
95
+ - **Add `CONSTITUTION.md`** at repo root *only if* your project
96
+ has real invariants worth codifying (e.g., "we use Postgres",
97
+ "all auth is server-side"). Most projects don't need one.
98
+
99
+ No automated migration tooling. The transition is intentional and
100
+ unhurried.
101
+
102
+ ## Related
103
+
104
+ - [SPEC.md](./SPEC.md) — what this package is and isn't.
105
+ - [CHANGELOG.md](./CHANGELOG.md) — release history.
106
+ - Root cleepi [spec 0005](../../docs/specs/0005-sdd-redesign.md) —
107
+ the v0.2.0 redesign rationale.
package/SPEC.md ADDED
@@ -0,0 +1,104 @@
1
+ ---
2
+ title: "@cleepi/sdd"
3
+ status: shipped
4
+ created: 2026-05-24
5
+ updated: 2026-05-27
6
+ owner: Honza
7
+ related:
8
+ - ../../docs/specs/0001-development-process.md (partially superseded)
9
+ - ../../docs/specs/0005-sdd-redesign.md (drives v0.2.0)
10
+ - ../../docs/adr/0004-extract-sdd-as-package.md
11
+ ---
12
+
13
+ # `@cleepi/sdd`
14
+
15
+ ## What this package is
16
+
17
+ A pi package that ships the Cleepi Spec-Driven Development workflow
18
+ as durable instructions. Install it in any repo and pi sessions there
19
+ know how to write specs, journals, changelogs, and (optionally) a
20
+ constitution.
21
+
22
+ Three things ship:
23
+
24
+ - **Skill** (`skills/sdd/SKILL.md`) — canonical SDD workflow doc.
25
+ Loaded on demand or explicitly with `/skill:sdd`.
26
+ - **Prompts** — `/spec`, `/journal`, `/changelog`.
27
+ - **Templates** (`templates/`) — file skeletons the prompts fill in.
28
+
29
+ The workflow itself is documented in the skill, not here. Read
30
+ [`skills/sdd/SKILL.md`](skills/sdd/SKILL.md) for the canonical
31
+ version, including the discriminator test, voice/length discipline,
32
+ and folder layout.
33
+
34
+ ## What this package is not
35
+
36
+ - **Not a lint or CI enforcer.** The skill instructs; it doesn't
37
+ police. Enforcement is deferred until friction shows up.
38
+ - **Not an ADR framework.** ADRs as a separate artifact type were
39
+ dropped in v0.2.0. Decision rationale lives in the required
40
+ `## Decision` section inside specs. Durable invariants live in
41
+ the optional `CONSTITUTION.md`.
42
+ - **Not a project management tool.** No status boards, ownership
43
+ tracking, or dashboards.
44
+ - **Not a generic spec framework for non-pi contexts.** The skill
45
+ assumes pi conventions and a Cleepi-shaped workflow.
46
+ - **Not opinionated about ticket trackers.** `AC-NNN`, `LIN-NNN`,
47
+ `gh-NN`, `DRAFT-NNN` all work as folder prefixes; the skill
48
+ validates none of them.
49
+ - **Not a constitution requirement.** `CONSTITUTION.md` is an
50
+ *optional* artifact consumer projects opt into when they have
51
+ real invariants worth codifying.
52
+
53
+ ## Design at a glance
54
+
55
+ ```
56
+ packages/sdd/
57
+ package.json
58
+ README.md
59
+ SPEC.md ← this file
60
+ CHANGELOG.md
61
+ skills/sdd/SKILL.md ← the canonical workflow
62
+ prompts/spec.md ← /spec
63
+ prompts/journal.md ← /journal
64
+ prompts/changelog.md ← /changelog
65
+ templates/spec.md
66
+ templates/journal.md
67
+ templates/constitution.md
68
+ templates/changelog-section.md
69
+ ```
70
+
71
+ In a consumer repo using the workflow, layout looks like:
72
+
73
+ ```
74
+ <consumer-repo>/
75
+ CHANGELOG.md ← repo-level releases
76
+ CONSTITUTION.md ← optional, when project has invariants
77
+ AGENTS.md ← code rules + interaction style (project-shipped)
78
+ docs/
79
+ AC-101-pricing-page/
80
+ spec.md
81
+ journal.md
82
+ packages/<name>/
83
+ SPEC.md ← purpose-and-scope (singular, unnumbered)
84
+ CHANGELOG.md
85
+ docs/AC-201-billing-api/
86
+ spec.md
87
+ journal.md
88
+ ```
89
+
90
+ ## Versioning
91
+
92
+ Per-package SemVer. Pre-`1.0.0`, minor bumps may include breaking
93
+ changes (per SemVer §4).
94
+
95
+ **v0.2.0 is a breaking change from v0.1.x.** Artifact ontology,
96
+ folder layout, and slash commands all changed. See
97
+ [CHANGELOG.md](./CHANGELOG.md) for the migration path.
98
+
99
+ ## Related
100
+
101
+ - [skills/sdd/SKILL.md](./skills/sdd/SKILL.md) — canonical workflow.
102
+ - [CHANGELOG.md](./CHANGELOG.md) — release history with migration.
103
+ - Root cleepi [spec 0005](../../docs/specs/0005-sdd-redesign.md) —
104
+ the v0.2.0 redesign that drove this package's rewrite.
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@cleepi/sdd",
3
+ "version": "0.2.0",
4
+ "description": "Spec-Driven Development workflow for pi: skill, prompts, and templates for specs, journals, changelogs, and optional constitution. v0.2.0+ replaces ADRs with spec Decision sections.",
5
+ "keywords": [
6
+ "pi-package",
7
+ "cleepi",
8
+ "sdd",
9
+ "spec",
10
+ "journal",
11
+ "changelog",
12
+ "constitution",
13
+ "spec-driven"
14
+ ],
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/honzanemecek/cleepi.git",
19
+ "directory": "packages/sdd"
20
+ },
21
+ "bugs": "https://github.com/honzanemecek/cleepi/issues",
22
+ "homepage": "https://github.com/honzanemecek/cleepi/tree/main/packages/sdd#readme",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "pi": {
27
+ "skills": [
28
+ "./skills"
29
+ ],
30
+ "prompts": [
31
+ "./prompts"
32
+ ]
33
+ },
34
+ "files": [
35
+ "skills",
36
+ "prompts",
37
+ "templates",
38
+ "SPEC.md",
39
+ "CHANGELOG.md",
40
+ "README.md"
41
+ ]
42
+ }
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Add an entry to the [Unreleased] section of the current scope's CHANGELOG
3
+ argument-hint: "<added|changed|deprecated|removed|fixed|security> <text>"
4
+ ---
5
+
6
+ The user wants to add a changelog entry. Arguments: **$ARGUMENTS**
7
+
8
+ First token is the section name (one of `added`, `changed`, `deprecated`,
9
+ `removed`, `fixed`, `security`). Everything after is the entry text.
10
+
11
+ Follow the cleepi SDD workflow (load `/skill:sdd` if you haven't):
12
+
13
+ 1. **Resolve scope.** Determine which `CHANGELOG.md` to edit:
14
+ - If the change only affects one package, target =
15
+ `packages/<name>/CHANGELOG.md`.
16
+ - If it's a repo-level event (tooling, conventions, new package), target =
17
+ `/CHANGELOG.md` at the repo root.
18
+ - If ambiguous, ask the user.
19
+
20
+ 2. **Validate the section name.** Must be one of: `Added`, `Changed`,
21
+ `Deprecated`, `Removed`, `Fixed`, `Security`. Capitalize properly.
22
+
23
+ 3. **Read the target CHANGELOG.** Find the `## [Unreleased]` section. If it
24
+ doesn't exist, add it at the top (just under the file header), then
25
+ proceed. If the file doesn't exist at all, stop and ask the user — a
26
+ missing CHANGELOG suggests a missing package or wrong scope.
27
+
28
+ 4. **Find or create the subsection** (`### Added`, etc.) within `[Unreleased]`.
29
+ Preserve the conventional ordering (Added, Changed, Deprecated, Removed,
30
+ Fixed, Security) — insert new subsections in that order.
31
+
32
+ 5. **Append the entry** as a bullet point. If the entry text references a
33
+ spec the user mentioned, append a link in the form
34
+ `(see [spec AC-NNN](docs/AC-NNN-slug/spec.md))`. ADRs are no longer a
35
+ separate artifact — link to the spec whose `## Decision` section
36
+ records the rationale instead.
37
+
38
+ 6. **Report.** Tell the user which file you edited and show the new bullet.
39
+ Do not modify any released version sections — those are frozen.
@@ -0,0 +1,50 @@
1
+ ---
2
+ description: Append an entry to the current ticket's journal; overwrite Current state
3
+ argument-hint: "<entry text>"
4
+ ---
5
+
6
+ The user wants to append a journal entry. Text: **$ARGUMENTS**
7
+
8
+ Follow the @cleepi/sdd workflow (load `/skill:sdd` if you haven't,
9
+ specifically the "Journal discipline" and "Voice and length" sections).
10
+
11
+ 1. **Resolve the current ticket folder.**
12
+ - If `cwd` is inside `docs/<ticket-id>-slug/` or
13
+ `packages/<n>/docs/<ticket-id>-slug/`, use that folder.
14
+ - Otherwise ask: *"Which ticket is this entry for? Provide the
15
+ folder path or ticket ID."*
16
+
17
+ 2. **Find or create `<folder>/journal.md`.**
18
+ - If it exists, read it.
19
+ - If not, scaffold from the @cleepi/sdd `templates/journal.md`
20
+ template (substitute the ticket ID and slug into the header).
21
+
22
+ 3. **Append the log entry.**
23
+ - Find the `## Log` section.
24
+ - Insert a new dated entry at the **top** of the log
25
+ (newest first):
26
+ ```
27
+ ### YYYY-MM-DD — <author or session label>
28
+ - <entry text, broken into 1–5 bullets if multi-line>
29
+ ```
30
+ - Date = today.
31
+ - Author = the session user; ask if unclear.
32
+
33
+ 4. **Update Current state.**
34
+ - Ask the user: *"What's the current state in one line, after
35
+ this entry?"*
36
+ - Replace the bullets under `## Current state` with the
37
+ response. Don't append — overwrite.
38
+
39
+ 5. **Write the file. Report what changed** (one line: path +
40
+ what was appended + what Current state now says).
41
+
42
+ 6. **Discipline check.** If the entry text has no dead end,
43
+ blocker, surprise, or reasoning behind it, gently flag:
44
+ *"This looks like a changelog entry rather than journal
45
+ material — should I run `/changelog` instead?"* Don't refuse;
46
+ just ask.
47
+
48
+ Be concise (see skill "Voice and length"). The journal entry
49
+ itself goes in as the user wrote it — apply the delete test
50
+ only to your own surrounding output, not the user's content.
@@ -0,0 +1,58 @@
1
+ ---
2
+ description: Scaffold a new SDD spec in a ticket-keyed folder under the current scope
3
+ argument-hint: "<title>"
4
+ ---
5
+
6
+ The user wants to create a new spec titled: **$ARGUMENTS**
7
+
8
+ Follow the @cleepi/sdd workflow (load `/skill:sdd` if you haven't).
9
+
10
+ 1. **Resolve scope.**
11
+ - Inside `packages/<n>/` or the spec is clearly about one package
12
+ → scope = package. Target = `packages/<n>/docs/`.
13
+ - Otherwise → scope = repo. Target = `docs/`.
14
+ - Ambiguous → ask.
15
+
16
+ 2. **Resolve the ticket ID.** Ask: *"Ticket ID for this spec (e.g.
17
+ `AC-101`)? Leave empty if there's no tracker ticket yet."*
18
+ - User provides one → use it as the folder prefix and the
19
+ frontmatter `id` and `ticket` fields.
20
+ - User leaves empty → use `DRAFT-NNN` where `NNN` is the next
21
+ monotonic number among existing `DRAFT-*` folders in the
22
+ target. No `ticket:` field in frontmatter.
23
+
24
+ 3. **Slugify the title.** Lowercase, kebab-case, drop articles.
25
+ Folder name = `<ticket-id>-<slug>/`.
26
+
27
+ 4. **Create the folder** if it doesn't exist. **Refuse** if it
28
+ exists AND already contains a `spec.md`. (Don't overwrite.)
29
+
30
+ 5. **Load the spec template** from the installed @cleepi/sdd
31
+ package's `templates/spec.md`. In this repo:
32
+ `packages/sdd/templates/spec.md`.
33
+
34
+ 6. **Fill frontmatter:**
35
+ - `id`: ticket ID, or `DRAFT-NNN`.
36
+ - `title`: user's title (preserve human-readable casing).
37
+ - `status`: `draft`.
38
+ - `created`: today's date in `YYYY-MM-DD`.
39
+ - `owner`: ask if you don't know.
40
+ - `ticket`: ticket ID (omit field entirely if no tracker).
41
+ - `ticket-url`: ask if relevant; omit otherwise.
42
+ - `related`: leave empty.
43
+
44
+ 7. **Body.** Keep the three required sections (`## What`,
45
+ `## Why`, `## Decision`) from the template. Replace placeholder
46
+ text with a short first-draft sketch only if you already know
47
+ enough — never fabricate. Leave the "optional sections" comment
48
+ block at the bottom untouched; the author opts in as needed.
49
+
50
+ 8. **Write `<folder>/spec.md`.** Report the path.
51
+
52
+ 9. **Next step.** Tell the user: *"Spec drafted at `<path>`. Status
53
+ is `draft`. Iterate on What / Why / Decision, then flip to
54
+ `accepted` before we touch code (strict SDD). Use `/journal
55
+ <text>` to log friction as you work."*
56
+
57
+ Be concise throughout (see skill "Voice and length"). No throat-
58
+ clearing; no restating what the user just typed.
@@ -0,0 +1,432 @@
1
+ ---
2
+ name: sdd
3
+ description: Spec-Driven Development workflow for cleepi-style repos. Use when the user asks to write a spec, journal entry, changelog entry, or constitution entry; when starting non-trivial work that should be designed before coding; or when about to release a package version. Covers the three-artifact ontology (spec/journal/changelog) + optional constitution, the discriminator test for where content belongs, ticket-keyed folder layout, scope resolution (package vs repo), status lifecycles, and Keep-a-Changelog 1.1.0 conventions.
4
+ ---
5
+
6
+ # Spec-Driven Development (SDD)
7
+
8
+ The cleepi workflow for designing before coding, capturing in-flight
9
+ thinking so it doesn't get lost, and remembering what shipped.
10
+
11
+ ## Core idea
12
+
13
+ Three artifacts + one optional declarative file. Each has a single
14
+ responsibility — never conflate them.
15
+
16
+ | Artifact | Question it answers | When written | Lifecycle |
17
+ | --- | --- | --- | --- |
18
+ | **Spec** | *What* are we going to build, and *why this approach* over alternatives? | Before coding | `draft` → `accepted` → `shipped` (frozen) or `superseded` |
19
+ | **Journal** | *What's been tried, where are we now?* | During work, append-only | No formal status; per-ticket |
20
+ | **Changelog** | *What* shipped in version N? | At release | Append-only by SemVer (package) or date (repo) |
21
+ | **Constitution** *(optional)* | *What invariants* must always be true for this project? | When the project has real invariants worth codifying | Living document; entries cite originating spec when one exists |
22
+
23
+ ADRs are not used. Their "X over Y" function lives in a required
24
+ `## Decision` section inside specs. Their durable-rule function (for
25
+ true project invariants) lives in `CONSTITUTION.md` when a project
26
+ has one.
27
+
28
+ ## Voice and length
29
+
30
+ SDD artifacts are written by tired humans for tired humans. Straight
31
+ to the point. No padding. Nobody likes reading a long spec that
32
+ says nothing.
33
+
34
+ The default failure mode — especially for AI agents — is wordy
35
+ prose that says nothing concrete. This rule is not advisory: a long
36
+ artifact when a short one would do is a defect. Reviewers (human or
37
+ AI) reject it the same way they'd reject a missing Decision section.
38
+
39
+ ### Principles
40
+
41
+ - **Bullets over paragraphs.** Paragraphs connect ideas. Bullets
42
+ list things. SDD artifacts are mostly listing.
43
+ - **Specifics over generalities.** "Refactor pricing logic" is
44
+ generality. "Move `pricingEngine.compute()` from `billing/` to
45
+ `pricing/` and update three call sites" is specific.
46
+ - **Show the thing, don't describe it.** A file path, a code
47
+ snippet, a citation beats ten lines of prose.
48
+ - **No throat-clearing.** No "This document describes…", no
49
+ "In this section we will…", no "In conclusion…".
50
+ - **No filler adjectives.** Cut "comprehensive", "robust",
51
+ "elegant", "seamlessly", "industry-leading". They mean nothing.
52
+ - **No hedging.** "Could potentially" → "may". "It might be the
53
+ case that" → cut.
54
+ - **No restating the title or task.** The reader just read it.
55
+
56
+ ### The delete test
57
+
58
+ Read each sentence. *Can you delete it without losing information?*
59
+ If yes, delete it. Apply recursively until no sentence survives.
60
+ Reading time of an SDD artifact should equal the reading time of
61
+ its information content. Nothing else.
62
+
63
+ ### Length cues per artifact
64
+
65
+ - **Spec.** As long as the work demands; no longer. 100–300 lines
66
+ is typical for a non-trivial feature spec. Over 500 lines is
67
+ almost always a smell — either the scope is too big (split it)
68
+ or the prose is padded (cut it).
69
+ - **Journal entry.** 3–5 bullets per entry. One line if nothing
70
+ surprising happened. The whole journal is 3–10 entries for a
71
+ ticket.
72
+ - **Changelog entry.** One bullet. Cites the spec with a link.
73
+ - **Constitution entry.** One line. Cites the spec with a link.
74
+ If you can't state the invariant in one line, it's probably not
75
+ an invariant — it's a rule (see AGENTS.md).
76
+
77
+ If you find yourself writing "this section is more detailed than
78
+ usual because of X," delete the section and write a shorter version.
79
+
80
+ ## The discriminator test — where does this belong?
81
+
82
+ When unsure where to put something, ask: *what happens if it's
83
+ violated?*
84
+
85
+ - The codebase becomes a *fundamentally different project* (we suddenly
86
+ aren't a Bun project anymore) → **CONSTITUTION**.
87
+ - A PR gets review feedback ("use repository pattern here") →
88
+ **AGENTS.md** (or whatever the project's code-conventions file is).
89
+ - It was a choice for one specific feature ("we picked Stripe SDK
90
+ directly for this billing work") → the spec's **`## Decision`
91
+ section**.
92
+ - It's about how SDD itself works ("specs go draft → accepted →
93
+ shipped") → this **sdd skill**.
94
+
95
+ ### Worked examples
96
+
97
+ **Constitution** — tribal knowledge, foundational, "crossing this
98
+ changes what the project is":
99
+
100
+ - We use Bun, not Node or Deno.
101
+ - We use PostgreSQL, not MySQL.
102
+ - Deployed only to AWS eu-central-1.
103
+ - All authentication through Auth0.
104
+ - Production data never leaves AWS.
105
+
106
+ **AGENTS.md** — current code rules, evolves with the codebase:
107
+
108
+ - Don't do unnecessary `as unknown as` casts.
109
+ - Prefer `unknown` over `any`.
110
+ - Database access through the repository pattern.
111
+ - Test files live next to source: `foo.ts` + `foo.test.ts`.
112
+ - Use Zod at trust boundaries.
113
+ - Be a partner not order-taker (AI interaction style).
114
+
115
+ **Spec `## Decision` section** — one-off, per-feature:
116
+
117
+ - "Used Stripe SDK directly rather than abstracting; revisit if we
118
+ add a second payment provider."
119
+ - "Picked nock over msw for mocking; msw doesn't intercept the SDK's
120
+ internal HTTPS validation."
121
+
122
+ **Sdd skill** — process, not content:
123
+
124
+ - Specs go `draft` → `accepted` → `shipped`.
125
+ - Numbering is per-directory monotonic for repo-level specs; ticket-ID
126
+ for ticket-keyed folders.
127
+ - Ticket-keyed folder layout is `docs/<ticket-or-slug>/`.
128
+
129
+ ## Folder layout
130
+
131
+ Ticket-keyed, flat. The folder name is the link to the tracker
132
+ (Jira, Linear, GitHub Issues, or a project-local convention).
133
+
134
+ ```
135
+ my-repo/
136
+ ├── README.md
137
+ ├── CHANGELOG.md ← repo-level events
138
+ ├── CONSTITUTION.md ← OPTIONAL; only when the project
139
+ │ has real invariants to codify
140
+ ├── AGENTS.md ← code rules + interaction style
141
+ │ (project-specific; not shipped here)
142
+ └── docs/
143
+ ├── AC-100-billing-revamp/
144
+ │ ├── spec.md
145
+ │ └── journal.md
146
+ ├── AC-101-pricing-page/
147
+ │ ├── spec.md
148
+ │ └── journal.md
149
+ └── AC-999-decide-monorepo/ ← meta-tickets for cross-cutting
150
+ ├── spec.md decisions are just ticket folders too
151
+ └── journal.md
152
+ ```
153
+
154
+ In a monorepo, each package can have the same structure inside
155
+ `packages/<name>/docs/`, with the package's own `CHANGELOG.md`,
156
+ `SPEC.md` (singular, purpose-and-scope), and optional
157
+ `CONSTITUTION.md`.
158
+
159
+ **Ticket ID format is not validated.** `AC-101-slug`, `LIN-42-slug`,
160
+ `gh-7-slug`, `CLEEPI-001-slug` all work. For pre-tracker work, use
161
+ `DRAFT-NNN-slug` and rename when a ticket is cut.
162
+
163
+ ## Scope resolution
164
+
165
+ When creating a spec, journal, or changelog entry, determine **scope**
166
+ first:
167
+
168
+ - **Package scope** — when working inside `packages/<n>/`, write to:
169
+ - `packages/<n>/docs/<ticket-or-slug>/spec.md` (and `journal.md`)
170
+ - `packages/<n>/CHANGELOG.md`
171
+ - `packages/<n>/CONSTITUTION.md` (if applicable)
172
+ - **Repo scope** — when the change is cross-cutting (affects multiple
173
+ packages, repo tooling, conventions, adding/removing a package),
174
+ write to:
175
+ - `docs/<ticket-or-slug>/spec.md` (and `journal.md`)
176
+ - `/CHANGELOG.md`
177
+ - `/CONSTITUTION.md` (if applicable)
178
+
179
+ When in doubt: if it only affects one package, it's package scope.
180
+
181
+ The package's own `SPEC.md` (singular, capitalized, at
182
+ `packages/<n>/SPEC.md`) is a special file — it describes the
183
+ package's *purpose and scope*, not a feature. It is not numbered,
184
+ has no formal lifecycle, and isn't replaced by ticket folders.
185
+
186
+ ## Status lifecycle (specs)
187
+
188
+ - `draft` — being written, open for changes. No `## Decision` section
189
+ required yet.
190
+ - `accepted` — design agreed; implementation can start (strict mode).
191
+ `## Decision` section **must** be populated before flipping to this
192
+ status.
193
+ - `shipped` — implementation complete and released; spec is now
194
+ **frozen**. Future changes go in a new spec marked
195
+ `supersedes: docs/<old-folder>/spec.md`.
196
+ - `superseded` — replaced by a later spec. Set
197
+ `superseded-by: docs/<new-folder>/spec.md` in frontmatter.
198
+
199
+ ## Spec format
200
+
201
+ Every spec has frontmatter plus a body. Required sections:
202
+
203
+ ```yaml
204
+ ---
205
+ id: AC-101 # the ticket ID, or a project-local
206
+ # identifier for non-tracker specs
207
+ title: <human-readable title>
208
+ status: draft # → accepted → shipped/superseded
209
+ created: YYYY-MM-DD
210
+ accepted: YYYY-MM-DD # added when flipped to accepted
211
+ shipped: YYYY-MM-DD # added when flipped to shipped
212
+ owner: <human>
213
+ ticket: AC-101 # tracker ticket ID (optional for
214
+ # repo-internal specs)
215
+ ticket-url: https://... # optional, full URL
216
+ related:
217
+ - docs/<other-folder>/spec.md
218
+ ---
219
+ ```
220
+
221
+ Body sections — minimal core, everything else opt-in.
222
+
223
+ **Required:**
224
+
225
+ - **`## What`** — what's being built. Concrete, specific. Works for
226
+ features, refactors, and bug fixes equally. Show the thing.
227
+ - **`## Why`** — the reason. Both the motivation and the timing,
228
+ in one section.
229
+ - **`## Decision`** — required before `status: accepted` (stub OK
230
+ while draft). Format:
231
+ - **Alternatives considered** (honest summary + why rejected, for each)
232
+ - **Rationale** (why the picked option wins, anchored on What and Why)
233
+ - **Consequences** (what becomes easier, harder, locked-in)
234
+
235
+ **Optional — include only when they add information:**
236
+
237
+ - **`## Concrete surface`** — the files this delivers/changes.
238
+ Often filled during iteration by analysis (scout phase), not at
239
+ initial draft. Skip when obvious.
240
+ - **`## Phased rollout`** — for multi-phase work. Each phase has
241
+ deliverables and acceptance criteria. Skip for single-pass
242
+ changes.
243
+ - **`## Open questions`** — unresolved choices, with default-
244
+ proposed answers where possible. Mark which phase resolves each.
245
+ - **`## Non-goals`** — only when scope is genuinely ambiguous.
246
+ Forced "we won't boil the ocean" filler fails the delete test.
247
+ - **`## Risks`** — real risks with mitigations. Synthetic "what if
248
+ it breaks" risks fail the delete test.
249
+
250
+ Apply the delete test to every section. A spec with three sections
251
+ (What / Why / Decision) is better than a spec with eight where five
252
+ are filler.
253
+
254
+ A spec without a Decision section is fine as `draft`; it cannot be
255
+ promoted to `accepted` until the section is populated.
256
+
257
+ ## Journal discipline
258
+
259
+ Each ticket folder may contain a `journal.md` capturing in-flight
260
+ thinking. Two sections:
261
+
262
+ ```markdown
263
+ # Journal — <ticket-id> <slug>
264
+
265
+ ## Current state
266
+ *(overwritten each session — kept terse)*
267
+
268
+ - <where things stand right now>
269
+ - <what's blocked, what's next>
270
+
271
+ ## Log
272
+
273
+ ### YYYY-MM-DD — <author or session id>
274
+ - <what was tried, what worked, what didn't, what's blocked>
275
+
276
+ ### YYYY-MM-DD — earlier session
277
+ - <older entries below>
278
+ ```
279
+
280
+ **Hard rules:**
281
+
282
+ - One entry per work session, not per action.
283
+ - Capture **friction** (dead ends, blockers, surprises, decisions
284
+ that changed). If everything went smoothly, one line is enough.
285
+ - No code in the journal. Reference commits/PRs.
286
+ - Bullets over paragraphs.
287
+ - 3–10 log entries per ticket is normal; 20+ is a smell (split the
288
+ ticket, or stop logging routine progress).
289
+ - Append-only on the log; "Current state" is overwritten.
290
+ - On ticket ship: final entry citing the changelog version, then
291
+ the log stops appending. Not deleted.
292
+
293
+ **Journal vs Changelog (one-line litmus):** *if an entry has no dead
294
+ end, blocker, or reasoning, it's not journal material — it's a
295
+ changelog entry waiting to happen.*
296
+
297
+ ## Constitution discipline (when used)
298
+
299
+ `CONSTITUTION.md` is **optional**. Use it when the project has real
300
+ invariants worth making explicit — things everyone on the team
301
+ already follows but never wrote down, and that crossing would
302
+ fundamentally change what the project is.
303
+
304
+ **Don't use it** for:
305
+
306
+ - Code style or lint rules → AGENTS.md
307
+ - "Prefer X over Y" conventions → AGENTS.md
308
+ - Per-feature design choices → spec Decision sections
309
+ - Process rules → this sdd skill
310
+
311
+ **Maintenance:** when a spec is promoted to `accepted`, the author
312
+ considers whether the spec's Decision section establishes a new
313
+ invariant (commits the project to something indefinitely, not just
314
+ a one-off). If yes, a corresponding CONSTITUTION entry is added in
315
+ the same change. Most specs do NOT establish invariants — they
316
+ establish features.
317
+
318
+ **To change an invariant:** write a new spec that supersedes the
319
+ originating one. Don't edit CONSTITUTION.md directly.
320
+
321
+ ## Strict-mode workflow
322
+
323
+ For non-trivial work:
324
+
325
+ 1. Cut a ticket (Jira / Linear / GitHub Issue / local `DRAFT-NNN`).
326
+ 2. Create the ticket folder: `docs/<ticket-id>-<slug>/`.
327
+ 3. Draft `spec.md`. Status `draft`. Use the `/spec` slash command.
328
+ 4. Iterate on the spec; populate the Decision section. Flip status
329
+ to `accepted` when ready.
330
+ 5. Implement. Append to `journal.md` as you go — friction, blockers,
331
+ surprises only (`/journal` slash command).
332
+ 6. When merged/released: flip spec status to `shipped`. Add a
333
+ `CHANGELOG.md` entry for the relevant scope (`/changelog`).
334
+ 7. If the spec's Decision section established a new invariant,
335
+ propagate it to CONSTITUTION.md in the same change.
336
+
337
+ ### What's "trivial" (skip the dance)
338
+
339
+ No spec required for: typo fixes, formatting, documentation polish,
340
+ mechanical renames, dependency bumps that don't change behavior,
341
+ obvious bug fixes. Trivial changes still go in the relevant changelog
342
+ if user-visible.
343
+
344
+ ### Bootstrap exception
345
+
346
+ The single commit that *introduces* SDD into a repo is allowed without
347
+ a pre-existing accepted spec, because the spec defining the process is
348
+ created in that same commit. One-off. Does not apply to any later
349
+ work.
350
+
351
+ ## Changelog conventions
352
+
353
+ [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/). One
354
+ file per package at `packages/<n>/CHANGELOG.md`, plus one at the
355
+ repo root for repo-level events (tooling, new packages,
356
+ conventions).
357
+
358
+ Section names (use only the ones with content): `Added`, `Changed`,
359
+ `Deprecated`, `Removed`, `Fixed`, `Security`.
360
+
361
+ Always keep an `## [Unreleased]` section at the top. On release,
362
+ rename it to the new version with today's date, then re-add an empty
363
+ `[Unreleased]`.
364
+
365
+ ```markdown
366
+ ## [Unreleased]
367
+
368
+ ## [0.2.0] — 2026-06-01
369
+
370
+ ### Added
371
+ - Thing A (see [spec AC-101](docs/AC-101-thing-a/spec.md)).
372
+
373
+ ### Fixed
374
+ - Thing B.
375
+ ```
376
+
377
+ ## SemVer
378
+
379
+ Each package versions independently. Pre-`1.0.0`, minor bumps may
380
+ include breaking changes (per SemVer §4). At `1.0.0`, commit to
381
+ standard SemVer.
382
+
383
+ The repo itself isn't versioned — root `CHANGELOG.md` uses
384
+ `[Unreleased]` and dated sections without version numbers.
385
+
386
+ ## Templates
387
+
388
+ Live in `packages/sdd/templates/`:
389
+
390
+ - `spec.md` — the four required sections + Decision template
391
+ - `journal.md` — stack-pointer-plus-log skeleton
392
+ - `constitution.md` — invariants-only skeleton with inline
393
+ guidance on what belongs vs doesn't
394
+ - `changelog-section.md` — Keep-a-Changelog section block
395
+
396
+ The `/spec`, `/journal`, `/changelog` prompts use these. If invoked
397
+ manually:
398
+
399
+ ```bash
400
+ # Make the ticket folder, copy template:
401
+ mkdir -p docs/AC-101-pricing-page
402
+ cp <sdd-pkg>/templates/spec.md docs/AC-101-pricing-page/spec.md
403
+ # Fill frontmatter and body.
404
+ ```
405
+
406
+ ## Quick reference
407
+
408
+ | You want to... | Use |
409
+ | --- | --- |
410
+ | Start a non-trivial change | `/spec <title>` (asks for ticket ID interactively) |
411
+ | Log a session's friction / progress | `/journal <text>` |
412
+ | Note something shipped | `/changelog <added\|changed\|fixed\|...> <text>` |
413
+ | Add a project invariant | Edit `CONSTITUTION.md` directly (no slash command) |
414
+ | Freeze a shipped spec | Edit frontmatter `status: shipped` |
415
+ | Replace a spec | New spec; old one's status becomes `superseded`, with `superseded-by:` set |
416
+
417
+ ## Migration from sdd v0.1.x
418
+
419
+ If you're upgrading from sdd v0.1.x:
420
+
421
+ - `/adr` is gone. Move ADR content into the spec's `## Decision`
422
+ section. Mark old ADRs as `superseded by spec <id>`.
423
+ - `docs/specs/NNNN-*.md` files don't have to move. New specs go
424
+ in ticket-keyed folders; old ones stay as historical record
425
+ (with `status: shipped` or `superseded`).
426
+ - `docs/adr/` becomes a read-only archive directory.
427
+ - Add an optional `CONSTITUTION.md` at the relevant scope if the
428
+ project has invariants to codify.
429
+ - Start using `journal.md` for active work.
430
+
431
+ No automated migration tooling. The transition is intentional and
432
+ unhurried.
@@ -0,0 +1,28 @@
1
+ <!--
2
+ Use one or more of these subsections under [Unreleased] or a
3
+ version heading. Only include subsections that have content.
4
+ Order is conventional (Added → Security), not enforced by
5
+ Keep-a-Changelog.
6
+
7
+ One bullet per entry. Cite the spec with a link.
8
+
9
+ See @cleepi/sdd skill "Voice and length" section.
10
+ -->
11
+
12
+ ### Added
13
+ - New feature description. See [spec AC-NNN](docs/AC-NNN-slug/spec.md).
14
+
15
+ ### Changed
16
+ - What changed in existing behavior. See [spec AC-NNN](docs/AC-NNN-slug/spec.md).
17
+
18
+ ### Deprecated
19
+ - Feature scheduled for removal in version X.Y.0.
20
+
21
+ ### Removed
22
+ - Feature removed. Note migration path if any.
23
+
24
+ ### Fixed
25
+ - Bug description. Link to issue/PR if applicable.
26
+
27
+ ### Security
28
+ - Vulnerability fixed. CVE if applicable. Affected versions.
@@ -0,0 +1,39 @@
1
+ <!--
2
+ Invariants only. Things that must always be true for this project.
3
+ If violated, the project becomes something else.
4
+
5
+ Not for:
6
+ - Code rules ("prefer X over Y") → put in AGENTS.md
7
+ - Process rules ("specs go draft→accepted") → @cleepi/sdd skill
8
+ - One-off design choices → spec Decision section
9
+
10
+ One line per invariant. Cite the spec that established it when
11
+ one exists. Most invariants pre-date specs and are codified
12
+ retroactively — citation optional in that case.
13
+
14
+ This file is OPTIONAL. Many projects don't need one. Add it only
15
+ when the project has real invariants worth making explicit.
16
+
17
+ See @cleepi/sdd skill "Constitution discipline" section.
18
+ -->
19
+
20
+ # Constitution
21
+
22
+ The invariants for this project — things that must always be true.
23
+
24
+ To change an invariant, write a new spec that supersedes the
25
+ originating one. Don't edit this file directly to amend an invariant
26
+ — surface the change through SDD.
27
+
28
+ ## Stack
29
+
30
+ - We use <X>, not <Y>. ([spec](docs/<folder>/spec.md))
31
+ - <invariant>.
32
+
33
+ ## Process
34
+
35
+ - <invariant>. ([spec](docs/<folder>/spec.md))
36
+
37
+ ## Domain
38
+
39
+ - <invariant>. ([spec](docs/<folder>/spec.md))
@@ -0,0 +1,33 @@
1
+ <!--
2
+ Stack pointer + log. Overwrite "Current state" each session;
3
+ append to "Log". Capture friction (dead ends, blockers, surprises),
4
+ not flow. One entry per work session, not per action. 3–5 bullets
5
+ per entry. Whole journal is 3–10 entries for a ticket.
6
+
7
+ If an entry has no dead end, blocker, or reasoning, it's not
8
+ journal material — it's a changelog entry waiting to happen.
9
+
10
+ See @cleepi/sdd skill "Journal discipline" and "Voice and length"
11
+ sections.
12
+ -->
13
+
14
+ # Journal — <ticket-id> <slug>
15
+
16
+ ## Current state
17
+
18
+ *(overwritten each session — kept terse)*
19
+
20
+ - <where things stand right now>
21
+ - <what's blocked, what's next>
22
+ - <active branch / PR if applicable>
23
+
24
+ ## Log
25
+
26
+ ### YYYY-MM-DD — <author or session id>
27
+
28
+ - <what was tried, what worked, what didn't, what's blocked>
29
+ - <reference commits/PRs, no inline code>
30
+
31
+ ### YYYY-MM-DD — <earlier session>
32
+
33
+ - <older entries below; append-only>
@@ -0,0 +1,75 @@
1
+ ---
2
+ id: AC-NNN # ticket ID, or DRAFT-NNN for pre-tracker
3
+ title: <Specific title, not "X improvements">
4
+ status: draft # draft → accepted → shipped/superseded
5
+ created: YYYY-MM-DD
6
+ accepted: # filled when flipped to accepted
7
+ shipped: # filled when flipped to shipped
8
+ owner: <human>
9
+ ticket: AC-NNN # tracker ID; optional for repo-internal specs
10
+ ticket-url: # optional, full URL
11
+ related: []
12
+ ---
13
+
14
+ <!--
15
+ Be concise. Apply the delete test before flipping to accepted.
16
+ See @cleepi/sdd skill "Voice and length" section.
17
+ -->
18
+
19
+ # Spec AC-NNN: <Title>
20
+
21
+ ## What
22
+
23
+ What's being built. Concrete, specific. Show the thing, don't
24
+ describe it. Works equally for features, refactors, and bug fixes.
25
+
26
+ ## Why
27
+
28
+ Why this work. Cite prior specs, constitution entries, or package
29
+ SPEC.md if relevant.
30
+
31
+ ## Decision
32
+
33
+ <!-- Required before status: accepted. Stub OK while draft. -->
34
+
35
+ We chose **<X>** over **<Y>**.
36
+
37
+ ### Alternatives considered
38
+
39
+ - **<X>** (chosen) — what it is, why it wins.
40
+ - **<Y>** — what it is, why rejected.
41
+
42
+ ### Rationale
43
+
44
+ Why <X> wins, anchored on What and Why.
45
+
46
+ ### Consequences
47
+
48
+ - What becomes easier or possible.
49
+ - What becomes harder or locked-in.
50
+ - What we accept as the cost.
51
+
52
+ <!--
53
+ Optional sections — add only when they add information.
54
+ Apply the delete test: if a section would be filler, omit it.
55
+
56
+ ## Concrete surface
57
+ The files this delivers or changes. Often filled during
58
+ iteration by analysis (scout) rather than at initial draft.
59
+
60
+ ## Phased rollout
61
+ For multi-phase work. Each phase: deliverables + acceptance
62
+ criteria. Skip for single-pass changes.
63
+
64
+ ## Open questions
65
+ Unresolved choices. Include default-proposed answer where
66
+ possible. Mark which phase resolves each.
67
+
68
+ ## Non-goals
69
+ Only when scope is genuinely ambiguous. "We won't boil the
70
+ ocean" filler fails the delete test — skip it.
71
+
72
+ ## Risks
73
+ Real risks with mitigations. Synthetic "what if it breaks"
74
+ risks fail the delete test — skip them.
75
+ -->