Cuts work into children the plan gate accepts: EARS criteria, scope globs, dependencies, a demo command. Use at DECOMPOSE or when a plan gate refuses a child.
Installs into .claude/skills of the current project.
Are you the author of Decompose Plan?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/niksavis-decompose-plan)
---
name: decompose-plan
description: 'Cuts work into children the plan gate accepts: EARS criteria, scope globs, dependencies, a demo command. Use at DECOMPOSE or when a plan gate refuses a child.'
---
<!-- Generated by `basicly skills-build` from skill.yaml. Do not edit; edit the source. -->
# Decompose a plan the gate accepts
This skill cuts a unit into children that the plan gate accepts before BUILD.
A refusal here finds an incomplete plan before implementation starts.
## Rules
- **Slice vertically.** Each child must do something that a consumer can see.
- **Give every child a runnable demonstration.** A child with no demonstration was sliced horizontally.
- **Scope the file that produces the value, not the file that shows it.** A wrong scope bounces at the landing gate.
- **Declare the true scope, even when the band then prices it higher.** An under-declared scope collides at landing.
- **Name the child's own file, never a directory glob.** The band prices every file that a glob matches.
- **Flatten, never nest.** A child that needs children was cut wrong.
## The plan fields
Each child in `plan.toml` requires `{title, acceptance, scope, depends_on, demonstration}`.
Spending limits and historical integrity fields are optional; do not ask the user to supply them.
The gate names each missing field.
| Field | Refused when | Notes |
| --- | --- | --- |
| `acceptance` | absent | The gate checks only presence. Write each criterion in EARS form (trigger, state, condition, optional feature, ubiquitous), so a check can be derived from it. |
| `scope` | absent | Overlapping scopes serialize. Two children that write one path collide at the merge queue. |
| `depends_on` | absent, or cyclic | Lists sibling titles. An empty list is a declaration. An absent key is not. Each edge becomes a `blocks` dependency. A cycle is refused with its members, before any issue is created. |
| `budget_tokens` | present but invalid | Optional explicit spending limit. Omit it when the user sets no limit. |
| `integrity` | present but invalid | Optional historical classification. Required checks derive from the actual scope without a permission-level question. |
| `demonstration` | absent, or no backticked runnable span | A command, a request or a test through the consumer surface. |
| `shared` | optional | Literal paths from `scope` that the child only appends its own entry to (a manifest, a lockfile). Without it, that path serializes every child that declares it. |
Preview the grouping, then create the children:
```sh
basicly decompose <feature> --plan plan.toml --dry-run
basicly decompose <feature> --plan plan.toml
```
The dry run names each path that collapsed the grouping.
## Slice vertically
The horizontal cut puts all schema in one child, all tests in another and all CLI wiring in a third.
It gives the cleanest scopes, because scope overlap follows file adjacency.
But no child in it does anything a consumer can see, so verify has nothing to check.
Cut along the `change-shape` artifact instead. It comes from the call graph, so one slice can cross directories.
## Find the producer
A scope says where a wrong value is produced. The file that shows the value is usually a different module.
Find the producer before dispatch:
```sh
rg -n '<the literal the defect prints>' <source-dir>
rg -n 'def <the function whose result is wrong>' <source-dir>
```
The file that emits the value is the scope. A renderer usually sits one call above the builder that owns the fact.
Then ask: does this value have more than one consumer, or reach more than one surface?
A projected artifact often has several outputs.
`basicly skills-build` writes `.claude/skills` and `.agents/skills`, and a scope that names only one fails the projection gate.
## Name the child's own file
Name the file that the child creates:
| Output | Scope entry |
| --- | --- |
| changelog fragment | `changelog.d/<epic-id>.<n>.<category>.md` |
| config fragment | `basicly.d/<epic-id>.<n>.toml` |
| projected skill | `.claude/skills/<name>/SKILL.md` |
`<n>` is the child's position in the plan, because children get the ids `<epic-id>.1`, `<epic-id>.2`, and so on.
A glob such as `changelog.d/*.md` or `.claude/skills/**` makes the band read every match into every lane.
If a glob matches more than a few files, say why in the plan.