task-pipeline-skill 1.93.3 → 1.95.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 +145 -0
- package/CONTRIBUTING.md +32 -0
- package/HOW-IT-WORKS.md +4 -3
- package/README.md +59 -15
- package/SKILL-CARD.md +2 -2
- package/bin/task-pipeline.js +64 -33
- package/cursor/rules/task-pipeline.mdc +10 -5
- package/evals/RESULTS.md +1 -1
- package/evals/task-pipeline.evals.json +16 -0
- package/package.json +3 -3
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/agents/verifier.md +5 -2
- package/plugins/task-pipeline/commands/task-pipeline.md +25 -10
- package/plugins/task-pipeline/hooks/memory-nudge.sh +45 -3
- package/plugins/task-pipeline/hooks/release-gate.sh +1 -1
- package/plugins/task-pipeline/skills/evidence-docs/references/gates.md +6 -3
- package/plugins/task-pipeline/skills/evidence-docs/references/hooks.md +2 -1
- package/plugins/task-pipeline/skills/evidence-docs/references/retrospective.md +26 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +24 -20
- package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +89 -4
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +7 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +25 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/brainstorm.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +46 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/continuity.md +97 -26
- package/plugins/task-pipeline/skills/task-pipeline/references/deploy-targets.md +30 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +20 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +6 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/hooks.md +2 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/iteration.md +387 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +4 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +13 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +26 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +7 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-00-intake.md +158 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-01-docs-study.md +10 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-02-brainstorm.md +52 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-03-spec.md +66 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-04-plan.md +11 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-05-dev.md +55 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-06-tests.md +11 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-07-lint-deploy.md +15 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-08-post-deploy.md +29 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-09-docs-wiki.md +45 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-10-acceptance.md +91 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +60 -475
- package/plugins/task-pipeline/skills/task-pipeline/references/verification.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/waves.md +76 -36
- package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +54 -5
- package/plugins/task-pipeline/skills/task-pipeline/scripts/backlog_sources.py +54 -13
- package/plugins/task-pipeline/skills/task-pipeline/scripts/context_packets.py +3 -3
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +205 -22
- package/plugins/task-pipeline/skills/task-pipeline/scripts/lessons.py +1137 -0
- package/plugins/task-pipeline/skills/task-pipeline/scripts/stage_checkpoint.py +264 -44
- package/plugins/task-pipeline/skills/task-pipeline/scripts/waves.py +546 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/README.md +6 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/backlog-sources.schema.json +96 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/canvas.md +97 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/dossier.md +82 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/inventory.schema.json +94 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/lesson.schema.json +221 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/questions.md +45 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/retro.md +4 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
|
@@ -15,7 +15,10 @@ tools: Read, Grep, Glob, Bash
|
|
|
15
15
|
> and wrong one level out, and a single context cannot see both. Doctrine:
|
|
16
16
|
> `references/certification.md`. This agent remains for the case `certify` does not
|
|
17
17
|
> cover: a verdict already in flight, or a hand-written one fed to
|
|
18
|
-
> `close --verdict` directly. Reach for the three tiers first.
|
|
18
|
+
> `close --verdict` directly. Reach for the three tiers first. **A node that carries
|
|
19
|
+
> `risk` cannot be closed by a hand-written verdict alone**: `close` refuses it until
|
|
20
|
+
> `certify` has recorded the passing rounds its class owes, or `waive` records an
|
|
21
|
+
> authorized exception.
|
|
19
22
|
|
|
20
23
|
You close **one node**. You do not fix, you do not implement, and you do not
|
|
21
24
|
review style. You answer four questions about work that claims to be finished, and
|
|
@@ -108,6 +111,6 @@ ledger exists to catch.
|
|
|
108
111
|
|
|
109
112
|
## Where the doctrine is
|
|
110
113
|
|
|
111
|
-
`references/
|
|
114
|
+
`references/stage-08-post-deploy.md` for what verification means here;
|
|
112
115
|
`references/verification.md` for the ledger your evidence lands in;
|
|
113
116
|
`references/gates.md` for what a gate's exit code obliges.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Run a task through task-pipeline's gated stages (intake grill → docs → brainstorm → spec → plan → build → tests → deploy → post-deploy → docs/wiki → acceptance). Also: `waves` — close the whole board in waves; `setup` — audit the docs you already have; `checkup` — what has shipped unverified, with no task running."
|
|
3
|
-
argument-hint: "<one-line task> | waves | setup | checkup"
|
|
2
|
+
description: "Run a task through task-pipeline's gated stages (intake grill → docs → brainstorm → spec → plan → build → tests → deploy → post-deploy → docs/wiki → acceptance). Also: `waves` — close the whole board in waves; `iteration` — the release loop around the waves; `setup` — audit the docs you already have; `checkup` — what has shipped unverified, with no task running."
|
|
3
|
+
argument-hint: "<one-line task> | waves | iteration | setup | checkup"
|
|
4
4
|
---
|
|
5
5
|
Run the task below through `task-pipeline`'s gated stages. **Every stage's doctrine
|
|
6
6
|
ships inside the skill** — no companion plugin is required for any of it. The
|
|
@@ -8,10 +8,11 @@ reference files are indexed in `SKILL.md`; this page is the run order, not the i
|
|
|
8
8
|
|
|
9
9
|
Task: $ARGUMENTS
|
|
10
10
|
|
|
11
|
-
> **
|
|
12
|
-
> `
|
|
13
|
-
>
|
|
14
|
-
>
|
|
11
|
+
> **Four other modes.** `waves` takes the whole board instead of one task;
|
|
12
|
+
> `iteration` runs the release loop around the waves — survey, design, build, release,
|
|
13
|
+
> the next pool; `setup` audits the documentation this project already has; `checkup`
|
|
14
|
+
> reports what has shipped without a person confirming it, with no task in flight. All
|
|
15
|
+
> four are at the bottom of this page.
|
|
15
16
|
|
|
16
17
|
**Idempotent entry — inspect state first, never restart blindly.** If a pipeline
|
|
17
18
|
TaskList from a previous run exists for this task, **resume** from the first incomplete
|
|
@@ -34,8 +35,9 @@ naming the standard is one an operator can call out for missing it.
|
|
|
34
35
|
- **Model.** Recommend the most capable one the environment offers, never a hardcoded
|
|
35
36
|
id. Confirmed once, then the whole run uses it without re-asking.
|
|
36
37
|
- **Companions.** Print the detection block once (`references/companion-skills.md`).
|
|
37
|
-
Absent ones state their fallback
|
|
38
|
-
user-facing
|
|
38
|
+
Absent ones state their fallback and name any unavailable check as NOT_RUN.
|
|
39
|
+
On user-facing tasks stage 3 gates the valid scenario artifact, not package
|
|
40
|
+
presence; use the provider rule in that reference.
|
|
39
41
|
|
|
40
42
|
## Stage 0 — the harvest, then the grill
|
|
41
43
|
|
|
@@ -103,8 +105,8 @@ Anything deferred enters the carry-over ledger the moment it is said.
|
|
|
103
105
|
| 10 | Acceptance | the ladder walk first, then the table, then the retrospective |
|
|
104
106
|
|
|
105
107
|
**Honor every gate by its type**: `auto` — verify the check yourself; `judgment` —
|
|
106
|
-
record the named judge's ruling as judgement, never as a measurement; `manual` —
|
|
107
|
-
|
|
108
|
+
record the named judge's ruling as judgement, never as a measurement; `manual` — cite
|
|
109
|
+
an explicit go or specific standing authorization naming the act, otherwise wait.
|
|
108
110
|
|
|
109
111
|
## Cross-cutting — the three that fire at any stage
|
|
110
112
|
|
|
@@ -203,6 +205,19 @@ It takes the next wave without asking, says once when the board is empty, and le
|
|
|
203
205
|
every sign-in, consent, payment and outward act to a person.
|
|
204
206
|
Doctrine: `references/waves.md`.
|
|
205
207
|
|
|
208
|
+
## `/task-pipeline iteration`
|
|
209
|
+
|
|
210
|
+
**The loop around the waves: a project moves in whole releases.** Survey every source into
|
|
211
|
+
one inventory (`scripts/waves.py merge`), write module dossiers in parallel, integrate them
|
|
212
|
+
into one canvas until a pass changes nothing, ask the operator in batches (rounds), never
|
|
213
|
+
one question at a time, then build in parallel. Each node is verified as it lands, in one
|
|
214
|
+
to three rounds by its risk class (R1–R3); a wave's stage 7 integrates without tagging, and
|
|
215
|
+
the release's stage-7 gate and stage 8's trio run once on what was released. The next pool
|
|
216
|
+
is re-measured and handed back once. Every run reads earlier runs' lessons
|
|
217
|
+
(`scripts/lessons.py query`) and writes its own at the retro. A finding made mid-iteration
|
|
218
|
+
joins the inventory; only the closed hotfix lane ships alone.
|
|
219
|
+
Doctrine: `references/iteration.md`.
|
|
220
|
+
|
|
206
221
|
## `/task-pipeline setup`
|
|
207
222
|
|
|
208
223
|
**The entry audit instead of a feature.** Seven passes over the documentation this
|
|
@@ -8,10 +8,19 @@
|
|
|
8
8
|
# matters: once per stage line, as context the model reads, and never again for the same
|
|
9
9
|
# line. It decides nothing and blocks nothing.
|
|
10
10
|
#
|
|
11
|
+
# Silent for the rest of a run that recorded memory unavailable FOR THE RUN
|
|
12
|
+
# (`stage_checkpoint.py record --unavailable "<why>" --for-run` writes a marker into
|
|
13
|
+
# .task-pipeline/memory.json carrying a hash of the Run: line's topic and date; the marker
|
|
14
|
+
# is honoured only while the ledger names that same run and still carries the marker's own
|
|
15
|
+
# ledger line, and a later `record --answer` clears it). Without that marker a
|
|
16
|
+
# machine with no Observatory paid about eleven nudges per run for one unchanging fact
|
|
17
|
+
# (CHANGELOG, Unreleased). The first nudge of a run also says where Observatory comes from, once.
|
|
18
|
+
#
|
|
11
19
|
# Silent everywhere else: no ledger means exit 0 after one file test.
|
|
12
20
|
set -uo pipefail
|
|
13
21
|
ledger="${CLAUDE_PROJECT_DIR:-$PWD}/.task-pipeline/run.md"
|
|
14
22
|
[ -f "$ledger" ] || exit 0
|
|
23
|
+
TP_SCRIPTS="$(cd "$(dirname "${BASH_SOURCE[0]}")/../skills/task-pipeline/scripts" 2>/dev/null && pwd)" \
|
|
15
24
|
python3 - "$ledger" <<'PY' 2>/dev/null || true
|
|
16
25
|
import hashlib, json, os, re, sys
|
|
17
26
|
ledger = sys.argv[1]
|
|
@@ -27,8 +36,27 @@ for i, l in enumerate(lines):
|
|
|
27
36
|
last_mem = i
|
|
28
37
|
if last_stage < 0 or last_mem > last_stage:
|
|
29
38
|
sys.exit(0)
|
|
39
|
+
here = os.path.dirname(ledger)
|
|
40
|
+
# The run key comes from stage_checkpoint.py's own helper — one definition of "this run" for
|
|
41
|
+
# the marker it writes and the pointer below. Unimportable: no key, so the marker is not
|
|
42
|
+
# honoured and the nudge behaves as before (never blocks).
|
|
43
|
+
try:
|
|
44
|
+
sys.path.insert(0, os.environ["TP_SCRIPTS"])
|
|
45
|
+
import pathlib
|
|
46
|
+
from stage_checkpoint import run_key, marker_for_this_run
|
|
47
|
+
this_run = run_key(lines)
|
|
48
|
+
except Exception:
|
|
49
|
+
this_run = marker_for_this_run = None
|
|
50
|
+
try:
|
|
51
|
+
state = json.load(open(os.path.join(here, "memory.json"), encoding="utf-8"))
|
|
52
|
+
# Honoured only for the run that wrote it — same topic and start date, and its own
|
|
53
|
+
# `unavailable for this run` line still in this ledger (a reseeded ledger has none).
|
|
54
|
+
if marker_for_this_run and marker_for_this_run(pathlib.Path(ledger), state):
|
|
55
|
+
sys.exit(0)
|
|
56
|
+
except (OSError, ValueError, AttributeError, TypeError):
|
|
57
|
+
pass # no marker, or one that cannot be read: nudge as before, never block
|
|
30
58
|
line = lines[last_stage]
|
|
31
|
-
mark = os.path.join(
|
|
59
|
+
mark = os.path.join(here, ".memory-nudged")
|
|
32
60
|
key = hashlib.sha256(line.encode()).hexdigest()[:16]
|
|
33
61
|
try:
|
|
34
62
|
if open(mark).read().strip() == key:
|
|
@@ -42,8 +70,22 @@ except OSError:
|
|
|
42
70
|
sid = re.match(r"^stage:\s*(\S+)", line).group(1)
|
|
43
71
|
msg = (f"task-pipeline: stage {sid}'s gate returned and no workflow-memory line follows it. "
|
|
44
72
|
"With Observatory's tools: `scripts/stage_checkpoint.py emit` → observatory_checkpoint_write "
|
|
45
|
-
"→ `stage_checkpoint.py record --answer -`. Without them: "
|
|
46
|
-
"`stage_checkpoint.py record --unavailable \"<why>\"`. (references/continuity.md, Part 3)")
|
|
73
|
+
"→ `stage_checkpoint.py record --answer -`. Without them, once for the whole run: "
|
|
74
|
+
"`stage_checkpoint.py record --unavailable \"<why>\" --for-run`. (references/continuity.md, Part 3)")
|
|
75
|
+
# Once per run, keyed by the ledger's `Run:` line: where the tools come from.
|
|
76
|
+
run_id = this_run or hashlib.sha256(ledger.encode()).hexdigest()[:16]
|
|
77
|
+
pointer = os.path.join(here, ".memory-pointer")
|
|
78
|
+
try:
|
|
79
|
+
shown = open(pointer).read().strip() == run_id
|
|
80
|
+
except OSError:
|
|
81
|
+
shown = False
|
|
82
|
+
if not shown:
|
|
83
|
+
msg += (" Observatory is the public engine passioncode-ai/project-observatory-dashboard "
|
|
84
|
+
"(its README: Install, MCP).")
|
|
85
|
+
try:
|
|
86
|
+
open(pointer, "w").write(run_id + "\n")
|
|
87
|
+
except OSError:
|
|
88
|
+
pass
|
|
47
89
|
print(json.dumps({"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": msg}}))
|
|
48
90
|
PY
|
|
49
91
|
exit 0
|
|
@@ -118,7 +118,7 @@ def outward(tokens):
|
|
|
118
118
|
if sub == "push":
|
|
119
119
|
if any(a in ("--tags", "--follow-tags") for a in args):
|
|
120
120
|
return "git push --tags"
|
|
121
|
-
if any(a.startswith("refs/tags/") or re.fullmatch(r"v?\d+\.\d+\.\d+.*", a) for a in args):
|
|
121
|
+
if any(a.startswith("refs/tags/") or a.partition(":")[2].startswith("refs/tags/") or re.fullmatch(r"v?\d+\.\d+\.\d+.*", a) for a in args):
|
|
122
122
|
return "git push <tag>"
|
|
123
123
|
if t.endswith("gh") and rest[:2] == ["release", "create"]:
|
|
124
124
|
return "gh release create"
|
|
@@ -50,12 +50,14 @@ From [`../pipeline.schema.json`](https://github.com/ssheleg/task-pipeline/blob/m
|
|
|
50
50
|
|---|---|---|
|
|
51
51
|
| `auto` | the orchestrator verifies the `check` itself, pass/fail, and stops on fail | advancing on an unverified check |
|
|
52
52
|
| `judgment` | somebody **rules** on it, because no complete deterministic check exists; the gate names its `judge` | recording the ruling in the slot reserved for what a machine established |
|
|
53
|
-
| `manual` |
|
|
53
|
+
| `manual` | the operator's **explicit** go, or specific standing authorization naming the act | treating an auto verification as the approval |
|
|
54
54
|
|
|
55
55
|
**An auto gate never substitutes for a required manual approval.** A green table is
|
|
56
56
|
not the operator confirming it is what they asked for, and no amount of checking
|
|
57
57
|
makes it one. Which stages are manual is the **operator's** decision, recorded in
|
|
58
58
|
their `pipeline.json`; the framework fixes no stage count and no gate assignment.
|
|
59
|
+
A standing authorization is cited with its source and scope, not inferred from a generic
|
|
60
|
+
loop flag ([`continuity.md`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/references/continuity.md) → *The limit, before the capability*).
|
|
59
61
|
|
|
60
62
|
**That sentence is about the pipeline's SHAPE, and nothing else.** It says a project
|
|
61
63
|
chooses how many stages it runs and which of them wait for a person. It does not say the
|
|
@@ -495,8 +497,9 @@ run:
|
|
|
495
497
|
what it does not cover, stated, beats two measurements and no decision.
|
|
496
498
|
|
|
497
499
|
**This never licenses skipping a gate.** The gates are the floor, and the floor is
|
|
498
|
-
not proportionate to anything — a `manual` gate waits
|
|
499
|
-
|
|
500
|
+
not proportionate to anything — a `manual` gate waits without an explicit go or a
|
|
501
|
+
specific standing authorization naming its act, cited with source and scope;
|
|
502
|
+
`unknown` fails stage 10, and a green nobody watched fail is not evidence at any blast radius. What is
|
|
500
503
|
proportionate is the work *above* the floor: how many axes, how many passes, how
|
|
501
504
|
much of the corpus. Cutting the floor to go faster is not speed; it is the failure
|
|
502
505
|
this whole file exists to prevent, arriving on schedule.
|
|
@@ -219,7 +219,8 @@ Since v1.50.0 the plugin carries hooks of its own. `hooks/release-gate.sh`
|
|
|
219
219
|
tag push, `gh release create`, `npm publish` — while the run says the suite has not
|
|
220
220
|
passed. `hooks/gate-observer.sh` (`PostToolUse` and `PostToolUseFailure`) records
|
|
221
221
|
what the declared gate command actually did. `hooks/memory-nudge.sh` (`PostToolUse` on `Bash|Edit|Write|MultiEdit`) reminds,
|
|
222
|
-
once per returned gate, that no workflow-memory line follows it
|
|
222
|
+
once per returned gate, that no workflow-memory line follows it — unless the run recorded
|
|
223
|
+
memory unavailable with `--for-run`
|
|
223
224
|
([`continuity.md`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/references/continuity.md), Part 3).
|
|
224
225
|
|
|
225
226
|
**Two lessons from v1.50.0, both shipped as defects and both fixed in v1.51.0.**
|
|
@@ -44,6 +44,7 @@ file exists to stop.
|
|
|
44
44
|
- A fix to one call site closes a call site, not a class
|
|
45
45
|
- The loop closes at stage 0
|
|
46
46
|
- Where a lesson goes when it is not about this project
|
|
47
|
+
- Recording to a shared lesson store, where the host has one
|
|
47
48
|
- Publishing the insight — the skill learns from every project that runs it
|
|
48
49
|
- The improvement iteration — what happens to a published insight next
|
|
49
50
|
- What may leave the project — the redaction list
|
|
@@ -416,6 +417,28 @@ file that accumulates universal rules is a fork of the skill that nobody named.
|
|
|
416
417
|
trigger and no authorization** — an instruction on rung 1 that everybody read as done.
|
|
417
418
|
The rest of this section is the mechanism.
|
|
418
419
|
|
|
420
|
+
## Recording to a shared lesson store, where the host has one
|
|
421
|
+
|
|
422
|
+
**One job: let the next agent on another project read this lesson at its stage 0.** An
|
|
423
|
+
entry whose class would be true in another project carries a `**Lesson:**` line — the class
|
|
424
|
+
key, the class in one sentence, when it applies, 3–8 search nouns. That line makes it a
|
|
425
|
+
*lesson* ([`lesson.schema.json`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/templates/lesson.schema.json), lesson/1): with task-pipeline installed, its `scripts/lessons.py add` puts it in the
|
|
426
|
+
local index every install has, and where the session lists a shared lesson store (an
|
|
427
|
+
Observatory) it is also recorded there, as a proposal. An entry without the line stays
|
|
428
|
+
private to this project.
|
|
429
|
+
|
|
430
|
+
**A lesson is not a publication, but the redaction list below binds it too — with one
|
|
431
|
+
relaxation.** On this machine or estate (the local index, a shared store), rule 2 is relaxed
|
|
432
|
+
for exactly two fields: the evidence commit and the pseudonymous project key (`p-` and 12 hex
|
|
433
|
+
of the root commit, the same key in the store, never the repository's name or a
|
|
434
|
+
`project:<slug>` id). A private repository's SHA names nothing; a public repository's SHA is
|
|
435
|
+
searchable, so it stays in its field and never in text. Rules 1, 3, 4 and 5 still bind every
|
|
436
|
+
text field: no path at all, no code or value, no person's, company's, customer's or
|
|
437
|
+
product's name, a title that states the class. `retro.publish` strips the whole origin.
|
|
438
|
+
The read side is source 7b of [`knowledge-sources.md`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md). Where no store exists the run
|
|
439
|
+
says `shared lessons: absent` rather than nothing.
|
|
440
|
+
Mechanics and the read and write recipes: [`iteration.md`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/references/iteration.md) → *The learning loop*.
|
|
441
|
+
|
|
419
442
|
## Publishing the insight — the skill learns from every project that runs it
|
|
420
443
|
|
|
421
444
|
**One job: stop a lesson dying in the repository that learned it.**
|
|
@@ -507,7 +530,9 @@ is what you want them to do.
|
|
|
507
530
|
## What may leave the project — the redaction list
|
|
508
531
|
|
|
509
532
|
An issue is a **public artefact in someone else's repository**. What travels is the
|
|
510
|
-
*class*; what stays is everything that identifies where it happened.
|
|
533
|
+
*class*; what stays is everything that identifies where it happened. This list binds
|
|
534
|
+
whatever leaves the estate, and every lesson too; *Recording to a shared lesson store*
|
|
535
|
+
above names the one relaxation a lesson kept on this machine or estate gets.
|
|
511
536
|
|
|
512
537
|
| Goes | Stays |
|
|
513
538
|
|---|---|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-pipeline
|
|
3
|
-
description: "Use when work changes the repository — feature, fix, bug, refactor, migration, integration, rewrite, adoption or hardening; фича, фикс, баг, рефактор, миграция, интеграция, доработать, починить, внедрить, перевести — or a finding that lands in it: audit/аудит, bug hunt/проверь ошибки, production check/проверь прод, PR review/ревью PR — or on 'run this through the pipeline'
|
|
3
|
+
description: "Use when work changes the repository — feature, fix, bug, refactor, migration, integration, rewrite, adoption or hardening; фича, фикс, баг, рефактор, миграция, интеграция, доработать, починить, внедрить, перевести — or a finding that lands in it: audit/аудит, bug hunt/проверь ошибки, production check/проверь прод, PR review/ревью PR — or on 'run this through the pipeline'/'прогони по конвейеру', 'the full cycle'/'полный цикл', /task-pipeline. Runs a substantial task through gated stages: intake grill, docs, brainstorm, spec, plan, build, tests, deploy, post-deploy, docs/wiki, acceptance. 'waves'/'волнами'/'release iteration'/'итерация релиза' closes the board; 'checkup'/'чекап' lists unconfirmed releases; 'setup' audits docs. Not for: answering a question, explaining, a typo, a one-line edit, a rename, recon that lands nothing — say 'no pipeline'/'без пайплайна' to opt out."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: "Doctrine runs on any agent. The bundled scripts need python3; the run needs git. Missing either degrades, never blocks — the graph verbs and seeded gates go unused, and the run says so."
|
|
6
6
|
---
|
|
@@ -46,7 +46,7 @@ kernel field. Each gate has a **type**: `auto` (the
|
|
|
46
46
|
orchestrator verifies the `check` itself, pass/fail), `judgment` (no complete
|
|
47
47
|
deterministic check exists — a named judge rules, and the ruling is recorded as
|
|
48
48
|
judgement, never as a measurement; `references/gates.md` → *The judgment gate*)
|
|
49
|
-
or `manual` (
|
|
49
|
+
or `manual` (an explicit go, including specific standing authorization); which stages are manual is the
|
|
50
50
|
operator's call. In the
|
|
51
51
|
example's `skills[]`, `task-pipeline:<name>` denotes this skill's own built-in
|
|
52
52
|
doctrine (`references/<name>.md`) and `host:<name>` denotes the host project's own
|
|
@@ -59,9 +59,9 @@ the environment resolves.
|
|
|
59
59
|
plugin, nothing to resolve at preflight and no version skew with someone else's
|
|
60
60
|
repo. Stages 1 and 6–9 additionally run the *host's own* commands and optional
|
|
61
61
|
tools, and **no stage blocks on an install** — stage 1 falls back to web search, the
|
|
62
|
-
wiki and the code graph are recommendations.
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
wiki and the code graph are recommendations. On user-facing tasks stage 3 requires
|
|
63
|
+
a valid scenario artifact; the provider rule below governs equivalent providers
|
|
64
|
+
and the inline fallback.
|
|
65
65
|
|
|
66
66
|
Which reference owns which stage — all forty-odd of them, by stage number:
|
|
67
67
|
[`references/doctrine-map.md`](./references/doctrine-map.md).
|
|
@@ -122,11 +122,10 @@ Stage 0 reads those standing instructions in full, which is why the prune is a g
|
|
|
122
122
|
criterion: a rule nobody reads to the end is worse than no rule, because everyone
|
|
123
123
|
believes it is covered.
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
- **The design destination** with Figma on — *which* file per surface, in which team, decided at stage 0. Left to drawing time it is answered by whoever holds the brush, and the answer is usually *create a new file*.
|
|
125
|
+
**At stage 0, read [grill.md](references/grill.md)** for domain awareness
|
|
126
|
+
(`CONTEXT.md` / ADRs; write resolved terms back), the autonomy sweep (pre-resolve
|
|
127
|
+
stages 1→10), and the Figma design destination (file and team per surface, settled
|
|
128
|
+
before drawing, never invented by the drawing agent).
|
|
130
129
|
|
|
131
130
|
## How to run
|
|
132
131
|
|
|
@@ -154,12 +153,12 @@ Three things the grill does beyond clarifying the request, each in full in
|
|
|
154
153
|
autonomy sweep is covered, **the REQ table is
|
|
155
154
|
written (one row per independently verifiable deliverable, each naming its
|
|
156
155
|
check)** and the brief is locked
|
|
157
|
-
(`references/
|
|
156
|
+
(`references/stage-00-intake.md`). Do not touch stage 1 before the brief is
|
|
158
157
|
committed and confirmed. **Entered from super-ux?**
|
|
159
158
|
(a validated `docs/ux/` chain and/or a `docs/ux/plans/…` fix plan already
|
|
160
159
|
exists — super-ux's `/ux` hands off here) → don't re-grill or rebuild the UX
|
|
161
160
|
chain: just check it's OK (`/ux-lint` green), confirm scope in one line, and
|
|
162
|
-
skip ahead to the first stage with real work (see `references/
|
|
161
|
+
skip ahead to the first stage with real work (see `references/stage-00-intake.md`).
|
|
163
162
|
3. Walk stages 1→10 on the model confirmed at preflight. **Don't re-ask about the
|
|
164
163
|
model at every boundary** — only when the operator recorded a per-stage override
|
|
165
164
|
map and the next stage's entry differs (`references/model-tiering.md`).
|
|
@@ -176,13 +175,16 @@ Three things the grill does beyond clarifying the request, each in full in
|
|
|
176
175
|
build order, one brick at a time — stages 0–2 run once, and the module map's
|
|
177
176
|
status column is the resume point (`references/stages.md` → *The program loop*).
|
|
178
177
|
**The whole board?** `/task-pipeline waves` (`references/waves.md`): stages
|
|
179
|
-
0–4 once, 5–8 per wave, 9–10 to close.
|
|
178
|
+
0–4 once, 5–8 per wave, 9–10 to close. **The project moves in releases**: the loop
|
|
179
|
+
around the waves — survey, module dossiers, one design, parallel build, checks that
|
|
180
|
+
start as each node lands, release, post-release check, next pool — is
|
|
181
|
+
`references/iteration.md`. A finding joins the inventory; it is not fixed alone.
|
|
180
182
|
4. Do **not** advance until the stage **gate** passes (`references/stages.md`).
|
|
181
183
|
Honor the gate **type**: for `auto`, verify the gate's `check` yourself and
|
|
182
184
|
stop/return on fail; for `judgment`, record the named judge's ruling as
|
|
183
|
-
judgement, never as a measurement; for `manual`, present the result and
|
|
184
|
-
**
|
|
185
|
-
|
|
185
|
+
judgement, never as a measurement; for `manual`, present the result and cite the
|
|
186
|
+
**operator's explicit go or standing authorization naming this act**. Other gate
|
|
187
|
+
types and generic loop flags cannot supply that authority (`references/continuity.md`).
|
|
186
188
|
5. **The cross-cutting rules fire at any stage**, not only here — the Doc Loop, the
|
|
187
189
|
loop guard, the audit's exit, the frozen REQ list, the carry-over ledger, and
|
|
188
190
|
what counts as evidence, and **every gate prints `holds: N`** — what this run left
|
|
@@ -191,7 +193,7 @@ Three things the grill does beyond clarifying the request, each in full in
|
|
|
191
193
|
unaccounted (`references/residue.md`). The rest are in
|
|
192
194
|
[`references/gates.md`](references/gates.md) → *Cross-cutting, at every stage*.
|
|
193
195
|
|
|
194
|
-
## Stages (
|
|
196
|
+
## Stages (gates and routes in `references/stages.md`)
|
|
195
197
|
|
|
196
198
|
All stages run on the **one model confirmed at preflight** (default: the most
|
|
197
199
|
capable available — see `references/model-tiering.md`).
|
|
@@ -211,9 +213,11 @@ capable available — see `references/model-tiering.md`).
|
|
|
211
213
|
| 10 | **Acceptance** | the ladder walk ran and its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; no unresolved ledger row; **every repository clean, pushed and pointed at**; the hand-back written and the environment given back; the retrospective written **last**, and in order | manual |
|
|
212
214
|
|
|
213
215
|
**Every gate above is the short form**, and the long form is the point of
|
|
214
|
-
[`references/stages.md`](references/stages.md) — one
|
|
215
|
-
|
|
216
|
-
|
|
216
|
+
[`references/stages.md`](references/stages.md) — one gate and exact detail route per
|
|
217
|
+
default stage. Before work on entry or resume, read that stage’s routed detail,
|
|
218
|
+
including waves and approved short paths; never preload all details. CUSTOM
|
|
219
|
+
profiles use their own declared doctrine; matching numeric ids do not select
|
|
220
|
+
default details. Full obligations stay in the spine and the selected detail.
|
|
217
221
|
|
|
218
222
|
**Several repositories?** A submodule is finished when its parent says so — a clone
|
|
219
223
|
can still get the commit before it while neither repository looks wrong alone. The
|
|
@@ -91,9 +91,10 @@
|
|
|
91
91
|
"running",
|
|
92
92
|
"done",
|
|
93
93
|
"blocked",
|
|
94
|
-
"parked"
|
|
94
|
+
"parked",
|
|
95
|
+
"waiting"
|
|
95
96
|
],
|
|
96
|
-
"description": "`blocked` is waiting on an edge; `parked` is the verifier's deliberate *«this is a blocker, continue around it»*. The two are different facts and collapsing them loses the one a person needs."
|
|
97
|
+
"description": "`blocked` is waiting on an edge; `parked` is the verifier's deliberate *«this is a blocker, continue around it»*. The two are different facts and collapsing them loses the one a person needs. `waiting` records an external event and a watcher locator; it is never runnable."
|
|
97
98
|
},
|
|
98
99
|
"claim": {
|
|
99
100
|
"type": [
|
|
@@ -205,6 +206,10 @@
|
|
|
205
206
|
],
|
|
206
207
|
"description": "The class of the user-facing surface this node builds, copied from the brief's `surface_class` (stage 0). It selects the gate profile, and `graph.py certify` reads it: on `flagship` or `product` the fourth, `visual` tier report is REQUIRED, because none of unit, seam or product opens the contact sheet; on any other class a `visual` report is accepted when given. Absent on a node that builds no user-facing surface. `references/certification.md` → *The fourth reading*."
|
|
207
208
|
},
|
|
209
|
+
"risk": {
|
|
210
|
+
"enum": ["R1", "R2", "R3"],
|
|
211
|
+
"description": "The node's risk class (`references/iteration.md` → *Verification starts when a node lands*), computed from what it touches and never lowered to save time. It sets how many PASSING certification rounds the node owes (a failed round counts for nothing): R1 one, R2 two, R3 three, one of them recorded adversarial (`certify --kind adversarial`). A round is the three blind tiers plus one fix cycle. Absent outside wave mode or a release iteration. `graph.py close` refuses a node until the rounds its class owes have passed."
|
|
212
|
+
},
|
|
208
213
|
"wave": {
|
|
209
214
|
"type": "integer",
|
|
210
215
|
"minimum": 1,
|
|
@@ -264,6 +269,11 @@
|
|
|
264
269
|
"type": "string",
|
|
265
270
|
"minLength": 1
|
|
266
271
|
},
|
|
272
|
+
"kinds": {
|
|
273
|
+
"type": "array",
|
|
274
|
+
"description": "One entry per round: `blind` (the default) or `adversarial` (`graph.py certify --kind adversarial`). An R3 node owes three passing rounds, one of them adversarial (`references/certification.md` → *Rounds owed by risk class*).",
|
|
275
|
+
"items": {"enum": ["blind", "adversarial"]}
|
|
276
|
+
},
|
|
267
277
|
"history": {
|
|
268
278
|
"type": "array",
|
|
269
279
|
"minItems": 1,
|
|
@@ -392,6 +402,9 @@
|
|
|
392
402
|
}
|
|
393
403
|
},
|
|
394
404
|
"description": "The IMMUTABLE dispatch packet this node was built from (FIX-PF-05.01): address + digest of the compiled packet (REQ refs, constraints, interfaces, artifact digests, base, scope, budget, profile, skill lock — no ephemeral secret). Links the node to the exact context it ran under, so a graph in a git-ignored workspace still points at a durable, content-addressed packet."
|
|
405
|
+
},
|
|
406
|
+
"waiting_on": {
|
|
407
|
+
"$ref": "#/definitions/wait_record"
|
|
395
408
|
}
|
|
396
409
|
},
|
|
397
410
|
"allOf": [
|
|
@@ -406,6 +419,9 @@
|
|
|
406
419
|
},
|
|
407
420
|
{
|
|
408
421
|
"$ref": "#/definitions/rule_running_needs_claim"
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
"$ref": "#/definitions/rule_waiting_needs_watcher"
|
|
409
425
|
}
|
|
410
426
|
]
|
|
411
427
|
},
|
|
@@ -450,9 +466,12 @@
|
|
|
450
466
|
"close",
|
|
451
467
|
"invalidate",
|
|
452
468
|
"waive",
|
|
453
|
-
"wave"
|
|
469
|
+
"wave",
|
|
470
|
+
"risk",
|
|
471
|
+
"wait",
|
|
472
|
+
"resume"
|
|
454
473
|
],
|
|
455
|
-
"description": "Which mutation made this entry. `close` joined the two on 2026-08-17 with T-5 — and it was caught by a probe rather than by the fixture asserting *the graph after a close still validates*, because `violations()` never reaches an enum. The same disagreement B-084 records, one field over. `invalidate` joined with PF-02.02: a REQ/interface/brief change supersedes a node and resets its downstream proofs. `wave` joined with wave mode: the re-cut after every wave moves nodes between waves, and a move nobody recorded is the quiet re-plan `references/planning.md` refuses."
|
|
474
|
+
"description": "Which mutation made this entry. `close` joined the two on 2026-08-17 with T-5 — and it was caught by a probe rather than by the fixture asserting *the graph after a close still validates*, because `violations()` never reaches an enum. The same disagreement B-084 records, one field over. `invalidate` joined with PF-02.02: a REQ/interface/brief change supersedes a node and resets its downstream proofs. `wave` joined with wave mode: the re-cut after every wave moves nodes between waves, and a move nobody recorded is the quiet re-plan `references/planning.md` refuses. `risk` joined with the release iteration: `waves.py sync-graph` sets a node's risk class from the plan, and a lowering carries its own reason."
|
|
456
475
|
},
|
|
457
476
|
"node": {
|
|
458
477
|
"type": "string",
|
|
@@ -468,6 +487,9 @@
|
|
|
468
487
|
"precondition": {
|
|
469
488
|
"type": "string",
|
|
470
489
|
"description": "The tree the mutation was made against — the proven HEAD for a `close` (FIX-PF-02.01). A revision then carries a VERSION, so a brief/REQ/interface change that moves the tree is a visibly different precondition, which is what invalidates a proof taken before it."
|
|
490
|
+
},
|
|
491
|
+
"waiting_on": {
|
|
492
|
+
"$ref": "#/definitions/wait_record"
|
|
471
493
|
}
|
|
472
494
|
}
|
|
473
495
|
},
|
|
@@ -575,6 +597,69 @@
|
|
|
575
597
|
}
|
|
576
598
|
}
|
|
577
599
|
}
|
|
600
|
+
},
|
|
601
|
+
"rule_waiting_needs_watcher": {
|
|
602
|
+
"if": {
|
|
603
|
+
"properties": {
|
|
604
|
+
"status": {
|
|
605
|
+
"const": "waiting"
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
"required": [
|
|
609
|
+
"status"
|
|
610
|
+
]
|
|
611
|
+
},
|
|
612
|
+
"then": {
|
|
613
|
+
"required": [
|
|
614
|
+
"waiting_on"
|
|
615
|
+
],
|
|
616
|
+
"properties": {
|
|
617
|
+
"claim": {
|
|
618
|
+
"type": "null"
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
"else": {
|
|
623
|
+
"not": {
|
|
624
|
+
"required": [
|
|
625
|
+
"waiting_on"
|
|
626
|
+
]
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
"wait_record": {
|
|
631
|
+
"type": "object",
|
|
632
|
+
"additionalProperties": false,
|
|
633
|
+
"required": [
|
|
634
|
+
"id",
|
|
635
|
+
"kind",
|
|
636
|
+
"watcher"
|
|
637
|
+
],
|
|
638
|
+
"properties": {
|
|
639
|
+
"id": {
|
|
640
|
+
"type": "string",
|
|
641
|
+
"pattern": "^[a-f0-9]{32}$",
|
|
642
|
+
"minLength": 32,
|
|
643
|
+
"maxLength": 32
|
|
644
|
+
},
|
|
645
|
+
"kind": {
|
|
646
|
+
"enum": [
|
|
647
|
+
"ci",
|
|
648
|
+
"review",
|
|
649
|
+
"peer",
|
|
650
|
+
"release",
|
|
651
|
+
"time",
|
|
652
|
+
"lease"
|
|
653
|
+
]
|
|
654
|
+
},
|
|
655
|
+
"watcher": {
|
|
656
|
+
"type": "string",
|
|
657
|
+
"pattern": "\\S",
|
|
658
|
+
"not": {
|
|
659
|
+
"pattern": "[\\r\\n]"
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
578
663
|
}
|
|
579
664
|
}
|
|
580
665
|
}
|
|
@@ -205,6 +205,13 @@
|
|
|
205
205
|
"type": "string",
|
|
206
206
|
"description": "Free prose beside `goal`."
|
|
207
207
|
},
|
|
208
|
+
"authorized_by": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"minLength": 1,
|
|
211
|
+
"pattern": "\\S",
|
|
212
|
+
"not": {"pattern": "[\\r\\n]"},
|
|
213
|
+
"description": "Optional single-line source locator (for example docs/DECISIONS.md:42) for the specific standing authorization covering the tag and its publication. The locator is not authorization: read the source and verify its authority, currentness and scope at stage 7. Absent: inspect existing recorded authority before asking; do not infer a grant from checks approval, loop mode or this field's mere presence (references/deploy-targets.md)."
|
|
214
|
+
},
|
|
208
215
|
"approval": {
|
|
209
216
|
"enum": [
|
|
210
217
|
"checks",
|
|
@@ -201,7 +201,7 @@ plugins/task-pipeline/
|
|
|
201
201
|
audit.md # cross-cutting: the ladder + seams
|
|
202
202
|
loop-guard.md # cross-cutting: churn detection
|
|
203
203
|
progress.md # cross-cutting: what the run prints about itself
|
|
204
|
-
stages.md model-tiering.md
|
|
204
|
+
stages.md stage-*.md model-tiering.md # gates, per-stage detail, model policy
|
|
205
205
|
conventions.md artifacts.md # host conventions, this layout
|
|
206
206
|
companion-skills.md # optional companions + preflight
|
|
207
207
|
templates/ # skeletons seeded into a host project
|
|
@@ -21,6 +21,7 @@ exactly one seam, and that seam already existed as a dangling pointer.
|
|
|
21
21
|
- A row that says work exists names where it lives
|
|
22
22
|
- Priority is computed, not assigned
|
|
23
23
|
- The shape is not fixed, so nothing may assume it
|
|
24
|
+
- A declared source list — `docs/backlog-sources.json`
|
|
24
25
|
- A decision is not debt — `waived`
|
|
25
26
|
- What a loop iteration does with it
|
|
26
27
|
- Rationalizations
|
|
@@ -161,6 +162,30 @@ The same rule governs the verification ledger, where five shapes exist across th
|
|
|
161
162
|
and only one carries a column that can say a *person* looked
|
|
162
163
|
([`exposure.md`](exposure.md)).
|
|
163
164
|
|
|
165
|
+
## A declared source list — `docs/backlog-sources.json`
|
|
166
|
+
|
|
167
|
+
A project whose open work lives in several files — a board, a roadmap, a lane per product —
|
|
168
|
+
can declare them, and then the board is exactly those files. Wave 0's harvest reads only the
|
|
169
|
+
sources the manifest lists, with the id, title and status columns each one names
|
|
170
|
+
([`waves.md`](waves.md) → *Wave 0*). A source of open work the manifest does not list is
|
|
171
|
+
reported as a finding, never silently added; a status change lands only in the owning file,
|
|
172
|
+
under a lease.
|
|
173
|
+
|
|
174
|
+
**The shape is [`templates/backlog-sources.schema.json`](../templates/backlog-sources.schema.json)**
|
|
175
|
+
(backlog-sources/1), and it is the rule for anyone using this skill:
|
|
176
|
+
- `schema` is 1, `repository` the repository's canonical GitHub URL, `sources` 1–100 entries;
|
|
177
|
+
- each source is a relative `path` (no hidden, `.` or `..` segment), a `goal` anchor, and a
|
|
178
|
+
`kind` — `tasks` (the default) or `context`;
|
|
179
|
+
- a `tasks` source has a `format`: `table`, `checklist` or `json-tasks`. A table names its
|
|
180
|
+
`idColumn` and `titleColumn`, and exactly one of `statusColumn` or `defaultStatus: "open"`;
|
|
181
|
+
- `idPattern` is a literal prefix, optionally `[0-9]+`, anchored at both ends; `excludeIds`
|
|
182
|
+
a unique list.
|
|
183
|
+
|
|
184
|
+
Two rules a schema cannot state are the harvest's to check: each path is a regular file
|
|
185
|
+
reached through no symlink, and no two declarations are identical. The Fabric workspace keeps
|
|
186
|
+
a source contract this one is compatible with; that page is provenance, not authority, and a
|
|
187
|
+
public reader never needs it.
|
|
188
|
+
|
|
164
189
|
## A decision is not debt — `waived`
|
|
165
190
|
|
|
166
191
|
`open` is work not done. `dropped` is an idea abandoned. Neither fits a deliberate **no**
|
|
@@ -146,7 +146,7 @@ is either covered now or explicitly dropped by the operator, with the drop writt
|
|
|
146
146
|
into the carry-over ledger. For a platform, the module map
|
|
147
147
|
([`decomposition.md`](decomposition.md)) is committed and approved as part of this
|
|
148
148
|
same gate. Two more criteria close it, and the gate of record —
|
|
149
|
-
[`
|
|
149
|
+
[`stage-02-brainstorm.md`](stage-02-brainstorm.md) → *2 — Brainstorm + decompose* — states both in full:
|
|
150
150
|
**the queue is an artifact rather than a recollection** (where it is a work graph,
|
|
151
151
|
`graph.py validate` exits 0 and `graph.py coverage` names any requirement no node
|
|
152
152
|
serves), and **the loop's arming state is printed** — armed with its queue and
|
|
@@ -169,7 +169,7 @@ having read no pixels at all. The **functional look** and the **visual half** ar
|
|
|
169
169
|
checks; neither discharges the other.
|
|
170
170
|
|
|
171
171
|
**When it runs, and when it gates — by the brief's `surface_class`**
|
|
172
|
-
([`
|
|
172
|
+
([`stage-00-intake.md`](stage-00-intake.md) → *0 — Intake grill — MANDATORY*, the surface-class bullet):
|
|
173
173
|
|
|
174
174
|
| Class | Visual half at stages 5–6 | Human pass at stage 10 |
|
|
175
175
|
|---|---|---|
|