task-pipeline-skill 1.21.0 → 1.22.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 CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.22.0
4
+
5
+ ### When a thing exists twice, ask which one is used — `learned.md` rule 20
6
+
7
+ A service had **two Dockerfiles**. One was added at the repository root by a run that checked for a
8
+ Dockerfile by looking where it expected one; `docker/Dockerfile` had been there all along, and
9
+ `.github/workflows/ci.yml` says `file: docker/Dockerfile`. They disagreed about the port — 8080 at
10
+ the root, 8000 in `docker/` — and the disagreement surfaced two days later as a **deployed service
11
+ that answered nothing**, while `docker ps` said `Up` and `systemctl` said `active`. The built one
12
+ also ran as root and copied the whole context including `.git`; the hardened one was the one nobody
13
+ built.
14
+
15
+ Diffing the two files finds the difference and not the **direction**, and the direction is the whole
16
+ finding. Only the consumer says which one ships, and it is one grep.
17
+
18
+ Its second shape: **a rule written in two documents is two rules.** This skill's own autonomy sweep
19
+ lives in `grill.md` (what the grill ASKS) and `templates/brief.md` (what the brief RECORDS), and in
20
+ the two releases before this one a row was added to one and not the other — twice — each time caught
21
+ by a validator that knew to look at both.
22
+
23
+ - `references/learned.md` — rule 20 and incident 20.
24
+ - `references/audit.md` — "Two copies, and which one wins", including why the copy that ships is
25
+ usually the one nobody hardened.
26
+ - `references/grill.md` + `templates/brief.md` — sweep row `0 Duplicates`: the consumer line, quoted.
27
+ - `test/validate.py` — a guard, watched failing against three planted defects, the third being the
28
+ sweep row present in one file and not the other.
29
+
3
30
  ## v1.21.0
4
31
 
5
32
  ### An empty measurement is a refused measurement — `learned.md` rule 19
package/SKILL-CARD.md CHANGED
@@ -12,7 +12,7 @@ harmless.
12
12
  |---|---|
13
13
  | **Purpose** | Runs a substantial task through ten gated delivery stages — intake grill, docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs+registers, acceptance — refusing to advance until each gate passes |
14
14
  | **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
15
- | **Version** | 1.21.0 |
15
+ | **Version** | 1.22.0 |
16
16
  | **Surface** | Claude Code (filesystem skill + plugin) and the vercel `skills` CLI. **Not** uploaded to the Skills API; custom Skills do not sync across surfaces |
17
17
  | **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
18
18
  | **Evaluation status** | Suite authored (15 evals, 5 categories). **Never executed** — see [`evals/RESULTS.md`](evals/RESULTS.md) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
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"
@@ -2,7 +2,7 @@
2
2
  "name": "task-pipeline",
3
3
  "displayName": "Task Pipeline",
4
4
  "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.",
5
- "version": "1.21.0",
5
+ "version": "1.22.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -20,6 +20,7 @@ whose whole job is "audit X" runs nothing else.
20
20
  - Why "look again, more carefully" stops working
21
21
  - The ladder
22
22
  - How one audit pass runs
23
+ - Two copies, and which one wins
23
24
  - Silence is not a reading
24
25
  - Exit criterion — the part usually skipped
25
26
  - The three rules that stop this becoming another loop
@@ -175,6 +176,27 @@ spine*). A finding that contradicts the spec goes back to stage 3; one that
175
176
  contradicts the plan goes back to stage 4. Auditing is not a licence to edit
176
177
  across layers in place.
177
178
 
179
+ ## Two copies, and which one wins
180
+
181
+ `learned.md` rule 20. When something exists twice — two build files, a schema and its mirror, a
182
+ vendored library, one rule written in two documents — the useful question is not *do they agree*.
183
+ Diffing them finds the difference and not the **direction**, and the direction is the whole finding:
184
+ one of them is what runs, and the other is what somebody reads and edits.
185
+
186
+ The copies cannot answer it about themselves. The consumer can, and usually in one line:
187
+
188
+ ```bash
189
+ grep -rn "Dockerfile\|schema.json\|VERSION" .github/workflows/ Makefile* package.json
190
+ ```
191
+
192
+ Two consequences worth stating separately, because they fail differently:
193
+
194
+ - **The copy that wins is often the one nobody hardened.** Attention goes to the copy people open,
195
+ and the build reads the other.
196
+ - **A rule written in two documents is two rules.** One asks, one records; one describes, one
197
+ decides. Edit only the first and the second silently disagrees — which is why a check that knows
198
+ about both is worth more than a note asking people to remember.
199
+
178
200
  ## Silence is not a reading
179
201
 
180
202
  `learned.md` rule 19. The ladder's evidence is commands and their output, and a command that
@@ -142,6 +142,7 @@ explicit "stop and ask me here":
142
142
  | run-wide | the model decision ([`model-tiering.md`](model-tiering.md)); what to decide autonomously vs escalate |
143
143
  | run-wide Pacing | the **run mode** ([`continuity.md`](continuity.md)): does the run advance item-by-item with no check-in between items, and on what interval? Read `pipeline.json` → `run.loop` first — a recorded mode is the answer and is not re-asked. **Absent, it is off**: recommend it, take the answer, record it. It never collapses a `manual` gate or an outward act, so this row buys pacing, not authorization |
144
144
  | 0 Harvest | doc sources beyond this repo — other repos, hosted doc systems, the knowledge wiki, **the code graph** ([`knowledge-graph.md`](knowledge-graph.md): built / installed-not-built / absent) — and whether stage 9 may write to them (another repo is outward: propose + PR, never a direct push) |
145
+ | 0 Duplicates | for every artifact the build reads — a Dockerfile, a schema, a lockfile, a spec — **which copy does the consumer actually name**. Quoted from the workflow or the Makefile, not inferred from the tree: the copy that ships is often not the copy people open (`learned.md` rule 20) | the consumer line, quoted |
145
146
  | 0 Fixtures | what **persists between runs** on this machine — a database, a volume, a cache, generated files — and the command that recreates it from nothing. A suite green against accumulated state carries a premise that is false on every runner (`learned.md` rule 18) | the recreate command, stated |
146
147
  | 0 Source | for a repository with an upstream — **is this checkout the one that ships**. `git rev-list --count HEAD..@{u}`, printed, before the first edit. Behind means stop and pull: an edit on a stale copy deletes newer work by fast-forward, and nothing complains (`learned.md` rule 17) | the count, stated |
147
148
  | 0 Work-list | which register holds task **state** — a roadmap, a board, a backlog, a tracker — and the **command that reads it**. Recorded once; the harvest and every loop iteration re-run it, and a closing report that names what is left cites it. No register → record the row empty, and the rule costs nothing ([`knowledge-sources.md`](knowledge-sources.md) → *Carried-in claims*) |
@@ -44,6 +44,7 @@ to be enforced and is not is the same failure as a gate that prints `FAIL` and e
44
44
  | 17 | **The copy you are about to edit may not be the copy that ships** | any run editing a repository that has an upstream — a skill, a plugin, a vendored library, a fork | `git rev-list --count HEAD..@{u}` **before the first edit**; non-zero means stop and pull | the run states the count it measured, or it has not started |
45
45
  | 18 | **State that accumulates locally is created from nothing everywhere else** | any run whose tests, migrations or fixtures read a database, a cache or a checkout that persists between runs on this machine | run the suite once against a **freshly created** instance of it, not the one that has been here for weeks | the run names the fresh instance it used, or the green is a green from residue |
46
46
  | 19 | **An empty measurement is a refused measurement** | any command run to establish a fact — a count, a probe, a query, a suite | assert the output is **non-empty and shaped as expected** before reading meaning into it; a command that printed nothing did not answer | the run quotes the output it read, not the conclusion it drew from silence |
47
+ | 20 | **When a thing exists twice, ask which one is used — not whether they agree** | any artifact with a second copy: two build files, a vendored library, a schema and its mirror, doctrine in two documents | find the **consumer** and read what it names; the copies cannot answer this about themselves | the run names the file the build/test/deploy actually reads, quoted from the consumer |
47
48
 
48
49
  ---
49
50
 
@@ -133,6 +134,8 @@ run's belief about the work-list against the register; the claim only ever appea
133
134
 
134
135
  **19 · Silence read as assent.** Three failures in one session, all the same shape. A `docker run` without `-i` does not attach stdin, so a heredoc carrying `ALTER ROLE` stopped at the docker CLI; `psql` read an empty script, did nothing, and exited **0** — and the step printed "password set". A `grep` pattern written against the wrong output format matched nothing, so three consecutive planted-defect runs printed empty strings that read as passes. And a migration step printed no lines at all, which looked like a step that had not run and was in fact a step that had. In every case the instrument failed and the failure was **indistinguishable from success**, because both produce nothing. Rule 11 covers the exit code; this covers the other half, which is louder in practice: an exit code of 0 from a command that never ran is the most convincing lie a run can tell itself.
135
136
 
137
+ **20 · The copy that wins.** A service had **two Dockerfiles**. One was added at the repository root by a run that checked whether a Dockerfile existed by looking where it expected one; `docker/Dockerfile` had been there all along, and `.github/workflows/ci.yml` says `file: docker/Dockerfile`. They disagreed about the port — 8080 at the root, 8000 in `docker/` — and the disagreement surfaced two days later as a **deployed service that answered nothing**, while `docker ps` said `Up` and `systemctl` said `active`. The built one also ran as root and copied the whole context, including `.git` and any `.env`; the hardened one was the one nobody built. Comparing the two files would have found the difference and not the direction. Only the workflow line says which one ships, and it is one grep. The same session hit this three more times: an autonomy sweep row added to the file that ASKS and not the file that RECORDS, twice, caught by a validator that knew to look at both.
138
+
136
139
  The same class had already bitten that project twice from the other side, and its roadmap names the
137
140
  property exactly: seven rows read `blocked` on producers the dependency board recorded as delivered,
138
141
  and *"no gate can catch it because it breaks nothing — it only removes work from consideration"*;
@@ -120,6 +120,7 @@ is not neutral — it is a scheduled interruption.
120
120
  | run-wide | Decide autonomously vs escalate to me | … |
121
121
  | run-wide Pacing | Run mode: item-by-item with no check-in between items, and on what interval? (the skill's `references/continuity.md`; read `pipeline.json` → `run.loop` first) | … (**absent ⇒ off**; it never collapses a manual gate or an outward act) |
122
122
  | 0 Harvest | Doc sources beyond this repo — other repos, hosted docs, the knowledge wiki, the code graph; and may stage 9 write to them? | … (another repo is outward: propose + PR, never a direct push; graph built / not built) |
123
+ | 0 Duplicates | the line in the workflow/Makefile naming which copy the build reads, quoted (`learned.md` rule 20) | |
123
124
  | 0 Fixtures | the command that recreates local persistent state from nothing, and the run's statement that the suite was seen green against it (`learned.md` rule 18) | |
124
125
  | 0 Source | `git rev-list --count HEAD..@{u}` before the first edit, printed. Behind means stop and pull — an edit on a stale checkout deletes newer work by fast-forward and nothing complains (`learned.md` rule 17) | |
125
126
  | 0 Work-list | Which register holds task **state**, and the command that reads it — re-run at every harvest, at every loop iteration and at the close | … (e.g. `bash scripts/board.sh`; none → record empty) |