task-pipeline-skill 1.78.4 → 1.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +184 -2
- package/README.md +5 -3
- package/SKILL-CARD.md +1 -1
- package/cursor/rules/task-pipeline.mdc +3 -1
- package/evals/RESULTS.md +212 -9
- package/evals/evidence-docs.evals.json +109 -0
- package/evals/project-audit.evals.json +108 -0
- package/evals/run.py +47 -19
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +3 -2
- package/plugins/task-pipeline/commands/task-pipeline.md +2 -1
- package/plugins/task-pipeline/hooks/build-gate.sh +6 -1
- package/plugins/task-pipeline/hooks/gate-observer.sh +35 -14
- package/plugins/task-pipeline/hooks/release-gate.sh +70 -9
- package/plugins/task-pipeline/skills/evidence-docs/SKILL.md +33 -2
- package/plugins/task-pipeline/skills/project-audit/SKILL.md +7 -2
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +50 -57
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +4 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/adoption.md +15 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +4 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +6 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/brainstorm.md +6 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +11 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +7 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +33 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/documentation.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/exposure.md +7 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +17 -185
- package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/model-tiering.md +13 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/prioritisation.md +165 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/probing.md +202 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +8 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +60 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +52 -54
- package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +28 -5
- package/plugins/task-pipeline/skills/task-pipeline/templates/backlog.md +6 -2
- package/plugins/task-pipeline/skills/task-pipeline/templates/brief.md +4 -3
- package/plugins/task-pipeline/skills/task-pipeline/templates/retro.md +6 -4
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
|
@@ -30,13 +30,9 @@ elsewhere and is not restated here:
|
|
|
30
30
|
- False success — when a mechanism reports a win it never checked
|
|
31
31
|
- Anatomy of a project gate
|
|
32
32
|
- Writing the check itself
|
|
33
|
-
- Probing — plant, run, restore
|
|
34
|
-
- A probe rots, and every way it rots reports green
|
|
35
33
|
- A ratchet prices the rule, not the exception
|
|
36
34
|
- Run the whole suite locally before you push the tag
|
|
37
|
-
- The neighbour probe — plant the evidence outside the subject
|
|
38
35
|
- A ratchet's matcher is itself a check, and it needs a near-miss
|
|
39
|
-
- A green probe is evidence only if the mutation is known to have landed
|
|
40
36
|
- The false-positive budget
|
|
41
37
|
- Ratchets
|
|
42
38
|
- The result is the goal; the check is how you know
|
|
@@ -107,6 +103,15 @@ Gate assignment is the operator's call and the framework fixes none — so shipp
|
|
|
107
103
|
reclassified stage list would contradict the sentence above it. The type exists; the
|
|
108
104
|
project chooses where it applies.
|
|
109
105
|
|
|
106
|
+
**The rubric steers the builder before it judges the work.** A judgment gate's
|
|
107
|
+
criteria are read twice — by the judge at the gate, and earlier by whoever builds
|
|
108
|
+
toward it — and the second reading is absorbed as direction: Anthropic reports
|
|
109
|
+
agents converging on one aesthetic because a rubric's adjective ("museum
|
|
110
|
+
quality") was obeyed as a target rather than weighed as a bar (read 2026-08-30).
|
|
111
|
+
So write criteria as the direction you want taken, not only as the bar to clear;
|
|
112
|
+
the words will be obeyed either way, and a rubric written carelessly is an
|
|
113
|
+
instruction issued accidentally.
|
|
114
|
+
|
|
110
115
|
| Rationalization | Why it is wrong |
|
|
111
116
|
|---|---|
|
|
112
117
|
| *"The reviewer approved it, so the gate passed."* | It did — as a judgement. Type it as one, or the table claims a machine agreed |
|
|
@@ -191,7 +196,10 @@ Four preconditions. Skipping any of them turns a run into a claim.
|
|
|
191
196
|
added to an already-red base passes for the wrong reason and proves nothing.
|
|
192
197
|
2. **The check has been probed.** Green from a check nobody has watched fail is
|
|
193
198
|
worth nothing. If you did not plant the defect, you do not know what the green
|
|
194
|
-
means.
|
|
199
|
+
means. How to plant, what a probe owes, and every way one rots is
|
|
200
|
+
[`probing.md`](probing.md) — the harness is `test/probe.py`
|
|
201
|
+
(`npm run test:probe`), and hand-rolling a fourth copy of its loop is how
|
|
202
|
+
three probes in one day proved the wrong guard.
|
|
195
203
|
3. **You have read its scope header** and know what it does **not** cover. A gate
|
|
196
204
|
is evidence for exactly the surface it walks; quoting it beyond that is how
|
|
197
205
|
"the gate is green" becomes a false statement made in good faith.
|
|
@@ -338,89 +346,6 @@ exit 0
|
|
|
338
346
|
|
|
339
347
|
---
|
|
340
348
|
|
|
341
|
-
## Probing — plant, run, restore
|
|
342
|
-
|
|
343
|
-
The law is [`audit.md`](audit.md)'s exit criterion. The procedure is this, and it is
|
|
344
|
-
not optional for a check you intend to trust:
|
|
345
|
-
|
|
346
|
-
```bash
|
|
347
|
-
cp -R . /tmp/probe && cd /tmp/probe
|
|
348
|
-
python3 - <<'PY' # plant IN PYTHON, never sed -i
|
|
349
|
-
p = "docs/DECISIONS.md"
|
|
350
|
-
s = open(p).read().replace("DEC-0001", "DEC-9999", 1)
|
|
351
|
-
open(p, "w").write(s)
|
|
352
|
-
PY
|
|
353
|
-
bash scripts/check-docs.sh; echo "planted -> exit=$?" # MUST be non-zero
|
|
354
|
-
cd - && bash scripts/check-docs.sh; echo "clean -> exit=$?" # MUST be 0
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
**Assert on `$?`, not on a `FAIL` line in the output.** A line on stdout is a
|
|
358
|
-
decoration; the exit code is what CI reads.
|
|
359
|
-
|
|
360
|
-
**Doubt the probe before you doubt the check.** On the project this comes from,
|
|
361
|
-
**four of five** silent probes were the probe's fault: one added a *definition*
|
|
362
|
-
where the check looks for an unresolved *reference*; one edited a string whose
|
|
363
|
-
whitespace did not match; one hit the first prose mention instead of the table row;
|
|
364
|
-
one flipped a row whose cell was already empty, so nothing was planted. A silent
|
|
365
|
-
check is a claim about two things, and the probe is the one to doubt first — prove
|
|
366
|
-
your edit landed in the text the check actually parses.
|
|
367
|
-
|
|
368
|
-
**Three assertions, and the third is the one hand-rolled probes keep missing.** A
|
|
369
|
-
plant that trips some *other* check has proved that other check works. Three probes
|
|
370
|
-
in one day passed that way: one removed 1 of 3 identical lines and left the shape
|
|
371
|
-
intact; one decremented a number inside an **already-released** section; one deleted
|
|
372
|
-
the shouted spelling of a phrase and left the lowercase one. Each landed somewhere
|
|
373
|
-
real and demonstrated nothing about the guard it was written for. So:
|
|
374
|
-
|
|
375
|
-
1. **the substitution landed** — `replace` matching nothing returns the string
|
|
376
|
-
unchanged and raises nothing;
|
|
377
|
-
2. **the exit code is non-zero** — not a `FAIL` line on stdout;
|
|
378
|
-
3. **the message that fired belongs to the guard under test** — named up front, not
|
|
379
|
-
recognised afterwards.
|
|
380
|
-
|
|
381
|
-
`test/probe.py` does all three (`npm run test:probe` self-tests the harness, including
|
|
382
|
-
its own failure branches, because a harness whose failure path has never executed is
|
|
383
|
-
the thing it exists to stop). Declare the plant as `Plant(label, path, old, new,
|
|
384
|
-
expect=<the guard's own words>)` rather than hand-rolling a fourth copy of the loop.
|
|
385
|
-
|
|
386
|
-
**Record the probe.** One line per section, in the change that ships the check.
|
|
387
|
-
Otherwise the next reader has to redo it to know whether it was ever done.
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## A probe rots, and every way it rots reports green
|
|
392
|
-
|
|
393
|
-
The three assertions above prove a probe works **today**. They say nothing about the
|
|
394
|
-
day after, and a probe is uniquely exposed: the thing it guards is the thing that moves
|
|
395
|
-
it. Four rotted in one release on 2026-08-22, and none of them failed loudly — two
|
|
396
|
-
reported `caught`, two reported nothing at all.
|
|
397
|
-
|
|
398
|
-
**1. The anchor is a literal the guarded thing moves.** A probe pinned to *"the bundle
|
|
399
|
-
is N reference files"* stops landing the day a reference file is added — on the release
|
|
400
|
-
that changes the very number it guards. Same for a version, a count word, a phrase a
|
|
401
|
-
release rewrites. **Derive the anchor**: read whatever the text currently says and make
|
|
402
|
-
*that* wrong. A probe that computes `wrong = stated - 1` never needs maintaining.
|
|
403
|
-
|
|
404
|
-
**2. The precondition is inherited from the tree rather than created.** This is the
|
|
405
|
-
subtle one, because it is triggered by the system working correctly. A probe that
|
|
406
|
-
narrows a declared gap to expose *releases after the newest run stamp* has nothing to
|
|
407
|
-
expose the moment a release writes an honest stamp — the newest release is now the
|
|
408
|
-
newest stamp. A probe requiring an `## Unreleased` section has none the moment a release
|
|
409
|
-
absorbs it. **Both landed. Both proved nothing.** A probe must construct the state it
|
|
410
|
-
needs: remove the stamp, write the section, then plant the defect.
|
|
411
|
-
|
|
412
|
-
**3. The document quotes the form the probe removes.** Covered as
|
|
413
|
-
[`documentation.md`](documentation.md) canon 2's second half, and it belongs here too
|
|
414
|
-
because the probe is where it surfaces: prose describing the wrong shape *with real
|
|
415
|
-
values in it* is a second instance of the shape. The probe deletes the real one, the
|
|
416
|
-
narrative still matches, the guard is silent.
|
|
417
|
-
|
|
418
|
-
**How to see it before CI does.** Ask one question per probe: *what does this probe
|
|
419
|
-
LOOK FOR, and who is allowed to change it?* Where the answer is "the thing it guards",
|
|
420
|
-
it is rotting already. A repository-wide sweep is one grep — a two-digit literal inside
|
|
421
|
-
a needle, an `assert` or a `replace` — and the triage is: the number a probe **writes**
|
|
422
|
-
is correct, the number it **looks for** is the defect.
|
|
423
|
-
|
|
424
349
|
## A ratchet prices the rule, not the exception
|
|
425
350
|
|
|
426
351
|
A floor that counts assertions is a floor that can be lowered by improving the code, if
|
|
@@ -477,61 +402,11 @@ the tag-ancestry check, the version-sync check and the run-stamp check have no e
|
|
|
477
402
|
opportunity to fire. Locally, run them the way the release does — against the tree you are
|
|
478
403
|
about to tag, with the suite the release claims.
|
|
479
404
|
|
|
480
|
-
## The neighbour probe — plant the evidence outside the subject
|
|
481
|
-
|
|
482
|
-
A probe proves a guard rejects **the phrasing its author had in mind**. That is less than
|
|
483
|
-
it looks, and the gap has one shape: **a check answered by text that is not its subject.**
|
|
484
|
-
|
|
485
|
-
Measured on one project in one session, six times, each found by a reader planting a
|
|
486
|
-
defect and watching `PASS`:
|
|
487
|
-
|
|
488
|
-
| The check's subject | The text that answered it instead |
|
|
489
|
-
|---|---|
|
|
490
|
-
| stage 2 names the loop's arming | *"it **arms** the UX track"*, present since an earlier release |
|
|
491
|
-
| the section states the authorization floor | the same phrase in a Rationalizations row, and in a section written twenty-nine releases before |
|
|
492
|
-
| the run stamps have a cap | the **standing instructions'** `max 10`, in the same table cell — and, once the check was narrowed past it, the same cap moved to the other side of the `·` |
|
|
493
|
-
| a section read in full stays capped | rows under **one** heading, while a second heading in the same file held forty more |
|
|
494
|
-
|
|
495
|
-
Every one of those guards had a probe. Every probe fired. The probes and the guards were
|
|
496
|
-
written in the same hour from the same reading, so they shared the same blind spot.
|
|
497
|
-
|
|
498
|
-
**So a guard that reads a scoped span owes a second probe, and it plants in two places at
|
|
499
|
-
once:**
|
|
500
|
-
|
|
501
|
-
1. **break the subject** — remove the thing the guard is about;
|
|
502
|
-
2. **plant the guard's own evidence next door** — in a sibling section, an adjacent table
|
|
503
|
-
cell, a rationalizations row, the other side of a separator;
|
|
504
|
-
3. require the guard to **still fail**.
|
|
505
|
-
|
|
506
|
-
A guard that passes step 3 is reading its subject. A guard that goes green is reading the
|
|
507
|
-
neighbourhood, and the ordinary probe cannot tell the difference — which is why this one
|
|
508
|
-
is separate rather than a stricter version of it.
|
|
509
|
-
|
|
510
|
-
**Step 2 means the literal the predicate matches *today*, read out of the guard.** The
|
|
511
|
-
first three neighbour probes written against this section got that wrong on their first
|
|
512
|
-
run: one planted the needles of two **retired** predicates, which proves the guards that
|
|
513
|
-
used to exist were neighbour-answerable and says nothing about the one that does. A
|
|
514
|
-
neighbour probe keyed to a needle the guard no longer reads is the same defect it was
|
|
515
|
-
written to catch, one level up.
|
|
516
|
-
|
|
517
|
-
**A probe that only deletes is not a neighbour probe.** It may still be a correct probe —
|
|
518
|
-
but if it relies on copies that already sit next door, it must **assert they are there**.
|
|
519
|
-
Otherwise a later edit removes them and the probe quietly becomes a delete-only test that
|
|
520
|
-
still passes, having stopped testing the thing it is named for.
|
|
521
|
-
|
|
522
|
-
**Positional narrowing is not scoping.** Three of the six were "fixed" by cutting the
|
|
523
|
-
search down to a row, then to everything after a phrase, and fell each time to text that
|
|
524
|
-
was still inside the cut. Scope by *what the span is about*: split to the cell, then to
|
|
525
|
-
the item, then match on flattened text so an emphasis marker cannot hide the boundary.
|
|
526
|
-
|
|
527
|
-
**And state the span in the guard.** One line above the predicate — *what it reads, and
|
|
528
|
-
where that ends*. It costs nothing and it is the only part of a check a later reader can
|
|
529
|
-
disagree with before the defect arrives.
|
|
530
|
-
|
|
531
405
|
## A ratchet's matcher is itself a check, and it needs a near-miss
|
|
532
406
|
|
|
533
|
-
Reported from another project through `retro.publish`, and it is the neighbour
|
|
534
|
-
own class
|
|
407
|
+
Reported from another project through `retro.publish`, and it is the neighbour
|
|
408
|
+
probe's own class ([`probing.md`](probing.md) → *The neighbour probe*) arrived at
|
|
409
|
+
independently — which is the strongest evidence either has.
|
|
535
410
|
|
|
536
411
|
A run built a ratchet to hold a coverage debt: a list of units with no test, a guard that
|
|
537
412
|
fails when the list grows, a count printed at the gate. Exactly the shape
|
|
@@ -558,49 +433,6 @@ the reason.** In the reporting project the corrected count was *identical* to th
|
|
|
558
433
|
and the composition was not: rows credited falsely came back in as rows genuinely paid off
|
|
559
434
|
went out. A single number with no delta reads as a run where nothing happened.
|
|
560
435
|
|
|
561
|
-
## A green probe is evidence only if the mutation is known to have landed
|
|
562
|
-
|
|
563
|
-
Also reported from another project, three times in one day, each caught only because the
|
|
564
|
-
result was too good:
|
|
565
|
-
|
|
566
|
-
1. a scripted substitution missed on indentation — the file was unchanged and the probe
|
|
567
|
-
measured nothing;
|
|
568
|
-
2. an assertion written against a bare identifier kept matching the **import line** after
|
|
569
|
-
the field it guarded was deleted;
|
|
570
|
-
3. a file-extension alternation matched the longer extension as though it were the
|
|
571
|
-
shorter, reporting nine live files as missing.
|
|
572
|
-
|
|
573
|
-
In all three the observable was identical to success. *"See it fail once"* has an unstated
|
|
574
|
-
precondition — **that the thing you changed is the thing the check reads** — and a planted
|
|
575
|
-
defect that did not land produces the same green as a check that cannot fail.
|
|
576
|
-
|
|
577
|
-
**So a probe that mutates an existing file asserts its plant landed, in the same breath as
|
|
578
|
-
planting it.** A probe that writes a whole file has no such question: the file exists or
|
|
579
|
-
the command failed. This repository measured itself while writing this section and got the
|
|
580
|
-
number wrong three times. A hand-rolled classifier said *206 of 206 already carry it*.
|
|
581
|
-
The guard written from the rule said **22 did not** — and was itself too narrow, matching
|
|
582
|
-
one spelling of the assertion, so six probes that already had it in lower case were
|
|
583
|
-
called defective. A sweep then "fixed" those six and **corrupted five**, splitting live
|
|
584
|
-
statements. The true figure was **16**, and it took the guard, a compile check and a
|
|
585
|
-
restore from git to find it.
|
|
586
|
-
|
|
587
|
-
Two things are worth keeping from that. **The check corrected the measurement that
|
|
588
|
-
motivated it** — which is the argument for writing checks rather than counting by hand.
|
|
589
|
-
And **a check keyed to one spelling of a rule is the class two sections above**: it
|
|
590
|
-
reported as defective the probes that obeyed the rule in different words. **Every**
|
|
591
|
-
mutating probe carries the assertion now — the figure is deliberately not
|
|
592
|
-
written here. A first draft said *201*, which was true of the branch point and false in
|
|
593
|
-
the same commit, because the twelve probes added for this release are themselves mutating
|
|
594
|
-
probes. The guard computes it; a number in prose beside a check that can count is the
|
|
595
|
-
class this bundle calls restating instead of computing. Probes that write a whole file
|
|
596
|
-
need none: the file exists or the command
|
|
597
|
-
failed.
|
|
598
|
-
|
|
599
|
-
**Prefer an assertion that names the construct over one that names a substring of it.** A
|
|
600
|
-
guard written against a bare identifier survives the deletion of everything it guarded,
|
|
601
|
-
because the identifier still appears in an import. That is case 2 above and it is the same
|
|
602
|
-
class as the section before this one, one level down.
|
|
603
|
-
|
|
604
436
|
## The false-positive budget
|
|
605
437
|
|
|
606
438
|
Run a new heuristic over the **real corpus** before shipping it and count the false
|
|
@@ -772,7 +604,7 @@ of is deleted in the next refactor by someone who assumed it was dead.
|
|
|
772
604
|
|
|
773
605
|
## Cross-cutting, at every stage
|
|
774
606
|
|
|
775
|
-
|
|
607
|
+
**When anything is settled — scope, a contract, a
|
|
776
608
|
name, a policy, a vocabulary — run the Doc Loop
|
|
777
609
|
(`references/documentation.md`) before the run moves on**: reserve the id,
|
|
778
610
|
record it, resolve the question it answers, propagate by the matrix, commit
|
|
@@ -50,7 +50,7 @@ makes the grill's answers *checkable* instead of merely confident.
|
|
|
50
50
|
| 4b | **The task register, for its *state*** | `docs/ROADMAP.md`, a board, a backlog, the tracker `CLAUDE.md` names | **what is open right now** — read with a command, never from memory; see *Carried-in claims* |
|
|
51
51
|
| 5 | **Product/UX docs** | `docs/ux/` (super-ux chain), `README`, runbooks | user-facing behavior that is already specified |
|
|
52
52
|
| 6 | **Pipeline history** | `<artifacts>/specs/`, `plans/`, past `-carryover.md` | what a previous run of this pipeline decided or deferred |
|
|
53
|
-
| 7 | **The retro, in force** | `<artifacts>/retro.md` ([`retrospective.md`](retrospective.md)) | what previous runs got wrong here — **read in full**: standing instructions (capped at ten)
|
|
53
|
+
| 7 | **The retro, in force** | `<artifacts>/retro.md` ([`retrospective.md`](retrospective.md)) | what previous runs got wrong here — **read in full**: standing instructions (capped at ten) and run stamps (one line each), both bounded by construction; the *Recent log* is **queried** by the task's nouns, like the archive — nothing caps it |
|
|
54
54
|
| 7a | **The retro archive** | `<artifacts>/retro/YYYY-QN.md` | *have we been bitten by this class before?* — **queried** by the task's nouns, never read end to end |
|
|
55
55
|
| 8 | **The knowledge wiki** | see below | distilled cross-project knowledge, prior sessions, why decisions were made |
|
|
56
56
|
| 9 | **Other doc repos the project names** | a docs repo URL or submodule in `CLAUDE.md`/`README`, a sibling checkout, a `docs/` monorepo package | specs, contracts and runbooks that live outside this repo |
|
|
@@ -63,3 +63,16 @@ and no silent downgrade to a cheaper tier.
|
|
|
63
63
|
The recommendation is a **reminder, not a block**. If the recommended tier isn't
|
|
64
64
|
available, keep the current model, state plainly which one is in use, and run. The
|
|
65
65
|
pipeline never stalls on a model it can't get.
|
|
66
|
+
|
|
67
|
+
## A harness clause encodes a model's weakness — stress-test it per generation
|
|
68
|
+
|
|
69
|
+
Every fixed control in this pipeline — a cap, a mandatory checkpoint, a fix-loop
|
|
70
|
+
ceiling — encodes an assumption about what the confirmed model cannot yet do
|
|
71
|
+
reliably, and those assumptions expire: Anthropic reports removing an entire
|
|
72
|
+
construct from its own long-running harness when a newer model generation stopped
|
|
73
|
+
needing it (*Harness design for long-running agents*,
|
|
74
|
+
anthropic.com/engineering, read 2026-08-30). So when the confirmed tier moves a
|
|
75
|
+
generation, re-test the clauses that exist to compensate the old one instead of
|
|
76
|
+
carrying them as doctrine — a control the model has outgrown is not free, it is a
|
|
77
|
+
stop nobody can name the reason for. The retro's cold-retirement trigger is the
|
|
78
|
+
same rule applied to standing instructions; this is it applied to the harness.
|
|
@@ -57,11 +57,13 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
57
57
|
| **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
|
|
58
58
|
| **The context budget** — the evidence rule and what a flush actually updates | `references/continuity.md` |
|
|
59
59
|
| **The board** — the work-list between runs, its computed priority, and the ledger seam it resolves | `references/backlog.md` |
|
|
60
|
+
| **The order** — the impact ladder, confidence and ease, research before scoring, and where the human goes | `references/prioritisation.md` |
|
|
60
61
|
| **The verification ledger** — what shipped, and whether a human ever confirmed it | `references/verification.md` |
|
|
61
62
|
| **Exposure** — the unconfirmed count as a named vector, never a probability, and the `checkup` mode | `references/exposure.md` |
|
|
62
63
|
| The retro: prune, cap, commits, archive | `references/retrospective.md` |
|
|
63
64
|
| Rules earned by failure | `references/learned.md` |
|
|
64
65
|
| **The routing default and its boundary** | `templates/routing-rule.md` |
|
|
66
|
+
| **Probing** — plant, run, restore; how a probe rots; the neighbour probe; the landed-mutation rule | `references/probing.md` |
|
|
65
67
|
| The seeded doc map, registers and gate | `templates/docmap.md`, `templates/decisions.md`, `templates/open-questions.md`, `templates/docgate.sh` |
|
|
66
68
|
| Which agent-introduced defects are found, and that the agent fixes them rather than the script | `templates/hygiene.sh`, `references/build.md` |
|
|
67
69
|
| What a stage-3/4 self-review must read back, and that its trace is computed numbers | `references/spec.md`, `references/planning.md`, `references/learned.md` |
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Prioritisation — what to do next, and why that and not the other thing
|
|
2
|
+
|
|
3
|
+
**Load this when** the task was not named, when the next row comes off the backlog, when
|
|
4
|
+
the operator asks what to work on, or when a run is about to spend a day on something and
|
|
5
|
+
nobody has checked that it is the most valuable day available.
|
|
6
|
+
|
|
7
|
+
`backlog.md` owns the **board** — what a row is, where it lives, how it closes. This owns
|
|
8
|
+
the **order** the rows come off it.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- The default, and its one exception
|
|
13
|
+
- 1. The impact ladder
|
|
14
|
+
- 2. Confidence and Ease
|
|
15
|
+
- 3. The order, and why it is not a product
|
|
16
|
+
- 4. Research before scoring, not after
|
|
17
|
+
- 5. Where the human goes
|
|
18
|
+
- 6. Two models in one family, and why both are right
|
|
19
|
+
|
|
20
|
+
## The default, and its one exception
|
|
21
|
+
|
|
22
|
+
**Every run assumes a backlog exists and that this task competes with it.** A task arriving
|
|
23
|
+
with no stated priority is not priority-free; it is unranked, which is a different and
|
|
24
|
+
worse thing.
|
|
25
|
+
|
|
26
|
+
**The exception is the operator, and it is absolute.** When they name the task, that is the
|
|
27
|
+
task. The most this file authorises is **one line** — *"`BL-14` scores higher: a checkout
|
|
28
|
+
error affecting paying users. Say the word and I switch; otherwise starting yours now"* —
|
|
29
|
+
and then starting theirs. Not a second ask, not a hedge, not a silent substitution. An
|
|
30
|
+
operator who knows what they are doing is the most reliable prioritiser in the system, and
|
|
31
|
+
an agent that argues with them twice has made itself expensive to use.
|
|
32
|
+
|
|
33
|
+
## 1. The impact ladder
|
|
34
|
+
|
|
35
|
+
Impact is the rung, not a feeling. The ladder exists so a bug and a feature can be compared
|
|
36
|
+
at all — without it, "impact" is scored per-item by whoever is looking, and every item is
|
|
37
|
+
somebody's priority.
|
|
38
|
+
|
|
39
|
+
| Rung | What it means | Test |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **I5** | the product does not work for someone **right now** | data loss, an outage, a broken purchase, a blocked signup |
|
|
42
|
+
| **I4** | a product or business metric moves | revenue, activation, retention, traffic, conversion |
|
|
43
|
+
| **I3** | it works, and the experience degrades | crash-free rate, error rate, latency, a rough edge people hit |
|
|
44
|
+
| **I2** | our own speed | debt, tooling, tests, anything that changes how fast the next thing ships |
|
|
45
|
+
| **I1** | polish | nobody's metric moves; it is better and that is all |
|
|
46
|
+
|
|
47
|
+
Two rules that carry most of the value:
|
|
48
|
+
|
|
49
|
+
- **An unmeasured claim of I4 is I3 until it is measured.** "This will lift conversion" is
|
|
50
|
+
a hypothesis; the rung is what the evidence supports, and the gap goes in Confidence.
|
|
51
|
+
- **Blocking is not a rung, it is a multiplier on someone else.** A task nobody can proceed
|
|
52
|
+
past inherits the highest rung it blocks. State whose work it blocks, or it is not
|
|
53
|
+
blocking — it is just old.
|
|
54
|
+
|
|
55
|
+
## 2. Confidence and Ease
|
|
56
|
+
|
|
57
|
+
Both are 1–3, both are judgement, and both are written down **as** judgement — small
|
|
58
|
+
integers a reader can disagree with, in the row, next to the rung.
|
|
59
|
+
|
|
60
|
+
**Confidence** — how sure are we that doing this produces the effect claimed?
|
|
61
|
+
|
|
62
|
+
| | |
|
|
63
|
+
|---|---|
|
|
64
|
+
| **C3** | measured, or the mechanism is obvious and the change is local |
|
|
65
|
+
| **C2** | reasoned from something real — a trace, a ticket, one user |
|
|
66
|
+
| **C1** | a guess we believe. Fine to hold, not fine to hide |
|
|
67
|
+
|
|
68
|
+
**Ease** — how cheap is it, including the parts nobody counts?
|
|
69
|
+
|
|
70
|
+
| | |
|
|
71
|
+
|---|---|
|
|
72
|
+
| **E3** | within a run, one surface, reversible |
|
|
73
|
+
| **E2** | a few surfaces, or one that needs coordination |
|
|
74
|
+
| **E1** | crosses repositories, needs a migration or a credential, or cannot be undone cheaply |
|
|
75
|
+
|
|
76
|
+
Ease counts the **whole** cost: the migration, the review, the rollback, the second
|
|
77
|
+
repository. An E3 that turns out to need a credential from a person who is asleep was an E1
|
|
78
|
+
and the estimate was the defect.
|
|
79
|
+
|
|
80
|
+
## 3. The order, and why it is not a product
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
sort by I descending the ladder dominates
|
|
84
|
+
then by C × E descending 1..9 within the rung
|
|
85
|
+
then by age descending the tie-break, oldest first
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Classic ICE multiplies I × C × E, and this deliberately does not.** Multiplying lets a
|
|
89
|
+
trivial certain easy win outrank a hard uncertain critical one — `I1×C3×E3 = 9` beats
|
|
90
|
+
`I5×C1×E1 = 5` — and shipping the 9 while the 5 waits is precisely the failure this file
|
|
91
|
+
exists to prevent. It is also the failure that feels most productive from inside: a
|
|
92
|
+
stream of small completed things while the thing that matters sits.
|
|
93
|
+
|
|
94
|
+
So the ladder is a **gate**, not a factor. `C × E` orders within a rung and never across
|
|
95
|
+
one.
|
|
96
|
+
|
|
97
|
+
**What age may and may not do.** It breaks ties, and past **30 days** the row is reported
|
|
98
|
+
as one the queue has been lying about — surfaced in the run's output, not silently
|
|
99
|
+
promoted. Age never lifts a row across a rung: a polish item that has waited a year is
|
|
100
|
+
still polish, and letting it climb is how a queue ends up sorted by patience.
|
|
101
|
+
|
|
102
|
+
**`prio` in `backlog.md` is not replaced.** That formula (`sev × blast + age_bonus`) ranks
|
|
103
|
+
*findings against each other* and stays the board's own column. This file's ordering is
|
|
104
|
+
what runs when findings and product work compete in **one** list — the finding's rung comes
|
|
105
|
+
from the ladder above, and `sev × blast` is evidence for it, not a substitute.
|
|
106
|
+
|
|
107
|
+
## 4. Research before scoring, not after
|
|
108
|
+
|
|
109
|
+
**A row is scored from what it touches, never from its title.** "Fix the login redirect"
|
|
110
|
+
is E3 by its name and E1 once you find it crosses an auth library, a cookie domain and a
|
|
111
|
+
cached edge rule. Scoring first and discovering second produces an order that was wrong
|
|
112
|
+
before the first task started.
|
|
113
|
+
|
|
114
|
+
So, before an order is emitted:
|
|
115
|
+
|
|
116
|
+
1. **Fan out one researcher per candidate row** — same rules as `build.md` §4.2: fresh
|
|
117
|
+
context each, given the row and nothing else, no shared working tree because they write
|
|
118
|
+
nothing.
|
|
119
|
+
2. **Each returns four things and no opinion**: what it touches (`file:line`, services,
|
|
120
|
+
external systems), what it depends on and what depends on it, what is already
|
|
121
|
+
*measured* about the claimed effect, and what would have to be true for it to be wrong.
|
|
122
|
+
3. **Score after they return.** The rung comes from the evidence, `C` from what the
|
|
123
|
+
researcher could and could not confirm, `E` from the surfaces they found.
|
|
124
|
+
4. **Emit the ordered list once**, with the three numbers and one line of why per row.
|
|
125
|
+
|
|
126
|
+
A researcher that comes back with "seems fine, medium effort" has returned nothing. The
|
|
127
|
+
four fields are the contract; anything else is a subagent that spent context to guess.
|
|
128
|
+
|
|
129
|
+
**Do not fan out to score two rows.** The dispatch costs more than reading them.
|
|
130
|
+
|
|
131
|
+
## 5. Where the human goes
|
|
132
|
+
|
|
133
|
+
The operator is a **scarce, high-value input**, and the failure mode is spending them one
|
|
134
|
+
question at a time.
|
|
135
|
+
|
|
136
|
+
- **Ask at the start, or in a batch at a boundary. Never after each task.** If the whole
|
|
137
|
+
queue needs one decision, ask it before the queue starts.
|
|
138
|
+
- **A blocked row does not stop the run.** When something needs a person: first satisfy
|
|
139
|
+
yourself that you are actually right and it is actually blocked — most "I need input"
|
|
140
|
+
is an unread file — then write the question **into the row**, mark it `needs-operator`,
|
|
141
|
+
and take the next row that is not blocked by the same answer.
|
|
142
|
+
- **The question in the row is answerable without context.** What was tried, what is
|
|
143
|
+
needed, and what happens under each answer. A question that requires re-reading the run
|
|
144
|
+
to understand is a question that waits another day.
|
|
145
|
+
- **Batch the answers back.** The operator returns to a list of questions with their
|
|
146
|
+
consequences, not to a transcript.
|
|
147
|
+
|
|
148
|
+
The measure of this section: **how much of the queue moved while nobody was watching**, and
|
|
149
|
+
whether the things that stopped genuinely could not proceed.
|
|
150
|
+
|
|
151
|
+
## 6. Two models in one family, and why both are right
|
|
152
|
+
|
|
153
|
+
`seo-aeo-audit` triages on impact, irreversibility, uncertainty and coordination, and states
|
|
154
|
+
that **effort is recorded and never ranks**.
|
|
155
|
+
This file makes Ease rank. That is not a contradiction and the difference is the queue:
|
|
156
|
+
|
|
157
|
+
| | an **audit** | a **backlog** |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| the list is | everything that is wrong | everything that could be done |
|
|
160
|
+
| letting effort rank means | a blocker gets skipped for being hard, and the audit lies by omission | the queue self-selects toward value per day |
|
|
161
|
+
| so effort | is recorded and never ranks | ranks, inside the rung |
|
|
162
|
+
|
|
163
|
+
An audit must be complete before it is ordered; a backlog is ordered because it will never
|
|
164
|
+
be complete. Reach for the wrong one and the symptom is recognisable: an audit that
|
|
165
|
+
quietly dropped its hardest finding, or a backlog where nothing small ever ships.
|