task-pipeline-skill 1.22.0 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,81 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.23.1
4
+
5
+ ### Four documents that had gone false, and the config this repository never wrote
6
+
7
+ A review of the hallucination-mitigation literature against this skill produced an
8
+ uncomfortable result: the doctrine already covers almost every applicable mitigation the
9
+ field names — grounding, constrained generation, post-processing that blocks unproven
10
+ assertions, self-contradiction detection. What it does not cover is **this repository
11
+ applying that doctrine to itself.** Everything below is a class the skill documents,
12
+ found in the skill.
13
+
14
+ **Four surfaces were stating numbers that had stopped being true.**
15
+
16
+ - `README.md` and `SKILL.md` said `learned.md` carries *"fifteen rules"*. The table has
17
+ twenty-one. Both now describe the file without counting it — the table is the count,
18
+ the same fix `CLAUDE.md` already applies to the invariant list, and the reason is that
19
+ a hand-written count goes stale on the next rule rather than on the next audit.
20
+ - `evals/RESULTS.md` opened with *"the suite is authored and has not been executed"* and
21
+ ratcheted *"Dated runs recorded 0"* — directly above a dated run, and directly on top
22
+ of `evals/run.py`, which computes `recorded runs: 1` and had been printing it for five
23
+ releases. The document and the tool beneath it disagreed, and nothing compared them.
24
+ The ratchet now carries what actually matters: one run, **self-observed**, and **zero
25
+ blind** — because collapsing those into a single total is how a self-check gets quoted
26
+ as a result.
27
+ - `docs/DOCMAP.md` claimed two standing instructions against the retro's four, and
28
+ duplicated both eval numbers. Its ratchet table now names **homes and commands, never
29
+ values**. A ratchet copied into a second document is two ratchets, and the copy nobody
30
+ runs is the one people read.
31
+
32
+ **`learned.md`'s own routing table stopped at rule 16.** Rules 17–21 were in the rule
33
+ table, each guarded in its consumer files, and absent from *Where these bind in the
34
+ pipeline* — the section an agent reads to learn *when* a rule applies. The rule's own
35
+ failure mode, applied to the map of the rules. All twenty-one now name their stage, and
36
+ the two mis-aimed citations that first attempt introduced were caught by the citation
37
+ guard rather than by a reader, which is the guard doing exactly its job.
38
+
39
+ **This repository had no `pipeline.json`.** The project that ships the config contract
40
+ had never written its own, so `run.loop` was unrecorded, the mode defaulted to off, and
41
+ every loop it ran was authorised in a chat message. There is now a real one: this repo's
42
+ eleven stages with its real host commands, its release block, and the loop mode recorded
43
+ as a file rather than remembered — including the note that the mode collapses
44
+ discretionary check-ins only, and is never the authorization for the tag push.
45
+
46
+ **Not fixed here, and named rather than quietly carried:** rule 21 changed the retro's
47
+ order to *stamp first* in `references/retrospective.md` and in no other file. Eight
48
+ sibling surfaces — `SKILL.md` included, which is what an agent loads first — still teach
49
+ the deadlocked *prune first*. That is a gate contract, so it ships on its own branch with
50
+ a guard that compares the class rather than one literal.
51
+
52
+ ## v1.23.0
53
+
54
+ ### A step that consumes what a later step produces is a deadlock — `learned.md` rule 21
55
+
56
+ The retrospective stage said **prune first, then stamp**. One of the prune's three retirement
57
+ triggers is *it has not fired in the last five run stamps* — so the trigger read a counter the same
58
+ stage wrote afterwards. On any list it had never run on real data, and it stays unreadable for
59
+ exactly as long as nobody stamps.
60
+
61
+ Measured on a real project: last entry five days old; stamps per day 33, 20, 26, **3, 0** — the zero
62
+ on a day with 107 commits — and the list sitting at **10 of 10**. Every run arrived at a stage that
63
+ opened with a full list, an unusable trigger and a mandatory deletion. It was not skipped out of
64
+ laziness: its first step could not be performed, and the cheap step that would have made it
65
+ performable was queued behind it.
66
+
67
+ Two changes, and the second only works because of the first:
68
+
69
+ - **Stamp first, then prune, then write.** The stamp is one line and costs nothing; it is also the
70
+ only thing that makes the cold trigger computable.
71
+ - **Each trigger is a command, not a judgement.** All three are now runnable — grep for the rule's
72
+ words in anything that executes, resolve every path and tool it names, count its firings across
73
+ the last five stamps. A retirement condition nobody can run is one nobody applies, which is how a
74
+ list reaches ten and stops being read.
75
+
76
+ `test/validate.py` guards all three: the new ordering, the absence of the old "runs BEFORE" wording,
77
+ and the triggers being expressed as commands. Watched failing against two planted defects.
78
+
3
79
  ## v1.22.0
4
80
 
5
81
  ### When a thing exists twice, ask which one is used — `learned.md` rule 20
package/CONTRIBUTING.md CHANGED
@@ -67,10 +67,13 @@ These are what the validator enforces. Breaking one is not a style disagreement
67
67
  it ships a wrong pipeline to every install. Numbered in reading order; the numbers
68
68
  are labels, not priorities.
69
69
 
70
- **1. Four-way version sync.** `package.json`, `.claude-plugin/marketplace.json`
71
- (`plugins[0].version`), `plugins/task-pipeline/.claude-plugin/plugin.json` and the
72
- top `## vX.Y.Z` heading in `CHANGELOG.md` must all carry the same version.
73
- `SKILL-CARD.md`'s Version row is held to it too.
70
+ **1. Version sync across every manifest surface.** `package.json`,
71
+ `.claude-plugin/marketplace.json` (`plugins[0].version`),
72
+ `plugins/task-pipeline/.claude-plugin/plugin.json`, the top `## vX.Y.Z` heading in
73
+ `CHANGELOG.md` **and `SKILL-CARD.md`'s Version row** must all carry the same version.
74
+ The invariant was called *four-way* until 2026-08-08 while listing five surfaces and
75
+ while the validator enforced five — a name that counts is a number, and it drifts like
76
+ one. The list is the count.
74
77
 
75
78
  **2. The stage list lives on three surfaces and may not drift.** `SKILL.md`'s
76
79
  table, `references/stages.md`'s per-stage sections, and `pipeline.example.json`.
package/README.md CHANGED
@@ -808,7 +808,7 @@ recommendation, so you arm the whole run in one exchange. Detail:
808
808
  | [`references/adoption.md`](plugins/task-pipeline/skills/task-pipeline/references/adoption.md) | the first run in a project: greenfield seeding, and the brownfield walkthrough |
809
809
  | [`references/setup.md`](plugins/task-pipeline/skills/task-pipeline/references/setup.md) | the entry audit: seven passes over the docs a project already has, offered once, output as a fix plan |
810
810
  | [`references/portability.md`](plugins/task-pipeline/skills/task-pipeline/references/portability.md) | the manifest of workflow decisions and their homes in the bundle, and the boundary against a project's own answers |
811
- | [`references/learned.md`](plugins/task-pipeline/skills/task-pipeline/references/learned.md) | fifteen rules earned by failure on a real multi-repository build, each with its incident, its check and its exit criterion |
811
+ | [`references/learned.md`](plugins/task-pipeline/skills/task-pipeline/references/learned.md) | rules earned by failure on a real multi-repository build, each with its incident, its check and its exit criterion — the table is the count, and it grows |
812
812
  | [`SKILL-CARD.md`](SKILL-CARD.md) | the registry entry and risk-tier disclosure a reviewer needs before deploying it |
813
813
  | [`evals/`](evals/RESULTS.md) | the behavioural evaluation suite, its protocol, and what has actually been observed |
814
814
  | [`CHANGELOG.md`](CHANGELOG.md) | every release, with the reasoning behind it |
@@ -817,8 +817,8 @@ recommendation, so you arm the whole run in one exchange. Detail:
817
817
  ## Contributing
818
818
 
819
819
  Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for
820
- the repo's invariants (the structural validator, four-way version sync, and the
821
- surfaces that must never drift apart). Security reports:
820
+ the repo's invariants (the structural validator, version sync across every manifest
821
+ surface, and the surfaces that must never drift apart). Security reports:
822
822
  [SECURITY.md](SECURITY.md). Everyone participating is expected to follow the
823
823
  [Code of Conduct](CODE_OF_CONDUCT.md).
824
824
 
package/SKILL-CARD.md CHANGED
@@ -12,7 +12,7 @@ harmless.
12
12
  |---|---|
13
13
  | **Purpose** | Runs a substantial task through ten gated delivery stages — intake grill, docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs+registers, acceptance — refusing to advance until each gate passes |
14
14
  | **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
15
- | **Version** | 1.22.0 |
15
+ | **Version** | 1.23.1 |
16
16
  | **Surface** | Claude Code (filesystem skill + plugin) and the vercel `skills` CLI. **Not** uploaded to the Skills API; custom Skills do not sync across surfaces |
17
17
  | **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
18
18
  | **Evaluation status** | Suite authored (15 evals, 5 categories). **Never executed** — see [`evals/RESULTS.md`](evals/RESULTS.md) |
package/evals/RESULTS.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # Evaluation results — task-pipeline
2
2
 
3
- **Status: the suite is authored and has not been executed.** Recorded here rather
4
- than left blank, because an empty results file and an unrun suite look identical,
5
- and this repository's own doctrine calls that the failure a skip is not a pass.
3
+ **Status: the suite is authored. One run is recorded and it was self-observed by the
4
+ author; no blind run has been made on any model.** Recorded this way rather than left
5
+ blank, because an empty results file and an unrun suite look identical, and this
6
+ repository's own doctrine calls that the failure — a skip is not a pass.
7
+
8
+ **The numbers below are computed, not asserted.** `python3 evals/run.py` counts the
9
+ suite and the dated run headings in this file. A value typed here that disagrees with
10
+ what it prints is the defect, and it is the document that is wrong — this file said
11
+ *"has not been executed"* and *"Dated runs recorded 0"* for five releases while the
12
+ tool beneath it printed `recorded runs: 1`, which is the self-contradiction canon 2
13
+ exists to prevent, in the one file whose whole job is honesty about evidence.
6
14
 
7
15
  Running these needs a fresh session per query, per model. That is a human or agent
8
16
  step; `evals/run.py` prints the protocol and deliberately never reports a pass it
@@ -29,19 +37,23 @@ or it belongs in a check.
29
37
 
30
38
  ## Ratchet
31
39
 
32
- | Metric | Value | As of |
33
- |---|---|---|
34
- | Evals authored | 15 | 2026-08-03 |
35
- | Categories covered | 5 of 5 | 2026-08-03 |
36
- | Models exercised | **0 of 3** | 2026-08-03 |
37
- | Dated runs recorded | **0** | 2026-08-03 |
40
+ | Metric | Value | Computed by | As of |
41
+ |---|---|---|---|
42
+ | Evals authored | 15 | `python3 evals/run.py` → `suite: N evals` | 2026-08-08 |
43
+ | Categories covered | 5 of 5 | the suite's own `category` fields | 2026-08-08 |
44
+ | Dated runs recorded | **1** | `python3 evals/run.py` → `recorded runs: N` | 2026-08-08 |
45
+ | …of those, **blind** | **0** | run headings not marked `self-observed` | 2026-08-08 |
46
+ | Models exercised blind | **0 of 3** | distinct models across blind runs | 2026-08-08 |
47
+
48
+ **The last three rows are the honest state of this skill's behavioural evidence**, and
49
+ the split matters more than the total: a run the author watched, knowing the expected
50
+ behaviour, is an observation of instruction-following and not an evaluation. Collapsing
51
+ the two into one "runs recorded" number is how a self-check gets quoted as a result.
38
52
 
39
- The bottom two numbers are the honest state of this skill's behavioural evidence.
40
53
  Everything else in this repository is proven by structural guards — the count is
41
- whatever `npm run test:all` prints, deliberately not restated here — that check the
42
- *form*; these are the only checks that would speak to the *behaviour*, and they have
43
- not been run yet. Printed here so "63 of 63 green" is never read as "the skill is
44
- known to work".
54
+ whatever `npm run test:all` prints, deliberately not restated here — and those check
55
+ the *form*. These are the only checks that speak to the *behaviour*. Printed here so a
56
+ green structural suite is never read as "the skill is known to work".
45
57
 
46
58
  ## Runs
47
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.22.0",
3
+ "version": "1.23.1",
4
4
  "description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "task-pipeline": "bin/task-pipeline.js"
@@ -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.22.0",
5
+ "version": "1.23.1",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -334,7 +334,7 @@ automation is on — `pipeline.schema.json` is the only contract.
334
334
  - `references/deploy-targets.md` — stages 7–8: writing the runbook when there is none, the template, per-platform deploy and log verbs, and the verification trio
335
335
  - `references/hooks.md` — agent-time enforcement: the PreToolUse contract, the fail-open hazard, placement, and the Claude-Code-only limit
336
336
  - `references/audit.md` — cross-cutting: the L0→L7 ladder and its seams (what was never written), axis rotation, ratchets, proven checks
337
- - `references/learned.md` — cross-cutting: fifteen 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
337
+ - `references/learned.md` — cross-cutting: 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. The table is the count — a number written here is a number that goes stale on the next rule
338
338
  - `references/brainstorm.md` — stage 2: design dialogue, approaches, UI detection, hard gate
339
339
  - `references/spec.md` — stage 3: UX track order, the spec contract, self-review, review gate
340
340
  - `references/planning.md` — stage 4: zero-context plan format, parallel groups, no placeholders
@@ -45,6 +45,7 @@ to be enforced and is not is the same failure as a gate that prints `FAIL` and e
45
45
  | 18 | **State that accumulates locally is created from nothing everywhere else** | any run whose tests, migrations or fixtures read a database, a cache or a checkout that persists between runs on this machine | run the suite once against a **freshly created** instance of it, not the one that has been here for weeks | the run names the fresh instance it used, or the green is a green from residue |
46
46
  | 19 | **An empty measurement is a refused measurement** | any command run to establish a fact — a count, a probe, a query, a suite | assert the output is **non-empty and shaped as expected** before reading meaning into it; a command that printed nothing did not answer | the run quotes the output it read, not the conclusion it drew from silence |
47
47
  | 20 | **When a thing exists twice, ask which one is used — not whether they agree** | any artifact with a second copy: two build files, a vendored library, a schema and its mirror, doctrine in two documents | find the **consumer** and read what it names; the copies cannot answer this about themselves | the run names the file the build/test/deploy actually reads, quoted from the consumer |
48
+ | 21 | **A step that consumes what a later step produces is a deadlock, not an ordering** | any sequence where a check reads state another step writes — a prune reading stamps, a gate reading a ledger, a report reading counts | trace each input to the step that writes it; if that step is downstream, the check has never run on real data | every check names the step that produces its input, and that step is upstream of it |
48
49
 
49
50
  ---
50
51
 
@@ -136,6 +137,8 @@ run's belief about the work-list against the register; the claim only ever appea
136
137
 
137
138
  **20 · The copy that wins.** A service had **two Dockerfiles**. One was added at the repository root by a run that checked whether a Dockerfile existed by looking where it expected one; `docker/Dockerfile` had been there all along, and `.github/workflows/ci.yml` says `file: docker/Dockerfile`. They disagreed about the port — 8080 at the root, 8000 in `docker/` — and the disagreement surfaced two days later as a **deployed service that answered nothing**, while `docker ps` said `Up` and `systemctl` said `active`. The built one also ran as root and copied the whole context, including `.git` and any `.env`; the hardened one was the one nobody built. Comparing the two files would have found the difference and not the direction. Only the workflow line says which one ships, and it is one grep. The same session hit this three more times: an autonomy sweep row added to the file that ASKS and not the file that RECORDS, twice, caught by a validator that knew to look at both.
138
139
 
140
+ **21 · The prune that could not run.** A retrospective's standing-instruction list has a hard cap of ten and three retirement triggers, one of which is *it has not fired in the last five run stamps*. The stage's own instruction was **prune first, then stamp**. So the trigger read a counter the same stage wrote afterwards: on a fresh list it is unreadable, and it stays unreadable for as long as nobody stamps. Measured on a real project: the last retro entry was five days old, stamps per day ran 33, 20, 26, **3, 0** — the zero on a day with 107 commits — and the list sat at exactly **10 of 10**, so every run arrived at a stage that opened with a full list, an unusable trigger and a mandatory deletion. It was not skipped out of laziness. It was skipped because its first step could not be performed, and the cheap step that would have made it performable was queued behind it.
141
+
139
142
  The same class had already bitten that project twice from the other side, and its roadmap names the
140
143
  property exactly: seven rows read `blocked` on producers the dependency board recorded as delivered,
141
144
  and *"no gate can catch it because it breaks nothing — it only removes work from consideration"*;
@@ -193,6 +196,11 @@ answer would have exposed it in a minute.
193
196
  | 9 Docs | 8, 14 — every number computed, every target resolvable |
194
197
  | 10 Acceptance | 1, 3, 6, 7 — axis rotation recorded, closure verified against artefacts, classes swept, ratchets printed |
195
198
  | 10 Acceptance · every loop iteration | 16 — the work-list re-measured at close and printed beside its opening count ([`audit.md`](audit.md), [`continuity.md`](continuity.md)) |
199
+ | 0 Harvest · **before the first edit**, in any repository with an upstream | 17 — `git rev-list --count HEAD..@{u}` measured and its number printed, [`knowledge-sources.md`](knowledge-sources.md) → *The source is not the copy you have*; asked as row `0 Source` of [`grill.md`](grill.md) → *The autonomy sweep* |
200
+ | 0 Harvest · 5 Dev · 6 Tests | 18 — the suite run once against a **freshly created** instance of whatever persists between runs, [`tdd.md`](tdd.md) → *The green from residue*; asked as row `0 Fixtures` of [`grill.md`](grill.md) → *The autonomy sweep* |
201
+ | any command run to establish a fact — 6 Tests · 9 Docs · 10 Acceptance · 5 review | 19 — the output asserted non-empty and shaped as expected, and **quoted** rather than concluded from, [`audit.md`](audit.md) → *Silence is not a reading*; the reviewer's half is in [`review.md`](review.md) |
202
+ | 0 Harvest · 10 Acceptance | 20 — the **consumer** read to learn which copy ships, never the copies compared against each other, [`audit.md`](audit.md) → *Two copies, and which one wins*; asked as row `0 Duplicates` of [`grill.md`](grill.md) → *The autonomy sweep* |
203
+ | 10 Retro · **any gate or check you order** | 21 — each input traced to the step that writes it, and that step proven upstream, [`retrospective.md`](retrospective.md) → *Stamp first, then prune, then write* |
196
204
 
197
205
  **This file is the shipped list; a project keeps its own.** Every rule in the table
198
206
  above was earned on someone else's build and travels with the skill. The lessons *your*
@@ -26,7 +26,8 @@ file exists to stop.
26
26
  - Every lesson carries its commit
27
27
  - Rotation — the archive is how pruning stops losing things
28
28
  - Three grades of fix — take the highest one that can work
29
- - The prune mandatory, and it runs BEFORE the new entry is written
29
+ - Stamp first, then prune, then write
30
+ - The prune — mandatory, and it runs after the stamp
30
31
  - The loop closes at stage 0
31
32
  - Where a lesson goes when it is not about this project
32
33
  - Rationalizations
@@ -100,10 +101,30 @@ Prefer grade 1 whenever a check can decide it. This is the same law as
100
101
  [`audit.md`](audit.md) → *A class that repeats twice becomes a gate, not a note*: a
101
102
  rule that could have been a check gets read twice and obeyed once.
102
103
 
103
- ## The prune mandatory, and it runs BEFORE the new entry is written
104
+ ## Stamp first, then prune, then write
104
105
 
105
- Prune first, then write. A lesson that lands in a cluttered file is a lesson nobody
106
- will reach.
106
+ `learned.md` rule 21. This order used to be *prune first*, and that was a **deadlock**, not a
107
+ preference: the cold trigger below reads *the last five run stamps*, and the stamp was written after
108
+ the prune. The trigger read a counter the same stage produced later, so on any list it had never run
109
+ on real data — and it stays unreadable for exactly as long as nobody stamps.
110
+
111
+ Measured on a real project: last entry five days old; stamps per day 33, 20, 26, **3, 0** — the zero
112
+ on a day with 107 commits — and the list sitting at **10 of 10**. Every run arrived at a stage that
113
+ opened with a full list, an unusable trigger and a mandatory deletion. It was not skipped out of
114
+ laziness; its first step could not be performed, and the cheap step that would have made it
115
+ performable was queued behind it.
116
+
117
+ **The stamp is one line and costs nothing.** It is also the only thing that makes the prune
118
+ computable, which is why it goes first:
119
+
120
+ ```bash
121
+ printf '%s · %s\n' "$(date +%F)" "$(git rev-parse --short HEAD)" >> docs/superpowers/retro.md
122
+ ```
123
+
124
+ ## The prune — mandatory, and it runs after the stamp
125
+
126
+ A lesson that lands in a cluttered file is a lesson nobody will reach — so the prune still runs
127
+ before the entry is written. It runs *after* the stamp, because it reads it.
107
128
 
108
129
  Every row carries its own trigger in a **`Retire when`** column, written at birth —
109
130
  a rule whose retirement condition is decided later is a rule the prune can only
@@ -115,6 +136,25 @@ argue about. Check **every** standing instruction against three triggers:
115
136
  | **Its surface is gone** | resolve every path, command, stage and tool it names; any that no longer exists | delete it — it now describes a system nobody is running |
116
137
  | **It went cold** | it has not fired in the last **five run stamps** | delete it — five runs without firing is the evidence that it was situational |
117
138
 
139
+ **Each trigger is a command, not a judgement.** A retirement condition nobody can run is a
140
+ condition nobody applies, which is how a list reaches ten and stops being read:
141
+
142
+ ```bash
143
+ # became a check — the rule's own words appear in something that runs
144
+ grep -rl "$RULE_KEYWORD" scripts/ test/ .github/workflows/ Makefile* 2>/dev/null
145
+
146
+ # surface is gone — every path, command and tool it names, resolved
147
+ grep -oE '`[^`]+`' <<<"$RULE_TEXT" | tr -d '`' | while read -r t; do
148
+ [ -e "$t" ] || command -v "$t" >/dev/null || echo "MISSING: $t"; done
149
+
150
+ # went cold — fired in none of the last five stamps
151
+ tail -n 200 docs/superpowers/retro.md | grep -c "$RULE_ID"
152
+ ```
153
+
154
+ Anything the first two print is a deletion; a zero from the third across five stamps is a deletion.
155
+ What survives all three stays, and the run states the three counts rather than the conclusion
156
+ (`learned.md` rule 19 — an empty result and an unrun command look identical).
157
+
118
158
  Then the cap: **ten standing instructions, hard.** At eleven you do not get to keep
119
159
  them all — the oldest never-fired one goes. "But all of them matter" is precisely
120
160
  the state in which the list stopped being read, and the ninth stale rule is what