@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 +113 -0
- package/README.md +107 -0
- package/SPEC.md +104 -0
- package/package.json +42 -0
- package/prompts/changelog.md +39 -0
- package/prompts/journal.md +50 -0
- package/prompts/spec.md +58 -0
- package/skills/sdd/SKILL.md +432 -0
- package/templates/changelog-section.md +28 -0
- package/templates/constitution.md +39 -0
- package/templates/journal.md +33 -0
- package/templates/spec.md +75 -0
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.
|
package/prompts/spec.md
ADDED
|
@@ -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
|
+
-->
|