task-pipeline-skill 1.96.0 → 1.98.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 +90 -0
- package/HOW-IT-WORKS.md +17 -13
- package/README.md +23 -17
- package/SKILL-CARD.md +2 -2
- package/cursor/rules/task-pipeline.mdc +33 -21
- package/evals/task-pipeline.evals.json +3 -3
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +2 -2
- package/plugins/task-pipeline/commands/task-pipeline.md +14 -219
- package/plugins/task-pipeline/skills/evidence-docs/SKILL.md +8 -1
- package/plugins/task-pipeline/skills/evidence-docs/references/GENERATED.md +1 -1
- package/plugins/task-pipeline/skills/evidence-docs/references/learned.md +24 -1
- package/plugins/task-pipeline/skills/evidence-docs/references/retrospective.md +21 -576
- package/plugins/task-pipeline/skills/project-audit/SKILL.md +8 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +162 -230
- package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +9 -9
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +10 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/brainstorm.md +3 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +48 -11
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +7 -7
- package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +49 -44
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +32 -24
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/finish-line.md +13 -8
- package/plugins/task-pipeline/skills/task-pipeline/references/iteration.md +20 -23
- package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +5 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/learned.md +24 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +17 -7
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +47 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +5 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-00-intake.md +39 -25
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-05-dev.md +3 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-08-post-deploy.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +34 -22
- package/plugins/task-pipeline/skills/task-pipeline/references/tdd.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/waves.md +6 -4
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +77 -21
- package/plugins/task-pipeline/skills/task-pipeline/scripts/retro_budget.py +305 -0
- package/plugins/task-pipeline/skills/task-pipeline/scripts/short_path.py +70 -0
- package/plugins/task-pipeline/skills/task-pipeline/scripts/waves.py +22 -10
- package/plugins/task-pipeline/skills/task-pipeline/templates/browser-claims.json +5 -5
- package/plugins/task-pipeline/skills/task-pipeline/templates/canvas.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/templates/retro-archive.md +9 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/retro.md +10 -1
|
@@ -159,28 +159,25 @@ its slowest node before checking its fastest.
|
|
|
159
159
|
|
|
160
160
|
**The number of rounds follows the node's risk class.** The class is recorded on the node
|
|
161
161
|
as `risk` (R1–R3, [`work-graph.md`](work-graph.md)), computed from what the node touches.
|
|
162
|
-
It is never lowered to save time. **A round is the
|
|
163
|
-
[`certification.md`](certification.md)
|
|
164
|
-
the
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
-
|
|
180
|
-
|
|
181
|
-
→ a passing tier is re-run). A clean round does not cancel the next one, and only passing
|
|
182
|
-
rounds count. R3's adversarial round asks a different question — it hunts for a planted
|
|
183
|
-
defect — and always runs; it counts only when it passes.
|
|
162
|
+
It is never lowered to save time. **A round is the blind tiers the class owes, plus one
|
|
163
|
+
fix cycle** ([`certification.md`](certification.md)), and a clean round ends the node
|
|
164
|
+
unless the class is R3 or the surface is flagship:
|
|
165
|
+
|
|
166
|
+
| Class | Touches | Tiers | Rounds |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| R1 | docs, config, a mechanical change, one isolated file | one | 1 |
|
|
169
|
+
| R2 | an ordinary feature or fix inside one module | three | 1 |
|
|
170
|
+
| R3 | security, cryptography, money, a data migration, a public contract, a seam across repositories, concurrency | three | 2: one blind, one adversarial (plants defects, tries abuse cases, on another model where one is available) |
|
|
171
|
+
|
|
172
|
+
A flagship surface owes four tiers and two rounds, one adversarial, whatever its class.
|
|
173
|
+
|
|
174
|
+
- Each round's fix cycle stays inside [`loop-guard.md`](loop-guard.md)'s caps, and the
|
|
175
|
+
certification ceiling stops the node: it is parked with its evidence and a board row.
|
|
176
|
+
- `graph.py close` refuses a node until its owed rounds have passed, and an R3 or
|
|
177
|
+
flagship node until one of them was recorded adversarial
|
|
178
|
+
([`certification.md`](certification.md) → *Rounds owed by risk class*).
|
|
179
|
+
- A round after a fix re-runs every tier the class owes; a round on an unchanged tree is
|
|
180
|
+
refused unless it is the other kind. Only passing rounds count.
|
|
184
181
|
- Readers stay blind ([`certification.md`](certification.md) → *Blind*). Each reads the
|
|
185
182
|
diff, the packet and the contract, never the builder's reasoning.
|
|
186
183
|
|
|
@@ -384,7 +381,7 @@ release run performs, not unrelated deployments, messages or human-only actions.
|
|
|
384
381
|
|---|---|
|
|
385
382
|
| "This bug is tiny, fix it now" | Tiny fixes are what move a seam twice. It joins the inventory, or it is one of the hotfix lane's five entries |
|
|
386
383
|
| "Wait for the whole wave, then verify" | A barrier idles every finished node. Each node is certified when it lands |
|
|
387
|
-
| "R3 found nothing in round
|
|
384
|
+
| "R3 found nothing in its blind round, skip the adversarial round" | The adversarial round, in any position, asks a different question: it hunts for a planted defect. A clean blind round does not answer it |
|
|
388
385
|
| "Ask the operator now, it is quick" | Each question is a human round. Queue it and take another node |
|
|
389
386
|
| "The agent hit a rate limit, start it again" | Resume it with its context. Relaunching pays for the same reading twice |
|
|
390
387
|
| "No Observatory here, so no learning loop" | The project retro and learned.md are the loop's first layer, and every install has them |
|
|
@@ -51,7 +51,7 @@ makes the grill's answers *checkable* instead of merely confident.
|
|
|
51
51
|
| 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* |
|
|
52
52
|
| 5 | **Product/UX docs** | `docs/ux/` (super-ux chain), `README`, runbooks | user-facing behavior that is already specified |
|
|
53
53
|
| 6 | **Pipeline history** | `<artifacts>/specs/`, `plans/`, past `-carryover.md` | what a previous run of this pipeline decided or deferred |
|
|
54
|
-
| 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
|
|
54
|
+
| 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 under the floor's 12 000-byte budget, whose bytes and bytes/4 tokens `scripts/retro_budget.py check` prints into this row; the *Recent log* is **queried** by the task's nouns, like the archive — nothing caps it |
|
|
55
55
|
| 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 |
|
|
56
56
|
| 7b | **Lessons from other projects** | the local index every install has (`scripts/lessons.py query`), and a shared lesson store only where the session lists one — an Observatory — detected by its tools, never by a path ([`iteration.md`](iteration.md) → *The learning loop*, the read recipe) | *what did other projects' agents learn about this class?* — **queried** by the task's 3–6 nouns, at most ten lines from both; a lesson that fires is cited `[lesson L-…]` or `[lesson mem:…]`. The ledger names each layer's state: `local lessons: N match | absent | unavailable (no python3)`; `shared lessons: N match | 0 match (filter unknown) | unfilterable | absent`, where the first `observatory_search` call is the probe — and nothing else changes |
|
|
57
57
|
| 8 | **The knowledge wiki** | see below | distilled cross-project knowledge, prior sessions, why decisions were made |
|
|
@@ -79,8 +79,10 @@ Rules for the list:
|
|
|
79
79
|
|
|
80
80
|
`<artifacts>/retro.md` ([`retrospective.md`](retrospective.md)) is the one
|
|
81
81
|
harvested source whose binding part is **read in full rather than queried**: the
|
|
82
|
-
standing instructions are capped at ten
|
|
83
|
-
|
|
82
|
+
standing instructions are capped at ten rows of at most 600 characters, the run stamps
|
|
83
|
+
at ten lines of at most 300, and the two together at 12 000 bytes
|
|
84
|
+
([`retrospective.md`](retrospective.md) → *The floor has a byte budget*), precisely so
|
|
85
|
+
that this is cheap. Its narrative log is queried, not read — an uncapped section
|
|
84
86
|
inside a source that binds is how the capped part stops being read. They are what
|
|
85
87
|
previous runs of this pipeline got wrong *in this project* — the rules no check
|
|
86
88
|
could decide — and they bind this run.
|
|
@@ -58,6 +58,13 @@ to be enforced and is not is the same failure as a gate that prints `FAIL` and e
|
|
|
58
58
|
| 30 | **A gate scoped by exclusion judges every newcomer silently** | any lint, format or check configured with an ignore list rather than an include list | scope by what it COVERS; where the tool has no such switch, assert the covered set and fail on additions, deriving the allowlist by measuring the tool's own reach | the failure message names the intruder and the remedy, because the operator meets it mid-release |
|
|
59
59
|
| 31 | **A gate needs a third verdict — could not measure** | any check that can time out, lose a dependency, or run on a contended machine | distinguish *failed* from *could not measure* with different exit codes, and say which; neither is a verdict about the code | the refusal names its remedy, and a test that waits for a DURATION rather than an event is treated as a defect in the test |
|
|
60
60
|
| 32 | **A test whose assertion is implied by compilation is not a test** | any test whose name promises a behaviour | delete the subject: if that is a type or import error rather than a red test, the test is decoration | removing one asks what the name PROMISED and whether anything checks it — four of five such cases here were covered elsewhere and the fifth was a real gap only visible because the name was read as a claim |
|
|
61
|
+
| 33 | **Snapshot before you undo** | any `git checkout`, `git restore`, `git stash` or `reset` in a tree that may hold uncommitted work you did not write | copy the affected files first (to a dated folder, or `git diff > <file>.patch`) and restore from that copy, never from git | the run names the copy it took before the first destructive command |
|
|
62
|
+
| 34 | **One answer for inputs that should differ is a broken instrument** | any shell measurement, zsh above all | quote every expansion (`"$var"`, `'*.py'`), read data from files rather than inline literals, and feed it two inputs that should answer differently | the two answers differ, or the instrument is rewritten before its answer is used |
|
|
63
|
+
| 35 | **Release the tree you tested** | any tag or release | run the release workflow's own suite on the exact commit the tag will name, and select the CI run by that tag, never by branch | the run the tag triggered is green and its head SHA is the tagged commit |
|
|
64
|
+
| 36 | **A fix after a passing review is unreviewed** | any change made after a review or verifier passed | re-read the delta (`git diff <reviewed>..HEAD`) before merge | the merge names the reviewed SHA and who read the delta |
|
|
65
|
+
| 37 | **Call the real service once before writing its fake** | any mock, stub or fixture of an external API, CLI or service | make one real call, or read a recorded real response, and shape the fake from it | the fake cites the response it was shaped from |
|
|
66
|
+
| 38 | **Close blockers yourself; park only human gates** | any blocker about to be handed back | try every route the run holds (an API, a CLI, a credential door) first; park only a sign-in, consent, payment, typed secret or recorded operator decision | every handed-back item is a human gate, listed in one block with the route that failed |
|
|
67
|
+
| 39 | **Never retry an unchanged failing action** | any failed command, check or approach | change the input or the approach before trying again; after two failed approaches, change approach or record a blocker | no identical retry in the run ledger, and a third attempt names what changed |
|
|
61
68
|
|
|
62
69
|
---
|
|
63
70
|
|
|
@@ -163,6 +170,17 @@ that document is checked. This one governs a fact that crossed a **session bound
|
|
|
163
170
|
reported as current — the case where there is no document to check, only a memory that reads like
|
|
164
171
|
one.
|
|
165
172
|
|
|
173
|
+
**33 to 39 · The 2026-10-20 retro audit.** Read across ~54 retrospectives from ~50
|
|
174
|
+
projects, the same lessons recurred under different words, each in at least the number
|
|
175
|
+
of runs given: uncommitted work overwritten by a checkout, restore or stash with no copy
|
|
176
|
+
taken (17); a zsh glob or `=` left unquoted, so a command failed or a loop printed one
|
|
177
|
+
count for every file (8; this release's own run hit both); a tag cut from a tree the
|
|
178
|
+
release suite never ran on, or a CI run picked by branch rather than by tag (24, with
|
|
179
|
+
immutable tags burned); a fix landed after the review passed and merged unread; a fake
|
|
180
|
+
shaped from documentation that the real service contradicted (11); a hand-back listing
|
|
181
|
+
steps the agent could have done itself (12); and the same failing action retried
|
|
182
|
+
unchanged, round after round. None of them was new to the project that hit it again.
|
|
183
|
+
|
|
166
184
|
---
|
|
167
185
|
|
|
168
186
|
## The two that are not in the table, and why
|
|
@@ -214,6 +232,11 @@ answer would have exposed it in a minute.
|
|
|
214
232
|
| 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) |
|
|
215
233
|
| 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* |
|
|
216
234
|
| 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* |
|
|
235
|
+
| any stage · a destructive git command · a shell measurement | 33, 34 |
|
|
236
|
+
| 7 Release · 5 Dev after review | 35, 36 |
|
|
237
|
+
| 5 Dev · 6 Tests · a fake of an external service | 37 |
|
|
238
|
+
| 10 Acceptance · the hand-back | 38 |
|
|
239
|
+
| every stage · any retry | 39, [`loop-guard.md`](loop-guard.md) |
|
|
217
240
|
|
|
218
241
|
**This file is the shipped list; a project keeps its own.** Every rule in the table
|
|
219
242
|
above was earned on someone else's build and travels with the skill. The lessons *your*
|
|
@@ -276,7 +299,7 @@ evidence that something left, and the log below says what.
|
|
|
276
299
|
|
|
277
300
|
### Retired
|
|
278
301
|
|
|
279
|
-
**Numbers issued so far:
|
|
302
|
+
**Numbers issued so far: 39.** This is the high-water mark, and it is the only number
|
|
280
303
|
this file states about itself — deliberately, because the gap that proves a rule left
|
|
281
304
|
cannot be computed from the table alone: **deleting the highest-numbered rule shrinks
|
|
282
305
|
the maximum with it, and no gap ever opens.** That false negative shipped in the first
|
|
@@ -22,7 +22,7 @@ searches.
|
|
|
22
22
|
|
|
23
23
|
- Bookkeeping — the thing that makes detection mechanical
|
|
24
24
|
- Detection — any one of these trips the guard
|
|
25
|
-
- The review loop
|
|
25
|
+
- The review loop: a cap that stops, and says why
|
|
26
26
|
- The re-render loop — a budget of one, two at most
|
|
27
27
|
- The break protocol
|
|
28
28
|
- When to stop and hand back
|
|
@@ -66,12 +66,20 @@ stage's gate — which is the whole difference between a rule and a rule that ru
|
|
|
66
66
|
loop (another task, another module) already closed in this run — two owners for
|
|
67
67
|
one file.
|
|
68
68
|
|
|
69
|
-
Caps that trip the guard by themselves: **
|
|
69
|
+
Caps that trip the guard by themselves: **3 fix rounds** per task
|
|
70
70
|
([`build.md`](build.md)), **2 re-entries** per stage per artifact, **3 passes** per
|
|
71
|
-
module in the program loop,
|
|
72
|
-
|
|
71
|
+
module in the program loop, **3 review rounds** per artifact, and **3 failing
|
|
72
|
+
certification rounds** per node ([`certification.md`](certification.md)). Each one
|
|
73
|
+
**stops**: the remaining findings become blocker rows with their evidence and the run
|
|
74
|
+
moves on (since 1.98.0; the review cap used to measure only).
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
**Two rules hold under every cap.** Never retry an unchanged failing action: the same
|
|
77
|
+
command on the same input gives the same answer, so a retry is a loop with no
|
|
78
|
+
information in it. After two failed approaches to one problem, change the approach or
|
|
79
|
+
record a blocker; a third attempt of the same shape is the loop this file exists to
|
|
80
|
+
end ([`learned.md`](learned.md) rule 39).
|
|
81
|
+
|
|
82
|
+
## The review loop: a cap that stops, and says why
|
|
75
83
|
|
|
76
84
|
The caps above govern loops that **edit**. A review loop does both: the reader finds,
|
|
77
85
|
the run fixes, the reader reads again. It had no cap at all until 2026-08-10, and this
|
|
@@ -98,8 +106,10 @@ review cap reached — 3 rounds — artifact: test/validate.py
|
|
|
98
106
|
- **Self-inflicted ≥ new** — the axis is exhausted ([`audit.md`](audit.md) → *Every
|
|
99
107
|
pass changes the axis*). Stop. Every remaining finding becomes a board row with its
|
|
100
108
|
evidence ([`backlog.md`](backlog.md)); none is dropped.
|
|
101
|
-
- **New > self-inflicted** — the reader is still paying
|
|
102
|
-
|
|
109
|
+
- **New > self-inflicted** — the reader is still paying, and the loop still stops: the
|
|
110
|
+
open findings become board rows with the numbers beside them. A further round runs
|
|
111
|
+
only on the operator's explicit request, which is read when given and never waited
|
|
112
|
+
for.
|
|
103
113
|
|
|
104
114
|
At the level of a whole iteration only new **blocking** findings argue for continuing; a
|
|
105
115
|
deferred or noise finding is paid for on the board, not with another round
|
|
@@ -18,7 +18,7 @@ justifies reading it protects one section while the file below it doubles.
|
|
|
18
18
|
|
|
19
19
|
| Artifact | Parts | How it is read |
|
|
20
20
|
|---|---|---|
|
|
21
|
-
| `docs/evidence/retro.md` — **one per project** | **Standing instructions** (max **10**) · **Run stamps** (max **10**, oldest rotate out) | stage 0, **in full
|
|
21
|
+
| `docs/evidence/retro.md` — **one per project** | **Standing instructions** (max **10**) · **Run stamps** (max **10**, oldest rotate out) | stage 0, **in full**: both are bounded by a **cap** and, since 1.98.0, by a **byte budget** (*The floor has a byte budget*) |
|
|
22
22
|
| the same file's **Recent log** | narrative entries, **uncapped by design** — the heading said *entries from the last five run stamps* until 2026-08-20 while the section held 25 going back nine days, a bound in a heading that nothing enforced | stage 0, **queried** by the task's nouns. It said *in full* until 2026-08-10, when it measured **74%** of the file: an uncapped section inside a binding source is what makes the capped part get skimmed |
|
|
23
23
|
| `docs/evidence/retro/YYYY-QN.md` — the archive | every entry and every retirement ever written, append-only | **queried** by the task's nouns; never read end to end |
|
|
24
24
|
|
|
@@ -35,6 +35,8 @@ file exists to stop.
|
|
|
35
35
|
- Never amend a commit a record already names
|
|
36
36
|
- A release stamp names the TAG, and the merge commit — never the branch's own SHA
|
|
37
37
|
- The stamp table is capped at ten, and *one line per run* was never a cap
|
|
38
|
+
- The floor has a byte budget
|
|
39
|
+
- Before a standing row: search, cite, send upstream
|
|
38
40
|
- `publish:` is a line in the verdict, not a silence
|
|
39
41
|
- Rotation — the archive is how pruning stops losing things
|
|
40
42
|
- Three grades of fix — take the highest one that can work
|
|
@@ -66,8 +68,16 @@ Required fields, and none of them is optional:
|
|
|
66
68
|
| **Root cause** | why the pipeline permitted it. "The agent was careless" is not a cause — it is the absence of one, and it produces no fix |
|
|
67
69
|
| **Fix** | one of the three grades below |
|
|
68
70
|
| **The check** | what would have caught this the first time. If the honest answer is "nothing yet", that is the fix, and it is grade 1 |
|
|
71
|
+
| **Class** | one of: `exit-code`, `unwatched-check`, `release`, `collision`, `destructive-undo`, `claim-by-say-so`, `stale-doc`, `wrong-copy`, `sibling`, `truncated-output`, `shell-instrument`, `handback`, `loop`. **Recurrence is counted by class**, so a class seen before is named as such |
|
|
72
|
+
| **Cost** | what it cost: rounds, burned tags, time. An entry with no cost cannot be weighed against the check that would prevent it |
|
|
69
73
|
| **Commit** | the short SHA of the change that fixed it |
|
|
70
74
|
|
|
75
|
+
The classes come from the 2026-10-20 audit of ~54 retrospectives across ~50 projects,
|
|
76
|
+
where the same lessons recurred under different words: a gate's exit code read through
|
|
77
|
+
a pipe (≥26 runs), a check trusted before it was seen failing (≥26), a tag cut from a
|
|
78
|
+
tree the release suite never ran on (≥24), a shared checkout (≥20), uncommitted work
|
|
79
|
+
overwritten (≥17). Words hid the recurrence; a class key makes it a count.
|
|
80
|
+
|
|
71
81
|
## Every lesson carries its commit
|
|
72
82
|
|
|
73
83
|
A standing instruction carries **two** SHAs — `Commit` (the change that introduced
|
|
@@ -177,6 +187,38 @@ like every other rotation. **The count is printed at the prune**, beside the sta
|
|
|
177
187
|
instructions' own count, so a table that stops rotating is visible rather than merely
|
|
178
188
|
large.
|
|
179
189
|
|
|
190
|
+
## The floor has a byte budget
|
|
191
|
+
|
|
192
|
+
A cap of ten rows never bounded their **size**. Measured 2026-10-20 across ~50
|
|
193
|
+
projects, the floor stage 0 reads in full (standing instructions plus run stamps) ran
|
|
194
|
+
from ~3k to **~76k tokens**; one floor was 304 KB, and this repository's own was
|
|
195
|
+
27 620 bytes. A row that carries its incident and a stamp that carries its release
|
|
196
|
+
narrative are how a capped list grows anyway.
|
|
197
|
+
|
|
198
|
+
- **Budget:** the floor stays under **12 000 bytes**. A standing row is at most **600
|
|
199
|
+
characters**: the rule, why (one clause), the retire-when trigger and the id; the
|
|
200
|
+
story lives in the archive. A run stamp is **one line of at most 300 characters**.
|
|
201
|
+
- **Stage 0 prints it:** `python3 scripts/retro_budget.py check` gives the floor's bytes
|
|
202
|
+
and bytes/4 tokens, beside the source ledger's retro row.
|
|
203
|
+
- **Gate 10 fails over budget.** Before the new entry is written, `retro_budget.py
|
|
204
|
+
migrate --write` moves the narrative (an over-long stamp's verdict, a standing row's
|
|
205
|
+
`Because`) **verbatim** into the quarter's archive, each block carrying the sha256 of
|
|
206
|
+
its text, and leaves a pointer; `retro_budget.py verify` proves every pointer. An
|
|
207
|
+
instruction still over 600 characters after its story moved is rewritten by hand.
|
|
208
|
+
- **A prune that retires nothing writes its count into the stamp row**, as
|
|
209
|
+
`prune: 0 retired`, and no paragraph. Repeated "nothing to prune" notes were a
|
|
210
|
+
measured share of the floor.
|
|
211
|
+
|
|
212
|
+
## Before a standing row: search, cite, send upstream
|
|
213
|
+
|
|
214
|
+
- **Search first:** `references/learned.md` and the lesson index
|
|
215
|
+
(`scripts/lessons.py query`, by the class key and the nouns). A rule already there is
|
|
216
|
+
**cited by its number** (`learned.md` rule 22), never restated in a row.
|
|
217
|
+
- **A lesson standing in two projects goes upstream in the same run:** the entry gets
|
|
218
|
+
its `**Lesson:**` line and `scripts/lessons.py add`, and a universal rule is proposed
|
|
219
|
+
for `learned.md` (*Publishing the insight*, below). Two projects holding one rule is
|
|
220
|
+
a fork nobody named.
|
|
221
|
+
|
|
180
222
|
## `publish:` is a line in the verdict, not a silence
|
|
181
223
|
|
|
182
224
|
Reported from another project, and the report is about this file: an operator asked, after
|
|
@@ -265,6 +307,10 @@ computable, which is why it goes first:
|
|
|
265
307
|
printf '%s · %s\n' "$(date +%F)" "$(git rev-parse --short HEAD)" >> docs/evidence/retro.md
|
|
266
308
|
```
|
|
267
309
|
|
|
310
|
+
**The budget runs between the prune and the entry:** stamp, prune, `retro_budget.py
|
|
311
|
+
check` (and `migrate --write` when it fails), then write. An entry written onto a floor
|
|
312
|
+
already over budget is the growth the budget exists to stop.
|
|
313
|
+
|
|
268
314
|
## The prune — mandatory, and it runs after the stamp
|
|
269
315
|
|
|
270
316
|
A lesson that lands in a cluttered file is a lesson nobody will reach — so the prune still runs
|
|
@@ -18,7 +18,7 @@ Writing the approved design down so a zero-context implementer — human or suba
|
|
|
18
18
|
- Module dossier — when the run is one brick of a platform
|
|
19
19
|
- Self-review — before showing it
|
|
20
20
|
- Locked contracts are decisions — the register, not only the spec
|
|
21
|
-
- GATE (
|
|
21
|
+
- GATE (auto)
|
|
22
22
|
|
|
23
23
|
## Order of operations
|
|
24
24
|
|
|
@@ -280,13 +280,14 @@ spec section instead of restating the reasoning there.
|
|
|
280
280
|
and the next one supersedes it; an id survives. If this stage settled something and
|
|
281
281
|
no entry names it, the run has agreed to decide it again later.
|
|
282
282
|
|
|
283
|
-
## GATE (
|
|
283
|
+
## GATE (auto)
|
|
284
284
|
|
|
285
285
|
> "Spec written and committed to `<path>`. Review it and tell me if anything should
|
|
286
286
|
> change before I write the implementation plan."
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
Where the brief records a standing authorization (the default gate is `auto` since
|
|
289
|
+
1.98.0), an independent reader reviews the spec and the run continues; otherwise wait
|
|
290
|
+
for the operator. Changes requested → apply, re-run the self-review, and review again.
|
|
290
291
|
|
|
291
292
|
The gate is not only the operator's word: **every section carries `covers: REQ-…`
|
|
292
293
|
and every REQ in the brief appears in at least one section.** For UI tasks it
|
|
@@ -7,13 +7,13 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
7
7
|
- 0 — Intake grill — MANDATORY
|
|
8
8
|
|
|
9
9
|
## 0 — Intake grill — MANDATORY
|
|
10
|
-
- **Stage 0
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
- **Stage 0 always runs, and its depth is proportional.** The gap check, the
|
|
11
|
+
harvest and the brief are never skipped; the interview, the committed brief file
|
|
12
|
+
and stages 1-4 are what a small change does without (Phase 1d below, the
|
|
13
|
+
*proportional run*). A run that starts building without a brief and its REQ rows
|
|
14
|
+
(in the brief file, or on the short path in the run ledger) is a **failed run**:
|
|
15
|
+
stop and go back. The entry-from-super-ux short-circuit below is the other
|
|
16
|
+
sanctioned shortening.
|
|
17
17
|
- **Entry-from-super-ux short-circuit (check FIRST).** task-pipeline is often
|
|
18
18
|
launched *from* super-ux — its `/ux` action menu offers "execute autonomously
|
|
19
19
|
via the task-pipeline plugin" once the UX chain (and often a
|
|
@@ -40,8 +40,9 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
40
40
|
`affected` / `god-nodes` answer *reach*, which is what grep cannot), `CLAUDE.md`,
|
|
41
41
|
`CONTEXT.md`/ADRs, `docs/` + `docs/ux/`, past pipeline briefs and carry-over
|
|
42
42
|
ledgers, **the retro's standing instructions and run stamps** (`<artifacts>/retro.md`,
|
|
43
|
-
read **in full
|
|
44
|
-
|
|
43
|
+
read **in full**: ten standing rows and ten stamps, bounded by a cap and by a byte
|
|
44
|
+
budget; print `scripts/retro_budget.py check` first, which states the floor's bytes and
|
|
45
|
+
bytes/4 tokens. They bind this run; stamp each instruction as it fires. Its *Recent log* is **queried** by the
|
|
45
46
|
task's nouns, not read: uncapped narrative inside a binding source is what makes the
|
|
46
47
|
capped part get skimmed, [`retrospective.md`](retrospective.md)), **lessons from other
|
|
47
48
|
projects** (source 7b, [`knowledge-sources.md`](knowledge-sources.md): `scripts/lessons.py
|
|
@@ -81,30 +82,43 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
81
82
|
or they genuinely disagree and that is a decision. There is no fourth option, and
|
|
82
83
|
starting on an unresolved divergence means building against a system that does
|
|
83
84
|
not exist.
|
|
84
|
-
- **Phase 1d — the short-path triage
|
|
85
|
-
pipeline's
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
- **Phase 1d — the short-path triage, and the proportional run: a small change
|
|
86
|
+
takes the short path by default.** This pipeline's boundary exempts a typo and a one-line edit; until 1.98.0
|
|
87
|
+
the next size up still met eleven stages and five manual gates, because the short
|
|
88
|
+
path was only *proposed* and silence took the full flow. Under a standing "decide and
|
|
89
|
+
act" instruction silence is the normal answer, so a proposal was the full flow every
|
|
90
|
+
time. The triage now **decides**, from five answers with something behind each:
|
|
89
91
|
|
|
90
92
|
```
|
|
91
|
-
1. files the
|
|
93
|
+
1. files the change touches, resolved git ls-files -- <paths> -> N
|
|
92
94
|
2. any of them a public contract the surfaces the host's release
|
|
93
95
|
syncs, its schema or config
|
|
94
96
|
contracts, a shipped command,
|
|
95
97
|
its README -> yes/no
|
|
96
|
-
3. behaviour a user
|
|
98
|
+
3. behaviour a user observes changes a UI, a message, an output -> yes/no
|
|
99
|
+
4. a deploy target in the brief stage 7's target exists -> yes/no
|
|
100
|
+
5. risk class work-graph.md R1-R3 -> R1/R2/R3
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
**Small** means all of: the gap check left zero material unknowns, N ≤ 5, no public
|
|
104
|
+
contract, no user-observable change, no deploy, and risk **R1**. Small ⇒ the run takes
|
|
105
|
+
the short path and prints one line:
|
|
106
|
+
`short path: R1 · N files · no contract · no user-facing change · no deploy`.
|
|
107
|
+
`scripts/short_path.py` computes the decision from the five answers (exit 0 short,
|
|
108
|
+
3 full) and prints that line.
|
|
109
|
+
The short path is: the brief and its REQ rows written into the run ledger (no grill,
|
|
110
|
+
no committed brief file) → stage 5, build with tests → stage 6, the suite plus **one**
|
|
111
|
+
verification (one blind tier, [`certification.md`](certification.md)) → stage 9, the
|
|
112
|
+
docs the change makes false and the handoff → stage 10, the hand-back and a run stamp;
|
|
113
|
+
a retro entry only when the run taught a new lesson. Stages 1-4, 7 and 8 print `⊘`
|
|
114
|
+
with the triage line as their reason ([`progress.md`](progress.md)).
|
|
115
|
+
**Triggers that bring a skipped stage back:** a deploy target appears (7, 8); a wiki or
|
|
116
|
+
code graph exists and the change touched what it indexes (9 in full); a check reveals a
|
|
117
|
+
contract or a user-facing effect (leave the short path, resume at stage 2); the
|
|
118
|
+
operator asks for the full cycle. Any answer outside *small* takes the full flow,
|
|
119
|
+
printed the same way with the failing answer as its reason.
|
|
120
|
+
- **How it runs: [`grill.md`](grill.md)**, read only when the gap check leaves a
|
|
121
|
+
material unknown (a complete brief asks nothing). In short: close what the sources can, then ONE batch
|
|
108
122
|
of the material unknowns, ordered by dependency, a recommended answer with each —
|
|
109
123
|
one at a time only where answers depend on each other or the operator asks;
|
|
110
124
|
contradictions reconciled on the spot; **every answer that touches
|
|
@@ -7,7 +7,7 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
7
7
|
workspace (native worktree tool first, git fallback, baseline tests), keep a
|
|
8
8
|
ledger under `.task-pipeline/build/<plan>/` so a compacted context can resume,
|
|
9
9
|
then one fresh implementer subagent per task with a file-based brief and report,
|
|
10
|
-
a review after every task ([`review.md`](review.md)), and a
|
|
10
|
+
a review after every task ([`review.md`](review.md)), and a three-round fix loop
|
|
11
11
|
with an explicit breaker. TDD per task ([`tdd.md`](tdd.md)): failing test →
|
|
12
12
|
watch it fail → minimal impl → watch it pass → commit. Pin subagents to the
|
|
13
13
|
run's confirmed model (`model-tiering.md`). The plan's parallel groups fan out
|
|
@@ -19,8 +19,8 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
19
19
|
contradiction that exists only between two of them.
|
|
20
20
|
- **Web front end? The task's own surface is checked in a browser, not in the diff.**
|
|
21
21
|
Where a browser channel is connected — `playwright` **or** `chrome-devtools`, either
|
|
22
|
-
one,
|
|
23
|
-
[`companion-skills.md`](companion-skills.md)): after a
|
|
22
|
+
one, on WebKit first with Chromium a stated exception (**how**, and the engine order:
|
|
23
|
+
[`browser.md`](browser.md); which: [`companion-skills.md`](companion-skills.md)): after a
|
|
24
24
|
task that changes a rendered surface, load it, take a snapshot and read the
|
|
25
25
|
console and the network log **before the task is marked DONE** — a component can be
|
|
26
26
|
correct and land under a fixed header, and a review of the diff cannot see that.
|
|
@@ -13,8 +13,9 @@ The full gate and freedom level remain in [stages.md](stages.md).
|
|
|
13
13
|
- **A deployed web target is opened, not curled.** A `200` proves the server
|
|
14
14
|
answered; it says nothing about whether the page rendered, whether a bundle 404'd,
|
|
15
15
|
or whether the console filled with errors on load — all three ship green past a
|
|
16
|
-
health check. Where a browser channel is connected — `playwright`
|
|
17
|
-
`chrome-devtools
|
|
16
|
+
health check. Where a browser channel is connected — `playwright` on WebKit first
|
|
17
|
+
**or** `chrome-devtools` as the stated Chromium exception, and a Chromium-only look
|
|
18
|
+
is reported as such; either one ([`browser.md`](browser.md)) — load the deployed URL and read
|
|
18
19
|
the console and the network log; quote what you read, not that you looked
|
|
19
20
|
([`companion-skills.md`](companion-skills.md)). Absent → say the check was an HTTP
|
|
20
21
|
response only, which is the honest name for it.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Stages — detail & gates
|
|
2
2
|
|
|
3
|
-
For the selected **default profile**, read
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
For the selected **default profile**, read **one stage section of this file when that
|
|
4
|
+
stage starts** (the stage table in `SKILL.md` is the index), then the one detail it
|
|
5
|
+
links, on every entry or resume, including wave iterations and approved short paths
|
|
6
|
+
(the triage approves the short path itself since 1.98.0). Never read this file end to
|
|
7
|
+
end. Do not preload all stage details. Missing or unreadable detail means stop that stage and repair its route, never guess. A custom
|
|
7
8
|
profile uses its own declared doctrine and stages; numeric ids do not select these
|
|
8
9
|
default details, and the kernel still applies.
|
|
9
10
|
|
|
@@ -14,7 +15,10 @@ orchestrator verifies the check itself, pass/fail), `judgment` (a named judge
|
|
|
14
15
|
rules where no complete deterministic check exists — [`gates.md`](gates.md) →
|
|
15
16
|
*The judgment gate*) or `manual` (requires the operator's explicit go, including a
|
|
16
17
|
specific standing authorization naming the act, cited with its source and scope;
|
|
17
|
-
otherwise wait).
|
|
18
|
+
otherwise wait). **This example ships every gate `auto`** (since 1.98.0): where it
|
|
19
|
+
names an approval, the operator's answer or the standing authorization recorded in the
|
|
20
|
+
brief satisfies it without a pause. A project makes a gate `manual` in its own
|
|
21
|
+
`pipeline.json`. These stages (0 intake + 1→10) are the plugin's
|
|
18
22
|
**example** flow, encoded in `pipeline.example.json` against the universal contract
|
|
19
23
|
`pipeline.schema.json`; a host project replaces it with its own
|
|
20
24
|
stages/agents/types (see SKILL.md → *Bring your own skills*).
|
|
@@ -84,7 +88,11 @@ never that the work was skipped quietly.
|
|
|
84
88
|
|
|
85
89
|
**On entry or resume:** read [stage-00-intake.md](stage-00-intake.md) before stage work.
|
|
86
90
|
|
|
87
|
-
- **
|
|
91
|
+
- **On the short path** (`stage-00-intake.md` → Phase 1d) this gate
|
|
92
|
+
is: the triage line printed, the brief and its REQ rows in the run ledger, the retro
|
|
93
|
+
floor read with its byte count, and the source ledger. Everything else below applies
|
|
94
|
+
to the full flow.
|
|
95
|
+
- **GATE (auto):** shared understanding reached — **the source ledger is written
|
|
88
96
|
(every source consulted, or an explicit "none found")** and **its `Contradictions:`
|
|
89
97
|
line is written under it** — the harvest is a fan-out that converges on one brief, and
|
|
90
98
|
nothing else compares the sources *with each other*; `Contradictions: none` is the
|
|
@@ -107,8 +115,8 @@ never that the work was skipped quietly.
|
|
|
107
115
|
is filled — objective, exit checks on the artefact the operator uses, scope, budget and
|
|
108
116
|
base** ([`finish-line.md`](finish-line.md)), the carry-over ledger is
|
|
109
117
|
seeded, **`.task-pipeline/run.md` exists and the header block has been printed**
|
|
110
|
-
([`progress.md`](progress.md)), the model decision is recorded, and the
|
|
111
|
-
|
|
118
|
+
([`progress.md`](progress.md)), the model decision is recorded, and the brief is
|
|
119
|
+
confirmed: the operator's answer, or the standing authorization recorded in it. Stop when a
|
|
112
120
|
re-scan surfaces no new branches (don't grill past diminishing returns;
|
|
113
121
|
reversible calls can be deferred with a note). Only then start stage 1.
|
|
114
122
|
- **The verification ledger is read.** `<artifacts>/verification.md` — the harvest
|
|
@@ -140,7 +148,8 @@ never that the work was skipped quietly.
|
|
|
140
148
|
|
|
141
149
|
**On entry or resume:** read [stage-02-brainstorm.md](stage-02-brainstorm.md) before stage work.
|
|
142
150
|
|
|
143
|
-
- **GATE (
|
|
151
|
+
- **GATE (auto):** the design is approved (the operator's go, or the brief's standing
|
|
152
|
+
authorization), the UI verdict is recorded, **the
|
|
144
153
|
queue is an artifact rather than a recollection** — where it is a work graph,
|
|
145
154
|
`graph.py validate` exits 0 and `graph.py coverage` names any requirement no node serves,
|
|
146
155
|
**every REQ is answered by the design** — a requirement the design doesn't
|
|
@@ -156,10 +165,11 @@ never that the work was skipped quietly.
|
|
|
156
165
|
|
|
157
166
|
**On entry or resume:** read [stage-03-spec.md](stage-03-spec.md) before stage work.
|
|
158
167
|
|
|
159
|
-
- **GATE (
|
|
168
|
+
- **GATE (auto):** the **`## Self-review` section written and committed with
|
|
160
169
|
computed values** — every check the spec names resolving or marked `review`, the
|
|
161
170
|
brief's decisions and stage 2's rejected options read back with no unresolved
|
|
162
|
-
contradiction, and the cost delta printed; spec committed **and**
|
|
171
|
+
contradiction, and the cost delta printed; spec committed **and** reviewed (by the
|
|
172
|
+
operator, or under the brief's standing authorization by an independent reader); **every section carries
|
|
163
173
|
`covers: REQ-…` and every REQ appears in at least one section**; for UI tasks
|
|
164
174
|
additionally: the super-ux chain (foundation → flows → screens → scenarios) is
|
|
165
175
|
designed, validated and approved; scenarios validated in `docs/ux/scenarios.md`;
|
|
@@ -254,8 +264,9 @@ never that the work was skipped quietly.
|
|
|
254
264
|
page rendered — a component can be correct and land under a fixed header, a request
|
|
255
265
|
can 404 while every unit test mocks it, and a console error costs nothing at test
|
|
256
266
|
time. Where a browser channel is connected — `playwright` **or** `chrome-devtools`,
|
|
257
|
-
either one
|
|
258
|
-
[`
|
|
267
|
+
either one, on WebKit first with Chromium a stated exception
|
|
268
|
+
([`browser.md`](browser.md) is the four commands this sentence means and the engine
|
|
269
|
+
order; [`companion-skills.md`](companion-skills.md) is which channel):
|
|
259
270
|
load the surface, take a snapshot, and read **the console and the network log**
|
|
260
271
|
before calling it green. Absent, say the surface was verified **by reading the
|
|
261
272
|
diff** — that is a weaker claim and the close-out records it as one, rather than
|
|
@@ -298,10 +309,10 @@ never that the work was skipped quietly.
|
|
|
298
309
|
|
|
299
310
|
**On entry or resume:** read [stage-07-lint-deploy.md](stage-07-lint-deploy.md) before stage work.
|
|
300
311
|
|
|
301
|
-
- **GATE (
|
|
312
|
+
- **GATE (auto):** lint clean (host linter **and**, for UI projects, the super-ux
|
|
302
313
|
linter) **and** suite green **before** deploy, **and no REQ is still `open`** — a
|
|
303
314
|
`partial` ships only with the operator's explicit acceptance. A gap is cheapest to
|
|
304
|
-
close before it ships
|
|
315
|
+
close before it ships. **The
|
|
305
316
|
carry-over count is printed beside this verdict.** Deploy is outward → explicit
|
|
306
317
|
operator go, or a specific standing authorization naming that act, cited with its source
|
|
307
318
|
and scope. Authorization to release does not silently authorize a separate deploy. If
|
|
@@ -375,7 +386,7 @@ never that the work was skipped quietly.
|
|
|
375
386
|
|
|
376
387
|
**On entry or resume:** read [stage-10-acceptance.md](stage-10-acceptance.md) before stage work.
|
|
377
388
|
|
|
378
|
-
- **GATE (
|
|
389
|
+
- **GATE (auto):** the ladder walk ran and its absences became REQ rows before
|
|
379
390
|
the table was written; **the hand-back is written** — the request quoted as it was
|
|
380
391
|
GIVEN, where the run stands against it, what was solved with its evidence, what
|
|
381
392
|
surfaced that nobody asked for, every decision still waiting **asked here with
|
|
@@ -421,10 +432,11 @@ never that the work was skipped quietly.
|
|
|
421
432
|
carries evidence; every `partial` names what's missing and where it's tracked;
|
|
422
433
|
every `deferred`/`dropped` has the operator's agreement and, for `deferred`, a
|
|
423
434
|
tracker entry; no carry-over row left `unresolved`, and the ledger's counts are
|
|
424
|
-
printed with the verdict; the
|
|
425
|
-
|
|
426
|
-
the table
|
|
427
|
-
asked for.
|
|
435
|
+
printed with the verdict; the hand-back asks the closing question and carries
|
|
436
|
+
the answer the operator can give at any time. `auto` by default since 1.98.0: a
|
|
437
|
+
check proves the table well-formed, and only the person who asked can confirm it is
|
|
438
|
+
what they asked for, so the run hands that question back rather than waiting on it.
|
|
439
|
+
A project that wants the wait sets this gate `manual`.
|
|
428
440
|
|
|
429
441
|
## The program loop — a platform, one brick at a time
|
|
430
442
|
|
|
@@ -485,8 +497,8 @@ cycle.
|
|
|
485
497
|
a feeling, and the ledger is what survives compaction.
|
|
486
498
|
- **Trips on:** revert-oscillation (A→B→A); the same file edited twice for the same
|
|
487
499
|
reason; a finding already ADDRESSED or parked coming back; a stage entered a third
|
|
488
|
-
time for one artifact; two loops editing one file. Hard caps:
|
|
489
|
-
task, 2 re-entries per stage per artifact, 3 passes per module.
|
|
500
|
+
time for one artifact; two loops editing one file. Hard caps, each a stop: 3 fix
|
|
501
|
+
rounds per task, 2 re-entries per stage per artifact, 3 passes per module.
|
|
490
502
|
- **On a trip: stop editing.** Name shapes A and B with their evidence, escalate to
|
|
491
503
|
the layer that owns the conflict (rubric → operator → plan → spec → module map),
|
|
492
504
|
re-plan the check as an ordered one-item-per-line checklist, then go through it in
|
|
@@ -102,8 +102,9 @@ database created ten seconds ago" are different claims, and only the second one
|
|
|
102
102
|
code does what its assertions say; it cannot see a component that renders correctly
|
|
103
103
|
and lands under a fixed header, a request that 404s while every unit test mocks it,
|
|
104
104
|
or a console error that costs nothing at test time. Where a browser channel is
|
|
105
|
-
connected — `playwright` **or** `chrome-devtools`, either one
|
|
106
|
-
([`companion-skills.md`](companion-skills.md)
|
|
105
|
+
connected — `playwright` **or** `chrome-devtools`, either one, on WebKit first with
|
|
106
|
+
Chromium a stated exception ([`companion-skills.md`](companion-skills.md);
|
|
107
|
+
[`browser.md`](browser.md) → *Engine order*) — open the surface and read
|
|
107
108
|
the console and the network log before calling it done — and **quote what you read**,
|
|
108
109
|
not that you looked. Absent, the honest sentence is *"verified by reading the diff"*,
|
|
109
110
|
which is a weaker claim and is recorded as one. Same family as a test that passes
|
|
@@ -57,10 +57,12 @@ on real agents, tasks and users rather than on the first guess.
|
|
|
57
57
|
| 5–8 Build → post-deploy | per wave, then the close pass. A wave's stage 7 integrates to the main branch **without tagging**; the release's tag, its approval mode and its go are stage 7's full gate, run once at the release ([`iteration.md`](iteration.md) → *The cycle*, step 10), and stage 8's trio follows on what was released (step 11) |
|
|
58
58
|
| 9 Docs + wiki · 10 Acceptance | once, to close the release, over everything the waves shipped |
|
|
59
59
|
|
|
60
|
-
**One planning gate, not three prompts.** The
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
**One planning gate, not three prompts.** The gates of stages 0, 2 and 3 are presented
|
|
61
|
+
together at the end of planning: the brief, the canvas, the wave plan and the question
|
|
62
|
+
batch in one message. Each gate's criteria are still checked and printed. They are `auto`
|
|
63
|
+
by default (since 1.98.0): the standing authorization recorded in the brief closes them
|
|
64
|
+
and the run continues; where the project made them `manual`, the operator is asked once,
|
|
65
|
+
the go names the gates it closes, and silence closes none.
|
|
64
66
|
|
|
65
67
|
## Wave 0 — the survey and the inventory
|
|
66
68
|
|