tiny-spec 1.2.0__tar.gz → 2.0.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: tiny-spec
3
- Version: 1.2.0
3
+ Version: 2.0.0
4
4
  Summary: A tiny, opinionated take on spec-driven development.
5
5
  Project-URL: Homepage, https://github.com/GrayMa77er/tiny-spec
6
6
  Project-URL: Source, https://github.com/GrayMa77er/tiny-spec
@@ -71,13 +71,13 @@ committed.
71
71
  That core is **three skills and two agents**. In front of it sit **two front doors** —
72
72
  pick the one that matches where you're starting. Over the top sits **one router**,
73
73
  `tiny-spec-run`, which drives the chain and, when you ask it to, works a whole list of
74
- stories through to merged code. No config file, no build step.
74
+ features through to merged code. No config file, no build step.
75
75
 
76
76
  ```
77
77
  GREENFIELD BROWNFIELD
78
78
  starting from an idea starting from a codebase
79
79
  tiny-spec-scope tiny-spec-adopt
80
- idea → Features → Stories real code → constitution
80
+ idea → Features real code → constitution
81
81
  BREAKDOWN.md constitution.md
82
82
  \ /
83
83
  └───────────┬───────────┘
@@ -85,16 +85,16 @@ stories through to merged code. No config file, no build step.
85
85
  tiny-spec-create → tiny-spec-plan → tiny-spec-build
86
86
  intent design + tasks per-task loop
87
87
  SPEC.md PLAN.md plan → implement
88
- tasks.md → review → commit
88
+ (+ ## Tasks) → review → commit
89
89
 
90
90
  tiny-spec-run one router. Walks the chain and stops before build —
91
- or, asked to, builds each story and merges it.
91
+ or, asked to, builds each feature and merges it.
92
92
  tiny-spec-design optional. Wireframes → tokens + gradeable screens.
93
93
  ```
94
94
 
95
95
  **Pick one front door, once per project.** Starting from an idea with no code yet? Run
96
96
  `tiny-spec-scope` — it interviews the idea into a `BREAKDOWN.md`, a flat list of
97
- Features → Stories with draft acceptance criteria. Working in a codebase that already
97
+ well-defined Features with draft acceptance criteria. Working in a codebase that already
98
98
  exists? Run `tiny-spec-adopt` — it reads your repo and derives the constitution from
99
99
  what's actually there: your real lint and test commands, your real layout, your real
100
100
  conventions. Have a single known ticket in a project that's already set up? Skip both
@@ -110,7 +110,7 @@ receipt rather than the adjective:
110
110
 
111
111
  | | skills / commands | agents | config | artifacts per feature |
112
112
  |---|---|---|---|---|
113
- | **tiny-spec** | **7** (3 core + 1 router + 3 optional) | **2** | **none** | **`SPEC` `PLAN` `tasks`** |
113
+ | **tiny-spec** | **7** (3 core + 1 router + 3 optional) | **2** | **none** | **`SPEC` `PLAN`** |
114
114
  | [GitHub Spec Kit](https://github.com/github/spec-kit) | 10 | — | `specify init` | `spec` `plan` `tasks` `checklist` `constitution` `research` `data-model` `contracts/` `quickstart` |
115
115
  | [OpenSpec](https://github.com/Fission-AI/OpenSpec) | 12 | — | `.openspec.yaml` | `proposal` `design` `tasks` `specs/` |
116
116
  | [BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) | 58 | 5 personas | 35 × `customize.toml` | `PRD` `architecture` `epics` `stories` `UX` `brief` `sprint-plan` |
@@ -197,7 +197,7 @@ uvx tiny-spec install
197
197
  Restart Claude Code so it picks up the new skills, then run the flow in your project:
198
198
 
199
199
  ```
200
- /tiny-spec-scope # starting from an idea: interview it into stories (BREAKDOWN.md)
200
+ /tiny-spec-scope # starting from an idea: interview it into features (BREAKDOWN.md)
201
201
  /tiny-spec-adopt # starting from a codebase: derive the constitution from real code
202
202
  /tiny-spec-create # capture intent and requirements (binds a ticket, optional)
203
203
  /tiny-spec-plan # design it, harden the constitution, slice the task list
@@ -219,10 +219,10 @@ forward. It writes nothing itself, it only delegates. By default it **stops befo
219
219
  Ask it to build and it goes all the way instead:
220
220
 
221
221
  ```
222
- /tiny-spec-run build the backlog # per story: branch → plan → build → merge → next
222
+ /tiny-spec-run build the backlog # per feature: branch → plan → build → merge → next
223
223
  ```
224
224
 
225
- It reads your `BREAKDOWN.md` (or a list you paste) and works the stories one after
225
+ It reads your `BREAKDOWN.md` (or a list you paste) and works the features one after
226
226
  another, merging each finished branch into `main` locally before starting the next —
227
227
  until it's done or reaches a **terminal state** it names out loud. See
228
228
  [Working a whole list](#working-a-whole-list). Which of the two it does is decided from
@@ -262,8 +262,8 @@ or install one set at a time.
262
262
  ### See a finished run first
263
263
 
264
264
  [`examples/todo-cli/`](examples/todo-cli/) is a real run of the flow on one small
265
- ticket, committed verbatim — the `TICKET.md` that went in, the `SPEC.md`, `PLAN.md`,
266
- `tasks.md` and `constitution.md` the suite wrote, and the code and tests it produced.
265
+ ticket, committed verbatim — the `TICKET.md` that went in, the `SPEC.md`, `PLAN.md`
266
+ and `constitution.md` the suite wrote, and the code and tests it produced.
267
267
  The tests pass; you can clone it and run the gate yourself.
268
268
 
269
269
  ## How it works
@@ -464,7 +464,7 @@ proved the same thing repeatedly and was the slowest part of the loop.
464
464
 
465
465
  ```mermaid
466
466
  flowchart TB
467
- SPEC[SPEC.md<br/>intent] --> PLAN[PLAN.md<br/>design] --> TASKS[tasks.md<br/>checklist]
467
+ SPEC[SPEC.md<br/>intent] --> PLAN[PLAN.md<br/>design] --> TASKS[PLAN.md ## Tasks<br/>checklist]
468
468
 
469
469
  TASKS -->|pause: set| H[Halt — paused<br/>task stays unchecked]
470
470
  TASKS --> P[Plan task]
@@ -498,40 +498,39 @@ resumes from the checklist state.
498
498
  ### Working a whole list
499
499
 
500
500
  Ask `/tiny-spec-run` to build — "build the backlog", "work through the breakdown",
501
- "spec it out and build it" — and it takes a list of stories and works them in batches.
502
- Per story it does the same four moves:
501
+ "spec it out and build it" — and it takes a list of features and works them in batches.
502
+ Per feature it does the same four moves:
503
503
 
504
504
  ```
505
505
  cut a branch from main → walk the chain → tiny-spec-build → merge back to main
506
506
  ```
507
507
 
508
- Each branch is cut **fresh from main**, so a later story sees the earlier ones already
508
+ Each branch is cut **fresh from main**, so a later feature sees the earlier ones already
509
509
  merged — which is what makes an ordered list build correctly.
510
510
 
511
- **Independent stories build at the same time.** A story can declare what it must follow
511
+ **Independent features build at the same time.** A feature can declare what it must follow
512
512
  with a `needs:` line in `BREAKDOWN.md`; everything with no unmet `needs:` forms a batch
513
- and builds **concurrently, one git worktree per story**, three at a time by default.
513
+ and builds **concurrently, one git worktree per feature**, three at a time by default.
514
514
  The batch merges, then the next one starts.
515
515
 
516
516
  ```
517
- ## Feature: interface
517
+ ## Feature: expose both helpers on a CLI slug: cli
518
518
 
519
- - Story: expose both helpers on a CLI slug: cli
520
- - AC: `textkit slugify "Hi There"` prints "hi-there"
521
- - needs: slugify, wordwrap
519
+ - AC: `textkit slugify "Hi There"` prints "hi-there"
520
+ - needs: slugify, wordwrap
522
521
  ```
523
522
 
524
- Omit `needs:` when a story stands alone — that's the common case, and the field is meant
523
+ Omit `needs:` when a feature stands alone — that's the common case, and the field is meant
525
524
  to be rare. A `needs:` you didn't need costs you parallelism forever; one you missed
526
525
  costs a single merge conflict, which the run already catches and halts on. You can also
527
526
  just name the set yourself at invocation ("build these three at once"), which overrides
528
- the graph. A cycle, or a `needs:` naming a story that isn't there, stops the run rather
527
+ the graph. A cycle, or a `needs:` naming a feature that isn't there, stops the run rather
529
528
  than being guessed past.
530
529
 
531
- **Tasks *inside* a story never run in parallel.** They share files and each one assumes
532
- the last landed, so they stay strictly sequential. Parallelism is across stories only.
530
+ **Tasks *inside* a feature never run in parallel.** They share files and each one assumes
531
+ the last landed, so they stay strictly sequential. Parallelism is across features only.
533
532
 
534
- **The list is `BREAKDOWN.md` by default** — its `- Story:` entries, in file order,
533
+ **The list is `BREAKDOWN.md` by default** — its `## Feature:` entries, in file order,
535
534
  each already carrying a `slug:` (the branch and directory name) and `AC:` lines. Paste
536
535
  a list at invocation instead and that wins; but a bare feature name has no acceptance
537
536
  criteria, so `tiny-spec-create` will interview you when it reaches it. That's the
@@ -541,26 +540,26 @@ honest trade: a breakdown runs unattended, a pasted list is supervised.
541
540
 
542
541
  | | |
543
542
  |---|---|
544
- | `done` | every story built **and merged** |
543
+ | `done` | every feature built **and merged** |
545
544
  | `blocked` | an upstream document is wrong — go fix the spec or the plan |
546
545
  | `exhausted` | a task stayed red past two fix attempts |
547
546
  | `paused` | it reached a `pause:` point |
548
547
  | `fork` | a real either/or the plan doesn't answer |
549
- | `conflict` | a story's branch wouldn't merge cleanly |
548
+ | `conflict` | a feature's branch wouldn't merge cleanly |
550
549
 
551
- **Only `done` means the work is built** — and in a story run, that means *all* of them.
552
- Stopping at story 2 of 7 and reporting "done" is what autonomous loops get wrong most
550
+ **Only `done` means the work is built** — and in a feature run, that means *all* of them.
551
+ Stopping at feature 2 of 7 and reporting "done" is what autonomous loops get wrong most
553
552
  often, so the state is always named alongside what merged and what's still untouched.
554
553
 
555
554
  **A halt stops the lane it happened in, and ends the run after that batch.** Its siblings
556
555
  were declared independent, so they finish and merge — killing working lanes because one
557
- failed throws away good work. But the run does not start the next batch: later stories
556
+ failed throws away good work. But the run does not start the next batch: later features
558
557
  usually assume the earlier ones landed, so skipping ahead past a failure just produces a
559
- second, more confusing failure downstream. With more than one lane you get each story's
558
+ second, more confusing failure downstream. With more than one lane you get each feature's
560
559
  own state, and the run's state is the worst of them — four green lanes and one `blocked`
561
560
  is a `blocked` run.
562
561
 
563
- **Pause points are technical, not per-story.** Any task can carry a `pause:` line, and
562
+ **Pause points are technical, not per-feature.** Any task can carry a `pause:` line, and
564
563
  the build halts *before* running it:
565
564
 
566
565
  ```
@@ -572,7 +571,7 @@ the build halts *before* running it:
572
571
  `tiny-spec-plan` proposes these for genuinely irreversible work — migrations,
573
572
  destructive file operations, a new dependency, an auth boundary, a public API contract.
574
573
  You can also give the run a standing policy up front ("halt before anything that touches
575
- auth") and it gets applied as each story's tasks are sliced.
574
+ auth") and it gets applied as each feature's tasks are sliced.
576
575
 
577
576
  **What it will not do to your repo.** It runs exactly seven git commands — `switch`,
578
577
  `switch -c`, `merge --no-ff`, `merge --abort`, `worktree add`, `worktree list`, and
@@ -584,11 +583,11 @@ the merge alone and tells you the undo command rather than running it — and it
584
583
  back the `git worktree remove` commands for the lanes instead of running those either,
585
584
  since a halted lane's worktree is the tree you need to look at.
586
585
 
587
- **Walk away and come back.** Progress isn't written down, it's derived: a story whose
588
- ticked `tasks.md` is on `main` is done, a `.spec/<slug>/` with an unchecked task is in
586
+ **Walk away and come back.** Progress isn't written down, it's derived: a feature whose
587
+ ticked `## Tasks` is on `main` is done, a `.spec/<slug>/` with an unchecked task is in
589
588
  progress, no directory means not started. Ask again tomorrow in a fresh session and it
590
589
  picks up where it stopped. No run-state file, no lock, no budget to configure — the
591
- story list *is* the budget.
590
+ feature list *is* the budget.
592
591
 
593
592
  **It never fixes a blocker for you.** A blocker means one of your documents is wrong,
594
593
  and a run allowed to rewrite the requirement its own task just failed would be grading
@@ -613,7 +612,7 @@ It is namespaced per ticket, with a shared spine at the root:
613
612
  constitution.md project-wide, shared across tickets
614
613
  memory.md operational lessons, shared across tickets
615
614
  <ticket-id>/ one directory per ticket (PROJ-123/, gh-42/, …)
616
- SPEC.md PLAN.md tasks.md decisions.md
615
+ SPEC.md PLAN.md decisions.md (PLAN.md ends in the ## Tasks checklist)
617
616
  ```
618
617
 
619
618
  `BREAKDOWN.md` and `design/` sit at your project root rather than inside `.spec/`,
@@ -34,13 +34,13 @@ committed.
34
34
  That core is **three skills and two agents**. In front of it sit **two front doors** —
35
35
  pick the one that matches where you're starting. Over the top sits **one router**,
36
36
  `tiny-spec-run`, which drives the chain and, when you ask it to, works a whole list of
37
- stories through to merged code. No config file, no build step.
37
+ features through to merged code. No config file, no build step.
38
38
 
39
39
  ```
40
40
  GREENFIELD BROWNFIELD
41
41
  starting from an idea starting from a codebase
42
42
  tiny-spec-scope tiny-spec-adopt
43
- idea → Features → Stories real code → constitution
43
+ idea → Features real code → constitution
44
44
  BREAKDOWN.md constitution.md
45
45
  \ /
46
46
  └───────────┬───────────┘
@@ -48,16 +48,16 @@ stories through to merged code. No config file, no build step.
48
48
  tiny-spec-create → tiny-spec-plan → tiny-spec-build
49
49
  intent design + tasks per-task loop
50
50
  SPEC.md PLAN.md plan → implement
51
- tasks.md → review → commit
51
+ (+ ## Tasks) → review → commit
52
52
 
53
53
  tiny-spec-run one router. Walks the chain and stops before build —
54
- or, asked to, builds each story and merges it.
54
+ or, asked to, builds each feature and merges it.
55
55
  tiny-spec-design optional. Wireframes → tokens + gradeable screens.
56
56
  ```
57
57
 
58
58
  **Pick one front door, once per project.** Starting from an idea with no code yet? Run
59
59
  `tiny-spec-scope` — it interviews the idea into a `BREAKDOWN.md`, a flat list of
60
- Features → Stories with draft acceptance criteria. Working in a codebase that already
60
+ well-defined Features with draft acceptance criteria. Working in a codebase that already
61
61
  exists? Run `tiny-spec-adopt` — it reads your repo and derives the constitution from
62
62
  what's actually there: your real lint and test commands, your real layout, your real
63
63
  conventions. Have a single known ticket in a project that's already set up? Skip both
@@ -73,7 +73,7 @@ receipt rather than the adjective:
73
73
 
74
74
  | | skills / commands | agents | config | artifacts per feature |
75
75
  |---|---|---|---|---|
76
- | **tiny-spec** | **7** (3 core + 1 router + 3 optional) | **2** | **none** | **`SPEC` `PLAN` `tasks`** |
76
+ | **tiny-spec** | **7** (3 core + 1 router + 3 optional) | **2** | **none** | **`SPEC` `PLAN`** |
77
77
  | [GitHub Spec Kit](https://github.com/github/spec-kit) | 10 | — | `specify init` | `spec` `plan` `tasks` `checklist` `constitution` `research` `data-model` `contracts/` `quickstart` |
78
78
  | [OpenSpec](https://github.com/Fission-AI/OpenSpec) | 12 | — | `.openspec.yaml` | `proposal` `design` `tasks` `specs/` |
79
79
  | [BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) | 58 | 5 personas | 35 × `customize.toml` | `PRD` `architecture` `epics` `stories` `UX` `brief` `sprint-plan` |
@@ -160,7 +160,7 @@ uvx tiny-spec install
160
160
  Restart Claude Code so it picks up the new skills, then run the flow in your project:
161
161
 
162
162
  ```
163
- /tiny-spec-scope # starting from an idea: interview it into stories (BREAKDOWN.md)
163
+ /tiny-spec-scope # starting from an idea: interview it into features (BREAKDOWN.md)
164
164
  /tiny-spec-adopt # starting from a codebase: derive the constitution from real code
165
165
  /tiny-spec-create # capture intent and requirements (binds a ticket, optional)
166
166
  /tiny-spec-plan # design it, harden the constitution, slice the task list
@@ -182,10 +182,10 @@ forward. It writes nothing itself, it only delegates. By default it **stops befo
182
182
  Ask it to build and it goes all the way instead:
183
183
 
184
184
  ```
185
- /tiny-spec-run build the backlog # per story: branch → plan → build → merge → next
185
+ /tiny-spec-run build the backlog # per feature: branch → plan → build → merge → next
186
186
  ```
187
187
 
188
- It reads your `BREAKDOWN.md` (or a list you paste) and works the stories one after
188
+ It reads your `BREAKDOWN.md` (or a list you paste) and works the features one after
189
189
  another, merging each finished branch into `main` locally before starting the next —
190
190
  until it's done or reaches a **terminal state** it names out loud. See
191
191
  [Working a whole list](#working-a-whole-list). Which of the two it does is decided from
@@ -225,8 +225,8 @@ or install one set at a time.
225
225
  ### See a finished run first
226
226
 
227
227
  [`examples/todo-cli/`](examples/todo-cli/) is a real run of the flow on one small
228
- ticket, committed verbatim — the `TICKET.md` that went in, the `SPEC.md`, `PLAN.md`,
229
- `tasks.md` and `constitution.md` the suite wrote, and the code and tests it produced.
228
+ ticket, committed verbatim — the `TICKET.md` that went in, the `SPEC.md`, `PLAN.md`
229
+ and `constitution.md` the suite wrote, and the code and tests it produced.
230
230
  The tests pass; you can clone it and run the gate yourself.
231
231
 
232
232
  ## How it works
@@ -427,7 +427,7 @@ proved the same thing repeatedly and was the slowest part of the loop.
427
427
 
428
428
  ```mermaid
429
429
  flowchart TB
430
- SPEC[SPEC.md<br/>intent] --> PLAN[PLAN.md<br/>design] --> TASKS[tasks.md<br/>checklist]
430
+ SPEC[SPEC.md<br/>intent] --> PLAN[PLAN.md<br/>design] --> TASKS[PLAN.md ## Tasks<br/>checklist]
431
431
 
432
432
  TASKS -->|pause: set| H[Halt — paused<br/>task stays unchecked]
433
433
  TASKS --> P[Plan task]
@@ -461,40 +461,39 @@ resumes from the checklist state.
461
461
  ### Working a whole list
462
462
 
463
463
  Ask `/tiny-spec-run` to build — "build the backlog", "work through the breakdown",
464
- "spec it out and build it" — and it takes a list of stories and works them in batches.
465
- Per story it does the same four moves:
464
+ "spec it out and build it" — and it takes a list of features and works them in batches.
465
+ Per feature it does the same four moves:
466
466
 
467
467
  ```
468
468
  cut a branch from main → walk the chain → tiny-spec-build → merge back to main
469
469
  ```
470
470
 
471
- Each branch is cut **fresh from main**, so a later story sees the earlier ones already
471
+ Each branch is cut **fresh from main**, so a later feature sees the earlier ones already
472
472
  merged — which is what makes an ordered list build correctly.
473
473
 
474
- **Independent stories build at the same time.** A story can declare what it must follow
474
+ **Independent features build at the same time.** A feature can declare what it must follow
475
475
  with a `needs:` line in `BREAKDOWN.md`; everything with no unmet `needs:` forms a batch
476
- and builds **concurrently, one git worktree per story**, three at a time by default.
476
+ and builds **concurrently, one git worktree per feature**, three at a time by default.
477
477
  The batch merges, then the next one starts.
478
478
 
479
479
  ```
480
- ## Feature: interface
480
+ ## Feature: expose both helpers on a CLI slug: cli
481
481
 
482
- - Story: expose both helpers on a CLI slug: cli
483
- - AC: `textkit slugify "Hi There"` prints "hi-there"
484
- - needs: slugify, wordwrap
482
+ - AC: `textkit slugify "Hi There"` prints "hi-there"
483
+ - needs: slugify, wordwrap
485
484
  ```
486
485
 
487
- Omit `needs:` when a story stands alone — that's the common case, and the field is meant
486
+ Omit `needs:` when a feature stands alone — that's the common case, and the field is meant
488
487
  to be rare. A `needs:` you didn't need costs you parallelism forever; one you missed
489
488
  costs a single merge conflict, which the run already catches and halts on. You can also
490
489
  just name the set yourself at invocation ("build these three at once"), which overrides
491
- the graph. A cycle, or a `needs:` naming a story that isn't there, stops the run rather
490
+ the graph. A cycle, or a `needs:` naming a feature that isn't there, stops the run rather
492
491
  than being guessed past.
493
492
 
494
- **Tasks *inside* a story never run in parallel.** They share files and each one assumes
495
- the last landed, so they stay strictly sequential. Parallelism is across stories only.
493
+ **Tasks *inside* a feature never run in parallel.** They share files and each one assumes
494
+ the last landed, so they stay strictly sequential. Parallelism is across features only.
496
495
 
497
- **The list is `BREAKDOWN.md` by default** — its `- Story:` entries, in file order,
496
+ **The list is `BREAKDOWN.md` by default** — its `## Feature:` entries, in file order,
498
497
  each already carrying a `slug:` (the branch and directory name) and `AC:` lines. Paste
499
498
  a list at invocation instead and that wins; but a bare feature name has no acceptance
500
499
  criteria, so `tiny-spec-create` will interview you when it reaches it. That's the
@@ -504,26 +503,26 @@ honest trade: a breakdown runs unattended, a pasted list is supervised.
504
503
 
505
504
  | | |
506
505
  |---|---|
507
- | `done` | every story built **and merged** |
506
+ | `done` | every feature built **and merged** |
508
507
  | `blocked` | an upstream document is wrong — go fix the spec or the plan |
509
508
  | `exhausted` | a task stayed red past two fix attempts |
510
509
  | `paused` | it reached a `pause:` point |
511
510
  | `fork` | a real either/or the plan doesn't answer |
512
- | `conflict` | a story's branch wouldn't merge cleanly |
511
+ | `conflict` | a feature's branch wouldn't merge cleanly |
513
512
 
514
- **Only `done` means the work is built** — and in a story run, that means *all* of them.
515
- Stopping at story 2 of 7 and reporting "done" is what autonomous loops get wrong most
513
+ **Only `done` means the work is built** — and in a feature run, that means *all* of them.
514
+ Stopping at feature 2 of 7 and reporting "done" is what autonomous loops get wrong most
516
515
  often, so the state is always named alongside what merged and what's still untouched.
517
516
 
518
517
  **A halt stops the lane it happened in, and ends the run after that batch.** Its siblings
519
518
  were declared independent, so they finish and merge — killing working lanes because one
520
- failed throws away good work. But the run does not start the next batch: later stories
519
+ failed throws away good work. But the run does not start the next batch: later features
521
520
  usually assume the earlier ones landed, so skipping ahead past a failure just produces a
522
- second, more confusing failure downstream. With more than one lane you get each story's
521
+ second, more confusing failure downstream. With more than one lane you get each feature's
523
522
  own state, and the run's state is the worst of them — four green lanes and one `blocked`
524
523
  is a `blocked` run.
525
524
 
526
- **Pause points are technical, not per-story.** Any task can carry a `pause:` line, and
525
+ **Pause points are technical, not per-feature.** Any task can carry a `pause:` line, and
527
526
  the build halts *before* running it:
528
527
 
529
528
  ```
@@ -535,7 +534,7 @@ the build halts *before* running it:
535
534
  `tiny-spec-plan` proposes these for genuinely irreversible work — migrations,
536
535
  destructive file operations, a new dependency, an auth boundary, a public API contract.
537
536
  You can also give the run a standing policy up front ("halt before anything that touches
538
- auth") and it gets applied as each story's tasks are sliced.
537
+ auth") and it gets applied as each feature's tasks are sliced.
539
538
 
540
539
  **What it will not do to your repo.** It runs exactly seven git commands — `switch`,
541
540
  `switch -c`, `merge --no-ff`, `merge --abort`, `worktree add`, `worktree list`, and
@@ -547,11 +546,11 @@ the merge alone and tells you the undo command rather than running it — and it
547
546
  back the `git worktree remove` commands for the lanes instead of running those either,
548
547
  since a halted lane's worktree is the tree you need to look at.
549
548
 
550
- **Walk away and come back.** Progress isn't written down, it's derived: a story whose
551
- ticked `tasks.md` is on `main` is done, a `.spec/<slug>/` with an unchecked task is in
549
+ **Walk away and come back.** Progress isn't written down, it's derived: a feature whose
550
+ ticked `## Tasks` is on `main` is done, a `.spec/<slug>/` with an unchecked task is in
552
551
  progress, no directory means not started. Ask again tomorrow in a fresh session and it
553
552
  picks up where it stopped. No run-state file, no lock, no budget to configure — the
554
- story list *is* the budget.
553
+ feature list *is* the budget.
555
554
 
556
555
  **It never fixes a blocker for you.** A blocker means one of your documents is wrong,
557
556
  and a run allowed to rewrite the requirement its own task just failed would be grading
@@ -576,7 +575,7 @@ It is namespaced per ticket, with a shared spine at the root:
576
575
  constitution.md project-wide, shared across tickets
577
576
  memory.md operational lessons, shared across tickets
578
577
  <ticket-id>/ one directory per ticket (PROJ-123/, gh-42/, …)
579
- SPEC.md PLAN.md tasks.md decisions.md
578
+ SPEC.md PLAN.md decisions.md (PLAN.md ends in the ## Tasks checklist)
580
579
  ```
581
580
 
582
581
  `BREAKDOWN.md` and `design/` sit at your project root rather than inside `.spec/`,
@@ -17,9 +17,9 @@ Everything you need and nothing you don't:
17
17
 
18
18
  - **the working directory** to operate in. Every path you read, write, or run a command
19
19
  against resolves against it. It may be a **git worktree** rather than the main checkout
20
- — a build can run several stories at once, each in its own worktree. **Never read or
20
+ — a build can run several features at once, each in its own worktree. **Never read or
21
21
  write outside the directory you were given**, and never `cd` to a sibling worktree to
22
- "check something": another story is being built there right now, and what you find will
22
+ "check something": another feature is being built there right now, and what you find will
23
23
  be wrong by the time you act on it;
24
24
  - the **task id**, **description**, and **acceptance** (the outcome that proves it done);
25
25
  - a **`files:` hint** — likely paths to touch (guidance, not a hard boundary);
@@ -15,8 +15,8 @@ back to `tiny-spec-build`; return data, not pleasantries.
15
15
 
16
16
  - **the working directory** to operate in — every path and every gate command resolves
17
17
  against it. It may be a **git worktree** rather than the main checkout, since a build
18
- can run several stories at once. **Never read, write, or run a gate outside the
19
- directory you were given**: a sibling worktree holds a different story mid-build, and
18
+ can run several features at once. **Never read, write, or run a gate outside the
19
+ directory you were given**: a sibling worktree holds a different feature mid-build, and
20
20
  measuring it would make your verdict meaningless;
21
21
  - the **task id**, **description**, and **acceptance** (the outcome that must hold);
22
22
  - the full **constitution** (`constitution.md`) — especially **Guiding invariants**,
@@ -87,10 +87,10 @@ Each case runs in a throwaway sandbox seeded with `IDEA.md` and the vendored ski
87
87
  ### What gets measured
88
88
 
89
89
  - **structural conformance** (deterministic) — BREAKDOWN has Problem and
90
- Goal & non-goals filled, a Decisions block, ≥1 Feature, Stories with a slug and ≥1 AC; the
90
+ Goal & non-goals filled, a Decisions block, ≥1 Feature, each with a slug and ≥1 AC; the
91
91
  planning skills left no `.spec/` behind.
92
92
  - **hand-off integrity** (LLM judge) — **coverage** (every PRD capability lands in ≥1
93
- story, nothing dropped) and **no fabrication** (every story traces to a capability,
93
+ feature, nothing dropped) and **no fabrication** (every feature traces to a capability,
94
94
  nothing invented). These are the high-value signals; a case PASSes only if structural
95
95
  conformance holds *and* the judge confirms both.
96
96
  - **quality** (LLM judge, reported not gated) — atomicity / user-observable phrasing,
@@ -10,6 +10,9 @@ workflow generates before you run it on your own work.
10
10
  > retouched to match the current artifact formats — a doctored example would defeat
11
11
  > the point. Later versions add a `## Design` section to `SPEC.md` (unused here: this
12
12
  > is a CLI with no design surface) and richer status flags. The shape is the same.
13
+ > One format move was applied after the fact: in 2.0 the checklist stopped being its
14
+ > own `tasks.md` and became `PLAN.md`'s `## Tasks` section, so the original `tasks.md`
15
+ > was moved there verbatim — same tasks, same ticks, no content edited.
13
16
 
14
17
  ## What's here
15
18
 
@@ -20,14 +23,13 @@ TICKET.md the input — a small "todo CLI" ask
20
23
  definition of done, and the verification gate
21
24
  todo-cli/
22
25
  SPEC.md intent + REQ-1..REQ-9 (what "done" means)
23
- PLAN.md the design and how each requirement is covered
24
- tasks.md the ordered checklist, all ticked [x]
26
+ PLAN.md the design, how each requirement is covered, and
27
+ the ordered ## Tasks checklist, all ticked [x]
25
28
  todo.py the produced CLI (stdlib only, 117 lines)
26
29
  test_todo.py the produced end-to-end test (129 lines)
27
30
  ```
28
31
 
29
- Read them in flow order: `TICKET.md` → `SPEC.md` → `PLAN.md` → `tasks.md` →
30
- `todo.py`. The `constitution.md` is the persistent context injected into every task.
32
+ Read them in flow order: `TICKET.md` → `SPEC.md` → `PLAN.md` → `todo.py`. The `constitution.md` is the persistent context injected into every task.
31
33
 
32
34
  ## It passes its own gate
33
35
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tiny-spec"
7
- version = "1.2.0"
7
+ version = "2.0.0"
8
8
  description = "A tiny, opinionated take on spec-driven development."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -15,7 +15,7 @@ there, then stops. It does **not** create a ticket dir, write a `SPEC.md`, switc
15
15
  branches, or modify a single line of source.
16
16
 
17
17
  **Starting from a blank page instead?** Use `tiny-spec-scope` — it interviews an idea
18
- into stories. The two are the suite's two front doors, and you generally want exactly
18
+ into features. The two are the suite's two front doors, and you generally want exactly
19
19
  one of them.
20
20
 
21
21
  ## The one thing that matters most
@@ -182,7 +182,7 @@ Say plainly that inferred sections need review before the first build.
182
182
  A constitution change invalidates work reviewed against the old one, so after applying
183
183
  any accepted change:
184
184
 
185
- For **each** ticket dir under `.spec/` whose `tasks.md` has checked tasks, set it
185
+ For **each** ticket dir under `.spec/` whose `PLAN.md` has checked tasks, set it
186
186
  `status: stale` and log a `decisions.md` entry in that ticket, creating the file if
187
187
  absent:
188
188