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/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.8.0",
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.8.0",
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 any substantial feature, fix or build should follow the disciplined cycle rather than ad-hoc coding, or on 'run this through the pipeline' / 'прогони по конвейеру', 'the full cycle' / 'полный цикл', /task-pipeline. 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 (most capable available, never a hardcoded id); reads host conventions so it stays project-agnostic."
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) → *Final review*; on the run's model, escalation offered
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) → *progressive arming*).
53
+ ([`gates.md`](gates.md) → *Progressive arming*).
54
54
 
55
55
  ---
56
56