tiny-spec 0.2.1__tar.gz → 0.4.0__tar.gz
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.
- tiny_spec-0.4.0/PKG-INFO +444 -0
- tiny_spec-0.4.0/README.md +407 -0
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/agents/tiny-spec-build-executor.md +22 -2
- tiny_spec-0.4.0/agents/tiny-spec-build-reviewer.md +171 -0
- tiny_spec-0.4.0/docs/eval/README.md +119 -0
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/pyproject.toml +5 -1
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny-spec-breakdown/SKILL.md +70 -6
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny-spec-build/SKILL.md +49 -7
- tiny_spec-0.4.0/tiny-spec-create/SKILL.md +439 -0
- tiny_spec-0.4.0/tiny-spec-plan/SKILL.md +152 -0
- tiny_spec-0.4.0/tiny-spec-prd/SKILL.md +160 -0
- tiny_spec-0.4.0/tiny-spec-run/SKILL.md +228 -0
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny-spec-tasks/SKILL.md +64 -6
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny_spec/__init__.py +1 -1
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny_spec/manifest.json +2 -0
- tiny_spec-0.2.1/PKG-INFO +0 -244
- tiny_spec-0.2.1/README.md +0 -207
- tiny_spec-0.2.1/agents/tiny-spec-build-reviewer.md +0 -69
- tiny_spec-0.2.1/tiny-spec-breakdown/templates/BREAKDOWN.template.md +0 -37
- tiny_spec-0.2.1/tiny-spec-build/templates/memory.template.md +0 -17
- tiny_spec-0.2.1/tiny-spec-create/SKILL.md +0 -133
- tiny_spec-0.2.1/tiny-spec-create/templates/SPEC.template.md +0 -51
- tiny_spec-0.2.1/tiny-spec-create/templates/constitution.template.md +0 -34
- tiny_spec-0.2.1/tiny-spec-plan/SKILL.md +0 -70
- tiny_spec-0.2.1/tiny-spec-plan/templates/PLAN.template.md +0 -45
- tiny_spec-0.2.1/tiny-spec-tasks/templates/tasks.template.md +0 -28
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/.gitignore +0 -0
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/LICENSE +0 -0
- {tiny_spec-0.2.1 → tiny_spec-0.4.0}/tiny_spec/cli.py +0 -0
tiny_spec-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tiny-spec
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: A tiny, opinionated take on spec-driven development.
|
|
5
|
+
Project-URL: Homepage, https://github.com/GrayMa77er/tiny-spec
|
|
6
|
+
Project-URL: Source, https://github.com/GrayMa77er/tiny-spec
|
|
7
|
+
Project-URL: Issues, https://github.com/GrayMa77er/tiny-spec/issues
|
|
8
|
+
Author: Snir Orlanczyk
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026 Snir Orlanczyk
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Keywords: ai-agents,claude,claude-code,skills,spec-driven-development
|
|
32
|
+
Classifier: Environment :: Console
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Requires-Python: >=3.9
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="images/logo.png" alt="tiny-spec" width="200">
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<h1 align="center">tiny-spec</h1>
|
|
43
|
+
|
|
44
|
+
<p align="center">A tiny, opinionated take on spec-driven development.</p>
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
|
|
48
|
+
<a href="https://docs.claude.com/en/docs/claude-code/overview"><img src="https://img.shields.io/badge/Claude%20Code-skills-d97757.svg" alt="Claude Code"></a>
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
tiny-spec is a four-step workflow for Claude Code that turns a ticket into shipped,
|
|
52
|
+
reviewed code. You write the intent, it produces a design, a task list, and then
|
|
53
|
+
builds the work one task at a time. Every task is implemented by one agent and
|
|
54
|
+
graded by an independent reviewer that runs the real tests before anything is
|
|
55
|
+
committed.
|
|
56
|
+
|
|
57
|
+
That core is **four skills and two agents**. In front of it sit **two optional
|
|
58
|
+
planning on-ramps** — `tiny-spec-prd` (idea → PRD) and `tiny-spec-breakdown`
|
|
59
|
+
(PRD → stories) — for when you're starting from an idea rather than a ready ticket.
|
|
60
|
+
`tiny-spec-run` walks the three planning steps in one command. No config file, no
|
|
61
|
+
build step.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
┌───────────────── tiny-spec-run ─────────────────┐
|
|
65
|
+
│ optional: one command, stops before build │
|
|
66
|
+
▼ ▼
|
|
67
|
+
PLANNING (optional on-ramps) EXECUTION (the core loop, one story at a time)
|
|
68
|
+
tiny-spec-prd ⇢ tiny-spec-breakdown ⇢ tiny-spec-create → tiny-spec-plan → tiny-spec-tasks → tiny-spec-build
|
|
69
|
+
idea → PRD PRD → stories intent design tasks per-task loop
|
|
70
|
+
PRD.md BREAKDOWN.md SPEC.md PLAN.md + tasks.md plan → implement → review → commit
|
|
71
|
+
constitution
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The two on-ramps are **optional** and stack. Have nothing written down? Run
|
|
75
|
+
`tiny-spec-prd` to interview your idea into a `PRD.md`. Have a PRD already? Run
|
|
76
|
+
`tiny-spec-breakdown` to carve it into a `BREAKDOWN.md` — a flat list of
|
|
77
|
+
Features → Stories with draft acceptance criteria. Have a single known piece of
|
|
78
|
+
work? Skip both and start at `tiny-spec-create`. Both on-ramps write a regenerable
|
|
79
|
+
file at your project root (not under `.spec/`); `tiny-spec-create` then reads the
|
|
80
|
+
breakdown one story at a time.
|
|
81
|
+
|
|
82
|
+
## New to spec-driven development?
|
|
83
|
+
|
|
84
|
+
Spec-driven development (SDD) means writing down *what* you want and *why* before
|
|
85
|
+
any code exists, then letting that spec drive the build. Instead of prompting an
|
|
86
|
+
agent and hoping, you hand it a small, explicit contract — the intent, a design,
|
|
87
|
+
and an ordered list of tasks — and it implements against that. The payoff: the
|
|
88
|
+
agent stops guessing. It knows what "done" looks like, you can review the plan
|
|
89
|
+
before a single line is written, and the result is checked against the spec
|
|
90
|
+
rather than vibes. tiny-spec is one small take on that idea.
|
|
91
|
+
|
|
92
|
+
## Quickstart
|
|
93
|
+
|
|
94
|
+
Install the skills and agents into your Claude Code config with
|
|
95
|
+
[uv](https://docs.astral.sh/uv/):
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
uvx tiny-spec install
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Restart Claude Code so it picks up the new skills, then run the flow in your project:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
/tiny-spec-prd # optional: interview a rough idea into a PRD (PRD.md)
|
|
105
|
+
/tiny-spec-breakdown # optional: carve a PRD + wireframes into stories (BREAKDOWN.md)
|
|
106
|
+
/tiny-spec-create # capture intent and requirements (binds a ticket, optional)
|
|
107
|
+
/tiny-spec-plan # turn the spec into a design and harden the constitution
|
|
108
|
+
/tiny-spec-tasks # slice the plan into an ordered checklist
|
|
109
|
+
/tiny-spec-build # build each task: implement, review, commit
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Or collapse the three planning steps into one and go straight to building:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
/tiny-spec-run # create → plan → tasks in one pass; stops before build
|
|
116
|
+
/tiny-spec-build # build each task: implement, review, commit
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`tiny-spec-run` resolves where your ticket stands and invokes whichever of
|
|
120
|
+
`create` / `plan` / `tasks` moves it forward, reconciling anything stale first. It
|
|
121
|
+
**stops before `tiny-spec-build`** — that's where you actually review the work — and
|
|
122
|
+
it writes nothing itself, it only delegates.
|
|
123
|
+
|
|
124
|
+
**Building from a mockup?** There is no design flag to pass. Commit your exports to
|
|
125
|
+
`design/` before the run and `tiny-spec-create` — whether you invoke it directly or
|
|
126
|
+
reach it through `tiny-spec-run` — reads what's there and asks which screens this
|
|
127
|
+
ticket covers. [Designs, if you have them](#designs-if-you-have-them) walks through it.
|
|
128
|
+
|
|
129
|
+
Re-run `install` any time to update; `tiny-spec uninstall` removes only what it
|
|
130
|
+
installed. Each skill is copied (not symlinked) so every install is
|
|
131
|
+
self-contained.
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary>Manual install (no uv)</summary>
|
|
135
|
+
|
|
136
|
+
The skills and agents are plain markdown — copy them in by hand. Claude Code
|
|
137
|
+
loads skills from `~/.claude/skills/` and agents from `~/.claude/agents/`:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
git clone https://github.com/GrayMa77er/tiny-spec.git
|
|
141
|
+
cd tiny-spec
|
|
142
|
+
|
|
143
|
+
mkdir -p "$HOME/.claude/skills" "$HOME/.claude/agents"
|
|
144
|
+
for s in tiny-spec-prd tiny-spec-breakdown tiny-spec-run tiny-spec-create tiny-spec-plan tiny-spec-tasks tiny-spec-build; do
|
|
145
|
+
cp -R "$s" "$HOME/.claude/skills/$s"
|
|
146
|
+
done
|
|
147
|
+
cp agents/*.md "$HOME/.claude/agents/"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If a skill name collides with one you already have, rename these before copying,
|
|
151
|
+
or install one set at a time.
|
|
152
|
+
|
|
153
|
+
</details>
|
|
154
|
+
|
|
155
|
+
## How it works
|
|
156
|
+
|
|
157
|
+
The constitution (`constitution.md`) is the spine. `tiny-spec-create` seeds it from a
|
|
158
|
+
short interview, `tiny-spec-plan` hardens it with concrete engineering rules, and
|
|
159
|
+
`tiny-spec-build` injects it whole into every task. It holds your style, standards,
|
|
160
|
+
invariants, definition of done, and verification commands.
|
|
161
|
+
|
|
162
|
+
Because it is project-wide it can also go missing — deleted, or never committed —
|
|
163
|
+
while your specs survive. Re-running `tiny-spec-create` then repairs it: it rebuilds
|
|
164
|
+
the constitution from whatever is already written down and marks completed tasks
|
|
165
|
+
stale, since they were reviewed against a document that wasn't there.
|
|
166
|
+
|
|
167
|
+
### Designs, if you have them
|
|
168
|
+
|
|
169
|
+
Wireframes usually get read once and forgotten. tiny-spec turns them into two durable
|
|
170
|
+
things — a project-wide token system in the constitution, and a per-screen entry in
|
|
171
|
+
the spec — so "does this look right?" becomes something the reviewer can fail a task
|
|
172
|
+
on. Skip all of it for a CLI or a library; the constitution simply has no design
|
|
173
|
+
section.
|
|
174
|
+
|
|
175
|
+
**Designs enter by convention, not by argument.** No skill takes a design flag or a
|
|
176
|
+
path parameter. `tiny-spec-create` reads every file in `design/` at your project root —
|
|
177
|
+
directly, or when `tiny-spec-run` reaches it — and asks which screens this ticket
|
|
178
|
+
covers; you can also just hand it paths during the interview. Change an export later and
|
|
179
|
+
re-running `create` (or `run`) re-hashes it, marking the spec stale exactly like editing
|
|
180
|
+
a requirement.
|
|
181
|
+
|
|
182
|
+
**1. Commit your exports.** Any format an agent can read — a Figma export, an HTML
|
|
183
|
+
mockup, an Excalidraw file, a photo of a whiteboard.
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
your-project/
|
|
187
|
+
design/
|
|
188
|
+
signup.png
|
|
189
|
+
dashboard.png
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**2. `tiny-spec-create` looks at them and proposes a design system.** Actually looks —
|
|
193
|
+
they are read as images. It infers *one* coherent scale across all of them rather than
|
|
194
|
+
measuring each screen separately, tells you what it rounded ("your wireframes had 19px
|
|
195
|
+
and 21px — proposing `space.5`=20px for both"), and on your approval writes it into
|
|
196
|
+
`.spec/constitution.md`:
|
|
197
|
+
|
|
198
|
+
```markdown
|
|
199
|
+
## Design system
|
|
200
|
+
- color: `color.surface.base` #FFFFFF · `color.text.default` #111111
|
|
201
|
+
`color.text.muted` #6B7280 · `color.text.danger` #B91C1C
|
|
202
|
+
- space: `space.1`=4px · `space.2`=8px · `space.4`=16px · `space.6`=24px
|
|
203
|
+
- type: `type.heading.lg` 24px/600/1.25 · `type.body` 16px/400/1.5
|
|
204
|
+
`type.caption` 13px/400/1.4
|
|
205
|
+
- states: every interactive surface defines default, focus, disabled, loading, empty, error
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Since it is project-wide, every screen from here on speaks this vocabulary — and a
|
|
209
|
+
redesign edits this one table instead of every file.
|
|
210
|
+
|
|
211
|
+
**3. Each screen becomes a `D<n>` in `SPEC.md`**, written in those token names:
|
|
212
|
+
|
|
213
|
+
```markdown
|
|
214
|
+
## Design
|
|
215
|
+
|
|
216
|
+
- D1 — Signup form
|
|
217
|
+
- source: figma.com/file/abc#node-12:34 (view-only)
|
|
218
|
+
- export: design/signup.png
|
|
219
|
+
- sha256: d21d6330648c504edeb924b5398bf7fb6485d3a4c1907e43d800970f39622a1d
|
|
220
|
+
- layout: single centered column, max 420px; title → field → error → submit
|
|
221
|
+
- elements:
|
|
222
|
+
- card `[data-testid="signup-card"]` → space.6 padding, color.surface.base
|
|
223
|
+
- title `[data-testid="signup-title"]` → type.heading.lg, space.4 below
|
|
224
|
+
- field `[data-testid="signup-email"]` → type.body, space.2 below
|
|
225
|
+
- error `[data-testid="signup-error"]` → type.caption, color.text.danger
|
|
226
|
+
- states: error (caption under the field), loading (spinner replaces button label)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The selectors are a **contract**, not a hint — the reviewer measures exactly these, so
|
|
230
|
+
your markup carries them verbatim. Prefer test ids over CSS classes: classes get
|
|
231
|
+
renamed by refactors and mangled by CSS-in-JS, and a selector that silently stops
|
|
232
|
+
matching is the failure this exists to prevent.
|
|
233
|
+
|
|
234
|
+
**4. Tag the tasks that build the surface** — and only those, not the API call behind
|
|
235
|
+
it. This is your blast radius:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
- [ ] T4 — Build the signup form
|
|
239
|
+
- acceptance: submitting a valid email advances to the verify step
|
|
240
|
+
- design: D1
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**5. The reviewer measures it, then looks at it, and fails on both:**
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
DESIGN: D1 — Signup form
|
|
247
|
+
[data-testid="signup-card"] padding 19px — not on the space.* scale (4/8/16/24)
|
|
248
|
+
[data-testid="signup-email"] MISSING FROM DOM — never built, or renamed
|
|
249
|
+
[data-testid="signup-error"] rgb(204,0,0) — color.text.danger is #B91C1C
|
|
250
|
+
state "loading" never renders: button label stays "Continue", no spinner
|
|
251
|
+
judge: read states default, error — compared against design/signup.png
|
|
252
|
+
state "error": signup-error sits behind the card — every token right, and the
|
|
253
|
+
user sees nothing where the export shows the red caption
|
|
254
|
+
state "default": submit label "Create account" truncates to "Create acco…"
|
|
255
|
+
FINDINGS:
|
|
256
|
+
- flag: title/field gap feels tight (on-scale — does not fail the task)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Numbers first, and never a screenshot diff — pixel comparison goes flaky on font
|
|
260
|
+
antialiasing and teams end up muting it. But no measurement catches an element that is
|
|
261
|
+
present, on-token, and still not on screen — occluded, clipped, truncated, or the same
|
|
262
|
+
color as what's behind it. So the last step reads a screenshot of each state next to
|
|
263
|
+
your export and grades presence, legibility, and correspondence. **Where a number
|
|
264
|
+
already settled the question the eye may only flag** — on-scale-but-cramped is never a
|
|
265
|
+
fail — which keeps the two halves from contradicting each other. Measurable or visible
|
|
266
|
+
violations fail; taste comes back as `flag:` notes so a bounded fix loop can't thrash. A
|
|
267
|
+
task with no `design:` tag is graded exactly as before.
|
|
268
|
+
|
|
269
|
+
<details>
|
|
270
|
+
<summary>The <code>visual:</code> command (you write this once)</summary>
|
|
271
|
+
|
|
272
|
+
tiny-spec ships no script — it can't know your stack. Write one, put it in the
|
|
273
|
+
constitution's **Verification commands**, and the reviewer runs it:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
## Verification commands
|
|
277
|
+
- test: `npm test`
|
|
278
|
+
- visual: `node visual.mjs`
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
// visual.mjs — node visual.mjs '<selector>' ['<selector>'...]
|
|
283
|
+
import { chromium } from 'playwright';
|
|
284
|
+
|
|
285
|
+
const b = await chromium.launch({ channel: 'chrome' }); // your Chrome, no download
|
|
286
|
+
const p = await b.newPage({ viewport: { width: 900, height: 700 } });
|
|
287
|
+
await p.goto('http://localhost:3000/signup'); // your dev server + route
|
|
288
|
+
|
|
289
|
+
for (const sel of process.argv.slice(2)) {
|
|
290
|
+
const el = await p.$(sel);
|
|
291
|
+
if (!el) { console.log(`${sel}\n MISSING FROM DOM`); continue; } // required
|
|
292
|
+
console.log(sel, JSON.stringify(await el.evaluate(n => {
|
|
293
|
+
const c = getComputedStyle(n), r = n.getBoundingClientRect();
|
|
294
|
+
return { padding: c.padding, margin: c.margin, fontSize: c.fontSize,
|
|
295
|
+
fontWeight: c.fontWeight, lineHeight: c.lineHeight, color: c.color,
|
|
296
|
+
background: c.backgroundColor, border: c.border,
|
|
297
|
+
opacity: c.opacity, visibility: c.visibility,
|
|
298
|
+
top: Math.round(r.top), w: Math.round(r.width), h: Math.round(r.height) };
|
|
299
|
+
})));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const state = process.env.STATE ?? 'default'; // however you drive states
|
|
303
|
+
const shot = `/tmp/visual-${state}.png`;
|
|
304
|
+
await p.screenshot({ path: shot, fullPage: true });
|
|
305
|
+
console.log('SCREENSHOT', state, shot); // this line arms the judge
|
|
306
|
+
|
|
307
|
+
await b.close();
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
The missing-selector branch **must print something** — that is what turns a renamed
|
|
311
|
+
element into a failure instead of a silent skip. `top` is what the layout-order check
|
|
312
|
+
reads, and `opacity`/`visibility` are worth printing because they turn the cheapest kind
|
|
313
|
+
of invisible element into a numeric failure. The `SCREENSHOT` line is what the reviewer
|
|
314
|
+
reads back to look at the render and catch the rest — occlusion, clipping, truncation,
|
|
315
|
+
same-color-on-same-color — none of which any single property reports. Drop it and the
|
|
316
|
+
numeric half still gates exactly as before, with the reviewer reporting `judge: not run`
|
|
317
|
+
rather than quietly skipping it. Without a `visual:` command at all, a task tagged
|
|
318
|
+
`design:` raises a blocker rather than passing quietly.
|
|
319
|
+
|
|
320
|
+
</details>
|
|
321
|
+
|
|
322
|
+
**No Figma token, plugin, or design SaaS.** A view-only account works fine: the
|
|
323
|
+
committed export is what the agents read, and `source:` keeps the trail back. Change
|
|
324
|
+
an export and its recorded `sha256` stops matching, which marks the spec stale exactly
|
|
325
|
+
like editing a requirement — so a design that moved under finished work can't pass
|
|
326
|
+
unnoticed.
|
|
327
|
+
|
|
328
|
+
`tiny-spec-build` walks the task list top to bottom. Each task runs through one loop:
|
|
329
|
+
|
|
330
|
+
1. Plan the task against the constitution (inline, brief).
|
|
331
|
+
2. Implement it with a fresh `tiny-spec-build-executor` agent.
|
|
332
|
+
3. Review it with an independent `tiny-spec-build-reviewer` agent that runs the gate
|
|
333
|
+
end to end and grades against the constitution and the task's acceptance.
|
|
334
|
+
4. On pass, commit the code plus a checklist tick. On fail, loop back to the
|
|
335
|
+
executor with the findings. After two failed attempts it becomes a blocker.
|
|
336
|
+
|
|
337
|
+
```mermaid
|
|
338
|
+
flowchart TB
|
|
339
|
+
SPEC[SPEC.md<br/>intent] --> PLAN[PLAN.md<br/>design] --> TASKS[tasks.md<br/>checklist]
|
|
340
|
+
|
|
341
|
+
TASKS --> P[Plan task]
|
|
342
|
+
P --> I[Implement<br/>executor]
|
|
343
|
+
I --> R[Review + run gate<br/>reviewer]
|
|
344
|
+
R -->|pass| C[Commit + tick]
|
|
345
|
+
C --> TASKS
|
|
346
|
+
R -->|fail| I
|
|
347
|
+
R -->|fail twice| B[Blocker logged to decisions.md]
|
|
348
|
+
|
|
349
|
+
CON([constitution.md]) -.-> P & I & R
|
|
350
|
+
MEM([memory.md]) -.-> I & R
|
|
351
|
+
DES([SPEC.md D-n + design/ export]) -.->|only on a design: task| I & R
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Solid arrows are the flow. Dotted arrows show the persistent context injected into
|
|
355
|
+
a step: the `constitution.md` goes into planning, implementation, and review, while
|
|
356
|
+
`memory.md` is handed to the executor and reviewer. A task tagged `design:` also
|
|
357
|
+
carries its screen's `D<n>` entry into both agents — and the review step then runs
|
|
358
|
+
the `visual:` gate on top of the usual one.
|
|
359
|
+
|
|
360
|
+
A small `memory.md` carries operational lessons between runs, so the executor and
|
|
361
|
+
reviewer (which start fresh each time) don't relearn the same pitfalls.
|
|
362
|
+
|
|
363
|
+
When a task can't pass because of a gap in the design or spec, the executor stops
|
|
364
|
+
and logs a blocker instead of hacking around it. You fix the gap upstream in
|
|
365
|
+
`tiny-spec-plan` or `tiny-spec-create`, then resume. Work runs one ticket at a time and
|
|
366
|
+
resumes from the checklist state.
|
|
367
|
+
|
|
368
|
+
## Why it's small
|
|
369
|
+
|
|
370
|
+
Most spec frameworks are generous by default:
|
|
371
|
+
many phases, many agents, many generated documents. tiny-spec makes the opposite
|
|
372
|
+
bet. Keep one safeguard, drop the rest.
|
|
373
|
+
|
|
374
|
+
A green unit test suite is not the same as working software, so the reviewer
|
|
375
|
+
exercises acceptance criteria end to end and a final smoke test confirms the whole
|
|
376
|
+
spec. That independent review is the safeguard — not the volume of planning
|
|
377
|
+
artifacts. One task, one commit, an external reviewer. Nothing gets added unless
|
|
378
|
+
it earns its place.
|
|
379
|
+
|
|
380
|
+
The case for staying small:
|
|
381
|
+
|
|
382
|
+
- **Documents are context, and context isn't free.** Generating large `spec.md`,
|
|
383
|
+
`plan.md`, `research.md`, and `data-model.md` files costs tokens to write, then
|
|
384
|
+
costs context to carry. Every paragraph the agent has to hold is room it no
|
|
385
|
+
longer has for your actual code. tiny-spec keeps the spine small — a
|
|
386
|
+
constitution and a short memory — and injects only what each task needs.
|
|
387
|
+
- **Real work is a ticket inside a system, not a greenfield repo.** Bigger kits
|
|
388
|
+
assume you're bootstrapping a project from a blank page. Day to day, you pick up
|
|
389
|
+
a ticket and change part of a system that already exists. tiny-spec binds to a
|
|
390
|
+
ticket, works one at a time, and references your task platform instead of
|
|
391
|
+
re-describing the world.
|
|
392
|
+
- **Rigid pipelines fight the user.** Mandatory phases and required sections
|
|
393
|
+
impose ceremony on work that doesn't need it. tiny-spec's extra structure is
|
|
394
|
+
optional by design — add shape where it pays, skip it where it doesn't.
|
|
395
|
+
- **More moving parts is more to maintain.** Orchestrators, ownership contracts,
|
|
396
|
+
checkpoint matrices, and config files are themselves a system you have to learn
|
|
397
|
+
and keep in sync. A few small skills and two agents are not.
|
|
398
|
+
- **Generated docs can fake rigor.** A folder of polished planning artifacts looks
|
|
399
|
+
like progress, but it isn't proof. The proof is the reviewer running your real
|
|
400
|
+
tests before each commit.
|
|
401
|
+
|
|
402
|
+
That's the whole trade: where larger kits add machinery, tiny-spec adds one
|
|
403
|
+
independent reviewer and stops.
|
|
404
|
+
|
|
405
|
+
## Project layout
|
|
406
|
+
|
|
407
|
+
Each skill is one self-contained `SKILL.md`, with every document skeleton inline in
|
|
408
|
+
it — no companion template files, no absolute paths, and no shared parent required
|
|
409
|
+
at runtime, so a skill works wherever you drop it. (It also means a run never stops
|
|
410
|
+
to ask permission to read a template out of your Claude config directory.)
|
|
411
|
+
|
|
412
|
+
tiny-spec creates a `.spec/` directory in your project root, never inside a skill.
|
|
413
|
+
It is namespaced per ticket, with a shared spine at the root:
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
.spec/
|
|
417
|
+
constitution.md project-wide, shared across tickets
|
|
418
|
+
memory.md operational lessons, shared across tickets
|
|
419
|
+
<ticket-id>/ one directory per ticket (PROJ-123/, gh-42/, …)
|
|
420
|
+
SPEC.md PLAN.md tasks.md decisions.md
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
`PRD.md`, `BREAKDOWN.md`, and `design/` sit at your project root rather than inside
|
|
424
|
+
`.spec/`, because they are yours: the first two are regenerable pre-spec planning
|
|
425
|
+
files, and the design exports are project files no skill ever writes.
|
|
426
|
+
|
|
427
|
+
`CONTRACTS.md` documents the formats for maintainers. The skills do not read it at
|
|
428
|
+
runtime; each is self-sufficient.
|
|
429
|
+
|
|
430
|
+
## Integrations
|
|
431
|
+
|
|
432
|
+
tiny-spec binds to a task platform (Jira, GitHub Issues, Azure DevOps, Monday) by
|
|
433
|
+
reference only: a `ticket` block in the spec and a `Refs:` footer on each
|
|
434
|
+
[Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/), so the
|
|
435
|
+
platform auto-links the work. No API calls or credentials are required.
|
|
436
|
+
|
|
437
|
+
## Contributing
|
|
438
|
+
|
|
439
|
+
Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md), and
|
|
440
|
+
read [AGENTS.md](AGENTS.md) before changing any skill or agent.
|
|
441
|
+
|
|
442
|
+
## License
|
|
443
|
+
|
|
444
|
+
[MIT](LICENSE)
|