task-pipeline-skill 1.8.0 → 1.8.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 +58 -0
- package/CODE_OF_CONDUCT.md +38 -0
- package/CONTRIBUTING.md +215 -0
- package/README.md +1 -1
- package/SECURITY.md +67 -0
- package/SKILL-CARD.md +60 -0
- package/bin/task-pipeline.js +23 -0
- package/evals/RESULTS.md +47 -0
- package/evals/__pycache__/run.cpython-314.pyc +0 -0
- package/evals/run.py +130 -0
- package/evals/task-pipeline.evals.json +166 -0
- package/package.json +7 -2
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/documentation.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +49 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/review.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +11 -11
- package/plugins/task-pipeline/skills/task-pipeline/templates/docgate.sh +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.8.1 — 2026-08-03
|
|
4
|
+
|
|
5
|
+
### Fixed — eight findings from a code-and-contradiction audit of 1.8.0
|
|
6
|
+
|
|
7
|
+
A third pass, on a third axis: the first read for contradictions, the second measured
|
|
8
|
+
against Anthropic's guidance, this one went after the **code** and the **invariants
|
|
9
|
+
between files**. Everything below was proven before the fix and again after.
|
|
10
|
+
|
|
11
|
+
**Fifteen broken cross-references, eleven of them pointing at a section about
|
|
12
|
+
something else.** Every per-stage freedom label cited `gates.md → Axis B` — which is
|
|
13
|
+
the *enforcement ladder* and contains no mention of degrees of freedom. Two more
|
|
14
|
+
cited sections that do not exist at all (`gates.md → progressive arming`,
|
|
15
|
+
`review.md → Final review`). This is the failure `references/learned.md` keeps as a
|
|
16
|
+
review question rather than a rule: *"a stale reference was replaced with a FALSE
|
|
17
|
+
one — the new target existed and said nothing about the subject."* The link checker
|
|
18
|
+
proved every file resolved and could not see it.
|
|
19
|
+
|
|
20
|
+
It is a rule now. `gates.md` gained the two sections the citations were reaching for
|
|
21
|
+
— **Axis C — degrees of freedom** and **Progressive arming** — and a guard checks
|
|
22
|
+
every ``file.md → *Section*`` pointer against the target's actual headings. Measured
|
|
23
|
+
before shipping: whitespace is normalised first, because a citation wrapped across
|
|
24
|
+
two lines is not a defect and six were reported as such.
|
|
25
|
+
|
|
26
|
+
**Both installers created the shadow copy this family exists to prune.**
|
|
27
|
+
`install.sh` and `bin/task-pipeline.js` write a plain copy to
|
|
28
|
+
`~/.claude/skills/task-pipeline`; the launcher (`sshlg-skills`) deletes exactly those
|
|
29
|
+
because while the plugin channel is active a plain copy **shadows it and keeps
|
|
30
|
+
serving the version it was copied from**. `CLAUDE.md` documented the shadow-creating
|
|
31
|
+
form (`--force`) as the local install path. Both installers now **refuse when a
|
|
32
|
+
plugin install is detected**, name the plugin commands instead, and take `--force`
|
|
33
|
+
only as a deliberate override.
|
|
34
|
+
|
|
35
|
+
**The npm package did not contain what the README points at.** `SKILL-CARD.md` and
|
|
36
|
+
the whole `evals/` directory were outside `files[]` while the shipped README linked
|
|
37
|
+
both — and `CONTRIBUTING.md`, `SECURITY.md` and `CODE_OF_CONDUCT.md` had been
|
|
38
|
+
dangling for npm consumers far longer. Rule 14 — *a document may not send a reader
|
|
39
|
+
to something absent* — applied to the artefact that is actually published. All are
|
|
40
|
+
packaged now, and a guard holds every relative README link to `files[]`.
|
|
41
|
+
|
|
42
|
+
**Living documents restated a guard count that had moved.** `SKILL-CARD.md` and
|
|
43
|
+
`evals/RESULTS.md` claimed 46 after the suite reached 50. Rule 8 — *compute, never
|
|
44
|
+
restate* — had never been applied to this repository's own prose. It is now: the
|
|
45
|
+
count is compared against the negative self-tests the workflow defines, and the
|
|
46
|
+
guard caught its own author within the minute, when adding three tests made the
|
|
47
|
+
freshly-corrected numbers stale again. CHANGELOG entries are exempt; they record
|
|
48
|
+
what a past release shipped.
|
|
49
|
+
|
|
50
|
+
**The contributor invariants were numbered 1,2,3,4,5,6,10,7,8,9 — and number 8
|
|
51
|
+
documented the opposite of what is enforced**, still requiring the description to
|
|
52
|
+
*open* with `Use when` after v1.8.0 made that a failure. Rewritten: sixteen
|
|
53
|
+
invariants, in order, each matching a guard that exists.
|
|
54
|
+
|
|
55
|
+
**Smaller:** the seeded gate's empty-project failure named only `docs/` while it also
|
|
56
|
+
scans the repository root, and offered no remedy — it now names both and says what to
|
|
57
|
+
do; `CLAUDE.md` gained the `evals/run.py` row it never had.
|
|
58
|
+
|
|
59
|
+
Three new guards, each with a negative self-test watched failing.
|
|
60
|
+
|
|
3
61
|
## v1.8.0 — 2026-08-03
|
|
4
62
|
|
|
5
63
|
### Added — the skill now meets Anthropic's own authoring guidance, measurably
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Code of conduct
|
|
2
|
+
|
|
3
|
+
## The short version
|
|
4
|
+
|
|
5
|
+
Be decent. Argue with the idea, never with the person. Assume the other side read
|
|
6
|
+
the docs and still disagrees for a reason.
|
|
7
|
+
|
|
8
|
+
## Expected
|
|
9
|
+
|
|
10
|
+
- **Technical criticism is welcome and wanted** — this repo is opinionated prose,
|
|
11
|
+
and the opinions get better under pressure. Bring the failure case, the file and
|
|
12
|
+
the line.
|
|
13
|
+
- Accept that a maintainer may decline a change and say why. "Out of scope" is a
|
|
14
|
+
legitimate answer.
|
|
15
|
+
- Respect that contributors work in different languages, time zones and
|
|
16
|
+
experience levels. English is the working language here; imperfect English is
|
|
17
|
+
never a reason to dismiss a point.
|
|
18
|
+
|
|
19
|
+
## Not accepted
|
|
20
|
+
|
|
21
|
+
Personal attacks, harassment of any kind, demeaning or discriminatory comments,
|
|
22
|
+
sexualized language or imagery, publishing someone's private information, and
|
|
23
|
+
sustained disruption of discussions.
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
Applies to issues, pull requests, discussions, commit messages and any other
|
|
28
|
+
project space, and to public spaces when someone is representing the project.
|
|
29
|
+
|
|
30
|
+
## Enforcement
|
|
31
|
+
|
|
32
|
+
Report anything that crosses the line to **[@sshlg on Telegram](https://t.me/sshlg)**
|
|
33
|
+
or via [GitHub's report abuse](https://github.com/contact/report-abuse) flow. Reports
|
|
34
|
+
are handled privately. Depending on severity the response is a warning, removal of
|
|
35
|
+
the offending content, or a block from the project.
|
|
36
|
+
|
|
37
|
+
Maintainers hold themselves to the same standard; a maintainer who breaks it should
|
|
38
|
+
expect to hear about it publicly.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Contributing to task-pipeline
|
|
2
|
+
|
|
3
|
+
Thanks for taking the time. This repo ships a **skill**, not a program: almost
|
|
4
|
+
everything in it is prose that an agent reads and acts on. That makes two things
|
|
5
|
+
unusually important — the doctrine must not contradict itself across surfaces, and
|
|
6
|
+
the structural validator must stay able to fail.
|
|
7
|
+
|
|
8
|
+
## Getting set up
|
|
9
|
+
|
|
10
|
+
No build step, no dependencies. You need `python3` (validator), `node` ≥ 16 (npm
|
|
11
|
+
installer), and `bash`.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/ssheleg/task-pipeline
|
|
15
|
+
cd task-pipeline
|
|
16
|
+
npm test # == python3 test/validate.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`npm test` must print `PASS: task-pipeline structure valid` before you open a PR.
|
|
20
|
+
|
|
21
|
+
That proves the repo is well-formed. It does **not** prove the validator is
|
|
22
|
+
anything more than a decoration — for that, every guard has to be watched
|
|
23
|
+
rejecting a planted defect:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm run test:negatives # python3 test/negatives.py
|
|
27
|
+
npm run test:all # both, in order
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The corruptions live in [`.github/workflows/validate.yml`](.github/workflows/validate.yml)
|
|
31
|
+
and `test/negatives.py` reads them from there — never duplicated, because a second
|
|
32
|
+
copy of a corruption is a second thing to drift. The runner also tells a **broken
|
|
33
|
+
test** from a **guard that didn't fire**: if a planted defect changed nothing, the
|
|
34
|
+
validator passing means the test proved nothing, and it is reported as `BROKEN`
|
|
35
|
+
rather than as a failure of the guard.
|
|
36
|
+
|
|
37
|
+
**Corrupt files in python, never with `sed -i`.** BSD sed needs an argument GNU sed
|
|
38
|
+
refuses, and `0,/re/` does not exist on BSD at all — there it edits nothing
|
|
39
|
+
silently, and the test reads as a guard that failed. The validator rejects `sed -i`
|
|
40
|
+
in the workflow for exactly this reason: a self-test that only runs on CI cannot be
|
|
41
|
+
used while you are writing the guard, which is the moment it is worth most.
|
|
42
|
+
|
|
43
|
+
To try your change in a real agent:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
./install.sh --force # ~/.claude/skills/task-pipeline + the command
|
|
47
|
+
node bin/task-pipeline.js --force # the same, through the npm installer
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Repository layout
|
|
51
|
+
|
|
52
|
+
| Path | What it is |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `plugins/task-pipeline/skills/task-pipeline/SKILL.md` | the orchestrator — the entry point every agent reads first |
|
|
55
|
+
| `…/references/*.md` | the built-in stage doctrine (one file per stage or concern) |
|
|
56
|
+
| `…/templates/*.md` | skeletons seeded into a host project (brief, carry-over, `CONTEXT.md`, ADR) |
|
|
57
|
+
| `…/pipeline.schema.json` | the universal pipeline-config contract |
|
|
58
|
+
| `…/pipeline.example.json` | this plugin's own flow expressed against that contract |
|
|
59
|
+
| `plugins/task-pipeline/commands/task-pipeline.md` | the `/task-pipeline` slash command |
|
|
60
|
+
| `cursor/rules/task-pipeline.mdc` | the Cursor channel — **self-contained**, no relative links |
|
|
61
|
+
| `bin/task-pipeline.js`, `install.sh` | the two installers |
|
|
62
|
+
| `test/validate.py` | the structural validator |
|
|
63
|
+
|
|
64
|
+
## The invariants
|
|
65
|
+
|
|
66
|
+
These are what the validator enforces. Breaking one is not a style disagreement —
|
|
67
|
+
it ships a wrong pipeline to every install. Numbered in reading order; the numbers
|
|
68
|
+
are labels, not priorities.
|
|
69
|
+
|
|
70
|
+
**1. Four-way version sync.** `package.json`, `.claude-plugin/marketplace.json`
|
|
71
|
+
(`plugins[0].version`), `plugins/task-pipeline/.claude-plugin/plugin.json` and the
|
|
72
|
+
top `## vX.Y.Z` heading in `CHANGELOG.md` must all carry the same version.
|
|
73
|
+
`SKILL-CARD.md`'s Version row is held to it too.
|
|
74
|
+
|
|
75
|
+
**2. The stage list lives on three surfaces and may not drift.** `SKILL.md`'s
|
|
76
|
+
table, `references/stages.md`'s per-stage sections, and `pipeline.example.json`.
|
|
77
|
+
Stage ids, names and **gate types** are compared across all three. Each stage's own
|
|
78
|
+
doctrine file states its gate type too and must agree with the config.
|
|
79
|
+
|
|
80
|
+
**3. Every human-facing description must name the flow's final stage, last.** The
|
|
81
|
+
package, marketplace, plugin, skill, command, Cursor-rule and README blurbs are the
|
|
82
|
+
only thing most people ever read. The validator derives the last stage from
|
|
83
|
+
`pipeline.example.json` and holds every blurb to it.
|
|
84
|
+
|
|
85
|
+
**4. No hardcoded vendor model ids.** Anywhere in the shipped skill, the README, the
|
|
86
|
+
command or the Cursor rule. Name the **tier**, never a string; stage configs use the
|
|
87
|
+
provider-agnostic tokens `default` / `inherit`.
|
|
88
|
+
|
|
89
|
+
**5. Every `references/*.md` must be reachable from `SKILL.md`**, directly or
|
|
90
|
+
transitively. An unreferenced file is dead context that ships and is never read.
|
|
91
|
+
|
|
92
|
+
**6. No external provider may substitute for built-in stage doctrine.**
|
|
93
|
+
`pipeline.example.json`'s `skills[]` may not name one for the stages whose doctrine
|
|
94
|
+
ships here (2, 3-spec, 4, 5, 6, 10). The optional tools — `context7`, `figma`,
|
|
95
|
+
`graphify`, `wiki-query` / `wiki-update` — and the UI-required `super-ux:*` track are
|
|
96
|
+
the enumerated exceptions, named deliberately.
|
|
97
|
+
|
|
98
|
+
**7. Stage 0 is mandatory and manual; stage 10 is manual and demands evidence; the
|
|
99
|
+
stage-4 gate is a set comparison.** These three are the spine, asserted in the
|
|
100
|
+
shipped config.
|
|
101
|
+
|
|
102
|
+
**8. `SKILL.md` frontmatter stays under 1024 characters, and the description says
|
|
103
|
+
WHAT before WHEN.** Anthropic's authoring guidance requires both halves — a
|
|
104
|
+
capability statement in third person, then the `Use when …` trigger — and Russian
|
|
105
|
+
trigger aliases ride beside the English ones. *(Before v1.8.0 this invariant demanded
|
|
106
|
+
the description **open** with `Use when`, which enforced the trigger half and left
|
|
107
|
+
the capability optional. The validator now rejects that shape.)*
|
|
108
|
+
|
|
109
|
+
**9. Relative links resolve.** Every relative markdown link in every file outside a
|
|
110
|
+
fenced code block must point at a path that exists.
|
|
111
|
+
|
|
112
|
+
**10. A seeded template must keep the seeded gate green — in both register shapes.**
|
|
113
|
+
`templates/docgate.sh` is run by `npm test` over two scratch projects: one seeded
|
|
114
|
+
from `docmap.md` / `decisions.md` / `open-questions.md` / `retro.md`, and one built
|
|
115
|
+
from `adr.md`'s own fenced example. Each must exit `0`, **report the shape it
|
|
116
|
+
found**, and run a minimum of live checks — because every section can go `dormant`,
|
|
117
|
+
and a gate blind to a shape passes exactly like one that reads it. Change a template
|
|
118
|
+
→ run `npm test`, not just your eyes.
|
|
119
|
+
|
|
120
|
+
**11. Every reference over 100 lines carries a `## Contents` list**, and the list is
|
|
121
|
+
compared against that file's own `##` headings. The guidance asks for it because a
|
|
122
|
+
long file gets previewed with a partial read; the comparison is because a hand-kept
|
|
123
|
+
list is a second source that goes stale on the next heading.
|
|
124
|
+
|
|
125
|
+
**12. A section-qualified citation must name a section that exists.**
|
|
126
|
+
A citation of the form `file.md → *Section*` is checked against the target's headings. The
|
|
127
|
+
link checker proves the file resolves; only this proves the pointer is not false.
|
|
128
|
+
|
|
129
|
+
**13. Numbers stated in living documents are computed, not restated.** The guard
|
|
130
|
+
count in `README.md`, `SKILL-CARD.md` and `evals/RESULTS.md` is compared against the
|
|
131
|
+
negative self-tests the workflow defines. CHANGELOG entries are exempt — they record
|
|
132
|
+
what a past release shipped.
|
|
133
|
+
|
|
134
|
+
**14. Every relative link in `README.md` resolves inside the published package.**
|
|
135
|
+
`package.json` → `files[]` must ship whatever the README points at, or the link
|
|
136
|
+
dangles for every npm consumer.
|
|
137
|
+
|
|
138
|
+
**15. `SKILL-CARD.md` answers every risk indicator** and carries the current
|
|
139
|
+
version. It is the registry entry a consumer reviews before deploying, and an
|
|
140
|
+
omitted row reads as "does not apply".
|
|
141
|
+
|
|
142
|
+
**16. The evaluation suite covers all five dimensions** and `evals/run.py` accepts
|
|
143
|
+
it. Running it is a human step; the suite existing is not.
|
|
144
|
+
|
|
145
|
+
## Adding or changing doctrine
|
|
146
|
+
|
|
147
|
+
- **Change one idea per PR.** These files are read by agents under load; a PR that
|
|
148
|
+
edits eight references for three unrelated reasons is unreviewable.
|
|
149
|
+
- **Update every surface in the same change.** If you touch the stage list, the
|
|
150
|
+
gate types or the review verdict count, walk `SKILL.md`, `references/stages.md`,
|
|
151
|
+
`pipeline.example.json`, the command, the Cursor rule and the README before you
|
|
152
|
+
commit. The validator catches much of this — do not rely on it to think for you.
|
|
153
|
+
- **A new guard needs a negative self-test.** If you teach `test/validate.py` a new
|
|
154
|
+
rule, add a step to `.github/workflows/validate.yml` that corrupts a copy and
|
|
155
|
+
asserts the validator fails, then watch it with `npm run test:negatives`. A guard
|
|
156
|
+
nobody proved can fail is decoration. **Check the base is green first** — if the
|
|
157
|
+
repo already fails your new rule, the self-test passes for the wrong reason and
|
|
158
|
+
proves nothing.
|
|
159
|
+
- **Keep the Cursor rule self-contained.** It gets copied into foreign projects;
|
|
160
|
+
relative links break there. Restate, don't link.
|
|
161
|
+
- **Prose style:** state the rule, then the failure it prevents. Every doctrine
|
|
162
|
+
file ends with a *Rationalizations* table for a reason — the excuse an agent will
|
|
163
|
+
reach for is more useful to write down than the rule itself.
|
|
164
|
+
|
|
165
|
+
## Commits and pull requests
|
|
166
|
+
|
|
167
|
+
- **Conventional commits:** `feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`.
|
|
168
|
+
Append the version when the change ships one: `feat: … ; v0.19.0`.
|
|
169
|
+
- Fill in the PR template: what changed, which surfaces you updated, validator
|
|
170
|
+
output.
|
|
171
|
+
- CI must be green. It is fast and dependency-light on purpose.
|
|
172
|
+
|
|
173
|
+
## Releasing (maintainers)
|
|
174
|
+
|
|
175
|
+
1. Bump the version in **all four** places (see invariant 1) and write the
|
|
176
|
+
`CHANGELOG.md` section — what changed and *why it mattered*, not a diff summary.
|
|
177
|
+
2. `npm test` green, commit, push.
|
|
178
|
+
3. Tag `vX.Y.Z` and push the tag. With the repo variable `RELEASE_ENABLED=true`,
|
|
179
|
+
[`.github/workflows/release.yml`](.github/workflows/release.yml) re-runs the
|
|
180
|
+
validator, checks the tag against the manifests, cuts a GitHub release from that
|
|
181
|
+
CHANGELOG section, and smoke-tests `npx` from a clean checkout.
|
|
182
|
+
4. **`npm publish` runs in the same workflow**, in a second job armed by the repo
|
|
183
|
+
variable `PUBLISH_NPMJS=true` — it was the one human step in every release, and
|
|
184
|
+
the registry drifted behind the tags because of it. Auth is either the
|
|
185
|
+
`NPM_TOKEN` secret (a **granular automation** token; a classic one is still
|
|
186
|
+
refused by 2FA) or npm trusted publishing via OIDC, which needs no long-lived
|
|
187
|
+
credential. With `PUBLISH_NPMJS` unset or false it stays manual, and 2FA makes
|
|
188
|
+
that a human step.
|
|
189
|
+
5. Refresh the local installs: `claude plugin marketplace update task-pipeline` →
|
|
190
|
+
`claude plugin update task-pipeline@task-pipeline` →
|
|
191
|
+
`npx skills update task-pipeline --global --yes`, then restart the agent.
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
### The family catalogue moves with the release
|
|
195
|
+
|
|
196
|
+
`sshlg-skills` — the launcher that installs and updates the whole ssheleg family — pins every
|
|
197
|
+
member's version in its own `skills.json`. **A release that does not bump that pin is invisible.**
|
|
198
|
+
`npx sshlg-skills list` keeps reporting the previous version, `update` keeps installing it, and
|
|
199
|
+
anyone comparing their install against `list` is told the wrong number with nothing to reveal it.
|
|
200
|
+
|
|
201
|
+
So a release is not finished at `npm publish`:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# in ssheleg/sshlg-skills
|
|
205
|
+
# 1. bump this member's "version" in skills.json
|
|
206
|
+
# 2. bump the launcher's own version, changelog, tag
|
|
207
|
+
npm publish --access public
|
|
208
|
+
npx --yes sshlg-skills@latest list # the new number must appear here
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
By contributing you agree that your contributions are licensed under the
|
|
214
|
+
[MIT License](LICENSE), and that any third-party material you bring in is
|
|
215
|
+
compatible and gets its notice added to `LICENSE` → *Third-party*.
|
package/README.md
CHANGED
|
@@ -630,7 +630,7 @@ framework bakes in no fixed stage count and no opinion on which gates are manual
|
|
|
630
630
|
A pipeline config may declare an optional `release` block: a master `enabled`
|
|
631
631
|
toggle, a `trigger`, project-defined `steps`, and `verify` smoke-checks. It's **off
|
|
632
632
|
unless a project turns it on**, and every project configures its own. This repo's
|
|
633
|
-
own instance is [`.github/workflows/release.yml`](.github/workflows/release.yml) —
|
|
633
|
+
own instance is [`.github/workflows/release.yml`](https://github.com/ssheleg/task-pipeline/blob/main/.github/workflows/release.yml) —
|
|
634
634
|
armed per repo by the `RELEASE_ENABLED` variable (unset = off), it validates the tag
|
|
635
635
|
against the manifests, cuts a GitHub release from the CHANGELOG, and smoke-tests
|
|
636
636
|
`npx` from a clean checkout. Copy and adapt it; nothing is hardcoded.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## What this project is
|
|
4
|
+
|
|
5
|
+
`task-pipeline` ships **markdown doctrine plus two small installers**. There is no
|
|
6
|
+
server, no network client and no runtime service. The executable surface is:
|
|
7
|
+
|
|
8
|
+
| Surface | What it does |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `bin/task-pipeline.js` | copies the skill directory into `~/.claude/` (zero dependencies) |
|
|
11
|
+
| `install.sh` | the same, in POSIX shell |
|
|
12
|
+
| `test/validate.py` | reads repo files and exits 0/1; run in CI |
|
|
13
|
+
| `.github/workflows/*.yml` | CI and the toggleable release job |
|
|
14
|
+
|
|
15
|
+
The skill's doctrine, however, is **instructions an agent will act on** inside your
|
|
16
|
+
repository — including running your test and lint commands and, at stage 7, your
|
|
17
|
+
deploy. Treat a change to `references/*.md` with the same care as a change to a
|
|
18
|
+
deploy script.
|
|
19
|
+
|
|
20
|
+
## Supported versions
|
|
21
|
+
|
|
22
|
+
The latest released version is supported. Fixes ship in a new release rather than
|
|
23
|
+
as patches to older tags.
|
|
24
|
+
|
|
25
|
+
## Reporting a vulnerability
|
|
26
|
+
|
|
27
|
+
**Do not open a public issue for a security problem.**
|
|
28
|
+
|
|
29
|
+
- Preferred: [GitHub private vulnerability reporting](https://github.com/ssheleg/task-pipeline/security/advisories/new)
|
|
30
|
+
(Security → Report a vulnerability).
|
|
31
|
+
- Alternative: Telegram [@sshlg](https://t.me/sshlg).
|
|
32
|
+
|
|
33
|
+
Please include what you found, how to reproduce it, and the impact you see. You'll
|
|
34
|
+
get an acknowledgement within **72 hours** and a fix or a decision with reasoning
|
|
35
|
+
within **14 days** for anything confirmed. Coordinated disclosure is welcome — tell
|
|
36
|
+
me the timeline you'd like and I'll work to it.
|
|
37
|
+
|
|
38
|
+
## In scope
|
|
39
|
+
|
|
40
|
+
- The installers writing outside `~/.claude/skills/task-pipeline` and
|
|
41
|
+
`~/.claude/commands/task-pipeline.md`, or overwriting files without `--force`.
|
|
42
|
+
- Anything in the shipped doctrine that would lead an agent to exfiltrate secrets,
|
|
43
|
+
push to a repository the task never named, deploy without the operator's go, or
|
|
44
|
+
bypass a gate that exists to require one.
|
|
45
|
+
- Command injection or path traversal through the validator or the workflows.
|
|
46
|
+
- A CI workflow that could be made to leak repository secrets.
|
|
47
|
+
|
|
48
|
+
## Out of scope
|
|
49
|
+
|
|
50
|
+
- The behavior of the AI agent that reads the skill. Agents are non-deterministic;
|
|
51
|
+
a model ignoring an instruction is a doctrine-quality bug — please file it as a
|
|
52
|
+
normal issue.
|
|
53
|
+
- Third-party companions (`super-ux`, `context7`, `obsidian-wiki`). Report those to
|
|
54
|
+
their own maintainers.
|
|
55
|
+
- Anything requiring an attacker who already controls the operator's machine or
|
|
56
|
+
their agent's configuration.
|
|
57
|
+
|
|
58
|
+
## Hardening notes for operators
|
|
59
|
+
|
|
60
|
+
- **Deploy authorization has a floor by design.** The pipeline treats deploy,
|
|
61
|
+
publish and PR-opening as outward actions that need an explicit go, or a standing
|
|
62
|
+
authorization that names the target *and* the preconditions. Do not record a
|
|
63
|
+
blanket "do everything" in a brief — it is specifically rejected.
|
|
64
|
+
- **Writes to another repository are always proposal + PR**, never a direct push.
|
|
65
|
+
- The build stage keeps its scratch state in a git-ignored `.task-pipeline/`
|
|
66
|
+
directory; confirm that directory is ignored before you run it in a repo with
|
|
67
|
+
strict commit hooks.
|
package/SKILL-CARD.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Skill card — task-pipeline
|
|
2
|
+
|
|
3
|
+
**What a reviewer needs before deploying this skill, in one page.** The fields are
|
|
4
|
+
the registry entry Anthropic's [Skills for enterprise](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/enterprise)
|
|
5
|
+
guidance asks every organisation to keep, plus an honest pass over its risk-tier
|
|
6
|
+
table. Written so somebody who did not build this can decide, not so it looks
|
|
7
|
+
harmless.
|
|
8
|
+
|
|
9
|
+
## Registry entry
|
|
10
|
+
|
|
11
|
+
| Field | Value |
|
|
12
|
+
|---|---|
|
|
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
|
+
| **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
|
|
15
|
+
| **Version** | 1.8.1 |
|
|
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
|
+
| **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
|
+
| **Evaluation status** | Suite authored (13 evals, 5 categories). **Never executed** — see [`evals/RESULTS.md`](evals/RESULTS.md) |
|
|
19
|
+
|
|
20
|
+
## Risk-tier disclosure
|
|
21
|
+
|
|
22
|
+
Every indicator from the enterprise risk table, answered — including the ones that
|
|
23
|
+
apply.
|
|
24
|
+
|
|
25
|
+
| Indicator | Applies? | What exactly |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **Code execution** | **Yes — High** | Ships `templates/docgate.sh` (seeded into the host project as its documentation gate), `bin/task-pipeline.js` and `install.sh` (installers), `test/*.py` and `evals/run.py` (repo checks). None run automatically; the gate is seeded and run by the host project |
|
|
28
|
+
| **MCP server references** | **Yes — High** | Instructions name `context7`, `figma`, `graphify`, `wiki-query`, `wiki-update`. All optional; absence degrades a stage, never blocks one, except super-ux on a UI task |
|
|
29
|
+
| **Tool invocations** | **Yes — Medium** | Instructs bash (git, test runners, the host's lint/deploy commands), file reads and writes, and a `PreToolUse` hook example that runs the docs gate before a commit |
|
|
30
|
+
| **Filesystem access scope** | **Yes — Medium** | Reads and writes inside the host project: `docs/`, `scripts/check-docs.sh`, `.task-pipeline/` scratch, `CONTEXT.md`. Stage 5 creates and removes git worktrees. Writing to **another repository** is treated as outward and requires an explicit go |
|
|
31
|
+
| **Instruction manipulation** | No | Nothing instructs Claude to bypass safety rules, hide actions, or behave conditionally on hidden inputs. Outward and irreversible actions (deploy, publish, PR, editing a shared design file) explicitly require operator authorization |
|
|
32
|
+
| **Network access patterns** | Minimal | No `curl`/`fetch`/`requests` in shipped code. The doctrine tells the agent to fetch **library documentation** at stage 1 and to re-fetch the hook contract; both are reads of vendor docs, named in the text |
|
|
33
|
+
| **Hardcoded credentials** | No | None. Release automation uses repository secrets in CI, never files in the skill |
|
|
34
|
+
|
|
35
|
+
## What to check before you trust it
|
|
36
|
+
|
|
37
|
+
1. Read `SKILL.md` and the 23 files under `references/` — that is the whole
|
|
38
|
+
instruction surface, and every one is linked directly from `SKILL.md`.
|
|
39
|
+
2. Read `templates/docgate.sh` before seeding it; it is the only shipped script a
|
|
40
|
+
host project will run on its own repository.
|
|
41
|
+
3. Run `npm run test:all` — 53 guards, each with a negative self-test that plants a
|
|
42
|
+
defect and requires rejection.
|
|
43
|
+
4. Run `python3 evals/run.py` for the behavioural protocol, and read
|
|
44
|
+
`evals/RESULTS.md` for what has actually been observed.
|
|
45
|
+
|
|
46
|
+
## Posture, stated rather than implied
|
|
47
|
+
|
|
48
|
+
- **Separation of duties is not in place.** The author and the reviewer are the same
|
|
49
|
+
person. The enterprise guidance asks for separation; a consumer should treat this
|
|
50
|
+
repository's own review as an author's self-review and do their own.
|
|
51
|
+
- **Commits are unsigned**, so provenance rests on GitHub account control rather than
|
|
52
|
+
cryptographic signature. Integrity verification by checksum is possible today
|
|
53
|
+
(`npm pack` / tag archives) and is not automated.
|
|
54
|
+
- **Versions are pinned by git tag** and mirrored into `sshlg-skills`'s catalogue.
|
|
55
|
+
Rollback is `git checkout v<previous>` or pinning the previous plugin version;
|
|
56
|
+
the previous version is never deleted.
|
|
57
|
+
- **Behavioural evidence is missing, not merely thin.** 53 structural guards prove
|
|
58
|
+
the skill is well-formed. Until `evals/RESULTS.md` carries a dated run, nothing in
|
|
59
|
+
this repository proves it *behaves* — triggers correctly, stays quiet on a
|
|
60
|
+
question, or performs the steps it documents.
|
package/bin/task-pipeline.js
CHANGED
|
@@ -78,6 +78,29 @@ function main(argv) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
const home = os.homedir(); // respects $HOME on POSIX — tests override via env
|
|
81
|
+
|
|
82
|
+
// One channel per agent. This installer writes a PLAIN copy to
|
|
83
|
+
// ~/.claude/skills/<id>, and while the Claude Code PLUGIN channel is active that
|
|
84
|
+
// copy SHADOWS the plugin — silently serving whatever version was copied, forever.
|
|
85
|
+
// The family launcher (sshlg-skills) prunes exactly these copies for that reason,
|
|
86
|
+
// so creating one without saying so undoes the thing it is paired with.
|
|
87
|
+
const pluginDirs = [
|
|
88
|
+
path.join(home, '.claude', 'plugins', 'marketplaces', 'task-pipeline'),
|
|
89
|
+
path.join(home, '.claude', 'plugins', 'cache', 'task-pipeline'),
|
|
90
|
+
];
|
|
91
|
+
if (!force && pluginDirs.some((d) => fs.existsSync(d))) {
|
|
92
|
+
console.error(`refusing: task-pipeline is already installed as a Claude Code PLUGIN.
|
|
93
|
+
|
|
94
|
+
A plain copy in ~/.claude/skills/ shadows the plugin and keeps serving the version
|
|
95
|
+
it was copied from — the failure this family prunes for. Prefer the plugin:
|
|
96
|
+
|
|
97
|
+
claude plugin marketplace update task-pipeline
|
|
98
|
+
claude plugin update task-pipeline@task-pipeline
|
|
99
|
+
|
|
100
|
+
Rerun with --force if you deliberately want the plain copy instead.`);
|
|
101
|
+
return 3;
|
|
102
|
+
}
|
|
103
|
+
|
|
81
104
|
installOne(
|
|
82
105
|
'task-pipeline skill ',
|
|
83
106
|
skillSrc,
|
package/evals/RESULTS.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Evaluation results — task-pipeline
|
|
2
|
+
|
|
3
|
+
**Status: the suite is authored and has not been executed.** Recorded here rather
|
|
4
|
+
than left blank, because an empty results file and an unrun suite look identical,
|
|
5
|
+
and this repository's own doctrine calls that the failure — a skip is not a pass.
|
|
6
|
+
|
|
7
|
+
Running these needs a fresh session per query, per model. That is a human or agent
|
|
8
|
+
step; `evals/run.py` prints the protocol and deliberately never reports a pass it
|
|
9
|
+
did not observe.
|
|
10
|
+
|
|
11
|
+
## How to record a run
|
|
12
|
+
|
|
13
|
+
One table per date + model. Verdict is `pass` / `fail` / `partial`, and a `fail`
|
|
14
|
+
carries what actually happened, not a shrug.
|
|
15
|
+
|
|
16
|
+
```markdown
|
|
17
|
+
## 2026-08-10 · sonnet
|
|
18
|
+
|
|
19
|
+
| id | verdict | what happened |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| TRIG-01 | pass | harvest ran first, ledger written, no code before the brief |
|
|
22
|
+
| NOTRIG-02 | fail | invoked the skill for a one-character README fix |
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then act on the result the way the enterprise guidance says: declining trigger
|
|
26
|
+
accuracy → change the description; coexistence conflicts → narrow it or consolidate;
|
|
27
|
+
persistent instruction-following failures → the instruction is not prominent enough,
|
|
28
|
+
or it belongs in a check.
|
|
29
|
+
|
|
30
|
+
## Ratchet
|
|
31
|
+
|
|
32
|
+
| Metric | Value | As of |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| Evals authored | 13 | 2026-08-03 |
|
|
35
|
+
| Categories covered | 5 of 5 | 2026-08-03 |
|
|
36
|
+
| Models exercised | **0 of 3** | 2026-08-03 |
|
|
37
|
+
| Dated runs recorded | **0** | 2026-08-03 |
|
|
38
|
+
|
|
39
|
+
The bottom two numbers are the honest state of this skill's behavioural evidence.
|
|
40
|
+
Everything else in this repository is proven by 53 structural guards that check the
|
|
41
|
+
*form*; these are the only checks that would speak to the *behaviour*, and they have
|
|
42
|
+
not been run yet. Printed here so "53 of 53 green" is never read as "the skill is
|
|
43
|
+
known to work".
|
|
44
|
+
|
|
45
|
+
## Runs
|
|
46
|
+
|
|
47
|
+
_(none yet)_
|
|
Binary file
|
package/evals/run.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate the evaluation suite and print the run protocol.
|
|
3
|
+
|
|
4
|
+
**This script does not run a model, and it never reports a pass.** Anthropic's
|
|
5
|
+
guidance ships no runner for Skill evaluations ("There is not currently a built-in
|
|
6
|
+
way to run these evaluations"), and a script that claimed to have executed one
|
|
7
|
+
would be the exact failure this repository's own doctrine is written against — a
|
|
8
|
+
tool describing a world it is not looking at.
|
|
9
|
+
|
|
10
|
+
What it does:
|
|
11
|
+
* checks the suite is well-formed and covers every required category;
|
|
12
|
+
* prints each query with its expected behaviours, ready to run;
|
|
13
|
+
* checks RESULTS.md exists and says, honestly, when the suite last ran.
|
|
14
|
+
|
|
15
|
+
python3 evals/run.py # validate + print the protocol
|
|
16
|
+
python3 evals/run.py --list # ids and categories only
|
|
17
|
+
|
|
18
|
+
Zero dependencies, same as the validator.
|
|
19
|
+
"""
|
|
20
|
+
import json
|
|
21
|
+
import os
|
|
22
|
+
import re
|
|
23
|
+
import sys
|
|
24
|
+
|
|
25
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
26
|
+
SUITE = os.path.join(ROOT, "evals", "task-pipeline.evals.json")
|
|
27
|
+
RESULTS = os.path.join(ROOT, "evals", "RESULTS.md")
|
|
28
|
+
|
|
29
|
+
# The enterprise guidance requires coverage of triggering (both directions) and
|
|
30
|
+
# ambiguity. The last two are ours: instruction following is where a ten-stage
|
|
31
|
+
# skill actually fails, and coexistence is what a broad description breaks.
|
|
32
|
+
REQUIRED = ("should_trigger", "should_not_trigger", "ambiguous",
|
|
33
|
+
"instruction_following", "coexistence")
|
|
34
|
+
MIN_EVALS = 3 # Anthropic: "At least three evaluations created"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def main(argv):
|
|
38
|
+
errors = []
|
|
39
|
+
if not os.path.isfile(SUITE):
|
|
40
|
+
print(f"FAIL: no suite at {os.path.relpath(SUITE, ROOT)}")
|
|
41
|
+
return 2
|
|
42
|
+
suite = json.load(open(SUITE, encoding="utf-8"))
|
|
43
|
+
evals = suite.get("evals") or []
|
|
44
|
+
|
|
45
|
+
seen = set()
|
|
46
|
+
for e in evals:
|
|
47
|
+
where = e.get("id", "<no id>")
|
|
48
|
+
if not e.get("id"):
|
|
49
|
+
errors.append("an eval has no id")
|
|
50
|
+
elif e["id"] in seen:
|
|
51
|
+
errors.append(f"duplicate eval id {e['id']}")
|
|
52
|
+
seen.add(e.get("id"))
|
|
53
|
+
if e.get("category") not in REQUIRED:
|
|
54
|
+
errors.append(f"{where}: category {e.get('category')!r} is not one of {list(REQUIRED)}")
|
|
55
|
+
if not (e.get("query") or "").strip():
|
|
56
|
+
errors.append(f"{where}: empty query")
|
|
57
|
+
beh = e.get("expected_behavior") or []
|
|
58
|
+
if len(beh) < 2:
|
|
59
|
+
errors.append(f"{where}: needs at least two expected behaviours — one is a hope, "
|
|
60
|
+
"two is a rubric")
|
|
61
|
+
if not (e.get("why") or "").strip():
|
|
62
|
+
errors.append(f"{where}: no `why` — an eval whose failure mode is unstated "
|
|
63
|
+
"cannot tell you what broke")
|
|
64
|
+
|
|
65
|
+
if len(evals) < MIN_EVALS:
|
|
66
|
+
errors.append(f"{len(evals)} eval(s); at least {MIN_EVALS} are required")
|
|
67
|
+
covered = {e.get("category") for e in evals}
|
|
68
|
+
for cat in REQUIRED:
|
|
69
|
+
if cat not in covered:
|
|
70
|
+
errors.append(f"no eval covers {cat!r}")
|
|
71
|
+
|
|
72
|
+
if errors:
|
|
73
|
+
print("FAIL: evaluation suite invalid")
|
|
74
|
+
for e in errors:
|
|
75
|
+
print(" - " + e)
|
|
76
|
+
return 1
|
|
77
|
+
|
|
78
|
+
by_cat = {}
|
|
79
|
+
for e in evals:
|
|
80
|
+
by_cat.setdefault(e["category"], []).append(e)
|
|
81
|
+
|
|
82
|
+
if "--list" in argv:
|
|
83
|
+
for cat in REQUIRED:
|
|
84
|
+
for e in by_cat.get(cat, []):
|
|
85
|
+
print(f" {e['id']:<10} {cat:<22} {e['query'][:60]}")
|
|
86
|
+
print(f"\n{len(evals)} evals across {len(by_cat)} categories")
|
|
87
|
+
return 0
|
|
88
|
+
|
|
89
|
+
print("=" * 72)
|
|
90
|
+
print("task-pipeline evaluation protocol")
|
|
91
|
+
print("=" * 72)
|
|
92
|
+
print("Run each query in a FRESH session with the skill installed, once per")
|
|
93
|
+
print("model in", suite.get("models", []), "— effectiveness varies by model.")
|
|
94
|
+
print("Record every verdict in evals/RESULTS.md with the date and the model.")
|
|
95
|
+
print("A query you did not run is not a pass; leave it blank and say so.\n")
|
|
96
|
+
for cat in REQUIRED:
|
|
97
|
+
print(f"\n--- {cat} ---")
|
|
98
|
+
for e in by_cat.get(cat, []):
|
|
99
|
+
print(f"\n[{e['id']}] {e['query']}")
|
|
100
|
+
print(f" why: {e['why']}")
|
|
101
|
+
for b in e["expected_behavior"]:
|
|
102
|
+
print(f" [ ] {b}")
|
|
103
|
+
|
|
104
|
+
print("\n" + "=" * 72)
|
|
105
|
+
if not os.path.isfile(RESULTS):
|
|
106
|
+
print("NO RESULTS FILE — the suite has never been recorded as run.")
|
|
107
|
+
return 1
|
|
108
|
+
body = open(RESULTS, encoding="utf-8").read()
|
|
109
|
+
# Count RUN HEADINGS only, outside fenced blocks. Counting every date in the
|
|
110
|
+
# file swept up the ratchet table and the fenced example and reported five runs
|
|
111
|
+
# against zero — a reporting tool that overstates its own subject, which is the
|
|
112
|
+
# one thing this script exists not to do.
|
|
113
|
+
outside, infence = [], False
|
|
114
|
+
for ln in body.split("\n"):
|
|
115
|
+
if re.match(r"^\s*(```|~~~)", ln):
|
|
116
|
+
infence = not infence
|
|
117
|
+
continue
|
|
118
|
+
if not infence:
|
|
119
|
+
outside.append(ln)
|
|
120
|
+
runs = [l for l in outside if re.match(r"^## 20\d{2}-\d{2}-\d{2}\b", l)]
|
|
121
|
+
print(f"suite: {len(evals)} evals · recorded runs: {len(runs)}")
|
|
122
|
+
if not runs:
|
|
123
|
+
print("RESULTS.md carries no dated run — the suite is authored and unexecuted.")
|
|
124
|
+
print("OK: suite valid. Execution is a human/agent step; this script never")
|
|
125
|
+
print(" reports a pass it did not observe.")
|
|
126
|
+
return 0
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
if __name__ == "__main__":
|
|
130
|
+
sys.exit(main(sys.argv[1:]))
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_note": "Behavioural evaluations for the task-pipeline skill. Format follows Anthropic's Skill authoring guidance (skills, query, expected_behavior), extended with `id`, `category` and `why` so a failure says which dimension broke. There is no built-in runner for these upstream; `run.py` validates the suite and prints the protocol, and results are recorded in RESULTS.md. Dimensions come from the enterprise guidance: triggering accuracy, isolation, coexistence, instruction following, output quality.",
|
|
3
|
+
"skill": "task-pipeline",
|
|
4
|
+
"models": ["haiku", "sonnet", "opus"],
|
|
5
|
+
"evals": [
|
|
6
|
+
{
|
|
7
|
+
"id": "TRIG-01",
|
|
8
|
+
"category": "should_trigger",
|
|
9
|
+
"skills": ["task-pipeline"],
|
|
10
|
+
"query": "run this through the pipeline: add per-tenant rate limiting to the public API",
|
|
11
|
+
"expected_behavior": [
|
|
12
|
+
"Invokes the task-pipeline skill rather than starting to design or code inline",
|
|
13
|
+
"Runs the stage-0 knowledge harvest BEFORE the first interview question, and writes a source ledger",
|
|
14
|
+
"Asks interview questions one at a time, each with a recommended answer",
|
|
15
|
+
"Writes no implementation code before a brief is committed and confirmed"
|
|
16
|
+
],
|
|
17
|
+
"why": "The explicit invocation phrase is the primary trigger; the failure it guards is jumping to code."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "TRIG-02",
|
|
21
|
+
"category": "should_trigger",
|
|
22
|
+
"skills": ["task-pipeline"],
|
|
23
|
+
"query": "полный цикл: перенести биллинг на нового провайдера",
|
|
24
|
+
"expected_behavior": [
|
|
25
|
+
"Invokes the task-pipeline skill from the Russian trigger alias",
|
|
26
|
+
"Continues the conversation in Russian while keeping identifiers and commands untranslated",
|
|
27
|
+
"Reaches stage 0 and does not skip the grill because the request looks clear"
|
|
28
|
+
],
|
|
29
|
+
"why": "The description carries Russian trigger aliases; if they do not fire, half the operator's phrasings miss the skill."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "TRIG-03",
|
|
33
|
+
"category": "should_trigger",
|
|
34
|
+
"skills": ["task-pipeline"],
|
|
35
|
+
"query": "build a support-agent dashboard with saved views and CSV export",
|
|
36
|
+
"expected_behavior": [
|
|
37
|
+
"Invokes the skill without an explicit pipeline phrase, because the request is a substantial build",
|
|
38
|
+
"Detects the user-facing surface and surfaces super-ux at intake",
|
|
39
|
+
"Records the UI verdict in the brief"
|
|
40
|
+
],
|
|
41
|
+
"why": "Substantial work must trigger without the magic words, or the skill only helps people who already know it exists."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "NOTRIG-01",
|
|
45
|
+
"category": "should_not_trigger",
|
|
46
|
+
"skills": ["task-pipeline"],
|
|
47
|
+
"query": "what does this regex do: ^(?!.*--)[a-z0-9-]{1,63}$",
|
|
48
|
+
"expected_behavior": [
|
|
49
|
+
"Answers the question directly",
|
|
50
|
+
"Does NOT invoke the task-pipeline skill",
|
|
51
|
+
"Does NOT create a TaskList or propose an intake grill"
|
|
52
|
+
],
|
|
53
|
+
"why": "A question is not a build. Triggering here is the 'description too broad' failure the enterprise guidance names."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "NOTRIG-02",
|
|
57
|
+
"category": "should_not_trigger",
|
|
58
|
+
"skills": ["task-pipeline"],
|
|
59
|
+
"query": "fix the typo in the README heading: 'Instalation' -> 'Installation'",
|
|
60
|
+
"expected_behavior": [
|
|
61
|
+
"Makes the edit directly",
|
|
62
|
+
"Does NOT invoke the task-pipeline skill",
|
|
63
|
+
"Does NOT run a ten-stage flow for a one-character change"
|
|
64
|
+
],
|
|
65
|
+
"why": "A trivial mechanical edit run through ten gates teaches the operator to route around the skill."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "NOTRIG-03",
|
|
69
|
+
"category": "should_not_trigger",
|
|
70
|
+
"skills": ["task-pipeline"],
|
|
71
|
+
"query": "explain how our auth middleware decides which routes are public",
|
|
72
|
+
"expected_behavior": [
|
|
73
|
+
"Reads the code and explains it",
|
|
74
|
+
"Does NOT invoke the task-pipeline skill"
|
|
75
|
+
],
|
|
76
|
+
"why": "Explanation is not delivery."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "AMB-01",
|
|
80
|
+
"category": "ambiguous",
|
|
81
|
+
"skills": ["task-pipeline"],
|
|
82
|
+
"query": "clean up the error handling in the payments module",
|
|
83
|
+
"expected_behavior": [
|
|
84
|
+
"Establishes scope before choosing a route — asks whether this is a bounded fix or a refactor worth the full cycle",
|
|
85
|
+
"Does NOT silently start the ten-stage flow, and does NOT silently start editing",
|
|
86
|
+
"States which route it is taking and why"
|
|
87
|
+
],
|
|
88
|
+
"why": "The honest failure here is a silent pick in either direction; the skill should make the choice visible."
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "AMB-02",
|
|
92
|
+
"category": "ambiguous",
|
|
93
|
+
"skills": ["task-pipeline"],
|
|
94
|
+
"query": "add an `is_archived` field to the user model",
|
|
95
|
+
"expected_behavior": [
|
|
96
|
+
"Recognises that a schema field touches contracts, migrations and documentation even though the change is small",
|
|
97
|
+
"Either runs the flow or states explicitly which parts it is skipping and why",
|
|
98
|
+
"Does not treat 'small diff' as 'no decision to record'"
|
|
99
|
+
],
|
|
100
|
+
"why": "Small changes with wide blast radius are where the doc track earns its keep or gets skipped."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"id": "COEX-01",
|
|
104
|
+
"category": "coexistence",
|
|
105
|
+
"skills": ["task-pipeline", "super-ux"],
|
|
106
|
+
"query": "redesign the settings screen so the security options are easier to find",
|
|
107
|
+
"expected_behavior": [
|
|
108
|
+
"Does not steal the trigger from super-ux for what is a UX-chain task",
|
|
109
|
+
"If task-pipeline runs, it routes the UX chain to super-ux at stage 3 rather than improvising one",
|
|
110
|
+
"If super-ux runs, task-pipeline stays out of the way until there is something to build"
|
|
111
|
+
],
|
|
112
|
+
"why": "The enterprise guidance calls this out directly: a broad description steals triggers from narrower skills."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "INSTR-01",
|
|
116
|
+
"category": "instruction_following",
|
|
117
|
+
"skills": ["task-pipeline"],
|
|
118
|
+
"query": "run this through the pipeline: add a webhook retry policy. When you reach stage 0, show me what you did before your first question.",
|
|
119
|
+
"expected_behavior": [
|
|
120
|
+
"The knowledge harvest ran first and produced a source ledger with a row per source consulted, or an explicit 'none found'",
|
|
121
|
+
"The documentation inventory ran and docs/DOCMAP.md exists or was seeded",
|
|
122
|
+
"Intent was reconciled against the as-built record, with divergences named",
|
|
123
|
+
"The first interview question came AFTER all of that"
|
|
124
|
+
],
|
|
125
|
+
"why": "Phase-1 ordering is the single most skipped instruction; if it slips, every later answer is unchecked."
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "INSTR-02",
|
|
129
|
+
"category": "instruction_following",
|
|
130
|
+
"skills": ["task-pipeline"],
|
|
131
|
+
"query": "you are at stage 9 of a pipeline run that changed a status enum and an API contract. Close the stage.",
|
|
132
|
+
"expected_behavior": [
|
|
133
|
+
"Walks the propagation matrix for every change type produced, not only the sources the harvest read",
|
|
134
|
+
"Records the settled decisions under ids and flips any answered questions",
|
|
135
|
+
"Runs the documentation gate and prints its ratchet counts beside the verdict",
|
|
136
|
+
"States any check that skipped, rather than passing silently"
|
|
137
|
+
],
|
|
138
|
+
"why": "Stage 9 is where 'docs in sync' used to be unfalsifiable; this eval is what makes the replacement real."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "INSTR-03",
|
|
142
|
+
"category": "instruction_following",
|
|
143
|
+
"skills": ["task-pipeline"],
|
|
144
|
+
"query": "you are a stage-5 implementer subagent in a worktree. While building, you settled that retries use exponential backoff capped at 30s. Record it.",
|
|
145
|
+
"expected_behavior": [
|
|
146
|
+
"Does NOT write to the decision register from inside the worktree",
|
|
147
|
+
"Puts the decision in the implementer report, and in the carry-over ledger if it outlives the task",
|
|
148
|
+
"States that the orchestrator runs the Doc Loop after integration, as a single writer"
|
|
149
|
+
],
|
|
150
|
+
"why": "Two worktrees appending to one append-only register is the collision the rule exists to prevent."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "INSTR-04",
|
|
154
|
+
"category": "instruction_following",
|
|
155
|
+
"skills": ["task-pipeline"],
|
|
156
|
+
"query": "you are at stage 10. Close the run. The REQ table looks complete.",
|
|
157
|
+
"expected_behavior": [
|
|
158
|
+
"Runs the ladder walk BEFORE writing the coverage table, and turns absences into new REQ rows first",
|
|
159
|
+
"Refuses to accept 'done' without evidence, downgrading to partial instead of upgrading the claim",
|
|
160
|
+
"Confirms every check it leans on — the documentation gate included — was seen failing once against a planted defect",
|
|
161
|
+
"Writes the retrospective last: prune, stamp with the run's commit, entry only on divergence"
|
|
162
|
+
],
|
|
163
|
+
"why": "'The table looks complete' is the exact prompt under which the ladder walk gets skipped."
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.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"
|
|
@@ -14,9 +14,14 @@
|
|
|
14
14
|
"bin",
|
|
15
15
|
"plugins",
|
|
16
16
|
"cursor",
|
|
17
|
+
"evals",
|
|
17
18
|
"README.md",
|
|
19
|
+
"SKILL-CARD.md",
|
|
18
20
|
"LICENSE",
|
|
19
|
-
"CHANGELOG.md"
|
|
21
|
+
"CHANGELOG.md",
|
|
22
|
+
"CONTRIBUTING.md",
|
|
23
|
+
"SECURITY.md",
|
|
24
|
+
"CODE_OF_CONDUCT.md"
|
|
20
25
|
],
|
|
21
26
|
"repository": "github:ssheleg/task-pipeline",
|
|
22
27
|
"homepage": "https://github.com/ssheleg/task-pipeline#readme",
|
|
@@ -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.8.
|
|
5
|
+
"version": "1.8.1",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -352,7 +352,7 @@ findings are neither fixed nor parked-with-ruling at the cap.
|
|
|
352
352
|
After the last task: build a package over `MERGE_BASE`..`HEAD`
|
|
353
353
|
(`git merge-base "$BASE_BRANCH" HEAD`, where `$BASE_BRANCH` is the base recorded in
|
|
354
354
|
the stage-0 brief — never a hardcoded `main`), dispatch the whole-branch review
|
|
355
|
-
([`review.md`](review.md) → *
|
|
355
|
+
([`review.md`](review.md) → *Prompt — final whole-branch review*; on the run's model, escalation offered
|
|
356
356
|
out loud per *Models* above), and point it at the
|
|
357
357
|
ledger's deferred-minor and parked lines so it can triage what must be fixed before
|
|
358
358
|
merge.
|
|
@@ -50,7 +50,7 @@ repository — the smallest one still decides *somewhere* that a thing is true
|
|
|
50
50
|
the only choice is whether that answer is written down or re-derived by each new
|
|
51
51
|
reader. What scales down is **volume**, never the rules: a register with three
|
|
52
52
|
entries is a register, and the seeded gate is green on exactly those three
|
|
53
|
-
([`gates.md`](gates.md) → *
|
|
53
|
+
([`gates.md`](gates.md) → *Progressive arming*).
|
|
54
54
|
|
|
55
55
|
---
|
|
56
56
|
|
|
@@ -23,6 +23,8 @@ elsewhere and is not restated here:
|
|
|
23
23
|
|
|
24
24
|
- Axis A — the stage gate type
|
|
25
25
|
- Axis B — the enforcement mechanism
|
|
26
|
+
- Axis C — degrees of freedom
|
|
27
|
+
- Progressive arming
|
|
26
28
|
- Before you run a check
|
|
27
29
|
- Anatomy of a project gate
|
|
28
30
|
- Writing the check itself
|
|
@@ -70,6 +72,53 @@ disprove. Left unwritten, it is indistinguishable from an omission.
|
|
|
70
72
|
|
|
71
73
|
---
|
|
72
74
|
|
|
75
|
+
## Axis C — degrees of freedom
|
|
76
|
+
|
|
77
|
+
Axis B says how hard a rule bites. This one says how much latitude the *instruction*
|
|
78
|
+
leaves, and it is a separate choice: a low-freedom instruction guarded by nothing is
|
|
79
|
+
a wish, and a high-freedom instruction behind a blocking hook is a bottleneck.
|
|
80
|
+
|
|
81
|
+
Match the level to how **fragile** the step is, not to how important it feels:
|
|
82
|
+
|
|
83
|
+
| Level | Shape | Use when | Example here |
|
|
84
|
+
|---|---|---|---|
|
|
85
|
+
| **high** | prose direction, no prescribed sequence | many routes reach a good answer and context decides | stage 2 — the design conversation |
|
|
86
|
+
| **medium** | a named order with room inside each step | the sequence is fixed, the content is judgement | stage 0 — two phases, adaptive questions |
|
|
87
|
+
| **low** | run exactly this, in this order, no variation | the operation is fragile, irreversible, or must be identical every time | stage 5's TDD order · stage 7's deploy · stage 9's matrix walk |
|
|
88
|
+
|
|
89
|
+
The picture worth keeping is an **open field versus a narrow bridge**. In the field,
|
|
90
|
+
say where to go and let the agent find the route. On the bridge there is one safe way
|
|
91
|
+
across, and the guardrails are the instruction.
|
|
92
|
+
|
|
93
|
+
**Over-constraining costs as much as under-constraining and is harder to see.** A
|
|
94
|
+
high-freedom step written as low freedom produces an agent that follows the letter
|
|
95
|
+
past the point where the letter stopped fitting — and reports success, because it did
|
|
96
|
+
what it was told. Where a step is genuinely open, say so out loud; that sentence is
|
|
97
|
+
what stops the next reader from hardening it.
|
|
98
|
+
|
|
99
|
+
Every stage in [`stages.md`](stages.md) declares its level and its reason, on the
|
|
100
|
+
line under its heading.
|
|
101
|
+
|
|
102
|
+
## Progressive arming
|
|
103
|
+
|
|
104
|
+
A gate seeded into a young project has almost nothing to check yet, and a gate that
|
|
105
|
+
starts red teaches everyone on day one that it is noise ([`learned.md`](learned.md)
|
|
106
|
+
rule 9). So each section reports one of four states and only one of them fails:
|
|
107
|
+
|
|
108
|
+
| State | Means | Fails? |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `ok` | the check ran and passed | no |
|
|
111
|
+
| `dormant: … — no <artefact> yet` | the input does not exist yet | no |
|
|
112
|
+
| `skip: … — <why>` | the input exists, the check could not run here | no |
|
|
113
|
+
| `ERR` | the check ran and found something | **yes** |
|
|
114
|
+
|
|
115
|
+
`dormant` and `skip` are **printed, never silent** — that is the whole reason they do
|
|
116
|
+
not quietly become permanent.
|
|
117
|
+
|
|
118
|
+
They also force one more obligation on the verdict line: it must report **what the
|
|
119
|
+
run actually looked at**. Every section dormant is indistinguishable from a gate
|
|
120
|
+
blind to the shape in front of it, and exit 0 alone cannot tell those two apart.
|
|
121
|
+
|
|
73
122
|
## Before you run a check
|
|
74
123
|
|
|
75
124
|
Four preconditions. Skipping any of them turns a run into a claim.
|
|
@@ -125,7 +125,7 @@ and the commit. Silent deletion is forbidden: the record is what survives, the
|
|
|
125
125
|
instruction is what leaves.
|
|
126
126
|
|
|
127
127
|
**Print the counts beside the gate verdict**, the same way the carry-over ledger
|
|
128
|
-
does ([`audit.md`](audit.md) → *ratchet, never TODO*):
|
|
128
|
+
does ([`audit.md`](audit.md) → *What can't be fixed now becomes a ratchet, never a TODO*):
|
|
129
129
|
|
|
130
130
|
```
|
|
131
131
|
GATE 10 acceptance: PASS — 14/14 REQ verified
|
|
@@ -182,7 +182,7 @@ exactly the sentence a future reader will hit in the code and re-litigate, so a
|
|
|
182
182
|
ruling that outlives the run goes through the **Doc Loop**
|
|
183
183
|
([`documentation.md`](documentation.md)) — via the report and the ledger, written by
|
|
184
184
|
the orchestrator after integration, never by a subagent
|
|
185
|
-
([`build.md`](build.md) →
|
|
185
|
+
([`build.md`](build.md) → *4.1a Decisions settled inside a task*).
|
|
186
186
|
|
|
187
187
|
Run the final review on the **run's confirmed model** like everything else
|
|
188
188
|
([`model-tiering.md`](model-tiering.md)). It is the one review that sees the whole
|
|
@@ -53,7 +53,7 @@ never that the work was skipped quietly.
|
|
|
53
53
|
- Cross-cutting — the audit
|
|
54
54
|
|
|
55
55
|
## 0 — Intake grill — MANDATORY
|
|
56
|
-
- **Freedom: medium** — the interview adapts to the answers; its two phases and their order do not ([`gates.md`](gates.md) → *Axis
|
|
56
|
+
- **Freedom: medium** — the interview adapts to the answers; its two phases and their order do not ([`gates.md`](gates.md) → *Axis C*).
|
|
57
57
|
- **Stage 0 is not optional and not skippable.** There is no "small enough task"
|
|
58
58
|
exemption, no "the request was already clear" exemption, no starting stage 1
|
|
59
59
|
"while the operator thinks". The only sanctioned bypass is the
|
|
@@ -154,7 +154,7 @@ never that the work was skipped quietly.
|
|
|
154
154
|
reversible calls can be deferred with a note). Only then start stage 1.
|
|
155
155
|
|
|
156
156
|
## 1 — Docs study
|
|
157
|
-
- **Freedom: medium** — which sources to fetch is judgement; grounding contracts on fetched docs is not ([`gates.md`](gates.md) → *Axis
|
|
157
|
+
- **Freedom: medium** — which sources to fetch is judgement; grounding contracts on fetched docs is not ([`gates.md`](gates.md) → *Axis C*).
|
|
158
158
|
- **What:** ground every external library / API / SDK the task touches on the
|
|
159
159
|
*current* docs, before locking any contract.
|
|
160
160
|
- **Invoke:** the `context7` MCP — `context7:resolve-library-id` → `context7:query-docs`,
|
|
@@ -164,7 +164,7 @@ never that the work was skipped quietly.
|
|
|
164
164
|
not recall. Unresolvable libraries are flagged in the spec.
|
|
165
165
|
|
|
166
166
|
## 2 — Brainstorm + decompose
|
|
167
|
-
- **Freedom: high** — many designs are valid — this is the open field, and the only fixed thing is the gate ([`gates.md`](gates.md) → *Axis
|
|
167
|
+
- **Freedom: high** — many designs are valid — this is the open field, and the only fixed thing is the gate ([`gates.md`](gates.md) → *Axis C*).
|
|
168
168
|
- **How it runs: [`brainstorm.md`](brainstorm.md)** — built into this skill. Read
|
|
169
169
|
the brief first (stage 0 already answered scope/constraints/done-criteria), then
|
|
170
170
|
explore the codebase, scope-check for decomposition, one question at a time, 2–3
|
|
@@ -194,7 +194,7 @@ never that the work was skipped quietly.
|
|
|
194
194
|
contracts named with their owner.
|
|
195
195
|
|
|
196
196
|
## 3 — Spec — with UX track for user-facing tasks
|
|
197
|
-
- **Freedom: medium** — what the contract says is judgement; which contracts must be locked is a list ([`gates.md`](gates.md) → *Axis
|
|
197
|
+
- **Freedom: medium** — what the contract says is judgement; which contracts must be locked is a list ([`gates.md`](gates.md) → *Axis C*).
|
|
198
198
|
- **How it runs: [`spec.md`](spec.md)** — built into this skill: the UX-track order,
|
|
199
199
|
what the spec must lock (types, schemas, signatures, file layout, the **Global
|
|
200
200
|
Constraints** block stages 4–5 depend on), the self-review pass and the operator
|
|
@@ -250,7 +250,7 @@ never that the work was skipped quietly.
|
|
|
250
250
|
starts before this — the chain comes BEFORE interface.
|
|
251
251
|
|
|
252
252
|
## 4 — Plan
|
|
253
|
-
- **Freedom: low** — the task format is prescribed and the REQ set-comparison is mechanical ([`gates.md`](gates.md) → *Axis
|
|
253
|
+
- **Freedom: low** — the task format is prescribed and the REQ set-comparison is mechanical ([`gates.md`](gates.md) → *Axis C*).
|
|
254
254
|
- **How it runs: [`planning.md`](planning.md)** — built into this skill →
|
|
255
255
|
`docs/superpowers/plans/YYYY-MM-DD-<topic>.md` (same slug as the brief and the
|
|
256
256
|
spec). Zero-context tasks, exact
|
|
@@ -269,7 +269,7 @@ never that the work was skipped quietly.
|
|
|
269
269
|
same change (super-ux *same-change* rule).
|
|
270
270
|
|
|
271
271
|
## 5 — Dev
|
|
272
|
-
- **Freedom: low** — TDD order, worktree isolation and 'a subagent never writes the register' are the narrow bridge ([`gates.md`](gates.md) → *Axis
|
|
272
|
+
- **Freedom: low** — TDD order, worktree isolation and 'a subagent never writes the register' are the narrow bridge ([`gates.md`](gates.md) → *Axis C*).
|
|
273
273
|
- **How it runs: [`build.md`](build.md)** — built into this skill: isolate the
|
|
274
274
|
workspace (native worktree tool first, git fallback, baseline tests), keep a
|
|
275
275
|
ledger under `.task-pipeline/build/<plan>/` so a compacted context can resume,
|
|
@@ -291,7 +291,7 @@ never that the work was skipped quietly.
|
|
|
291
291
|
"leave it" recorded).
|
|
292
292
|
|
|
293
293
|
## 6 — Tests
|
|
294
|
-
- **Freedom: low** — green means the full suite, and no skip smuggles a red one past ([`gates.md`](gates.md) → *Axis
|
|
294
|
+
- **Freedom: low** — green means the full suite, and no skip smuggles a red one past ([`gates.md`](gates.md) → *Axis C*).
|
|
295
295
|
- **What:** consolidate test coverage for the change: confirm new functionality
|
|
296
296
|
has tests (written test-first in stage 5), update/repair existing tests the
|
|
297
297
|
change touched, and add edge-case + failure-path tests per DoD.
|
|
@@ -305,7 +305,7 @@ never that the work was skipped quietly.
|
|
|
305
305
|
([`audit.md`](audit.md)).
|
|
306
306
|
|
|
307
307
|
## 7 — Lint + deploy
|
|
308
|
-
- **Freedom: low** — outward and irreversible — the authorization floor is exact or the stage stops ([`gates.md`](gates.md) → *Axis
|
|
308
|
+
- **Freedom: low** — outward and irreversible — the authorization floor is exact or the stage stops ([`gates.md`](gates.md) → *Axis C*).
|
|
309
309
|
- Read host conventions (`conventions.md`): run the linter; fix failures. The suite
|
|
310
310
|
is already green from stage 6 — re-run it if code changed since. For UI projects,
|
|
311
311
|
the **super-ux linter** (`python3 docs/ux/lint.py` / `/ux-lint`) is part of lint —
|
|
@@ -320,14 +320,14 @@ never that the work was skipped quietly.
|
|
|
320
320
|
operator go. Respect deploy-from-main rules if the project mandates them.
|
|
321
321
|
|
|
322
322
|
## 8 — Post-deploy
|
|
323
|
-
- **Freedom: medium** — where the logs live varies; 'clean boot or an honest degradation report' does not ([`gates.md`](gates.md) → *Axis
|
|
323
|
+
- **Freedom: medium** — where the logs live varies; 'clean boot or an honest degradation report' does not ([`gates.md`](gates.md) → *Axis C*).
|
|
324
324
|
- Tail deploy logs / health-check per conventions. Confirm clean boot, no error
|
|
325
325
|
spike, live subsystems healthy.
|
|
326
326
|
- **GATE (auto):** clean boot confirmed, or an **honest degradation report** with next
|
|
327
327
|
steps — never silent success.
|
|
328
328
|
|
|
329
329
|
## 9 — Docs + wiki
|
|
330
|
-
- **Freedom: low** — the matrix walk and the gate are mechanical; what a doc says is not this stage's call ([`gates.md`](gates.md) → *Axis
|
|
330
|
+
- **Freedom: low** — the matrix walk and the gate are mechanical; what a doc says is not this stage's call ([`gates.md`](gates.md) → *Axis C*).
|
|
331
331
|
- **The propagation sweep runs first** ([`documentation.md`](documentation.md)).
|
|
332
332
|
The ledger below names the documents you **read**; the matrix in `docs/DOCMAP.md`
|
|
333
333
|
names the documents you **owe**. They are not the same list, and the gap between
|
|
@@ -381,7 +381,7 @@ never that the work was skipped quietly.
|
|
|
381
381
|
carry-over count printed beside this verdict**.
|
|
382
382
|
|
|
383
383
|
## 10 — Acceptance
|
|
384
|
-
- **Freedom: medium** — the walk and the evidence rule are fixed; whether it is what was asked for is the operator's ([`gates.md`](gates.md) → *Axis
|
|
384
|
+
- **Freedom: medium** — the walk and the evidence rule are fixed; whether it is what was asked for is the operator's ([`gates.md`](gates.md) → *Axis C*).
|
|
385
385
|
- **What:** the closing stage — go back to the brief and account for **every**
|
|
386
386
|
requirement. Doctrine: [`acceptance.md`](acceptance.md). Every earlier gate asks
|
|
387
387
|
"is this artifact good?"; none asks "does this still contain everything that was
|
|
@@ -82,7 +82,9 @@ find . -maxdepth 1 -type f -name '*.md' 2>/dev/null | sort >> "$TMP/files" || tr
|
|
|
82
82
|
FILE_COUNT=$(wc -l < "$TMP/files" | tr -d ' ')
|
|
83
83
|
|
|
84
84
|
if [ "$FILE_COUNT" = "0" ]; then
|
|
85
|
-
echo "FAIL: documentation gate — no markdown found
|
|
85
|
+
echo "FAIL: documentation gate — no markdown found in $DOCS_DIR/ or the repository root."
|
|
86
|
+
echo " Seed the doc map and the registers first (task-pipeline stage 0, phase 1b),"
|
|
87
|
+
echo " or point DOCS_DIR at wherever this project keeps its documentation."
|
|
86
88
|
exit 1
|
|
87
89
|
fi
|
|
88
90
|
|