task-pipeline-skill 1.3.0 → 1.3.1
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 +30 -0
- package/cursor/rules/task-pipeline.mdc +14 -2
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/commands/task-pipeline.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +28 -1
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +40 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +15 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.3.1 — 2026-07-29
|
|
4
|
+
|
|
5
|
+
### Stage 10 closes on the parent repository, not only on the one you edited
|
|
6
|
+
|
|
7
|
+
A submodule is finished when its parent says so. A parent records each submodule as a pointer to
|
|
8
|
+
one commit, and moving the submodule does not move the pointer — so work can be committed, pushed,
|
|
9
|
+
green in CI and marked done in its own roadmap while a clone of the parent still gets the commit
|
|
10
|
+
before it. Neither repository looks wrong alone; the disagreement lives between them, which is why
|
|
11
|
+
it survives every check that runs inside one.
|
|
12
|
+
|
|
13
|
+
Stage 10's gate now requires every repository — parent included — to be clean, pushed and pointed
|
|
14
|
+
at, with the plain-git commands given and `/agent-sync finish` named for projects that have it.
|
|
15
|
+
|
|
16
|
+
The rule reaches all seven surfaces that carry the stage-10 close-out: `SKILL.md`, the gate in
|
|
17
|
+
`references/stages.md`, the doctrine in `references/acceptance.md`, the machine-readable check in
|
|
18
|
+
`pipeline.example.json`, `build.md`, `conventions.md`, the slash command and the Cursor rule.
|
|
19
|
+
|
|
20
|
+
### Validator — the class that caused this is now a check
|
|
21
|
+
|
|
22
|
+
This close-out has failed to reach every surface **twice**: v0.17.1 fixed it for the third review
|
|
23
|
+
verdict, and this release's own first pass declared the parent-repository rule in `SKILL.md`,
|
|
24
|
+
`build.md` and `conventions.md` while `acceptance.md`, `stages.md` and the config — *the three
|
|
25
|
+
places that actually define the gate* — never heard of it. A gate that says "now requires X" only
|
|
26
|
+
where X is not enforced is inert, and no existing check saw it: the validator compared stage ids,
|
|
27
|
+
names and gate types, never gate content.
|
|
28
|
+
|
|
29
|
+
Twice is a category, so it is a check now. Whatever close-out concept `SKILL.md` names, the
|
|
30
|
+
surfaces that enforce stage 10 must name it too. Proven against a planted defect, with a CI
|
|
31
|
+
negative self-test.
|
|
32
|
+
|
|
3
33
|
## v1.3.0 — 2026-07-29
|
|
4
34
|
|
|
5
35
|
**One design file, in a named team, decided before anything is drawn.** Left to
|
|
@@ -211,8 +211,20 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
|
|
|
211
211
|
watched fail against a planted defect is not evidence at all**. Then ask out
|
|
212
212
|
loud, list in hand: *here's what you asked for, here's what shipped, here's
|
|
213
213
|
what's deferred and where it lives — what's missing?* Ask it even when the
|
|
214
|
-
table is green.
|
|
215
|
-
a
|
|
214
|
+
table is green.
|
|
215
|
+
**In a project of several repositories, close the parent too.** A parent records
|
|
216
|
+
each submodule as a **pointer to one commit**, and moving the submodule does not
|
|
217
|
+
move the pointer — so the work is committed, pushed, CI green and done in its own
|
|
218
|
+
roadmap, while anyone cloning the parent gets the commit *before* the change.
|
|
219
|
+
Neither repository looks wrong on its own; the disagreement exists only between
|
|
220
|
+
them, which is why it survives every check that runs inside one. Require this to
|
|
221
|
+
report nothing, for the parent as well as every submodule:
|
|
222
|
+
`git submodule status` (no line starting `+` — a `+` is the missing bump),
|
|
223
|
+
`git -C <repo> status --porcelain`, `git -C <repo> log @{u}..HEAD --oneline`.
|
|
224
|
+
The fix is two commands and the second is the one that gets forgotten:
|
|
225
|
+
`git -C <submodule> push`, then `git add <submodule> && git commit`.
|
|
226
|
+
Gate: ladder walk ran, no REQ `unknown`, no ledger row without
|
|
227
|
+
a home, every repository clean/pushed/pointed-at, user signs off.
|
|
216
228
|
|
|
217
229
|
Cross-cutting: answer from the brief's autonomy section rather than re-asking, log every deferral in the ledger, never narrow the task silently, track
|
|
218
230
|
tasks, conventional commits, honest degradation (never claim a failed/skipped step
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"task-pipeline": "bin/task-pipeline.js"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline",
|
|
3
3
|
"description": "Runs a substantial task through a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine is built into the skill — no companion plugin required — with typed auto/manual gates, a frozen requirement spine that must close with evidence, a loop guard that breaks churn, one provider-agnostic model confirmed up front, and an optional super-ux UX track for user-facing work.",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ssheleg"
|
|
7
7
|
},
|
|
@@ -25,7 +25,7 @@ language, ADRs for hard-to-reverse calls) and covering the **autonomy sweep** (w
|
|
|
25
25
|
would otherwise stop stages 1→10: docs sources incl. doc repos and the wiki, branch/tracker
|
|
26
26
|
policy, test and lint commands, deploy target and authorization, log locations, docs/wiki targets, and for UI tasks whether the design is done visually in Figma or text-only, whether the Figma MCP is connected, and — if it isn't — whether to ship text-only or stop and connect it, since the UX chain degrades on its own and never blocks; **and with Figma on, the design destination: which team/org by name and which file** — the recorded one, a URL the operator gives, or creation in that named team explicitly authorized, written into the project's canonical record before the first frame, because a destination decided at drawing time is how a project ends up with three design files and no way to tell which is real. **Never create while a recorded file resolves; if it doesn't resolve, stop and ask — never create a replacement**) —
|
|
27
27
|
until the brief is locked — including the **REQ table**, the request as an addressable list where every row names how it is verified — so the rest runs autonomously and the final stage can account for all of it. The list is frozen: adding is free, removing needs the operator's agreement. Anything deferred goes into the carry-over ledger the moment it's said. For any user-facing task, recommend/use
|
|
28
|
-
**super-ux**. **If the brief describes a platform rather than a change**, stage 2 also cuts it into modules (`references/decomposition.md`) — module map committed, walking skeleton first, every REQ in exactly one module — and stages 3→10 then run per module, one brick at a time. **If any loop starts undoing an earlier pass** (same file edited twice for the same reason, a closed finding returning, a third entry into one stage), stop and run the loop guard (`references/loop-guard.md`): name both shapes, escalate to the layer that owns the conflict, re-plan the check as an ordered list, then go item by item. **The closing stage opens with the ladder walk** (`references/audit.md`): the REQ table finds what was named and lost, but a comparison needs two sides and an absence has one — so walk each REQ bottom-up through its rungs (decision → spec section → contract *and its failure behavior* → task → change → executed test → surface/docs), check the seam at each step, order findings by seam rather than by file, and turn every absence into a new REQ row **before** the coverage table is written. A green from a check nobody has watched fail against a planted defect is not evidence; a finding class seen twice becomes a script rather than a third ledger row; and the carry-over ledger's counts are printed beside every gate verdict, so "green" never reads as "verified". If a searching pass starts finding mostly what the previous pass's own fixes broke, the axis is exhausted — rotate it, don't look harder. Honor every stage gate by its type (`auto` = verify yourself;
|
|
28
|
+
**super-ux**. **If the brief describes a platform rather than a change**, stage 2 also cuts it into modules (`references/decomposition.md`) — module map committed, walking skeleton first, every REQ in exactly one module — and stages 3→10 then run per module, one brick at a time. **If any loop starts undoing an earlier pass** (same file edited twice for the same reason, a closed finding returning, a third entry into one stage), stop and run the loop guard (`references/loop-guard.md`): name both shapes, escalate to the layer that owns the conflict, re-plan the check as an ordered list, then go item by item. **The closing stage opens with the ladder walk** (`references/audit.md`): the REQ table finds what was named and lost, but a comparison needs two sides and an absence has one — so walk each REQ bottom-up through its rungs (decision → spec section → contract *and its failure behavior* → task → change → executed test → surface/docs), check the seam at each step, order findings by seam rather than by file, and turn every absence into a new REQ row **before** the coverage table is written. A green from a check nobody has watched fail against a planted defect is not evidence; a finding class seen twice becomes a script rather than a third ledger row; and the carry-over ledger's counts are printed beside every gate verdict, so "green" never reads as "verified". If a searching pass starts finding mostly what the previous pass's own fixes broke, the axis is exhausted — rotate it, don't look harder. **In a project of several repositories, stage 10 closes on the parent too:** a parent records each submodule as a pointer to one commit, and moving the submodule does not move the pointer — so the work can be committed, pushed and green while a clone of the parent still gets the commit before it. Neither repo looks wrong alone, which is why it survives every check that runs inside one. Require `git submodule status` with no line starting `+`, and every repo clean and pushed (`git -C <repo> status --porcelain`, `git -C <repo> log @{u}..HEAD`). The fix is two commands and the second gets forgotten: push the submodule, then `git add <submodule> && git commit`. Honor every stage gate by its type (`auto` = verify yourself;
|
|
29
29
|
`manual` = wait for explicit go). Confirm the **model once at preflight** —
|
|
30
30
|
recommend the most capable one the environment offers, never a hardcoded id — then
|
|
31
31
|
run the whole pipeline on it without re-asking.
|
|
@@ -194,7 +194,34 @@ capable available — see `references/model-tiering.md`).
|
|
|
194
194
|
| 7 | Lint + deploy | host lint → deploy per host convention | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
|
|
195
195
|
| 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report | auto |
|
|
196
196
|
| 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced | auto |
|
|
197
|
-
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; operator signs off | manual |
|
|
197
|
+
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off | manual |
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
### Stage 10 in a project of several repositories
|
|
201
|
+
|
|
202
|
+
**A submodule is finished when its parent says so.** A parent repository records each submodule as
|
|
203
|
+
a pointer to one commit, and moving the submodule does not move the pointer. So the work is
|
|
204
|
+
committed, pushed, its CI is green and its own roadmap says done — and anyone who clones the parent
|
|
205
|
+
gets the commit **before** the change. Nothing looks wrong in either repository on its own; the
|
|
206
|
+
disagreement exists only between them, which is why it survives every check that runs inside one.
|
|
207
|
+
|
|
208
|
+
Stage 10 does not close until:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
git submodule status # no line begins with '+' (a '+' is the missing bump)
|
|
212
|
+
git -C <each repo> status --porcelain && git -C <each repo> log @{u}..HEAD --oneline
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
report nothing — for the parent as well as every submodule. Where
|
|
216
|
+
[agent-sync](https://github.com/appvillis-com/agent-sync) is installed, `/agent-sync finish` runs
|
|
217
|
+
exactly this plus *no lease left held*, and `--gates` adds the project's own gate commands.
|
|
218
|
+
|
|
219
|
+
The fix, when it fails, is two commands and the second is the one that gets forgotten:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
git -C <submodule> push
|
|
223
|
+
git add <submodule> && git commit -m "chore: bump <name> submodule — <why>"
|
|
224
|
+
```
|
|
198
225
|
|
|
199
226
|
## Model — ask once, at preflight
|
|
200
227
|
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
],
|
|
159
159
|
"gate": {
|
|
160
160
|
"type": "manual",
|
|
161
|
-
"check": "Close the circle. FIRST the LADDER WALK (references/audit.md), because the REQ table can only find what was named and lost — a comparison needs two sides and an absence has one: walk each REQ bottom-up through its rungs (decision -> spec section -> contract AND its failure behavior -> plan task -> change -> executed test -> surface/docs), check the seam at each step, order findings BY SEAM not by file, and turn every absence into a new REQ row with its check BEFORE the table is written; findings belonging to a lower layer go back to that layer (spec -> stage 3, plan -> stage 4); record the pass's two counts (new findings vs findings caused by this run's own fixes) so the next pass can tell whether the axis is exhausted. THEN the coverage table: every REQ has a status (verified / partial / deferred / dropped) — none unknown; every verified carries evidence (a passing test name, file:line, a command and its output, or a scenario ID) — 'done' without evidence is downgraded to partial, not upgraded, and a green from a check nobody has watched fail against a planted defect is not evidence at all; every partial names what is missing and where it is tracked; every deferred/dropped has the operator's agreement and, for deferred, a tracker entry; no carry-over row is left unresolved and the ledger's counts are printed beside this verdict, so 'green' never reads as 'verified'; and the operator answers the closing question — here is what you asked for, here is what shipped, here is what is deferred, what is missing? — and signs off"
|
|
161
|
+
"check": "Close the circle. FIRST the LADDER WALK (references/audit.md), because the REQ table can only find what was named and lost — a comparison needs two sides and an absence has one: walk each REQ bottom-up through its rungs (decision -> spec section -> contract AND its failure behavior -> plan task -> change -> executed test -> surface/docs), check the seam at each step, order findings BY SEAM not by file, and turn every absence into a new REQ row with its check BEFORE the table is written; findings belonging to a lower layer go back to that layer (spec -> stage 3, plan -> stage 4); record the pass's two counts (new findings vs findings caused by this run's own fixes) so the next pass can tell whether the axis is exhausted. THEN the coverage table: every REQ has a status (verified / partial / deferred / dropped) — none unknown; every verified carries evidence (a passing test name, file:line, a command and its output, or a scenario ID) — 'done' without evidence is downgraded to partial, not upgraded, and a green from a check nobody has watched fail against a planted defect is not evidence at all; every partial names what is missing and where it is tracked; every deferred/dropped has the operator's agreement and, for deferred, a tracker entry; no carry-over row is left unresolved and the ledger's counts are printed beside this verdict, so 'green' never reads as 'verified'; EVERY REPOSITORY IS CLOSED, THE PARENT INCLUDED — a submodule is finished only when its parent points at it, so 'git submodule status' shows no line starting with '+' and every repo is clean and pushed ('git -C <repo> status --porcelain' and 'git -C <repo> log @{u}..HEAD' both empty), because a parent records a submodule as a pointer to one commit and moving the submodule does not move the pointer: neither repo looks wrong alone and the disagreement survives every check that runs inside one; and the operator answers the closing question — here is what you asked for, here is what shipped, here is what is deferred, what is missing? — and signs off"
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
],
|
|
@@ -104,6 +104,42 @@ and the test-honesty rules apply one level down, raised to the level of intent:
|
|
|
104
104
|
If the evidence for a requirement is "I read the code and it looks right", the
|
|
105
105
|
status is `partial`, not `verified` — say so plainly rather than upgrading it.
|
|
106
106
|
|
|
107
|
+
## Several repositories — a submodule is finished when its parent says so
|
|
108
|
+
|
|
109
|
+
A parent repository records each submodule as **a pointer to one commit**, and
|
|
110
|
+
moving the submodule does not move the pointer. So the work is committed, pushed,
|
|
111
|
+
its CI is green and its own roadmap says done — while anyone who clones the parent
|
|
112
|
+
gets the commit **before** the change.
|
|
113
|
+
|
|
114
|
+
Neither repository looks wrong on its own. The disagreement exists only *between*
|
|
115
|
+
them, which is why it survives every check that runs inside one — including this
|
|
116
|
+
stage, if this stage only ever looks at the repo it was working in.
|
|
117
|
+
|
|
118
|
+
Before the table is called complete, this reports nothing, **for the parent as well
|
|
119
|
+
as every submodule**:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git submodule status # no line begins with '+' (a '+' is the missing bump)
|
|
123
|
+
git -C <each repo> status --porcelain
|
|
124
|
+
git -C <each repo> log @{u}..HEAD --oneline
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Where [agent-sync](https://github.com/appvillis-com/agent-sync) is installed,
|
|
128
|
+
`/agent-sync finish` runs exactly this plus *no lease left held*, and `--gates`
|
|
129
|
+
adds the project's own gate commands.
|
|
130
|
+
|
|
131
|
+
When it fails, the fix is two commands and **the second is the one that gets
|
|
132
|
+
forgotten**:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
git -C <submodule> push
|
|
136
|
+
git add <submodule> && git commit -m "chore: bump <name> submodule — <why>"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
A REQ whose evidence lives in an unpushed commit, or in a submodule the parent
|
|
140
|
+
doesn't point at yet, is `partial` — the evidence is not reachable by anyone but
|
|
141
|
+
you.
|
|
142
|
+
|
|
107
143
|
## The closing question
|
|
108
144
|
|
|
109
145
|
The table is preparation. The stage exists for the question that follows it, asked
|
|
@@ -134,7 +170,10 @@ All of:
|
|
|
134
170
|
ledger or here) and, for `deferred`, a tracker entry.
|
|
135
171
|
7. **No carry-over row is left `unresolved`** — every one has a home, and the
|
|
136
172
|
ledger's counts are printed with this verdict, not just filed.
|
|
137
|
-
8. **
|
|
173
|
+
8. **Every repository is closed, the parent included** — `git submodule status`
|
|
174
|
+
shows no `+`, and each repo is clean and pushed. A submodule is finished when
|
|
175
|
+
its parent points at it.
|
|
176
|
+
9. **The operator answers the closing question** and signs off.
|
|
138
177
|
|
|
139
178
|
Manual by design. An automated check can prove the table is *well-formed*; only
|
|
140
179
|
the person who asked can confirm it is *what they asked for*. Do not let a green
|
|
@@ -300,8 +300,22 @@ stages/agents/types (see SKILL.md → *Bring your own skills*).
|
|
|
300
300
|
you asked for, here's what shipped, here's what's deferred and where it lives —
|
|
301
301
|
what's missing?* Ask it even when the table is green; the operator holds context
|
|
302
302
|
the brief never captured, and this is the cheapest moment in the run to hear it.
|
|
303
|
+
- **Several repositories: a submodule is finished when its parent says so.** A
|
|
304
|
+
parent records each submodule as a **pointer to one commit**, and moving the
|
|
305
|
+
submodule does not move the pointer — so the work is committed, pushed, CI green
|
|
306
|
+
and done in its own roadmap, while a clone of the parent still gets the commit
|
|
307
|
+
before it. Neither repo looks wrong alone; the disagreement lives between them,
|
|
308
|
+
which is why it survives every check that runs inside one. Before closing, this
|
|
309
|
+
reports nothing **for the parent as well as every submodule**:
|
|
310
|
+
`git submodule status` (no line starting `+`), plus `git -C <repo> status
|
|
311
|
+
--porcelain` and `git -C <repo> log @{u}..HEAD --oneline` per repo. With
|
|
312
|
+
[agent-sync](https://github.com/appvillis-com/agent-sync) installed,
|
|
313
|
+
`/agent-sync finish` runs exactly that. The fix is two commands and the second is
|
|
314
|
+
the forgotten one: `git -C <submodule> push`, then
|
|
315
|
+
`git add <submodule> && git commit`.
|
|
303
316
|
- **GATE (manual):** the ladder walk ran and its absences became REQ rows before
|
|
304
|
-
the table was written; **every
|
|
317
|
+
the table was written; **every repository is closed — the parent included:
|
|
318
|
+
`git submodule status` shows no `+`, each repo clean and pushed**; **every check this gate leans on has been seen failing
|
|
305
319
|
once against a planted defect** (an unproven check's green is not evidence);
|
|
306
320
|
every REQ has a status (none `unknown`); every `verified`
|
|
307
321
|
carries evidence; every `partial` names what's missing and where it's tracked;
|