task-pipeline-skill 1.85.2 → 1.86.3
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 +87 -0
- package/CONTRIBUTING.md +2 -2
- package/README.md +2 -1
- package/SKILL-CARD.md +1 -1
- package/bin/task-pipeline.js +70 -9
- package/evals/cases/evidence-docs.json +188 -0
- package/evals/cases/project-audit.json +188 -0
- package/evals/cases/task-pipeline.json +191 -0
- package/package.json +5 -4
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/evidence-docs/SKILL.md +16 -11
- package/plugins/task-pipeline/skills/evidence-docs/references/GENERATED.md +8 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/documentation.md +472 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/gates.md +645 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/hooks.md +279 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/learned.md +292 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/retrospective.md +551 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/setup.md +149 -0
- package/plugins/task-pipeline/skills/evidence-docs/templates/decisions.md +50 -0
- package/plugins/task-pipeline/skills/evidence-docs/templates/docgate.sh +537 -0
- package/plugins/task-pipeline/skills/project-audit/SKILL.md +66 -25
- package/plugins/task-pipeline/skills/project-audit/scripts/audit.py +11 -0
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +71 -54
- package/plugins/task-pipeline/skills/task-pipeline/execution-attempt.schema.json +68 -0
- package/plugins/task-pipeline/skills/task-pipeline/execution-packet.example.json +42 -0
- package/plugins/task-pipeline/skills/task-pipeline/execution-packet.schema.json +217 -0
- package/plugins/task-pipeline/skills/task-pipeline/execution-result.example.json +49 -0
- package/plugins/task-pipeline/skills/task-pipeline/execution-result.schema.json +261 -0
- package/plugins/task-pipeline/skills/task-pipeline/graph.example.json +10 -1
- package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +172 -2
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +50 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +7 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +23 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/audit.md +6 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +8 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +8 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +32 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +14 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/decomposition.md +83 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +53 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/documentation.md +3 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +27 -8
- package/plugins/task-pipeline/skills/task-pipeline/references/hooks.md +10 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/model-tiering.md +19 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/planning.md +203 -26
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +26 -8
- package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +7 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/context_packets.py +686 -0
- package/plugins/task-pipeline/skills/task-pipeline/scripts/execution_authority.py +271 -0
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +415 -18
- package/plugins/task-pipeline/skills/task-pipeline/scripts/packet.py +400 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/README.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/browser-claims.json +54 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/finding-evidence.json +42 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/hooks.example.json +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
|
@@ -15,7 +15,7 @@ coming back to the operator.
|
|
|
15
15
|
## Contents
|
|
16
16
|
|
|
17
17
|
- Phase 1 — harvest before you ask
|
|
18
|
-
- Phase 2 — the loop
|
|
18
|
+
- Phase 2 — the gap check, then the loop
|
|
19
19
|
- Domain awareness
|
|
20
20
|
- The autonomy sweep
|
|
21
21
|
- The design destination — one file, decided here, never invented later
|
|
@@ -42,11 +42,28 @@ Everything below runs against that harvest. An answer you can't check against a
|
|
|
42
42
|
source is a recollection, and the whole loop exists to stop the run from building
|
|
43
43
|
on one.
|
|
44
44
|
|
|
45
|
-
## Phase 2 — the loop
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
## Phase 2 — the gap check, then the loop
|
|
46
|
+
|
|
47
|
+
**Phase 2 opens with a verdict, not a question.** Walk the decision tree against
|
|
48
|
+
the harvest and the request FIRST and mark every branch: **answered** (the
|
|
49
|
+
request, the code, an ADR, a past brief or the wiki already decides it — record
|
|
50
|
+
the source, do not re-ask), **immaterial** (either answer ships the same work —
|
|
51
|
+
decide it yourself and note it), or **material unknown** (the answer changes
|
|
52
|
+
what gets built, is expensive to reverse, or would stop the run later). Only the
|
|
53
|
+
third kind earns a question. **A complete brief yields zero intake questions**
|
|
54
|
+
— the grill's output is then the brief itself, and going around the loop anyway
|
|
55
|
+
is re-negotiating what is already decided, which costs a human round and buys
|
|
56
|
+
nothing.
|
|
57
|
+
|
|
58
|
+
**A material unknown the operator cannot answer now** does not hold the whole
|
|
59
|
+
intake open: it becomes **one bounded decision task** — a named node in the
|
|
60
|
+
plan with the question, the options, the recommendation and the latest date it
|
|
61
|
+
can be decided without rework — and the run proceeds on the branches that do
|
|
62
|
+
not depend on it.
|
|
63
|
+
|
|
64
|
+
Where material unknowns remain, interview the operator about THOSE until you
|
|
65
|
+
reach a **shared understanding**. Walk down each unresolved branch of the
|
|
66
|
+
decision tree, resolving dependencies between decisions one by one.
|
|
50
67
|
|
|
51
68
|
1. **One question per turn.** Never bundle. Wait for the answer before the next.
|
|
52
69
|
2. **Recommend an answer with every question** (+ a one-line rationale). "What do
|
|
@@ -58,8 +75,10 @@ dependencies between decisions one by one.
|
|
|
58
75
|
decisions first, so later answers don't invalidate earlier ones.
|
|
59
76
|
5. **Reconcile contradictions immediately**, and chase dodges: "we'll decide
|
|
60
77
|
later" → "what's the latest you can decide and still ship?"
|
|
61
|
-
6. **Cover the autonomy sweep** (below). An unasked question is not
|
|
62
|
-
is a scheduled interruption at stage 6.
|
|
78
|
+
6. **Cover the autonomy sweep** (below). An unasked MATERIAL question is not
|
|
79
|
+
neutral — it is a scheduled interruption at stage 6. An answered or
|
|
80
|
+
immaterial one asked anyway is not neutral either — it is a human round
|
|
81
|
+
spent confirming what the sources already said.
|
|
63
82
|
|
|
64
83
|
**Stop** when a re-scan surfaces no new branches. Don't grill past diminishing
|
|
65
84
|
returns: genuinely reversible calls can be deferred with a note.
|
|
@@ -129,8 +129,13 @@ machine, and the first surprising denial is debugged in the wrong project.
|
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
- a tool-name pattern (`Edit|Write|…`), or `"*"` for every call;
|
|
132
|
-
- for a specific shell command, add `"if": "Bash(git commit *)"`
|
|
133
|
-
`"
|
|
132
|
+
- for a specific shell command, add `"if": "Bash(git commit *)"` **inside the
|
|
133
|
+
handler object**, beside `"type"` and `"command"` — never beside `"matcher"`.
|
|
134
|
+
A matcher group is only `matcher` + `hooks`; a key Claude Code does not know
|
|
135
|
+
there is ignored, and from 2.1.270 announced at every session start as
|
|
136
|
+
`hooks.json: unknown key "if" … ignored`. This skill's own template carried it
|
|
137
|
+
at group level until v1.86.2, so its gate filtered nothing and ran on every
|
|
138
|
+
Bash call.
|
|
134
139
|
|
|
135
140
|
`if` uses **permission-rule syntax** (`Bash(git *)`, `Edit(*.ts)`) and is evaluated
|
|
136
141
|
**only on tool events** — `PreToolUse`, `PostToolUse`, `PostToolUseFailure`,
|
|
@@ -177,9 +182,9 @@ the project's `.claude/settings.json`.
|
|
|
177
182
|
|
|
178
183
|
```json
|
|
179
184
|
{ "hooks": { "PreToolUse": [
|
|
180
|
-
{ "matcher": "Bash",
|
|
181
|
-
"hooks": [{ "type": "command", "
|
|
182
|
-
"command": "bash scripts/check-docs.sh >&2 || exit 2" }] } ] } }
|
|
185
|
+
{ "matcher": "Bash",
|
|
186
|
+
"hooks": [{ "type": "command", "if": "Bash(git commit *)", "shell": "bash",
|
|
187
|
+
"timeout": 60, "command": "bash scripts/check-docs.sh >&2 || exit 2" }] } ] } }
|
|
183
188
|
```
|
|
184
189
|
|
|
185
190
|
`|| exit 2` is the contract, not a flourish: without it the gate's own `exit 1`
|
|
@@ -30,6 +30,25 @@ even be on the same provider. So:
|
|
|
30
30
|
environment has no Opus-class model, the best available one is the right answer —
|
|
31
31
|
say which one you settled on and keep going.
|
|
32
32
|
|
|
33
|
+
## The operator's explicit choice is inherited, verbatim
|
|
34
|
+
|
|
35
|
+
**Advice and choice are different things, and the second wins.** The
|
|
36
|
+
recommendation above is ADVICE — printed once at preflight. A model or effort
|
|
37
|
+
the operator has set explicitly (`/model`, `/fast`, a config entry, an answer
|
|
38
|
+
at preflight) is the CHOICE, and the plan, every stage and every subagent
|
|
39
|
+
inherit it unchanged. **Task size is not a basis for switching**: a large task
|
|
40
|
+
does not upgrade the model, a mechanical stage does not downgrade it — the only
|
|
41
|
+
thing that changes the model mid-run is an override the operator RECORDED, with
|
|
42
|
+
its basis, in the per-stage map. A switch nobody recorded is a defect, whatever
|
|
43
|
+
it saved.
|
|
44
|
+
|
|
45
|
+
**An unsupported capability is its own line, never a silent swap.** When the
|
|
46
|
+
confirmed model cannot do what a stage needs — vision it lacks, a context
|
|
47
|
+
window the material exceeds, a tool the tier does not offer — the run states
|
|
48
|
+
that limitation by NAME, records it in the brief, and asks (or proceeds with
|
|
49
|
+
the gap named). Substituting a different model to cover the gap without the
|
|
50
|
+
operator's say-so is the same defect as the silent downgrade.
|
|
51
|
+
|
|
33
52
|
## Mechanic — confirm at preflight, then stop asking
|
|
34
53
|
|
|
35
54
|
Once, as part of the preflight (before stage 0):
|
|
@@ -19,7 +19,11 @@ Built into this skill; nothing to install.
|
|
|
19
19
|
- No placeholders
|
|
20
20
|
- Self-review — before handing off
|
|
21
21
|
- This stage settles nothing — and that is a rule, not an omission
|
|
22
|
+
- The UI handoff annex — a packet an executor can build without re-deriving
|
|
23
|
+
- Pre-dispatch — the last gate before a claim
|
|
24
|
+
- The leaf compiler — a slice survives a cold reader or it does not dispatch
|
|
22
25
|
- GATE (auto)
|
|
26
|
+
- Execution packets
|
|
23
27
|
|
|
24
28
|
## Audience
|
|
25
29
|
|
|
@@ -28,6 +32,12 @@ this toolset, has questionable taste, and will read **only their own task**.
|
|
|
28
32
|
Everything they need is in that task: exact paths, complete code, exact commands,
|
|
29
33
|
expected output. DRY. YAGNI. TDD. Frequent commits.
|
|
30
34
|
|
|
35
|
+
For independently dispatched agents, "that task" includes the resolved context
|
|
36
|
+
packet in [Execution packets](#execution-packets): relevant program/module
|
|
37
|
+
constraints, versioned interfaces, decisions and source digests travel with it.
|
|
38
|
+
Do not assume the executor has read a plan header or inherited the planning chat.
|
|
39
|
+
Planning may hand off at plan-ready without claiming implementation is complete.
|
|
40
|
+
|
|
31
41
|
Path: `<artifacts>/plans/YYYY-MM-DD-<topic>.md` — same `<topic>` slug as the
|
|
32
42
|
brief and the spec.
|
|
33
43
|
|
|
@@ -52,24 +62,26 @@ what each one owns. This is where decomposition gets locked in:
|
|
|
52
62
|
into **parallel groups** in topological order, and tag each task
|
|
53
63
|
`depends: [task ids]`.
|
|
54
64
|
|
|
55
|
-
**Then run the fake-edge test over what you just drew.**
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
**Then run the fake-edge test over what you just drew.** Keep dependencies that
|
|
66
|
+
carry data, an enforceable control condition, or resource ordering. Mere sequence
|
|
67
|
+
is not enough. Test each edge before assigning a parallel group:
|
|
58
68
|
|
|
59
69
|
1. Write every task as a box.
|
|
60
70
|
2. Draw an arrow between each pair you were about to order.
|
|
61
|
-
3.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
3. Ask what fails if B starts before A: missing output, unmet approval/control
|
|
72
|
+
condition, or conflicting ownership of a mutable resource?
|
|
73
|
+
4. Keep a justified edge and write its kind plus concrete payload/condition in
|
|
74
|
+
the `Carries` cell: `data: schema v2`, `control: review accepted`, or
|
|
75
|
+
`resource: release write lease on shared registry`.
|
|
76
|
+
5. Remove an edge only if none of those reasons applies. No data payload alone
|
|
77
|
+
does not make an edge fake. Do not remove approval or ownership constraints.
|
|
78
|
+
6. Nodes without incoming dependencies are candidates for group A; capability
|
|
79
|
+
and resource checks still determine whether they can start together.
|
|
80
|
+
|
|
81
|
+
**The stated dependency is reviewable.** An empty `Carries` cell requests a reason,
|
|
82
|
+
not automatic deletion. Keep a justified dependency, remove accidental ordering,
|
|
83
|
+
and leave an unresolved dependency blocked until its condition is understood.
|
|
84
|
+
There is no target number of edges to remove.
|
|
73
85
|
|
|
74
86
|
**File ownership is exclusive within a group.** No two tasks in the same parallel
|
|
75
87
|
group write the same file — that is the rule that makes stage-5 fan-out safe.
|
|
@@ -140,15 +152,15 @@ verbatim from the spec. Every task's requirements implicitly include this sectio
|
|
|
140
152
|
| Group | Tasks | Runs after | Carries |
|
|
141
153
|
|---|---|---|---|
|
|
142
154
|
| A | 1, 2 | — | — |
|
|
143
|
-
| B | 3 | A | <
|
|
155
|
+
| B | 3 | A | <kind: payload, control condition or resource ordering B requires> |
|
|
144
156
|
|
|
145
157
|
---
|
|
146
158
|
```
|
|
147
159
|
|
|
148
|
-
**The `Carries` cell is required on every edge and empty only on group A.**
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
**The `Carries` cell is required on every edge and empty only on group A.**
|
|
161
|
+
Record `data`, `control` or `resource` and its concrete condition. An unexplained
|
|
162
|
+
edge blocks dispatch until justified or removed after review; never delete an
|
|
163
|
+
approval/resource edge merely because it carries no file or value.
|
|
152
164
|
|
|
153
165
|
## Task structure — required
|
|
154
166
|
|
|
@@ -240,9 +252,9 @@ A checklist you run yourself, inline. No subagent:
|
|
|
240
252
|
`clearFullLayers()` in Task 7 is a bug, not a style difference.
|
|
241
253
|
5. **Parallel safety and the fake-edge test:** no two tasks in the same group write
|
|
242
254
|
the same file **or share any other mutable target**; every `depends:` points at a
|
|
243
|
-
task that
|
|
244
|
-
filled. Count
|
|
245
|
-
|
|
255
|
+
task that produces the input or establishes the required condition, and every edge's `Carries` cell is
|
|
256
|
+
filled. Count retained edges by kind and record removed edges with reasons.
|
|
257
|
+
Zero removals is valid when every original dependency is justified.
|
|
246
258
|
6. **DoD present and verifiable** on every task.
|
|
247
259
|
7. **Every command, path and file a DoD names resolves.** Walk each task's
|
|
248
260
|
*Definition of done* and its steps and check the targets exist — a DoD that says
|
|
@@ -270,7 +282,7 @@ before the gate; every line a **computed number, not a tick**.
|
|
|
270
282
|
- Decisions: checked against <the brief's D-table> and <stage 2's rejected options> — <verdict>
|
|
271
283
|
- Cost: <surfaces>/<guards>/<REQ> now, <…> at stage 2 — <proportionate | grown, and why>
|
|
272
284
|
- Hygiene: <n> checks, <n> findings, <n> open
|
|
273
|
-
- Edges: <n> declared, <n>
|
|
285
|
+
- Edges: <n> declared, <n> data, <n> control, <n> resource, <n> removed with reasons
|
|
274
286
|
- Placeholders: <n> · Ambiguity: <n> found, <n> resolved inline
|
|
275
287
|
```
|
|
276
288
|
|
|
@@ -287,6 +299,52 @@ back to stage 3 and is recorded there; a scope question goes back to the operato
|
|
|
287
299
|
A decision first made while sequencing tasks is a decision nothing downstream will
|
|
288
300
|
ever find, because nobody reads a plan after the build.
|
|
289
301
|
|
|
302
|
+
## The UI handoff annex — a packet an executor can build without re-deriving
|
|
303
|
+
|
|
304
|
+
A packet whose work is a screen carries a UI ANNEX beside its context: the
|
|
305
|
+
state IDs it touches, the components it reuses and the props they take, the
|
|
306
|
+
tokens and content strings, the accessibility requirements, and the exact
|
|
307
|
+
asset versions. With it, an executor implements the fixture without going
|
|
308
|
+
back to re-derive the visual spec; without it, the same work is re-decided
|
|
309
|
+
per session and drifts. The annex ADDS to the task context — it never
|
|
310
|
+
replaces the scheduler's claim or fence (that is `agent-sync`'s job, not the
|
|
311
|
+
packet's), and a stale visual spec (an asset version or a token that moved
|
|
312
|
+
under the plan) triggers a packet REVISION exactly as a moved source input
|
|
313
|
+
does, never a silent dispatch against old pixels.
|
|
314
|
+
|
|
315
|
+
The annex is a DOMAIN annex, optional by domain: a screen packet carries it,
|
|
316
|
+
a migration or a CLI packet does not — a non-UI task owes no visual spec,
|
|
317
|
+
and demanding one would be the mirror of the omission it fixes.
|
|
318
|
+
|
|
319
|
+
## Pre-dispatch — the last gate before a claim
|
|
320
|
+
|
|
321
|
+
Before a compiled leaf is claimed and worked
|
|
322
|
+
(`scripts/context_packets.py predispatch`), it passes one final check: every
|
|
323
|
+
input's digest is re-verified against the bytes on disk NOW (source drift
|
|
324
|
+
blocks — the plan was made against other bytes), each data prerequisite's
|
|
325
|
+
output must be materialized, the PRIMARY context must fit its budget (a
|
|
326
|
+
breach BLOCKS and is never a silent truncation — the budget cuts appendix,
|
|
327
|
+
never primary), and the declared capability and coordination claim must be
|
|
328
|
+
present. Any failure blocks the claim and names itself; nothing is trimmed
|
|
329
|
+
to fit.
|
|
330
|
+
|
|
331
|
+
## The leaf compiler — a slice survives a cold reader or it does not dispatch
|
|
332
|
+
|
|
333
|
+
Where the plan is compiled into execution packets
|
|
334
|
+
(`scripts/context_packets.py compile-leaf`), each outcome slice carries its
|
|
335
|
+
resolved decisions (bound by address+digest — an unresolved decision
|
|
336
|
+
dispatches NO leaf), its exact scope, its mapping onto the parent's
|
|
337
|
+
acceptance, and its material split into budgeted primary vs appendix — a
|
|
338
|
+
budget cuts appendix only and records the cut, never acceptance. The test of
|
|
339
|
+
a compiled packet is the **cold reader**: with no author history, the packet
|
|
340
|
+
alone answers eight questions — goal, inputs, decisions, scope, outputs,
|
|
341
|
+
acceptance, guards, resume (`readiness`); a missing version or output
|
|
342
|
+
contract fails readiness. Acceptance names at least one positive and one
|
|
343
|
+
negative case. A slice is selected by its explicit id, never by mtime; and
|
|
344
|
+
neither a design flow nor a `.design/TASKS.md` becomes a parallel plan
|
|
345
|
+
authority — leaves come from the plan through the compiler or they are not
|
|
346
|
+
leaves.
|
|
347
|
+
|
|
290
348
|
## GATE (auto)
|
|
291
349
|
|
|
292
350
|
**Set equality first:** the REQ ids in the brief equal the union of `Implements:`
|
|
@@ -298,6 +356,125 @@ Then: every spec requirement maps to a task; no placeholders; names and types
|
|
|
298
356
|
consistent across tasks; parallel-group tasks share no files **or other mutable
|
|
299
357
|
target**; each task has a verifiable DoD. **Every edge in the *Execution order*
|
|
300
358
|
table has a non-empty `Carries` cell, and the `Edges:` line of the self-review is
|
|
301
|
-
computed** —
|
|
302
|
-
|
|
359
|
+
computed** — each retained edge names data, control or resource semantics. An
|
|
360
|
+
unexplained edge blocks the gate until justified or safely removed. UI tasks carry their scenario IDs and `SCR-` screens. Verify all
|
|
303
361
|
of it yourself and stop on failure — this gate has no operator in it.
|
|
362
|
+
|
|
363
|
+
## Execution packets
|
|
364
|
+
|
|
365
|
+
Size independent-executor tasks with [`decomposition.md`](decomposition.md) →
|
|
366
|
+
Executor-sized tasks and context. Keep parent findings/features as containers;
|
|
367
|
+
dispatch only leaves with resolved material decisions and budgeted primary context.
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
Use this contract when research, intake, specification and planning happen in one
|
|
371
|
+
agent, while other agents execute individual tasks, or when a host pipeline owns
|
|
372
|
+
dispatch. It is an artifact and workflow contract. It does not claim that the
|
|
373
|
+
bundled graph CLI is a distributed scheduler or that it implements the fields
|
|
374
|
+
below as commands.
|
|
375
|
+
|
|
376
|
+
### Roles and boundaries
|
|
377
|
+
|
|
378
|
+
The planning agent harvests sources, resolves material decisions, produces the
|
|
379
|
+
program/module model, specifications, task packets and their dependencies. It may
|
|
380
|
+
finish at **plan-ready**. That state means the plan is available for execution;
|
|
381
|
+
it does not mean the requested product is implemented.
|
|
382
|
+
|
|
383
|
+
An executor receives one task and its resolved context. It does not restart
|
|
384
|
+
intake or independently redesign settled interfaces. If the packet conflicts with
|
|
385
|
+
source reality, it returns a change proposal with evidence to the planner rather
|
|
386
|
+
than silently editing a shared plan. A reviewer evaluates the produced artifact;
|
|
387
|
+
an integrator reconciles compatible outputs and owns the final delivery boundary.
|
|
388
|
+
These are roles, not hardcoded models or host-specific subagent names.
|
|
389
|
+
|
|
390
|
+
### The context closure a task must carry
|
|
391
|
+
|
|
392
|
+
Persist a program brief and decisions, a module/interface map, shared contracts,
|
|
393
|
+
and one task packet per independently reviewable deliverable. Each packet names:
|
|
394
|
+
|
|
395
|
+
- Stable task, program and module IDs; its requirement and finding IDs.
|
|
396
|
+
- The relevant program constraints and module boundaries, as explicit inputs.
|
|
397
|
+
- Decisions with provenance, rationale, rejected alternatives and change triggers.
|
|
398
|
+
- Every consumed/produced interface, including its version and responsible task.
|
|
399
|
+
- Source repository, base revision and digests for the files/inputs it relies on.
|
|
400
|
+
- Files to read, files permitted to change, new files explicitly marked Create,
|
|
401
|
+
and shared mutable resources. A directory name is not a complete ownership claim.
|
|
402
|
+
- Concrete implementation sequence, invariants and edge cases; exact code where
|
|
403
|
+
a signature or algorithm must be settled, without pretending speculative code
|
|
404
|
+
was tested against a future tree.
|
|
405
|
+
- Acceptance checks, required evidence type, scope exclusions and rollback.
|
|
406
|
+
- Output/return format, reviewer/integrator destination and context budget.
|
|
407
|
+
|
|
408
|
+
A linked file is useful only if the receiving agent can fetch it at the recorded
|
|
409
|
+
revision. Resolve required links before dispatch; a missing required contract
|
|
410
|
+
blocks dispatch, while optional context is labelled optional. Do not silently
|
|
411
|
+
truncate required constraints to fit a token budget. Produce a smaller coherent
|
|
412
|
+
task or move background material to retrievable references.
|
|
413
|
+
|
|
414
|
+
Priority, dependency readiness, context completeness and implementation status
|
|
415
|
+
are separate fields. An urgent row can be blocked; a detailed packet can still
|
|
416
|
+
depend on an unfinished contract. Never translate either into "ready" by prose.
|
|
417
|
+
|
|
418
|
+
### Dispatch, retries and changed inputs
|
|
419
|
+
|
|
420
|
+
Before dispatch, verify the packet's inputs and predecessor outputs against their
|
|
421
|
+
current digests. Changed relevant input makes the packet stale until it is
|
|
422
|
+
reconciled; an unrelated file change need not invalidate the whole program.
|
|
423
|
+
Record a new packet revision rather than rewriting the executor's historical input.
|
|
424
|
+
|
|
425
|
+
The host adapter must establish one execution attempt: task ID, packet revision,
|
|
426
|
+
attempt ID, owner, resource scope, expiry/heartbeat when applicable, and a fencing
|
|
427
|
+
token for takeover. A file lock protecting JSON writes is not an execution lease.
|
|
428
|
+
If the host cannot provide this boundary, serialize execution and state the
|
|
429
|
+
limitation; do not run independent workers that merely read the same ready list.
|
|
430
|
+
|
|
431
|
+
An executor returns output artifacts, changed-file digests, base/produced revisions,
|
|
432
|
+
checks with PASS/FAIL/NOT_RUN/TEST_ERROR, remaining risks and the attempt token.
|
|
433
|
+
Completion is accepted only for the current attempt and expected input revision.
|
|
434
|
+
Duplicate results are idempotent; a late stale worker cannot close a newer attempt.
|
|
435
|
+
Do not equate an agent's final message with an accepted business result.
|
|
436
|
+
|
|
437
|
+
Dependencies may carry data, a control/approval condition, or a resource ordering
|
|
438
|
+
constraint. Name the kind and reason. A dependency cannot be discarded solely
|
|
439
|
+
because it has no data payload. Dispatch a task only after all its declared
|
|
440
|
+
prerequisites are satisfied, and check overlapping write sets separately.
|
|
441
|
+
|
|
442
|
+
### Portable host integration
|
|
443
|
+
|
|
444
|
+
Keep the packet independent of Claude Code, Codex or any provider's conversation
|
|
445
|
+
format. Each adapter maps dispatch, artifact access, cancellation, progress and
|
|
446
|
+
result receipts to actual host capabilities. Record the capabilities used.
|
|
447
|
+
Fresh agents and resumed agents receive the same required context closure.
|
|
448
|
+
|
|
449
|
+
For an external platform, map both schemas explicitly: a stage list is not a work
|
|
450
|
+
graph, a handoff message is not an execution lease, and an artifact path is not
|
|
451
|
+
proof that a remote worker can read it. Until the adapter and its failure tests
|
|
452
|
+
exist, label integration proposed/manual rather than supported.
|
|
453
|
+
|
|
454
|
+
### UI task annex
|
|
455
|
+
|
|
456
|
+
For a UI outcome, attach the scenario/screen/state IDs, selected flow and visual
|
|
457
|
+
direction revision, component reuse/modify/create decisions, semantic token roles,
|
|
458
|
+
approved or explicitly provisional content, keyboard/accessibility expectations,
|
|
459
|
+
responsive/native behavior, and local asset provenance. Include only the portion
|
|
460
|
+
needed for this leaf. A non-UI task does not need this annex.
|
|
461
|
+
|
|
462
|
+
Keep behavior, its visual presentation and relevant states together when they
|
|
463
|
+
form one independently verifiable outcome. Do not split every screen into HTML,
|
|
464
|
+
CSS and interaction jobs. A changed flow, component contract or design revision
|
|
465
|
+
refreshes the affected packets; the executor does not guess which screenshot or
|
|
466
|
+
style discussion was authoritative. Preserve the existing family artifact paths.
|
|
467
|
+
|
|
468
|
+
### Audit to executable backlog
|
|
469
|
+
|
|
470
|
+
Every finding has a disposition and a task or a recorded reason for not acting.
|
|
471
|
+
Separate common enabling contracts from per-finding repairs; link each task to
|
|
472
|
+
the program/module/interface context it consumes. Build the graph, verify its
|
|
473
|
+
closure, and partition runnable tasks by disjoint write sets. Include input drift,
|
|
474
|
+
missing context, duplicate dispatch, late completion, multiple prerequisites,
|
|
475
|
+
cancellation and failure recovery in acceptance. A cold reader must understand
|
|
476
|
+
why the change exists and how its result fits the system without the original chat.
|
|
477
|
+
|
|
478
|
+
Store the packet set with the plan. Planning is complete when the declared scope
|
|
479
|
+
is covered, required inputs resolve, dependencies are acyclic and readiness is
|
|
480
|
+
reported honestly. Delivery remains a separate state with its own evidence.
|
|
@@ -41,6 +41,7 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
41
41
|
|---|---|
|
|
42
42
|
| The stage list, ids, names, gate types | `pipeline.example.json` |
|
|
43
43
|
| Per-stage criteria, freedom levels, the run checklist | `references/stages.md` |
|
|
44
|
+
| Which reference owns which stage (the doctrine map) | `references/doctrine-map.md` |
|
|
44
45
|
| What the intake grill asks, and the autonomy sweep | `references/grill.md` |
|
|
45
46
|
| **The escalation boundary** — what an agent may settle alone | `references/grill.md` |
|
|
46
47
|
| The knowledge harvest and its source ledger | `references/knowledge-sources.md` |
|
|
@@ -269,15 +269,31 @@ printf '%s · %s\n' "$(date +%F)" "$(git rev-parse --short HEAD)" >> docs/eviden
|
|
|
269
269
|
A lesson that lands in a cluttered file is a lesson nobody will reach — so the prune still runs
|
|
270
270
|
before the entry is written. It runs *after* the stamp, because it reads it.
|
|
271
271
|
|
|
272
|
-
Every row carries its own trigger in a **`Retire when`** column
|
|
273
|
-
a rule whose retirement condition is decided later is a
|
|
274
|
-
argue about.
|
|
272
|
+
Every row carries its own trigger in a **`Retire when`** column AND a **class**,
|
|
273
|
+
both written at birth — a rule whose retirement condition is decided later is a
|
|
274
|
+
rule the prune can only argue about. Three classes, because coldness means
|
|
275
|
+
three different things:
|
|
276
|
+
|
|
277
|
+
- **permanent** — a safety invariant, a contract, a recovery procedure. The
|
|
278
|
+
absence of the rare event it guards is not absence of value: **coldness never
|
|
279
|
+
retires a permanent rule** — only *became a check* or *surface gone* do.
|
|
280
|
+
- **situational** — fires when a named EXPOSURE occurs (a payment run, a
|
|
281
|
+
migration, a release). Its row names the exposure, and the prune counts
|
|
282
|
+
**exposure opportunities, not raw runs**: five runs that never touched
|
|
283
|
+
payments say nothing about a payment rule.
|
|
284
|
+
- **temporary** — a workaround with a **TTL** and the replacing mechanism named
|
|
285
|
+
at birth. TTL only exists on this class.
|
|
286
|
+
|
|
287
|
+
Check **every** standing instruction against three triggers:
|
|
275
288
|
|
|
276
289
|
| Trigger | Test | Then |
|
|
277
290
|
|---|---|---|
|
|
278
291
|
| **It became a check** | the rule is now enforced by a test, lint, gate or hook | delete it — the check is the memory, and keeping both means it is read twice and obeyed once |
|
|
279
292
|
| **Its surface is gone** | resolve every path, command, stage and tool it names; any that no longer exists | delete it — it now describes a system nobody is running |
|
|
280
|
-
| **It went cold** |
|
|
293
|
+
| **It went cold** | *situational only*: it fired in none of the last **five exposure opportunities** — or no exposure occurred in **sixty days** | mark **review-needed** and put the question to the operator with the exposure counts — cold is evidence worth reviewing, never an automatic deletion. *temporary*: TTL expired → archive it **once the replacing mechanism is verified present** (its check resolves and runs); an expired workaround whose replacement is absent is a live defect, not a retirement. *permanent*: not applicable |
|
|
294
|
+
|
|
295
|
+
Every removal stays explainable: the archive line names the class, the trigger
|
|
296
|
+
and the evidence (the exposure counts, or the replacing mechanism's check).
|
|
281
297
|
|
|
282
298
|
**Each trigger is a command, not a judgement.** A retirement condition nobody can run is a
|
|
283
299
|
condition nobody applies, which is how a list reaches ten and stops being read:
|
|
@@ -297,10 +313,12 @@ tail -n 200 docs/evidence/retro.md | grep -c "$RULE_ID"
|
|
|
297
313
|
git log -1 --format=%cd --date=short -S"$RULE_ID" -- docs/evidence/retro.md
|
|
298
314
|
```
|
|
299
315
|
|
|
300
|
-
Anything the first two print is a deletion
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
316
|
+
Anything the first two print is a deletion. A zero from the third — counted against
|
|
317
|
+
**exposure opportunities** for a situational rule (`grep -c "$EXPOSURE_MARK"` over the same
|
|
318
|
+
stamps, so the denominator is runs that COULD have fired it) — marks **review-needed**, and the
|
|
319
|
+
run states the counts rather than the conclusion (`learned.md` rule 19 — an empty result and an
|
|
320
|
+
unrun command look identical). Only the operator's answer, or a temporary rule's verified
|
|
321
|
+
replacement, turns review-needed into a removal.
|
|
304
322
|
|
|
305
323
|
**Why the cold trigger needs two units, and it is not belt-and-braces.** A run stamp is written by
|
|
306
324
|
a run *of this pipeline*. Where a project ships some of its work another way, the stamp counter
|
|
@@ -38,7 +38,7 @@ turn of every loop.
|
|
|
38
38
|
| `goal_clauses` | release work no requirement names. Enumerated, never matched against the goal's prose: substring-matching a sentence produces confidence without correctness |
|
|
39
39
|
| `nodes[].owner` | which role does it. A node nobody can dispatch never leaves the frontier and nothing says why |
|
|
40
40
|
| `nodes[].serves` | the REQ or goal clause it exists for. A node serving neither is **parked with that as the reason** |
|
|
41
|
-
| `nodes[].blocked_by` | what must
|
|
41
|
+
| `nodes[].blocked_by` | what must PRODUCE first. The frontier obeys a satisfaction predicate, and only `done` satisfies — a PARKED producer blocks its consumer, because a park is a decision not to produce, not a production. `next` names each held consumer with the park's reason; a valid alternative producer is an explicit, versioned edge change, never an implicit unblock |
|
|
42
42
|
| `nodes[].touches` | what it **mutates**. Two runnable nodes writing one file is the false parallelism [`planning.md`](planning.md) refuses — *distinct is not the same as independent, and the check is what they touch, never what they are called* |
|
|
43
43
|
| `nodes[].check` | **how this node will be closed** — one command, or the named judgement where no command can decide it. Required on every node except a `parked` one. The certification's `unit` tier runs it and reports its output as the evidence row ([`certification.md`](certification.md) — three blind tiers close a node, not one reader); before this field existed that instruction pointed at an absence, leaving a verifier the two things it forbids — invent a check, or run everything (B-080) |
|
|
44
44
|
| `nodes[].evidence` | required when `status` is `done`. A node called done by assertion is what evidence exists to prevent |
|
|
@@ -63,6 +63,12 @@ conditional on the code, never merely sequenced after it.**
|
|
|
63
63
|
| `close` | the goal, the new frontier count, and what was not verified | `0` · `1` refused **or the verdict stops the run** |
|
|
64
64
|
| `producer` | what produced this proof — actor, model, runtime, skill, config, commit, trace | `0` |
|
|
65
65
|
| `doctrine` | how many of the bundle's reference files this run opened | `0` |
|
|
66
|
+
| `claim` | **external mode** — arbitrate one runnable node to a single owner through the durable coordinator (`scripts/execution_authority.py`); prints the grant. `next` says what COULD run, `claim` says who MAY | `0` won · `5` lost the race · `4` not runnable · `1` authority unavailable — **and `1` means no work starts** (fail-closed) |
|
|
67
|
+
| `release` | give back a hold this run owns, matching its fence; a mismatch is a no-op, never a way to steal a live node | `0` released · `5` not held at that fence · `1` authority unavailable |
|
|
68
|
+
| `recover` | **external mode** — reclaim an EXPIRED node for a new owner, minting a higher fence; a still-live claim is not recoverable (that is stealing a working node) | `0` recovered · `5` still live · `1` authority unavailable |
|
|
69
|
+
| `complete` | **external mode** — record completion from the CURRENT fence-holder only; a late/superseded worker (stale fence) is refused, and the current holder completing twice is idempotent | `0` completed · `5` not the current holder · `1` authority unavailable |
|
|
70
|
+
| `waive` | record an AUTHORIZED EXCEPTION — reason + identity, its own disposition: the node is never marked certified, a failed certification stays visible, and `close` stamps the exception into the evidence | `0` waived · `1` refused (no reason, no identity, unknown node) |
|
|
71
|
+
| `invalidate` | a REQ/interface/brief change supersedes one node: a superseding revision is recorded, and the node plus every `done` DESCENDANT resets to pending with its evidence/proof/certification cleared — a proof certified against a contract that moved is a proof about a tree that no longer exists. Unrelated nodes keep their proofs; invalidation flows downstream only | `0` invalidated · `1` refused (no `--why`, unknown node, or the write would break the graph) |
|
|
66
72
|
|
|
67
73
|
**`next` is ordered by what each node unblocks, transitively, and the number is computed.**
|
|
68
74
|
A `priority` field is something somebody typed once and nobody revisits; this one moves when
|