task-pipeline-skill 1.8.0 → 1.9.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 +129 -0
- package/CODE_OF_CONDUCT.md +38 -0
- package/CONTRIBUTING.md +215 -0
- package/README.md +20 -1
- package/SECURITY.md +67 -0
- package/SKILL-CARD.md +60 -0
- package/bin/task-pipeline.js +23 -0
- package/evals/RESULTS.md +68 -0
- package/evals/__pycache__/run.cpython-314.pyc +0 -0
- package/evals/run.py +130 -0
- package/evals/task-pipeline.evals.json +225 -0
- package/package.json +7 -2
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +4 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/adoption.md +210 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.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 +16 -3
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,225 @@
|
|
|
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": [
|
|
5
|
+
"haiku",
|
|
6
|
+
"sonnet",
|
|
7
|
+
"opus"
|
|
8
|
+
],
|
|
9
|
+
"evals": [
|
|
10
|
+
{
|
|
11
|
+
"id": "TRIG-01",
|
|
12
|
+
"category": "should_trigger",
|
|
13
|
+
"skills": [
|
|
14
|
+
"task-pipeline"
|
|
15
|
+
],
|
|
16
|
+
"query": "run this through the pipeline: add per-tenant rate limiting to the public API",
|
|
17
|
+
"expected_behavior": [
|
|
18
|
+
"Invokes the task-pipeline skill rather than starting to design or code inline",
|
|
19
|
+
"Runs the stage-0 knowledge harvest BEFORE the first interview question, and writes a source ledger",
|
|
20
|
+
"Asks interview questions one at a time, each with a recommended answer",
|
|
21
|
+
"Writes no implementation code before a brief is committed and confirmed"
|
|
22
|
+
],
|
|
23
|
+
"why": "The explicit invocation phrase is the primary trigger; the failure it guards is jumping to code."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "TRIG-02",
|
|
27
|
+
"category": "should_trigger",
|
|
28
|
+
"skills": [
|
|
29
|
+
"task-pipeline"
|
|
30
|
+
],
|
|
31
|
+
"query": "полный цикл: перенести биллинг на нового провайдера",
|
|
32
|
+
"expected_behavior": [
|
|
33
|
+
"Invokes the task-pipeline skill from the Russian trigger alias",
|
|
34
|
+
"Continues the conversation in Russian while keeping identifiers and commands untranslated",
|
|
35
|
+
"Reaches stage 0 and does not skip the grill because the request looks clear"
|
|
36
|
+
],
|
|
37
|
+
"why": "The description carries Russian trigger aliases; if they do not fire, half the operator's phrasings miss the skill."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "TRIG-03",
|
|
41
|
+
"category": "should_trigger",
|
|
42
|
+
"skills": [
|
|
43
|
+
"task-pipeline"
|
|
44
|
+
],
|
|
45
|
+
"query": "build a support-agent dashboard with saved views and CSV export",
|
|
46
|
+
"expected_behavior": [
|
|
47
|
+
"Invokes the skill without an explicit pipeline phrase, because the request is a substantial build",
|
|
48
|
+
"Detects the user-facing surface and surfaces super-ux at intake",
|
|
49
|
+
"Records the UI verdict in the brief"
|
|
50
|
+
],
|
|
51
|
+
"why": "Substantial work must trigger without the magic words, or the skill only helps people who already know it exists."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "NOTRIG-01",
|
|
55
|
+
"category": "should_not_trigger",
|
|
56
|
+
"skills": [
|
|
57
|
+
"task-pipeline"
|
|
58
|
+
],
|
|
59
|
+
"query": "what does this regex do: ^(?!.*--)[a-z0-9-]{1,63}$",
|
|
60
|
+
"expected_behavior": [
|
|
61
|
+
"Answers the question directly",
|
|
62
|
+
"Does NOT invoke the task-pipeline skill",
|
|
63
|
+
"Does NOT create a TaskList or propose an intake grill"
|
|
64
|
+
],
|
|
65
|
+
"why": "A question is not a build. Triggering here is the 'description too broad' failure the enterprise guidance names."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "NOTRIG-02",
|
|
69
|
+
"category": "should_not_trigger",
|
|
70
|
+
"skills": [
|
|
71
|
+
"task-pipeline"
|
|
72
|
+
],
|
|
73
|
+
"query": "fix the typo in the README heading: 'Instalation' -> 'Installation'",
|
|
74
|
+
"expected_behavior": [
|
|
75
|
+
"Makes the edit directly",
|
|
76
|
+
"Does NOT invoke the task-pipeline skill",
|
|
77
|
+
"Does NOT run a ten-stage flow for a one-character change"
|
|
78
|
+
],
|
|
79
|
+
"why": "A trivial mechanical edit run through ten gates teaches the operator to route around the skill."
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "NOTRIG-03",
|
|
83
|
+
"category": "should_not_trigger",
|
|
84
|
+
"skills": [
|
|
85
|
+
"task-pipeline"
|
|
86
|
+
],
|
|
87
|
+
"query": "explain how our auth middleware decides which routes are public",
|
|
88
|
+
"expected_behavior": [
|
|
89
|
+
"Reads the code and explains it",
|
|
90
|
+
"Does NOT invoke the task-pipeline skill"
|
|
91
|
+
],
|
|
92
|
+
"why": "Explanation is not delivery."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "AMB-01",
|
|
96
|
+
"category": "ambiguous",
|
|
97
|
+
"skills": [
|
|
98
|
+
"task-pipeline"
|
|
99
|
+
],
|
|
100
|
+
"query": "clean up the error handling in the payments module",
|
|
101
|
+
"expected_behavior": [
|
|
102
|
+
"Establishes scope before choosing a route — asks whether this is a bounded fix or a refactor worth the full cycle",
|
|
103
|
+
"Does NOT silently start the ten-stage flow, and does NOT silently start editing",
|
|
104
|
+
"States which route it is taking and why"
|
|
105
|
+
],
|
|
106
|
+
"why": "The honest failure here is a silent pick in either direction; the skill should make the choice visible."
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "AMB-02",
|
|
110
|
+
"category": "ambiguous",
|
|
111
|
+
"skills": [
|
|
112
|
+
"task-pipeline"
|
|
113
|
+
],
|
|
114
|
+
"query": "add an `is_archived` field to the user model",
|
|
115
|
+
"expected_behavior": [
|
|
116
|
+
"Recognises that a schema field touches contracts, migrations and documentation even though the change is small",
|
|
117
|
+
"Either runs the flow or states explicitly which parts it is skipping and why",
|
|
118
|
+
"Does not treat 'small diff' as 'no decision to record'"
|
|
119
|
+
],
|
|
120
|
+
"why": "Small changes with wide blast radius are where the doc track earns its keep or gets skipped."
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id": "COEX-01",
|
|
124
|
+
"category": "coexistence",
|
|
125
|
+
"skills": [
|
|
126
|
+
"task-pipeline",
|
|
127
|
+
"super-ux"
|
|
128
|
+
],
|
|
129
|
+
"query": "redesign the settings screen so the security options are easier to find",
|
|
130
|
+
"expected_behavior": [
|
|
131
|
+
"Does not steal the trigger from super-ux for what is a UX-chain task",
|
|
132
|
+
"If task-pipeline runs, it routes the UX chain to super-ux at stage 3 rather than improvising one",
|
|
133
|
+
"If super-ux runs, task-pipeline stays out of the way until there is something to build"
|
|
134
|
+
],
|
|
135
|
+
"why": "The enterprise guidance calls this out directly: a broad description steals triggers from narrower skills."
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "INSTR-01",
|
|
139
|
+
"category": "instruction_following",
|
|
140
|
+
"skills": [
|
|
141
|
+
"task-pipeline"
|
|
142
|
+
],
|
|
143
|
+
"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.",
|
|
144
|
+
"expected_behavior": [
|
|
145
|
+
"The knowledge harvest ran first and produced a source ledger with a row per source consulted, or an explicit 'none found'",
|
|
146
|
+
"The documentation inventory ran and docs/DOCMAP.md exists or was seeded",
|
|
147
|
+
"Intent was reconciled against the as-built record, with divergences named",
|
|
148
|
+
"The first interview question came AFTER all of that"
|
|
149
|
+
],
|
|
150
|
+
"why": "Phase-1 ordering is the single most skipped instruction; if it slips, every later answer is unchecked."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "INSTR-02",
|
|
154
|
+
"category": "instruction_following",
|
|
155
|
+
"skills": [
|
|
156
|
+
"task-pipeline"
|
|
157
|
+
],
|
|
158
|
+
"query": "you are at stage 9 of a pipeline run that changed a status enum and an API contract. Close the stage.",
|
|
159
|
+
"expected_behavior": [
|
|
160
|
+
"Walks the propagation matrix for every change type produced, not only the sources the harvest read",
|
|
161
|
+
"Records the settled decisions under ids and flips any answered questions",
|
|
162
|
+
"Runs the documentation gate and prints its ratchet counts beside the verdict",
|
|
163
|
+
"States any check that skipped, rather than passing silently"
|
|
164
|
+
],
|
|
165
|
+
"why": "Stage 9 is where 'docs in sync' used to be unfalsifiable; this eval is what makes the replacement real."
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "INSTR-03",
|
|
169
|
+
"category": "instruction_following",
|
|
170
|
+
"skills": [
|
|
171
|
+
"task-pipeline"
|
|
172
|
+
],
|
|
173
|
+
"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.",
|
|
174
|
+
"expected_behavior": [
|
|
175
|
+
"Does NOT write to the decision register from inside the worktree",
|
|
176
|
+
"Puts the decision in the implementer report, and in the carry-over ledger if it outlives the task",
|
|
177
|
+
"States that the orchestrator runs the Doc Loop after integration, as a single writer"
|
|
178
|
+
],
|
|
179
|
+
"why": "Two worktrees appending to one append-only register is the collision the rule exists to prevent."
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"id": "INSTR-04",
|
|
183
|
+
"category": "instruction_following",
|
|
184
|
+
"skills": [
|
|
185
|
+
"task-pipeline"
|
|
186
|
+
],
|
|
187
|
+
"query": "you are at stage 10. Close the run. The REQ table looks complete.",
|
|
188
|
+
"expected_behavior": [
|
|
189
|
+
"Runs the ladder walk BEFORE writing the coverage table, and turns absences into new REQ rows first",
|
|
190
|
+
"Refuses to accept 'done' without evidence, downgrading to partial instead of upgrading the claim",
|
|
191
|
+
"Confirms every check it leans on — the documentation gate included — was seen failing once against a planted defect",
|
|
192
|
+
"Writes the retrospective last: prune, stamp with the run's commit, entry only on divergence"
|
|
193
|
+
],
|
|
194
|
+
"why": "'The table looks complete' is the exact prompt under which the ladder walk gets skipped."
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"id": "TRIG-04",
|
|
198
|
+
"category": "should_trigger",
|
|
199
|
+
"skills": [
|
|
200
|
+
"task-pipeline"
|
|
201
|
+
],
|
|
202
|
+
"query": "перепиши модуль экспорта на потоковую выдачу, он не держит большие выгрузки",
|
|
203
|
+
"expected_behavior": [
|
|
204
|
+
"Invokes the skill from a plain Russian refactor request with no pipeline phrase — the work changes the repository, which is the boundary",
|
|
205
|
+
"Runs stage 0 before touching code",
|
|
206
|
+
"Does not treat 'it's just a refactor' as an exemption from the brief"
|
|
207
|
+
],
|
|
208
|
+
"why": "Default-on is only real if it fires on ordinary work phrased ordinarily; a skill that needs magic words helps only people who already know it exists."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"id": "NOTRIG-04",
|
|
212
|
+
"category": "should_not_trigger",
|
|
213
|
+
"skills": [
|
|
214
|
+
"task-pipeline"
|
|
215
|
+
],
|
|
216
|
+
"query": "перепиши модуль экспорта на потоковую выдачу, без пайплайна",
|
|
217
|
+
"expected_behavior": [
|
|
218
|
+
"Does NOT invoke the skill, despite the task being repo-changing and otherwise qualifying",
|
|
219
|
+
"Says out loud that the cycle was skipped because the operator opted out",
|
|
220
|
+
"Does the work directly"
|
|
221
|
+
],
|
|
222
|
+
"why": "The opt-out phrase is the release valve that makes default-on acceptable. If it does not work, the boundary is a trap rather than a default."
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.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"
|
|
@@ -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.
|
|
5
|
+
"version": "1.9.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-pipeline
|
|
3
|
-
description: "Runs a substantial task through a full delivery pipeline: an intake grill that expands the request into a locked brief, then docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy check, docs/wiki sync and acceptance — gated stages whose doctrine ships inside this skill (no required companions). Use when
|
|
3
|
+
description: "Runs a substantial task through a full delivery pipeline: an intake grill that expands the request into a locked brief, then docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy check, docs/wiki sync and acceptance — gated stages whose doctrine ships inside this skill (no required companions). Use when work changes the repository — a feature, fix, refactor, migration, integration, rewrite, adoption or hardening; фича, фикс, рефактор, миграция, интеграция, доработать, починить, внедрить — or on 'run this through the pipeline' / 'прогони по конвейеру', 'the full cycle' / 'полный цикл', /task-pipeline. Not for: answering a question, explaining or reading code, a typo or a one-line edit — say 'без пайплайна' / 'quick' to opt out. The grill is mandatory and front-loads every decision, so stages 1→10 run without mid-flight questions; documentation is a deliverable with its own gate; recommends super-ux for user-facing work; confirms one model up front, never a hardcoded id."
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -61,6 +61,7 @@ gate stops until it is installed.
|
|
|
61
61
|
| 10 Acceptance (REQ close-out) | [`references/acceptance.md`](references/acceptance.md) |
|
|
62
62
|
| 10 Retrospective (the run's last act) | [`references/retrospective.md`](references/retrospective.md) |
|
|
63
63
|
| 10 + any audit (what's *missing*) | [`references/audit.md`](references/audit.md) |
|
|
64
|
+
| **first run in a project** (new or existing) | [`references/adoption.md`](references/adoption.md) |
|
|
64
65
|
| any repeating loop | [`references/loop-guard.md`](references/loop-guard.md) |
|
|
65
66
|
|
|
66
67
|
**Optional bridge.** If the operator already runs an equivalent skill set (e.g.
|
|
@@ -331,6 +332,8 @@ automation is on — `pipeline.schema.json` is the only contract.
|
|
|
331
332
|
- `references/tdd.md` — stages 5–6: the iron law, red/green/refactor, the suite gate
|
|
332
333
|
- `references/stages.md` — per-stage detail + exact gate criteria + gate types
|
|
333
334
|
- `references/model-tiering.md` — model map, ids, the `/model` reminder mechanic, override
|
|
335
|
+
- `references/adoption.md` — the first run in a project: greenfield seeding, and the
|
|
336
|
+
brownfield walkthrough whose third step baselines the ratchets at today
|
|
334
337
|
- `references/conventions.md` — how stages 6–10 read the host project's CLAUDE.md
|
|
335
338
|
- `references/companion-skills.md` — companion skills, install lines, preflight recommendation
|
|
336
339
|
- `references/artifacts.md` — the canonical document/artifact layout per stage
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Adoption — bringing a project onto the pipeline
|
|
2
|
+
|
|
3
|
+
**One job: get a repository to the state where stage 0 has something true to read.**
|
|
4
|
+
The pipeline assumes a documentation system exists or gets seeded
|
|
5
|
+
([`documentation.md`](documentation.md)). This file is what to do on the first run in
|
|
6
|
+
a project — and the two entry conditions are not the same problem.
|
|
7
|
+
|
|
8
|
+
## Contents
|
|
9
|
+
|
|
10
|
+
- Two entry conditions
|
|
11
|
+
- A new project — the seed is the whole of it
|
|
12
|
+
- An existing project — the register starts today
|
|
13
|
+
- Why history is not back-filled
|
|
14
|
+
- What good looks like the day after
|
|
15
|
+
- Rationalizations
|
|
16
|
+
|
|
17
|
+
## Two entry conditions
|
|
18
|
+
|
|
19
|
+
| | Greenfield | Brownfield |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| What exists | nothing, or a README | code, history, opinions, and docs that are partly true |
|
|
22
|
+
| The hard part | none — seeding is mechanical | **the decisions already exist and none of them are written down** |
|
|
23
|
+
| Failure if done wrong | a register nobody starts using | a gate that is red on day one, switched off on day two |
|
|
24
|
+
| First run's deliverable | the feature, with the system seeded on the way | **the system itself** — adoption is its own run |
|
|
25
|
+
|
|
26
|
+
**On a brownfield project, adoption is a run, not a preamble.** Give it a brief, a
|
|
27
|
+
REQ table and an acceptance, exactly like a feature. A doc system introduced as a
|
|
28
|
+
side effect of somebody else's task is a doc system with no owner.
|
|
29
|
+
|
|
30
|
+
## A new project — the seed is the whole of it
|
|
31
|
+
|
|
32
|
+
Stage 0 phase 1b already does it before the first interview question. Nothing to
|
|
33
|
+
prepare:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
docs/DOCMAP.md the map: registers, single homes, propagation matrix, gates, ratchets
|
|
37
|
+
docs/DECISIONS.md the register — DEC-####, append-only
|
|
38
|
+
docs/OPEN_QUESTIONS.md OQ-####, closed status vocabulary
|
|
39
|
+
scripts/check-docs.sh the gate, ten sections
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Three things are true on day one and worth knowing:
|
|
43
|
+
|
|
44
|
+
- **The gate is green immediately.** Sections whose input does not exist yet print
|
|
45
|
+
`dormant`, which is visible and passing ([`gates.md`](gates.md) → *Progressive
|
|
46
|
+
arming*). The skill proves this mechanically: its own validator seeds a scratch
|
|
47
|
+
project from these templates and requires exit `0`.
|
|
48
|
+
- **Both floors are `0`,** because there is no history to forgive.
|
|
49
|
+
- **The register's first entry is the decision to document this way.** A register
|
|
50
|
+
that starts with a real entry is a register somebody has already used once.
|
|
51
|
+
|
|
52
|
+
Then run the task. There is no separate adoption step.
|
|
53
|
+
|
|
54
|
+
## An existing project — the register starts today
|
|
55
|
+
|
|
56
|
+
Seven steps. Step 3 is the one that decides whether adoption survives contact with
|
|
57
|
+
the repository.
|
|
58
|
+
|
|
59
|
+
### Step 1 · Inventory — what is already here
|
|
60
|
+
|
|
61
|
+
Answer the four questions of [`documentation.md`](documentation.md) against reality,
|
|
62
|
+
not against the templates:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ls docs/DECISIONS.md docs/adr/ docs/OPEN_QUESTIONS.md docs/DOCMAP.md 2>/dev/null
|
|
66
|
+
ls scripts/check-docs.sh .github/workflows/ 2>/dev/null
|
|
67
|
+
grep -rl "ADR\|decision record\|DEC-" docs/ README.md CONTRIBUTING.md 2>/dev/null | head
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**One decision home, and you are looking for the one that already exists.** A
|
|
71
|
+
populated `docs/adr/` *is* the register — record it in the doc map and use it. Never
|
|
72
|
+
seed a second one beside it; that is the fork the SSOT rule exists to prevent.
|
|
73
|
+
|
|
74
|
+
A project whose decisions live in a CHANGELOG with reasons, or in commit messages
|
|
75
|
+
nobody will migrate, has a decision home too. Write down which it is. The choice
|
|
76
|
+
being *unrecorded* is the defect, not the choice.
|
|
77
|
+
|
|
78
|
+
### Step 2 · Seed what is missing
|
|
79
|
+
|
|
80
|
+
Usually the map and the gate; often the register already exists in some shape.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cp <skill>/templates/docmap.md docs/DOCMAP.md # only if absent
|
|
84
|
+
cp <skill>/templates/docgate.sh scripts/check-docs.sh # only if absent
|
|
85
|
+
chmod +x scripts/check-docs.sh
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Seeding never overwrites.** An existing brief, register or map is the project's
|
|
89
|
+
memory; the template is a skeleton.
|
|
90
|
+
|
|
91
|
+
### Step 3 · Baseline the ratchets — the step that decides adoption
|
|
92
|
+
|
|
93
|
+
Run the gate **before** deciding anything, and read what it actually says:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bash scripts/check-docs.sh; echo "exit=$?"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
On a repository with history this is red, often loudly — the practice this skill
|
|
100
|
+
comes from measured **162 missing propagations across 73 decisions** on its first
|
|
101
|
+
run. That number is not a to-do list. Fixing it blind would add 162 citations nobody
|
|
102
|
+
verified, and failing on it every day makes the gate something people switch off,
|
|
103
|
+
which costs more than the rows it would have caught.
|
|
104
|
+
|
|
105
|
+
So set the floors to **today**, and only ever lower them:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# PROP_FLOOR is an ID THRESHOLD: entries numbered >= it must have propagated.
|
|
109
|
+
# Set it to the next free id — from now on the rule binds, and the history
|
|
110
|
+
# becomes one printed number.
|
|
111
|
+
PROP_FLOOR=$(grep -o 'Next free ID:\**\s*`\?DEC-[0-9]*' docs/DECISIONS.md \
|
|
112
|
+
| grep -o '[0-9]*$' | sed 's/^0*//')
|
|
113
|
+
|
|
114
|
+
# RESIDUE_FLOOR is a COUNT: unmarked citations of retired decisions, as measured
|
|
115
|
+
# right now.
|
|
116
|
+
RESIDUE_FLOOR=$(bash scripts/check-docs.sh 2>&1 \
|
|
117
|
+
| grep -o 'residue [0-9]*' | grep -o '[0-9]*' | head -1)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Write both into the top of `scripts/check-docs.sh` and into `docs/DOCMAP.md` →
|
|
121
|
+
*Ratchets*, with the date. Re-run; the gate is now **green on today's state** and
|
|
122
|
+
red only on what happens next.
|
|
123
|
+
|
|
124
|
+
**Why this is not cheating.** A ratchet is a named, counted set that may only shrink,
|
|
125
|
+
printed beside every verdict ([`audit.md`](audit.md) → *What can't be fixed now
|
|
126
|
+
becomes a ratchet, never a TODO*). The backlog stays visible on every single run —
|
|
127
|
+
it just stops blocking work it was never going to fix today. A gate that starts red
|
|
128
|
+
teaches everyone on day one that it is noise
|
|
129
|
+
(`references/learned.md` rules 9 and 10).
|
|
130
|
+
|
|
131
|
+
### Step 4 · Build the propagation matrix
|
|
132
|
+
|
|
133
|
+
Not from the template — from what this project actually has. The five steps are in
|
|
134
|
+
[`documentation.md`](documentation.md) → *The propagation matrix*. Start with three
|
|
135
|
+
rows you can name today; a matrix with three true rows beats one with twenty
|
|
136
|
+
imported ones.
|
|
137
|
+
|
|
138
|
+
The third column is not optional: name the check that would notice, or write
|
|
139
|
+
`review` **with the one-line reason no check can decide it**.
|
|
140
|
+
|
|
141
|
+
### Step 5 · Record the adoption itself
|
|
142
|
+
|
|
143
|
+
The first entry in the register is the decision to adopt — regime, decision home,
|
|
144
|
+
where the map lives, what the floors were set to and on what date. It costs two
|
|
145
|
+
minutes and it is the cheapest possible demonstration that the register works, to
|
|
146
|
+
the next person who wonders whether anyone actually uses it.
|
|
147
|
+
|
|
148
|
+
### Step 6 · Arm the gate
|
|
149
|
+
|
|
150
|
+
Local first, then the one that binds people who never run it locally:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
echo 'bash scripts/check-docs.sh' >> .git/hooks/pre-commit # local, skippable
|
|
154
|
+
# CI: add the same line to the workflow that already runs the tests
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Optionally at agent time, which is the only rung that can stop a bad edit *before*
|
|
158
|
+
it lands — `templates/hooks.example.json`, and read
|
|
159
|
+
[`hooks.md`](hooks.md) first for the fail-open hazard.
|
|
160
|
+
|
|
161
|
+
### Step 7 · Several agents — add the leases
|
|
162
|
+
|
|
163
|
+
Only when more than one agent works the repository. Then the registers become shared
|
|
164
|
+
state ([`documentation.md`](documentation.md) → *Registers are shared state*) and a
|
|
165
|
+
coordination tool arbitrates: `guardedFiles` must list every register **plus
|
|
166
|
+
`docs/DOCMAP.md` and `docs/superpowers/retro.md`**, which are equally shared and
|
|
167
|
+
equally lossy under a concurrent write.
|
|
168
|
+
|
|
169
|
+
Without such a tool the run is **`ungated`** and must say so. The discipline still
|
|
170
|
+
applies; only the arbitration is missing.
|
|
171
|
+
|
|
172
|
+
## Why history is not back-filled
|
|
173
|
+
|
|
174
|
+
The decisions already exist — in the git log, in the code, in somebody's memory. The
|
|
175
|
+
temptation is to reconstruct them into the register so it looks complete.
|
|
176
|
+
|
|
177
|
+
Don't. A reconstructed decision carries a *guess* about why it was made, in a
|
|
178
|
+
register whose whole value is that entries are true. One invented rationale is worse
|
|
179
|
+
than a hundred absent ones, because absent ones are visibly absent and an invented
|
|
180
|
+
one is indistinguishable from a real one forever.
|
|
181
|
+
|
|
182
|
+
**The rule: an old decision enters the register the day somebody is about to
|
|
183
|
+
contradict it.** At that moment the reason is being discussed anyway, the person
|
|
184
|
+
holding the context is in the room, and the entry writes itself honestly — with the
|
|
185
|
+
new decision beside it.
|
|
186
|
+
|
|
187
|
+
## What good looks like the day after
|
|
188
|
+
|
|
189
|
+
- `bash scripts/check-docs.sh` exits `0`, prints its ratchet counts, and says which
|
|
190
|
+
sections were `dormant` or `skipped`.
|
|
191
|
+
- `docs/DOCMAP.md` answers the four questions, and its propagation matrix has no
|
|
192
|
+
empty *Checked by* cell.
|
|
193
|
+
- The register has at least one entry: the adoption.
|
|
194
|
+
- The gate runs in CI, not only on the adopter's laptop.
|
|
195
|
+
- The next task runs through the pipeline normally, and stage 9 has a matrix to walk
|
|
196
|
+
instead of a sentence to interpret.
|
|
197
|
+
|
|
198
|
+
Anything not true yet is a carry-over row with a home, not a promise.
|
|
199
|
+
|
|
200
|
+
## Rationalizations
|
|
201
|
+
|
|
202
|
+
| Excuse | Reality |
|
|
203
|
+
|---|---|
|
|
204
|
+
| "We'll adopt it properly when things calm down" | The backlog only grows, and the floors you would set today are the smallest numbers you will ever get to set. |
|
|
205
|
+
| "The gate is red, this clearly doesn't fit our repo" | The gate is red because it is measuring history nobody promised to fix. That is what step 3 is for, and it takes one command. |
|
|
206
|
+
| "Let's back-fill the last two years of decisions first" | Then the register's first hundred entries are guesses, and nobody can tell them from the real ones. Start today; back-fill exactly one entry at the moment it is contradicted. |
|
|
207
|
+
| "We already have ADRs, so we need to migrate to DECISIONS.md" | You do not. An existing ADR set *is* the register. Migrating is its own decision with its own entry — never a side effect of adopting. |
|
|
208
|
+
| "We'll set the floors to zero, it's more honest" | It is more honest for about a day, after which the gate is disabled and you have neither the floor nor the check. A printed backlog is the honest thing that survives. |
|
|
209
|
+
| "The matrix needs to be complete before it's useful" | Three true rows catch three real classes. Twenty imported rows catch nothing and teach everyone that the matrix is decoration. |
|
|
210
|
+
| "One agent works here, so leases are overkill" | Correct — skip step 7 and say so. Adopting coordination nobody needs is how a project learns to route around the parts it does need. |
|
|
@@ -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.
|
|
@@ -47,7 +47,7 @@ better, plus one that is required only for user-facing work.
|
|
|
47
47
|
| **Figma** (MCP) | stage 3 UX track, when the project designs visually — super-ux mirrors each `SCR-` screen/state into a frame | Optional, **UI + Figma-on only**. Absent → super-ux degrades to text-only *by itself and never blocks*, so shipping a UI feature with no mockups becomes a silent scope call — which is why the stage-0 sweep decides it | connect the Figma MCP server (`/mcp`, or your claude.ai connectors) |
|
|
48
48
|
| **[obsidian-wiki](https://github.com/ar9av/obsidian-wiki)** (`wiki-query`, `wiki-update`) | **stage 0 harvest** (query what's already known) **+ stage 9 sync** | **Recommended** — never a gate; absent → harvest runs on repo docs alone | `pip install obsidian-wiki` → `obsidian-wiki setup --vault /path/to/your/vault` |
|
|
49
49
|
| **[graphify](https://github.com/Graphify-Labs/graphify)** (`/graphify`, `graphify query\|affected\|god-nodes`) | **stage 0 harvest** (reach: what calls this, what breaks if it moves) **+ stage 9 refresh + the graph↔docs divergence check** ([`knowledge-graph.md`](knowledge-graph.md)) | **Recommended** — never a gate; absent → the harvest greps instead, and the divergence axis is unavailable | `uv tool install graphifyy` → `graphify install` → `/graphify .` |
|
|
50
|
-
| **[agent-sync](https://github.com/ssheleg/agent-sync)** (`/agent-sync`) | **guarded registers** — a lease before writing one, `reserve` before minting an id, `reconcile`/`record` for intent vs as-built, and `finish` for the stage-10 multi-repository close-out ([`documentation.md`](documentation.md)) | **Recommended** — never a gate. Absent → the run is **`ungated`** and must say so out loud; the discipline still applies, only the arbitration is missing | `npx sshlg-skills install` |
|
|
50
|
+
| **[agent-sync](https://github.com/ssheleg/agent-sync)** (`/agent-sync`, **≥ 1.3.0** — `finish` did not exist before it, so an older install turns the stage-10 close-out into a command that is not there) | **guarded registers** — a lease before writing one, `reserve` before minting an id, `reconcile`/`record` for intent vs as-built, and `finish` for the stage-10 multi-repository close-out ([`documentation.md`](documentation.md)) | **Recommended** — never a gate. Absent → the run is **`ungated`** and must say so out loud; the discipline still applies, only the arbitration is missing | `npx sshlg-skills install` |
|
|
51
51
|
| ~~superpowers~~ | — | **Not a dependency.** Stages 2/4/5/6 run on the built-in doctrine above. See *Optional bridge* | — |
|
|
52
52
|
| ~~grill-me / grilling~~ | — | **Not a dependency.** The stage-0 grill is built in (`references/grill.md`) | — |
|
|
53
53
|
|
|
@@ -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
|
|