task-pipeline-skill 1.58.0 → 1.59.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,48 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.59.0 — never amend a commit a record already names
4
+
5
+ ### Fixed
6
+
7
+ - **The stamping procedure invited the defect it then had to repair, twice in one
8
+ close-out.** `retrospective.md` says stamp the run with its own commit; the only way to
9
+ know that commit is to make it; so the stamp gets folded in with `--amend` — and the
10
+ amend mints a new SHA, leaving the stamp naming a commit that resolves on the machine
11
+ that wrote it and reaches no clone. It happened here on 2026-08-16 and then again in the
12
+ umbrella twenty minutes later, which is a procedure fault rather than two lapses.
13
+
14
+ The doctrine now says it in one line — **once a file names a SHA, that commit is
15
+ frozen** — states the order that removes the temptation (commit the work, *then* stamp in
16
+ a commit of its own), and names the only repair that does not re-enter the loop: a
17
+ follow-up commit, never a second amend.
18
+
19
+ - **The documentation gate asked the weaker of the two questions.** It required every
20
+ backticked SHA in the retro to *resolve*, and an amended-away commit resolves for as long
21
+ as the object survives locally. It now also requires **reachability from `HEAD`**
22
+ (`git merge-base --is-ancestor`), which is the question a reader two months later is
23
+ actually asking. Watched failing on a purpose-built repository whose stamped commit had
24
+ been amended away: `commit ... resolves but is NOT reachable from HEAD`.
25
+
26
+ - **Three id registers that could never allocate are removed** (`B-45`). They were declared
27
+ over the `fs` backend, whose `reserve` refuses by design, and `agent_sync.py check` had
28
+ been calling it a problem for as long as they stood. A declaration that cannot be served
29
+ is worse than none: it reads as a capability, so nobody writes the procedure it hides —
30
+ and on 2026-08-15 two sessions filed a different `B-073`. Allocation is manual, documented
31
+ in `CLAUDE.md`, and the guard that requires that documentation now fires on the **backend**
32
+ rather than on the declaration, so removing the registers could not retire it.
33
+
34
+ Guards: 344 → **344**. Property checks: 9 → 9. No new plant, and that is the honest
35
+ number: what changed is a gate script (`templates/docgate.sh`) rather than a validator
36
+ guard, and it was watched failing against a purpose-built repository whose stamped commit
37
+ had been amended away — the plant lives in that measurement rather than in the workflow,
38
+ because a gate that runs over a project's own git history cannot be planted from inside a
39
+ copy of this one.
40
+
41
+ - **The coordination snapshot exists and is linked.** `docs/AGENT_SYNC.md` was missing
42
+ entirely, which `check` had also been reporting. Generated from the live configuration and
43
+ linked from `CLAUDE.md`; `agent_sync.py check` → **exit 0, `setup healthy`**, for the first
44
+ time in this repository.
45
+
3
46
  ## v1.58.0 — a fan-out is not finished when its branches are
4
47
 
5
48
  The graph model this pipeline was audited against in v1.57.0 named one defect and fixed
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.58.0 |
15
+ | **Version** | 1.59.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, and **one of two browser channels** — `playwright` (CLI or MCP) or `chrome-devtools` (MCP); either satisfies the browser step and neither is required. 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, 5 categories. One recorded run, **self-observed by the author**; **zero blind runs on zero of three models** — the split, and the numbers, live in [`evals/RESULTS.md`](evals/RESULTS.md) and are computed by `evals/run.py` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.58.0",
3
+ "version": "1.59.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 closes with evidence, a work board and a verification ledger that outlive a run, an exposure line naming what shipped unconfirmed, a progress rail computed from the project's own config, a loop guard whose review ceiling measures rather than stops, and stage-3 tracks for what a product does, how it sounds and how it looks. Two modes need no task: `checkup` (what is unverified) and `setup` (audit existing docs). Retro insights can publish upstream as issues, opt-in and redacted.",
5
- "version": "1.58.0",
5
+ "version": "1.59.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -32,6 +32,7 @@ file exists to stop.
32
32
 
33
33
  - Write the entry only for a divergence — and name the layer that owned it
34
34
  - Every lesson carries its commit
35
+ - Never amend a commit a record already names
35
36
  - The stamp table is capped at ten, and *one line per run* was never a cap
36
37
  - `publish:` is a line in the verdict, not a silence
37
38
  - Rotation — the archive is how pruning stops losing things
@@ -76,11 +77,39 @@ message and the parent, so `git show <sha>` reconstructs the entire incident two
76
77
  months later — which is exactly when the same class comes back and somebody needs
77
78
  to know whether this was already understood.
78
79
 
79
- **Every SHA must resolve.** This is [`learned.md`](learned.md) rule 14 — *a
80
- document may not send a reader to something absent* — applied to history, and it is
81
- mechanical: the project's documentation gate runs `git rev-parse --verify --quiet
82
- <sha>^{commit}` over every backticked SHA in the retro and its archive
83
- ([`gates.md`](gates.md)).
80
+ **Every SHA must resolve and resolving is not enough.** This is
81
+ [`learned.md`](learned.md) rule 14 — *a document may not send a reader to something
82
+ absent* — applied to history, and it is mechanical: the documentation gate runs
83
+ `git rev-parse --verify --quiet <sha>^{commit}` over every backticked SHA in the retro
84
+ and its archive ([`gates.md`](gates.md)).
85
+
86
+ **But a commit that was amended away still resolves on the machine that amended it**,
87
+ and exists in no clone. The gate therefore also requires each SHA to be **reachable
88
+ from `HEAD`** — `git merge-base --is-ancestor <sha> HEAD` — because that is the
89
+ question a reader two months from now is actually asking, and the weaker one passes
90
+ for as long as the object survives locally.
91
+
92
+ ## Never amend a commit a record already names
93
+
94
+ Measured 2026-08-16, twice in one close-out and twenty minutes apart. The sequence is
95
+ seductive because each step is right on its own: stamp the run with its commit → the
96
+ stamp is part of the run, so fold it in with `--amend` → the amend mints a new SHA →
97
+ the stamp now names a commit that will never reach the remote.
98
+
99
+ The rule is one line and it is absolute: **once a file names a SHA, that commit is
100
+ frozen.** A correction goes in a *follow-up commit*, never a second amend — amending to
101
+ repair a stamp is the loop that produced the problem, and the second attempt lands in the
102
+ same place as the first.
103
+
104
+ Practically, that makes the order:
105
+
106
+ 1. commit the work;
107
+ 2. **then** stamp, in a commit of its own, naming the commit from step 1;
108
+ 3. prune and write the entry in that same second commit, or a third.
109
+
110
+ The stamp costs one line and one commit. A run that folds it back into the work to keep
111
+ the history tidy is trading a reader's ability to find the incident for the appearance of
112
+ tidiness — and the reader is the entire reason the stamp exists.
84
113
 
85
114
  ## The stamp table is capped at ten, and *one line per run* was never a cap
86
115
 
@@ -441,14 +441,22 @@ else
441
441
  while IFS=: read -r ln tok; do
442
442
  s=$(echo "$tok" | tr -d '`')
443
443
  case ${#s} in 7|8|9|10|11|12|40) ;; *) continue ;; esac
444
- git rev-parse --verify --quiet "$s^{commit}" >/dev/null 2>&1 ||
444
+ if ! git rev-parse --verify --quiet "$s^{commit}" >/dev/null 2>&1; then
445
445
  echo "$f:$ln: commit \`$s\` does not resolve" >> "$TMP/sha"
446
+ # Resolving is the weaker half. A commit that was AMENDED AWAY still resolves on
447
+ # the machine that amended it and reaches no clone — measured 2026-08-16, twice in
448
+ # one close-out: the stamp named the run's commit, the commit was amended to carry
449
+ # the stamp, and the SHA the stamp recorded stopped being reachable. Ask the
450
+ # question a reader actually has: is it in this history at all.
451
+ elif ! git merge-base --is-ancestor "$s^{commit}" HEAD >/dev/null 2>&1; then
452
+ echo "$f:$ln: commit \`$s\` resolves but is NOT reachable from HEAD — amended away, or on a branch this checkout does not have" >> "$TMP/sha"
453
+ fi
446
454
  done
447
455
  done
448
456
  if [ -s "$TMP/sha" ] 2>/dev/null; then
449
- err "unresolvable commit reference(s):"; sed 's/^/ /' "$TMP/sha"
457
+ err "commit reference(s) a clone could not follow:"; sed 's/^/ /' "$TMP/sha"
450
458
  else
451
- ok "every commit reference in $RETRO_GLOB resolves"
459
+ ok "every commit reference in $RETRO_GLOB resolves AND is reachable from HEAD"
452
460
  fi
453
461
  fi
454
462