task-pipeline-skill 1.3.1 → 1.4.2
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 +91 -0
- package/README.md +22 -3
- package/package.json +4 -2
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +7 -5
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/learned.md +135 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.4.2 — 2026-07-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **`pipeline.schema.json` identified itself with a URL that 404s.** The `$id`
|
|
7
|
+
read `https://github.com/ssheleg/task-pipeline/pipeline.schema.json` — a path
|
|
8
|
+
that has never existed (no `blob/main`, wrong depth). This file is installed
|
|
9
|
+
into `~/.claude/skills/task-pipeline/`, so every install carried a schema
|
|
10
|
+
whose declared identity could not be fetched by anything resolving it. Now the
|
|
11
|
+
raw URL that actually serves the file, matching `agent-sync`'s convention.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- `license: MIT` declared in the `marketplace.json` plugin entry and in the
|
|
15
|
+
skill's front matter — the `LICENSE` file was invisible to both surfaces.
|
|
16
|
+
|
|
17
|
+
## v1.4.1 — 2026-07-30
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- `agent-sync` moved to **`ssheleg/agent-sync`**. The three places this skill
|
|
21
|
+
links to it — `SKILL.md`, `references/stages.md`, `references/acceptance.md` —
|
|
22
|
+
now point at the new owner rather than relying on GitHub's redirect.
|
|
23
|
+
|
|
24
|
+
## v1.4.0 — 2026-07-29
|
|
25
|
+
|
|
26
|
+
### `references/learned.md` — fourteen rules earned by failure, each with its incident
|
|
27
|
+
|
|
28
|
+
Taught to the pipeline by a real build: a 229-decision specification across four repositories with
|
|
29
|
+
several agents working at once. Every rule names the failure that produced it, because a rule with
|
|
30
|
+
no incident behind it is somebody's preference and gets argued with at the worst moment.
|
|
31
|
+
|
|
32
|
+
The ones that cost the most, now gate criteria rather than advice:
|
|
33
|
+
|
|
34
|
+
- **A gate's exit code is part of its output.** One printed `FAIL` and returned `0`; CI had been
|
|
35
|
+
green over it for an unknown period.
|
|
36
|
+
- **Doubt the probe first.** Five probes failed before any check did — four times out of five the
|
|
37
|
+
planted defect was never planted, and the silence read as a passing check.
|
|
38
|
+
- **Absence needs its own check.** Comparing documents finds contradictions, and a contradiction
|
|
39
|
+
needs two sides; a whole missing subsystem has one. Only the reverse direction of a computed
|
|
40
|
+
mapping found it.
|
|
41
|
+
- **Tests create what they assert on.** A test read another test file's leftovers, so it passed on a
|
|
42
|
+
warm database and failed on the cold one every new developer has.
|
|
43
|
+
- **A generator seeds green** · **local infrastructure does not publish the host's default ports** ·
|
|
44
|
+
**compute rather than restate** · **sweep the class, not the finding** · **ratchet, never TODO**.
|
|
45
|
+
|
|
46
|
+
Wired into stages 5, 6, 9 and 10 as gate criteria, not as reading. Two lessons are deliberately kept
|
|
47
|
+
OUT of the table, as review questions — *is this the right citation* and *did this number come from
|
|
48
|
+
the contract or from prose about it* — because a rule that pretends to be enforced and is not is the
|
|
49
|
+
same failure as the gate that printed `FAIL` and exited `0`.
|
|
50
|
+
|
|
51
|
+
## v1.3.2 — 2026-07-29
|
|
52
|
+
|
|
53
|
+
**The 26 negative self-tests could not be run anywhere except CI** — which meant
|
|
54
|
+
that on the maintainer's own machine, a new guard could never be watched rejecting
|
|
55
|
+
its planted defect. The project's own `references/audit.md` demands exactly that
|
|
56
|
+
(*plant the defect, watch the check fail, then trust the green*), and the tooling
|
|
57
|
+
made it impossible at the one moment it is worth most: while the guard is being
|
|
58
|
+
written.
|
|
59
|
+
|
|
60
|
+
Found by running the full CI suite locally during a validity re-check. Nine of the
|
|
61
|
+
26 failed — every one on BSD sed, none on a repo defect.
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
- **`test/negatives.py`** — runs every negative self-test locally, zero
|
|
65
|
+
dependencies, same as the validator. `npm run test:negatives`, or
|
|
66
|
+
`npm run test:all` for validator-then-guards. The corruptions are **read from
|
|
67
|
+
`.github/workflows/validate.yml`, never duplicated** — a second copy of a
|
|
68
|
+
corruption is a second thing to drift.
|
|
69
|
+
- **It tells a broken test from a guard that didn't fire.** If a planted defect
|
|
70
|
+
changed nothing, the validator passing means the *test* proved nothing, not that
|
|
71
|
+
the guard is dead. That case now reports `BROKEN`, with the fix pointed at the
|
|
72
|
+
workflow. This is the failure mode that hid the sed problem in the first place: a
|
|
73
|
+
no-op corruption reads exactly like a broken guard.
|
|
74
|
+
- It also refuses to run if it finds fewer than 20 tests — a parser or format change
|
|
75
|
+
that silently matched nothing would otherwise report zero failures and look like
|
|
76
|
+
success.
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
- **Every `sed -i` corruption in the workflow is now python.** BSD sed needs an
|
|
80
|
+
argument GNU sed refuses, and `0,/re/` does not exist on BSD at all — there it
|
|
81
|
+
edits nothing *silently*, and the test reads as a guard that failed to fire.
|
|
82
|
+
Nine steps converted; CI and a laptop now run the identical script.
|
|
83
|
+
|
|
84
|
+
### Validator
|
|
85
|
+
- **`sed -i` in `.github/workflows/validate.yml` is now a failure**, and
|
|
86
|
+
`test/negatives.py` must exist. Without both, the guards drift back to
|
|
87
|
+
CI-only and stop being provable where they are written.
|
|
88
|
+
- The new self-test builds the forbidden token at runtime, because spelling it
|
|
89
|
+
literally would make the workflow trip the guard it is testing. Verified the
|
|
90
|
+
honest way: a clean copy passes, and the injected copy is the *only* reason the
|
|
91
|
+
corrupted one fails — a self-test that passes because the base is already red
|
|
92
|
+
proves nothing.
|
|
93
|
+
|
|
3
94
|
## v1.3.1 — 2026-07-29
|
|
4
95
|
|
|
5
96
|
### Stage 10 closes on the parent repository, not only on the one you edited
|
package/README.md
CHANGED
|
@@ -490,6 +490,19 @@ command into `~/.claude/commands/`; idempotent — rerun skips existing installs
|
|
|
490
490
|
|
|
491
491
|
### Updating
|
|
492
492
|
|
|
493
|
+
**The family updates as one package** — a bundle with one member current and the rest stale is a
|
|
494
|
+
combination nobody tested:
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
npx sshlg-skills update # installed but behind — updates everything
|
|
498
|
+
npx sshlg-skills install # nothing installed yet
|
|
499
|
+
npx --yes sshlg-skills@latest list # what the current release of each member is
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Restart your agent afterwards: skills and hooks load at session start.
|
|
503
|
+
|
|
504
|
+
Per-channel, when you are updating this one member only:
|
|
505
|
+
|
|
493
506
|
Pick **one** channel per agent — running the plugin and the plain/skills-CLI copy on
|
|
494
507
|
the same Claude Code install yields a duplicate, shadowing skill.
|
|
495
508
|
|
|
@@ -551,13 +564,19 @@ Built by ssheleg — [sshlg.me](https://sshlg.me)
|
|
|
551
564
|
- Telegram — [@sshlg](https://t.me/sshlg)
|
|
552
565
|
|
|
553
566
|
Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills):
|
|
554
|
-
`super-ux`, `task-pipeline`, `make-skill`, `sheleg-design`, `seo-aeo-audit`.
|
|
555
|
-
|
|
567
|
+
`super-ux`, `task-pipeline`, `agent-sync`, `make-skill`, `sheleg-design`, `seo-aeo-audit`.
|
|
568
|
+
**The family installs and updates as one package**, for every agent you use — a bundle with one
|
|
569
|
+
member current and the rest stale is a combination nobody tested:
|
|
556
570
|
|
|
557
571
|
```bash
|
|
558
|
-
npx sshlg-skills install
|
|
572
|
+
npx sshlg-skills install # nothing installed yet — the whole family, any agent
|
|
573
|
+
npx sshlg-skills update # installed but behind — updates everything
|
|
574
|
+
npx --yes sshlg-skills@latest list # what the current release of each member is
|
|
559
575
|
```
|
|
560
576
|
|
|
577
|
+
Restart your agent afterwards: skills and hooks load at session start, so the session that
|
|
578
|
+
updates is not the session that gets the new ones.
|
|
579
|
+
|
|
561
580
|
## License
|
|
562
581
|
|
|
563
582
|
MIT © 2026 ssheleg. Third-party portions (the ported stage doctrine) are credited
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.2",
|
|
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"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "python3 test/validate.py"
|
|
9
|
+
"test": "python3 test/validate.py",
|
|
10
|
+
"test:negatives": "python3 test/negatives.py",
|
|
11
|
+
"test:all": "python3 test/validate.py && python3 test/negatives.py"
|
|
10
12
|
},
|
|
11
13
|
"files": [
|
|
12
14
|
"bin",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline",
|
|
3
3
|
"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.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ssheleg"
|
|
7
7
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-pipeline
|
|
3
3
|
description: "Use when running a substantial task through the full end-to-end delivery pipeline — an up-front intake grill that expands the request into a complete brief, then docs study, brainstorm, spec, plan, subagent-driven build, tests, lint/deploy, post-deploy log check, docs/wiki sync and acceptance — as gated stages whose doctrine is built entirely into this skill (no required companion skills). Triggers - 'run this through the pipeline' / 'прогони по конвейеру', 'the full cycle' / 'полный цикл', /task-pipeline, or any substantial feature, fix, or build that should follow the disciplined cycle rather than ad-hoc coding. The intake grill is mandatory - it front-loads every decision, including the per-stage autonomy sweep, so stages 1→10 run without mid-flight questions; recommends super-ux for user-facing work; confirms one model up front (most capable available, never a hardcoded id); reads host-project conventions for deploy/docs/wiki so it stays project-agnostic."
|
|
4
|
+
license: MIT
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# task-pipeline
|
|
@@ -189,12 +190,12 @@ capable available — see `references/model-tiering.md`).
|
|
|
189
190
|
| 2 | Brainstorm + decompose | built in: [`references/brainstorm.md`](references/brainstorm.md) + **UI detection** + [`references/decomposition.md`](references/decomposition.md) for platforms | design approved; UI verdict recorded; every REQ answered; platform: module map approved | manual |
|
|
190
191
|
| 3 | Spec | built in: [`references/spec.md`](references/spec.md) — **UI → super-ux chain first** (`/ux` → `ux-foundation` CJM → `ux-flows` screens → `ux-scenarios` → `/ux-lint`), then spec `docs/superpowers/specs/…-design.md` | committed + reviewed; UI: chain validated, linter green, scenarios/`SCR-` traced | manual |
|
|
191
192
|
| 4 | Plan | built in: [`references/planning.md`](references/planning.md) → `docs/superpowers/plans/…md` | parallel-ready, DoD per task | auto |
|
|
192
|
-
| 5 | Dev | built in: [`references/build.md`](references/build.md) (worktree → subagent per task → review loop → integrate) + [`references/tdd.md`](references/tdd.md) | tasks DONE, TDD green per task, branch integrated per the brief | auto |
|
|
193
|
-
| 6 | Tests | host test runner + built-in [`references/tdd.md`](references/tdd.md) | full suite green; new/changed code covered | auto |
|
|
193
|
+
| 5 | Dev | built in: [`references/build.md`](references/build.md) (worktree → subagent per task → review loop → integrate) + [`references/tdd.md`](references/tdd.md) | tasks DONE, TDD green per task, branch integrated per the brief; **anything generated passes its own checks, and local infrastructure does not publish the host's default ports** ([`references/learned.md`](references/learned.md)) | auto |
|
|
194
|
+
| 6 | Tests | host test runner + built-in [`references/tdd.md`](references/tdd.md) + [`references/learned.md`](references/learned.md) | full suite green; new/changed code covered; **every new check probed both ways and asserted on its exit code**, and the suite run once against a cold environment | auto |
|
|
194
195
|
| 7 | Lint + deploy | host lint → deploy per host convention | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
|
|
195
196
|
| 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report | auto |
|
|
196
|
-
| 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced | auto |
|
|
197
|
-
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off | manual |
|
|
197
|
+
| 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced; **every number computed rather than restated, every named command or file resolvable** ([`references/learned.md`](references/learned.md)) | auto |
|
|
198
|
+
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off | manual |
|
|
198
199
|
|
|
199
200
|
|
|
200
201
|
### Stage 10 in a project of several repositories
|
|
@@ -213,7 +214,7 @@ git -C <each repo> status --porcelain && git -C <each repo> log @{u}..HEAD --one
|
|
|
213
214
|
```
|
|
214
215
|
|
|
215
216
|
report nothing — for the parent as well as every submodule. Where
|
|
216
|
-
[agent-sync](https://github.com/
|
|
217
|
+
[agent-sync](https://github.com/ssheleg/agent-sync) is installed, `/agent-sync finish` runs
|
|
217
218
|
exactly this plus *no lease left held*, and `--gates` adds the project's own gate commands.
|
|
218
219
|
|
|
219
220
|
The fix, when it fails, is two commands and the second is the one that gets forgotten:
|
|
@@ -258,6 +259,7 @@ automation is on — `pipeline.schema.json` is the only contract.
|
|
|
258
259
|
- `references/grill.md` — the built-in stage-0 grill: loop, domain awareness, autonomy sweep
|
|
259
260
|
- `references/acceptance.md` — the built-in stage-10 close-out: REQ coverage, evidence, sign-off
|
|
260
261
|
- `references/audit.md` — cross-cutting: the L0→L7 ladder and its seams (what was never written), axis rotation, ratchets, proven checks
|
|
262
|
+
- `references/learned.md` — cross-cutting: fourteen rules earned by failure on a real multi-repository build, each with the incident behind it, its check and its exit criterion; plus the two that no check can decide
|
|
261
263
|
- `references/brainstorm.md` — stage 2: design dialogue, approaches, UI detection, hard gate
|
|
262
264
|
- `references/spec.md` — stage 3: UX track order, the spec contract, self-review, review gate
|
|
263
265
|
- `references/planning.md` — stage 4: zero-context plan format, parallel groups, no placeholders
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/ssheleg/task-pipeline/main/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json",
|
|
4
4
|
"title": "task-pipeline config",
|
|
5
5
|
"description": "Generic contract for a pipeline config. An ordered list of stages; each stage is run by the host project's own skills/agents and guarded by a typed gate. The framework imposes no specific stages, skills, or gate assignments — those are entirely the host project's config. Copy pipeline.example.json and rewrite it to match your project.",
|
|
6
6
|
"type": "object",
|
|
@@ -124,7 +124,7 @@ git -C <each repo> status --porcelain
|
|
|
124
124
|
git -C <each repo> log @{u}..HEAD --oneline
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
Where [agent-sync](https://github.com/
|
|
127
|
+
Where [agent-sync](https://github.com/ssheleg/agent-sync) is installed,
|
|
128
128
|
`/agent-sync finish` runs exactly this plus *no lease left held*, and `--gates`
|
|
129
129
|
adds the project's own gate commands.
|
|
130
130
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Rules earned by failure
|
|
2
|
+
|
|
3
|
+
**One job: the mistakes that cost real time on a real project, each with the check that now catches
|
|
4
|
+
it.** Every rule here names the incident that produced it. A rule with no incident behind it is
|
|
5
|
+
somebody's preference, and it will be argued with at the worst moment.
|
|
6
|
+
|
|
7
|
+
They come from one 229-decision, 72-document specification built across four repositories with
|
|
8
|
+
several agents working at once. Nothing here is hypothetical.
|
|
9
|
+
|
|
10
|
+
**A rule belongs in the table only when it has a check.** Two of the lessons below could not be
|
|
11
|
+
mechanised and are kept out of it deliberately, as review questions — because a rule that pretends
|
|
12
|
+
to be enforced and is not is the same failure as a gate that prints `FAIL` and exits `0`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## The table — trigger · check · exit criterion
|
|
17
|
+
|
|
18
|
+
| # | Rule | Trigger | The check | Exit criterion |
|
|
19
|
+
|---|---|---|---|---|
|
|
20
|
+
| 1 | **Change the axis when it stops paying** | any second review or audit pass | count new findings and self-inflicted ones separately | self-inflicted exceeds new → change the axis, do not "look again more carefully" |
|
|
21
|
+
| 2 | **Absence needs its own check** | any two-layer model — entity/table, screen/frame, task/module, requirement/test | compute the mapping in **both** directions | zero orphans each way, printed |
|
|
22
|
+
| 3 | **Verify closure against the artefact** | closing anything that names a design, a build or a file | open the artefact, not the document describing it | the artefact carries a marker naming what it was last verified against |
|
|
23
|
+
| 4 | **Probe the detector** | every new check, lint rule or assertion | plant the defect → run → assert non-zero; restore → assert zero | both directions observed once, and recorded |
|
|
24
|
+
| 5 | **Doubt the probe first** | a check that stays silent when it should fire | prove the planted defect exists in the text the check actually parses | the probe is shown to have changed what the check reads |
|
|
25
|
+
| 6 | **Sweep the class, not the finding** | any correction | grep the whole corpus for the same shape before closing | the class is gated, or named in the note so the next reader can finish it |
|
|
26
|
+
| 7 | **Ratchet, never TODO** | anything that cannot be fixed now | a named, counted set printed on every run | the number may only fall, and `OK` prints it beside itself |
|
|
27
|
+
| 8 | **Compute, never restate** | any count or cross-reference stated in prose | derive it from the source at check time | the stated number and the computed one are the same object |
|
|
28
|
+
| 9 | **A generator seeds green** | any scaffold, template or code generator | run the generated project's own checks inside the generator's tests | fresh output exits zero |
|
|
29
|
+
| 10 | **Measure a detector before trusting it** | a new heuristic check | run it over the real corpus and count false positives | zero false positives, or the heuristic is replaced by a deterministic rule |
|
|
30
|
+
| 11 | **A gate's exit code is part of its output** | any gate or CI step | run it against a planted defect and assert on `$?` | non-zero, not merely a `FAIL` line on stdout |
|
|
31
|
+
| 12 | **Tests create what they assert on** | any test touching shared state | run the suite against a cold, empty environment | the cold run and the warm run agree |
|
|
32
|
+
| 13 | **Local infrastructure does not fight the host** | any dev compose or service definition | assume the host already runs the defaults | services reachable with the host's own still running |
|
|
33
|
+
| 14 | **A document may not send a reader to something absent** | any instruction naming a command, file or install | resolve it | the gate fails when the target does not exist |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## The incidents, so the rules are not abstract
|
|
38
|
+
|
|
39
|
+
**1 · Change the axis.** Seven passes of comparing documents against each other were instrumented.
|
|
40
|
+
Findings per pass: 12, 17, 13, 19 — and *caused by the previous pass*: 5, 9, 10, 4. By the sixth
|
|
41
|
+
pass the method was mostly repairing itself, because each pass edits the corpus the next one reads,
|
|
42
|
+
so the newest text is always the least reviewed. The fix is not more care; it is a different axis.
|
|
43
|
+
|
|
44
|
+
**2 · Absence.** Comparing documents found contradictions for weeks and never found that one
|
|
45
|
+
service had **no key store at all** — a decision made it the encryptor of every media object, the
|
|
46
|
+
other service's table had been modelled for weeks, and this one had no entity, no fields, no
|
|
47
|
+
rotation story. A contradiction needs two sides. Absence has one. The register that finally caught
|
|
48
|
+
it checks *entity → table* and *table → entity*, and **only the second direction found anything**:
|
|
49
|
+
four entities fully specified, cited by build tasks, with no schema anywhere.
|
|
50
|
+
|
|
51
|
+
**3 · Closure against the artefact.** Two gaps were marked **closed** while the design still
|
|
52
|
+
violated them — the closure had been verified by reading the specification, which had been fixed,
|
|
53
|
+
while the frames had not. Twice is a category, so every drawn screen now carries a marker naming the
|
|
54
|
+
newest decision its *frames* were checked against, and the linter fails when the prose cites
|
|
55
|
+
something newer.
|
|
56
|
+
|
|
57
|
+
**4 and 5 · Probes.** Every check written was exercised against a planted defect. **Five probes
|
|
58
|
+
failed before any check did:** one added a definition where the check looks for an unresolved
|
|
59
|
+
reference; one edited a string whose whitespace did not match; one hit the first prose mention
|
|
60
|
+
instead of the table row; one flipped a row whose producer cell was empty, so nothing was planted;
|
|
61
|
+
one counted matching lines and counted the check's own `INFO` line as a hit. Four times out of five
|
|
62
|
+
the probe was wrong, not the check.
|
|
63
|
+
|
|
64
|
+
**6 · Sweep the class.** A pass fixed four invented audit-action names in a table and stopped at the
|
|
65
|
+
rows it was looking at; two rows in the same table still said something else, found the next day.
|
|
66
|
+
The same shape recurred three times — a retired word corrected on one screen and left on two others,
|
|
67
|
+
a value fixed in a light frame and left in its dark twin, a stale retention window removed from
|
|
68
|
+
three documents' prose and surviving in a design.
|
|
69
|
+
|
|
70
|
+
**8 · Compute.** Two documents had to stop quoting totals after they went stale. The register that
|
|
71
|
+
replaced them computes its cross-reference column from lines the tables themselves carry, so the two
|
|
72
|
+
cannot disagree.
|
|
73
|
+
|
|
74
|
+
**9 · Seeds green.** A documentation gate added to a scaffold **failed on its own seeds** — it read
|
|
75
|
+
the template block and the allocation line as real identifiers. A project that starts red teaches
|
|
76
|
+
everyone on day one that the gate is noise.
|
|
77
|
+
|
|
78
|
+
**10 · Measure the detector.** A parity-based check for unbalanced markup produced **six false
|
|
79
|
+
positives out of six** on the real corpus. It was discarded for a deterministic rule. A gate that
|
|
80
|
+
cries wolf is removed by the third person who hits it.
|
|
81
|
+
|
|
82
|
+
**11 · Exit codes.** A repository's docs gate appended a check *after* its verdict block, so it
|
|
83
|
+
printed `FAIL` and returned `0`. CI had been green over it for an unknown period.
|
|
84
|
+
|
|
85
|
+
**12 · Cold runs.** An isolation test read whatever another test file had left in the database. Test
|
|
86
|
+
files run alphabetically and the one that creates that data runs later, so the test **passed on a
|
|
87
|
+
warm database and failed on a cold one** — which is what every new developer has.
|
|
88
|
+
|
|
89
|
+
**13 · Ports.** A dev compose published the default Postgres and Redis ports. The machine already
|
|
90
|
+
ran both, so the containers were silently shadowed: the tools connected to the host's services and
|
|
91
|
+
the migration failed with a permission error that named nothing about the collision.
|
|
92
|
+
|
|
93
|
+
**14 · Absent targets.** A repository's first instruction to every agent was to run a command that
|
|
94
|
+
was not installed, with no install line anywhere and no statement of what a session without it
|
|
95
|
+
actually is.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## The two that are not in the table, and why
|
|
100
|
+
|
|
101
|
+
Kept as review questions, because no check can decide them:
|
|
102
|
+
|
|
103
|
+
- **Is this the right citation?** A stale reference was replaced with a *false* one — the new target
|
|
104
|
+
existed and said nothing about the subject. A gate can prove an identifier resolves; only a reader
|
|
105
|
+
can prove it is the right one. **Ask at review: did you open the target and confirm it says the
|
|
106
|
+
thing?**
|
|
107
|
+
- **Does the prose match the contract, or another paragraph of prose?** A "correction" to an attempt
|
|
108
|
+
cap introduced a second vocabulary for one counter, because it was written against a description
|
|
109
|
+
instead of the schema. **Ask at review: which artefact did this number come from?**
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## The one instruction that would have prevented the most
|
|
114
|
+
|
|
115
|
+
> **Before trusting any tool's report about the world, make it report something you can already
|
|
116
|
+
> verify.**
|
|
117
|
+
|
|
118
|
+
Four of the worst failures on that project were the same failure wearing different clothes: a test
|
|
119
|
+
suite reporting green having skipped every assertion; a gate printing `FAIL` and exiting `0`;
|
|
120
|
+
containers reporting healthy while the tools talked to the host's services; a coordination plugin
|
|
121
|
+
reporting a lease held by an identity that belonged to a different session. In each case the tool
|
|
122
|
+
was describing a world it was not looking at, and in each case one deliberate check against a known
|
|
123
|
+
answer would have exposed it in a minute.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Where these bind in the pipeline
|
|
128
|
+
|
|
129
|
+
| Stage | Rules that apply |
|
|
130
|
+
|---|---|
|
|
131
|
+
| 3 Spec · 4 Plan | 2 (both directions), 8 (compute, never restate) |
|
|
132
|
+
| 5 Dev | 9 (generators seed green), 12 (tests create their own state), 13 (local infra) |
|
|
133
|
+
| 6 Tests | 4, 5, 10, 11 — every new check probed both ways, measured, and asserted on its exit code |
|
|
134
|
+
| 9 Docs | 8, 14 — every number computed, every target resolvable |
|
|
135
|
+
| 10 Acceptance | 1, 3, 6, 7 — axis rotation recorded, closure verified against artefacts, classes swept, ratchets printed |
|
|
@@ -309,7 +309,7 @@ stages/agents/types (see SKILL.md → *Bring your own skills*).
|
|
|
309
309
|
reports nothing **for the parent as well as every submodule**:
|
|
310
310
|
`git submodule status` (no line starting `+`), plus `git -C <repo> status
|
|
311
311
|
--porcelain` and `git -C <repo> log @{u}..HEAD --oneline` per repo. With
|
|
312
|
-
[agent-sync](https://github.com/
|
|
312
|
+
[agent-sync](https://github.com/ssheleg/agent-sync) installed,
|
|
313
313
|
`/agent-sync finish` runs exactly that. The fix is two commands and the second is
|
|
314
314
|
the forgotten one: `git -C <submodule> push`, then
|
|
315
315
|
`git add <submodule> && git commit`.
|