task-pipeline-skill 1.85.2 → 1.86.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -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 +274 -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/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/run.md +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: project-audit
|
|
3
|
-
description: "Use when someone asks what is actually true of a whole project right now — what is finished, what is half-built, what is broken, and what nobody has looked at. Walks a cold start: discover what the project is, run a registry of probes chosen from that, read production evidence (published artefact against source, CI history, telemetry present or absent), then leave a
|
|
3
|
+
description: "Use when someone asks what is actually true of a whole project right now — what is finished, what is half-built, what is broken, and what nobody has looked at. Walks a cold start: discover what the project is, run a registry of probes chosen from that, read production evidence (published artefact against source, CI history, telemetry present or absent), then leave a JSON sidecar so the next audit can say what moved, and a self-contained HTML report on request. Read-only: it proposes board rows and commits nothing. Triggers - 'project audit', 'audit the project', 'codebase audit', 'state of the project', 'what is unfinished', 'project health check', 'аудит проекта', 'проаудируй проект', 'состояние проекта', 'что не доделано', 'аудит кодовой базы'. Not for: auditing one deliverable inside a run (that is the pipeline's own ladder), reviewing a diff, or checking a skill's construction — say 'без диагностики' to opt out."
|
|
4
4
|
license: MIT
|
|
5
5
|
compatibility: "The collector (scripts/audit.py) needs python3 and reads committed state, so it needs git. Probes needing gh, npm, network or a browser declare it and report blind when it is absent — degraded, never silent."
|
|
6
6
|
---
|
|
@@ -122,23 +122,36 @@ audit: what a fix costs is the fixer's decision, not the finder's
|
|
|
122
122
|
([`references/prioritisation.md`](../task-pipeline/references/prioritisation.md)). An audit
|
|
123
123
|
that edits while it reads cannot be re-run to check itself.
|
|
124
124
|
|
|
125
|
-
## A finding
|
|
126
|
-
|
|
127
|
-
**
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
## A finding keeps its axes apart, or it is a guess wearing a verdict
|
|
126
|
+
|
|
127
|
+
**Mechanism status, exploit/reproduction, exposure, observed incidence and impact
|
|
128
|
+
uncertainty are FIVE axes, not one.** A row written from the mechanism alone is
|
|
129
|
+
indistinguishable from a real finding until each axis says what it knows — and one
|
|
130
|
+
audit had **eight consecutive rows** rewritten by measurement, two of which would
|
|
131
|
+
have destroyed inventory if remedied as written, because both read an absence of
|
|
132
|
+
sales as an absence of demand. But the correction cuts both ways:
|
|
133
|
+
|
|
134
|
+
- **A proven defect may have incidence UNKNOWN.** An auth bypass or a race
|
|
135
|
+
reproduced locally is a code defect BEFORE any incident — the reproduction is the
|
|
136
|
+
proof, and no production log is needed to license the row. A confirmed local
|
|
137
|
+
crash with no production logs stays a code defect, external incidence UNKNOWN.
|
|
138
|
+
- **UNKNOWN ≠ 0.** A zero sample is not zero risk; absent telemetry lowers what can
|
|
139
|
+
be said about EXPOSURE, never the technical truth — and the row says which.
|
|
140
|
+
- **Unknown attacker control lowers exploitability CONFIDENCE**, never the observed
|
|
141
|
+
behaviour: what was watched happening stays written as watched.
|
|
142
|
+
- **A documented exception does not turn a failed invariant into PASS** — decision
|
|
143
|
+
status and technical validity are the separate axes of the section below.
|
|
144
|
+
|
|
145
|
+
The incidence axis is still asked: **how often does the mechanism fire?** A query, a
|
|
146
|
+
log count, a telemetry read. Where the answer is *never*, keep the row priced as
|
|
147
|
+
**latent** (the remedy weighed against zero); where the measurement is impossible,
|
|
148
|
+
the INCIDENCE axis records `blind` — and the finding stands on its mechanism and
|
|
149
|
+
reproduction axes. Each row records its observation scope and time, keeping code
|
|
150
|
+
mechanism, deployment observation and assumptions apart —
|
|
151
|
+
`templates/finding-evidence.json` in task-pipeline is the minimal schema, and the
|
|
152
|
+
collector writes `mechanism`/`incidence`/`observed_scope`/`observed_at` into the
|
|
153
|
+
sidecar. Ask an operator only when the unknown would change the action — an
|
|
154
|
+
interview is not a prerequisite for a row.
|
|
142
155
|
|
|
143
156
|
Two rules follow from the same place:
|
|
144
157
|
|
|
@@ -159,9 +172,20 @@ Five of eight rows in one run were that.
|
|
|
159
172
|
- **Read the call site, not only the definition.** A finding about a module is not
|
|
160
173
|
written until the places that use it have been read.
|
|
161
174
|
- **Every row states which of three it is:** *(a)* undecided, *(b)* decided and
|
|
162
|
-
documented right here, *(c)* decided elsewhere and not propagated.
|
|
163
|
-
|
|
164
|
-
|
|
175
|
+
documented right here, *(c)* decided elsewhere and not propagated. **(a)** and **(c)**
|
|
176
|
+
are work — and so is a **(b)** that is still WRONG, because **decision status and
|
|
177
|
+
technical validity are DIFFERENT AXES.** A documented decision can be mistaken, stale,
|
|
178
|
+
or break an external contract; "it's by design" is not a proof of correctness. So a
|
|
179
|
+
**(b)** splits:
|
|
180
|
+
- **accepted trade-off** — a conscious limitation with a real, named cost the project
|
|
181
|
+
chose to pay (single-browser support under a matching contract): mark it *accepted
|
|
182
|
+
limitation* with its cost, not a defect.
|
|
183
|
+
- **documented violation** — a decision that STILL breaks a security invariant, an
|
|
184
|
+
external contract, or its own stated goal (an ADR that permits logging a refresh
|
|
185
|
+
token): this REMAINS a `finding`, carrying the `decision_id`, the reason to revisit,
|
|
186
|
+
and the counter-evidence. Recording a **(b)** the audit got wrong (a false positive)
|
|
187
|
+
is worth more than deleting the row; but excluding every documented decision from
|
|
188
|
+
findings is a systemic source of false NEGATIVES, which is the more expensive miss.
|
|
165
189
|
- **Where the verdict is (c), the remedy is a mechanical check, not an edit.** A
|
|
166
190
|
written rule nobody verifies reaches exactly as far as the place it was written; the
|
|
167
191
|
durable fix in all five cases was a guard that asks the project's own instruction of
|
|
@@ -210,7 +234,12 @@ Two more traps, both of which shipped in the first draft and are now fixtures:
|
|
|
210
234
|
## The artefacts — the sidecar always, the page on request
|
|
211
235
|
|
|
212
236
|
`docs/audit/<date>-audit.json` is written on every run. **The HTML page is written
|
|
213
|
-
only with `--report`.**
|
|
237
|
+
only with `--report`.** Three output modes, and only one needs a browser:
|
|
238
|
+
**stdout** (`--stdout` — the summary in the terminal, nothing written but the
|
|
239
|
+
sidecar), **json** (the sidecar alone, the default — a machine reads it, no
|
|
240
|
+
page and no browser), **html** (`--report` — the page too). A json-only or
|
|
241
|
+
stdout run **never opens a browser and never requires one**; the browser is a
|
|
242
|
+
concern of `--report` alone.
|
|
214
243
|
|
|
215
244
|
The split is not symmetry. The sidecar is what makes this a ratchet rather than a
|
|
216
245
|
snapshot, and the next run reads it — skipping it would silently turn every future run
|
|
@@ -230,6 +259,13 @@ stdout: an audit must not become the second place a credential leaks. Redaction
|
|
|
230
259
|
is total rather than a prefix — half a credential plus its context is often
|
|
231
260
|
enough to finish.
|
|
232
261
|
|
|
262
|
+
**"Read-only" is about the TARGET, not the disk.** The audit reads the
|
|
263
|
+
project's source, data and production evidence and mutates NONE of it, and it
|
|
264
|
+
commits nothing. It DOES write its own artefacts into its allowed output
|
|
265
|
+
directory (`docs/audit/` by default, `--out-dir` to relocate) — the sidecar
|
|
266
|
+
always, the page on `--report`. Writing the sidecar there is not a violation of
|
|
267
|
+
read-only; writing into the target's source, or `git add`-ing anything, is.
|
|
268
|
+
|
|
233
269
|
**The sidecar is what makes this a ratchet rather than a snapshot.** Each
|
|
234
270
|
finding carries an id derived from its probe and its place, so it survives a
|
|
235
271
|
rewording; the next run prints what closed, what is new, and what has now
|
|
@@ -252,16 +288,21 @@ could not look.
|
|
|
252
288
|
|
|
253
289
|
## Exit criterion
|
|
254
290
|
|
|
255
|
-
An audit is finished when
|
|
291
|
+
An audit is finished when — the criterion is CONDITIONAL on the deliverables
|
|
292
|
+
requested, not a fixed page-and-browser:
|
|
256
293
|
|
|
257
294
|
1. every probe has a verdict, and every `blind` one names why;
|
|
258
|
-
2. the
|
|
295
|
+
2. the sidecar is written (always). **On `--report`, and only then**, the HTML
|
|
296
|
+
page also exists, its internal links are safe and resolve, and its
|
|
297
|
+
inspect/render status is recorded (opened, or `--no-open` noted) — WITHOUT
|
|
298
|
+
`--report` no page is created and the run is still complete;
|
|
259
299
|
3. **every number in the report was produced by a command this run executed** —
|
|
260
300
|
a restated count is an assertion (`evidence-docs`);
|
|
261
301
|
4. at least one figure was **re-derived by a differently-shaped command** and
|
|
262
302
|
both were printed. Re-running the same command is a spell-check of the first
|
|
263
303
|
run;
|
|
264
|
-
5. the proposed rows are printed for the operator, with nothing written
|
|
304
|
+
5. the proposed rows are printed for the operator, with nothing written to the
|
|
305
|
+
target.
|
|
265
306
|
|
|
266
307
|
## Rationalizations
|
|
267
308
|
|
|
@@ -897,12 +897,23 @@ def open_in_browser(path, opener=None):
|
|
|
897
897
|
|
|
898
898
|
def _finding(probe_id, where, title, severity, blast, effort, remedy,
|
|
899
899
|
detail="", evidence=""):
|
|
900
|
+
# The axes stay apart (FIX-PA-02.01): every shipped probe reads the tree,
|
|
901
|
+
# so its MECHANISM is confirmed with evidence — while this collector
|
|
902
|
+
# measures no production, so INCIDENCE is "unknown", and UNKNOWN != 0: it
|
|
903
|
+
# never lowers the mechanism's truth, only what may be claimed about
|
|
904
|
+
# exposure. Scope and time of the observation ride in the sidecar so the
|
|
905
|
+
# next audit knows what was looked at, and when.
|
|
900
906
|
return {
|
|
901
907
|
"id": finding_id(probe_id, where, title), "probe": probe_id,
|
|
902
908
|
"title": title, "severity": severity, "where": where,
|
|
903
909
|
"detail": detail, "evidence": evidence, "remedy": remedy,
|
|
904
910
|
"blast": blast, "effort": effort, "runs_open": 0,
|
|
905
911
|
"first_seen": datetime.date.today().isoformat(),
|
|
912
|
+
"mechanism": "confirmed",
|
|
913
|
+
"incidence": "unknown",
|
|
914
|
+
"observed_scope": "local checkout",
|
|
915
|
+
"observed_at": datetime.datetime.now(datetime.timezone.utc)
|
|
916
|
+
.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
|
906
917
|
}
|
|
907
918
|
|
|
908
919
|
|
|
@@ -12,12 +12,15 @@ own built-in doctrine — no companion plugin required. Keeps the main thread
|
|
|
12
12
|
disciplined: no stage advances until its gate passes; the whole run uses one model,
|
|
13
13
|
confirmed before it starts.
|
|
14
14
|
|
|
15
|
-
**Grill first, then run autonomously.**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
**Grill first, then run autonomously.** Stage 0 is **mandatory**, but it is a
|
|
16
|
+
GAP CHECK before it is an interview: the brief is built from the request, the
|
|
17
|
+
files and the harvest first, and a question is asked only for a **material
|
|
18
|
+
unknown** the sources cannot answer. A complete brief yields ZERO intake
|
|
19
|
+
questions; what the request or the project already decided is recorded, never
|
|
20
|
+
re-negotiated. The interview, where gaps remain, is one-question-at-a-time and
|
|
21
|
+
sweeps stages 1→10 for anything that would stop the run later — then locks the
|
|
22
|
+
answers into a brief. Autonomy is bought there or not at all; every MATERIAL
|
|
23
|
+
question skipped at stage 0 comes back as an interruption at stage 6.
|
|
21
24
|
|
|
22
25
|
**Config contract: [`pipeline.schema.json`](pipeline.schema.json).** A pipeline is
|
|
23
26
|
a machine-readable config — an ordered list of stages, each with `skills[]` (the
|
|
@@ -25,9 +28,21 @@ skills/agents that run it) and a `gate {type, check}`. The schema is the univers
|
|
|
25
28
|
contract; it imposes **no** specific stages, skills, or gate assignments.
|
|
26
29
|
[`pipeline.example.json`](pipeline.example.json) is a **copy-and-rewrite example**
|
|
27
30
|
that encodes this plugin's own default flow (stage 0 intake + the 1→10 stages
|
|
28
|
-
tabled below) and an optional, toggleable `release` block.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
tabled below) and an optional, toggleable `release` block.
|
|
32
|
+
|
|
33
|
+
**Two layers, and only one is replaceable.** The **KERNEL** is what every
|
|
34
|
+
pipeline must carry no matter how few stages it has — for every unit of work:
|
|
35
|
+
its **scope** (what it may change), its **evidence** (a claim carries its
|
|
36
|
+
receipt), its **deps** (what it reads and what must precede it), and a
|
|
37
|
+
**resume** point (it survives context loss). The kernel is invariant. The
|
|
38
|
+
**PROFILE** is the STAGE LIST — how many stages, their names, their skills,
|
|
39
|
+
their gates — and a project **replaces the profile wholesale** (any number of
|
|
40
|
+
stages, its own skills/agents, its own gate types; see *Bring your own
|
|
41
|
+
skills*). **The stage numbers belong to the SELECTED profile, never to the
|
|
42
|
+
kernel:** a minimal three-stage profile has no "stage 7", and a rule keyed on a
|
|
43
|
+
global stage number is a rule about the default profile, not about every
|
|
44
|
+
pipeline. What a custom profile may drop is stages; what it may not drop is a
|
|
45
|
+
kernel field. Each gate has a **type**: `auto` (the
|
|
31
46
|
orchestrator verifies the `check` itself, pass/fail), `judgment` (no complete
|
|
32
47
|
deterministic check exists — a named judge rules, and the ruling is recorded as
|
|
33
48
|
judgement, never as a measurement; `references/gates.md` → *The judgment gate*)
|
|
@@ -48,53 +63,30 @@ wiki and the code graph are recommendations. The **one** exception is deliberate
|
|
|
48
63
|
named: on a user-facing task the stage-3 UX track requires super-ux, and the spec
|
|
49
64
|
gate stops until it is installed.
|
|
50
65
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
| 0, 9 · The documentation system | `references/documentation.md` |
|
|
54
|
-
| any stage · The canons, and where each is enforced | [`evidence-docs`](../evidence-docs/SKILL.md) — the sibling skill in this plugin |
|
|
55
|
-
| 6–10 · Gates | `references/gates.md` |
|
|
56
|
-
| 7–8 · Deploy targets | `references/deploy-targets.md` |
|
|
57
|
-
| any stage · Hooks | `references/hooks.md` |
|
|
58
|
-
| 0 Knowledge harvest (pre-grill) | `references/knowledge-sources.md` |
|
|
59
|
-
| 0, 9 The code graph (graphify — recommended, never required) | `references/knowledge-graph.md` |
|
|
60
|
-
| 0 Intake grill | `references/grill.md` |
|
|
61
|
-
| 2 Brainstorm | `references/brainstorm.md` |
|
|
62
|
-
| 2 Decompose (platforms only) | `references/decomposition.md` |
|
|
63
|
-
| 3 Spec | `references/spec.md` |
|
|
64
|
-
| 4 Plan | `references/planning.md` |
|
|
65
|
-
| the queue the loop walks | `references/work-graph.md` |
|
|
66
|
-
| 5–8 · how a **work-graph node** is CLOSED — three blind readings at three distances, all three required (ceiling 3); a **prose-plan task** closes through `review.md` instead — one reviewer, five-round cap | `references/certification.md` |
|
|
67
|
-
| 5 Build (worktree, subagents, fix loop) | `references/build.md` + `references/review.md` |
|
|
68
|
-
| 5–6 TDD + suite gate | `references/tdd.md` |
|
|
69
|
-
| 5, 6, 8 The browser — the look, the spec suite, and the difference | `references/browser.md` |
|
|
70
|
-
| 10 Acceptance (REQ close-out) | `references/acceptance.md` |
|
|
71
|
-
| 10 Retrospective (the run's last act) | `references/retrospective.md` |
|
|
72
|
-
| 10 + any audit (what's *missing*) | `references/audit.md` |
|
|
73
|
-
| **first run in a project** (new or existing) | `references/adoption.md` |
|
|
74
|
-
| **first run · the entry audit** (offered once) | `references/setup.md` |
|
|
75
|
-
| **what travels with the bundle vs stays in a project** | `references/portability.md` |
|
|
76
|
-
| any repeating loop | `references/loop-guard.md` |
|
|
77
|
-
| run-wide · what the run **leaves running and leaves behind** — every gate, and stage 10 | `references/residue.md` |
|
|
78
|
-
| run-wide · what the run **prints about itself** — the rail, the iteration line | `references/progress.md` |
|
|
79
|
-
| run-wide · how a run keeps going (the loop mode + the context budget) | `references/continuity.md` |
|
|
80
|
-
| run-wide · the work-list **between** runs, and the order it comes off | `references/backlog.md` + `references/prioritisation.md` |
|
|
81
|
-
| run-wide · whether a **human** ever confirmed what shipped, and when | `references/verification.md` |
|
|
82
|
-
| run-wide · how much unconfirmed work has piled up, and what to look at first | `references/exposure.md` |
|
|
83
|
-
| any stage · Where each artifact belongs | `references/artifacts.md` |
|
|
84
|
-
| preflight · Companion skills and their fallbacks | `references/companion-skills.md` |
|
|
85
|
-
| 6–10 · How the host project's CLAUDE.md is read | `references/conventions.md` |
|
|
86
|
-
| preflight · Model map, ids and the override | `references/model-tiering.md` |
|
|
66
|
+
Which reference owns which stage — all forty-odd of them, by stage number:
|
|
67
|
+
[`references/doctrine-map.md`](./references/doctrine-map.md).
|
|
87
68
|
|
|
88
69
|
**Optional bridge.** An equivalent skill set the operator already runs can be mapped
|
|
89
70
|
onto stages 2/4/5/6 in `pipeline.json` → `skills[]`. That is a **substitution, never a
|
|
90
|
-
requirement
|
|
91
|
-
|
|
71
|
+
requirement**. And the precedence is explicit, because two layers could seem to
|
|
72
|
+
disagree: on a CUSTOM profile the **kernel wins** — scope, evidence, deps and
|
|
73
|
+
resume are owed by every unit of work — while `references/stages.md` is the
|
|
74
|
+
**default profile's** normative gate set, governing the stages that profile
|
|
75
|
+
actually selects, not imposing its stage numbers on a profile that dropped
|
|
76
|
+
them. The built-in doctrine is normative for the default profile; the kernel is
|
|
77
|
+
normative for all. Nothing detects, recommends or waits for an external
|
|
78
|
+
provider.
|
|
92
79
|
|
|
93
|
-
**super-ux —
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
80
|
+
**super-ux — the preferred provider for ANY user-facing task.** The moment a task
|
|
81
|
+
implies an interface (web / mobile / CLI / TUI), the WHY→UI→scenario chain runs
|
|
82
|
+
through `/ux` and its linter, which belongs in the host's CI so UX drift cannot
|
|
83
|
+
merge. **But the stage-3 gate checks the ARTIFACT, not the package**: valid
|
|
84
|
+
scenarios covering the change — produced by super-ux, by an alternative provider
|
|
85
|
+
honouring the same contract, or written inline against
|
|
86
|
+
`references/companion-skills.md`'s fallback — pass the gate. What stops the gate
|
|
87
|
+
is the ABSENCE of any scenario artifact: then create one (super-ux is the
|
|
88
|
+
preferred way, the inline fallback is the floor), and a missing tool is reported
|
|
89
|
+
as the NAMED check that was not done, never as a failed task.
|
|
98
90
|
|
|
99
91
|
**The grill is built in and mandatory** (`references/grill.md`). No "clear enough task"
|
|
100
92
|
exemption and no stage 1 without a committed, operator-confirmed brief. It produces the
|
|
@@ -153,7 +145,8 @@ Three things the grill does beyond clarifying the request, each in full in
|
|
|
153
145
|
is built in, so this only checks the *optional* companions (super-ux for UI
|
|
154
146
|
tasks, context7, wiki-update, graphify) and emits ONE block covering them
|
|
155
147
|
**and the model decision** (`references/model-tiering.md`): recommend
|
|
156
|
-
the most capable model available, let the operator confirm or
|
|
148
|
+
the most capable model available (advice), let the operator confirm or
|
|
149
|
+
override (the choice — inherited verbatim by plan, stages and subagents), record
|
|
157
150
|
it. Ask once, here. **The same block carries the run mode**
|
|
158
151
|
(`references/continuity.md`): read `pipeline.json` → `run.loop`; where it is
|
|
159
152
|
recorded, arm it **at the point `run.loop.arm` names** — here at preflight, or
|
|
@@ -180,6 +173,15 @@ Three things the grill does beyond clarifying the request, each in full in
|
|
|
180
173
|
3. Walk stages 1→10 on the model confirmed at preflight. **Don't re-ask about the
|
|
181
174
|
model at every boundary** — only when the operator recorded a per-stage override
|
|
182
175
|
map and the next stage's entry differs (`references/model-tiering.md`).
|
|
176
|
+
**The SELECTED profile is compiled once, at preflight, and only ITS declared
|
|
177
|
+
stages and gates run** (FIX-TP-03.02): the numbers "1→10" name the DEFAULT
|
|
178
|
+
profile, and a custom profile with three stages runs three — no hidden stage
|
|
179
|
+
0, 7 or 10 is injected because the default profile has one. What a custom
|
|
180
|
+
profile does NOT escape is the KERNEL (03.01): scope, evidence, deps and
|
|
181
|
+
resume are owed by every stage of every profile, so dropping stages never
|
|
182
|
+
drops the evidence gate. And an unknown MANDATORY capability blocks the
|
|
183
|
+
compile — a profile whose `must_understand` names a capability this runtime
|
|
184
|
+
does not have is refused, never run with the capability silently absent.
|
|
183
185
|
**Is the brief a platform rather than a change?** Then stage 2 also cuts it into
|
|
184
186
|
modules (`references/decomposition.md`) and stages 3→10 run **per module** in
|
|
185
187
|
build order, one brick at a time — stages 0–2 run once, and the module map's
|
|
@@ -259,4 +261,19 @@ Most references are routed from the **Built-in doctrine** table above, keyed by
|
|
|
259
261
|
the stage that sends you there. The rest are routed by prose: `stages.md` (named
|
|
260
262
|
at every stage of *How to run*), `learned.md` (cited where a rule binds) and
|
|
261
263
|
`probing.md` (from `gates.md`, whose checks it proves). The config contracts sit
|
|
262
|
-
beside this file: `pipeline.schema.json` and `pipeline.example.json`.
|
|
264
|
+
beside this file: `pipeline.schema.json` and `pipeline.example.json`. The
|
|
265
|
+
family's task/context contract sits there too: `execution-packet.schema.json`
|
|
266
|
+
with `execution-packet.example.json` — an immutable, content-addressed packet
|
|
267
|
+
per dispatchable unit of work, validated dependency-free by
|
|
268
|
+
`scripts/packet.py` before anything acts on it (an unknown mandatory version,
|
|
269
|
+
a ref without its digest, or an unbound decision is rejected at the door) —
|
|
270
|
+
and its answer half, `execution-result.schema.json` with
|
|
271
|
+
`execution-result.example.json`: an AttemptGrant that a boolean can never
|
|
272
|
+
substitute for, and a ResultEnvelope whose stale candidate (older revision, or
|
|
273
|
+
a superseded fence) re-plans instead of landing as current
|
|
274
|
+
(`scripts/packet.py validate-result`). The compiler's first stage maps an
|
|
275
|
+
audit report onto parent tasks (`scripts/context_packets.py compile|verify`):
|
|
276
|
+
ids derived from finding ids — never positional, so a shuffled report compiles
|
|
277
|
+
byte-identically — evidence/limits/priority in their own fields separate from
|
|
278
|
+
status, and any row it cannot map blocks the whole compile rather than being
|
|
279
|
+
dropped silently.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/ssheleg/task-pipeline/main/plugins/task-pipeline/skills/task-pipeline/execution-attempt.schema.json",
|
|
4
|
+
"title": "task-pipeline execution attempt (grant)",
|
|
5
|
+
"description": "One attempt at running one node — the identity that a claim on a graph node carries, so `next` can be raced by two processes and only one wins. This is the record `graph.py acquire/start/renew/release/recover` reads and writes (the next implementation leaf); this schema is the contract those verbs must round-trip.\n\nThe defect this exists to close (PF-01): the node's `owner` is a ROLE name, not an identity. Two independent `next` runs both saw N-001 `pending`, both dispatched it, and a `running` node with no fenced grant could be left orphaned forever — `next` then exits 4 until a human edits the file. A grant is owned by a SESSION/ATTEMPT, fenced by a monotonic token and a node revision, and expires, so a lost holder is reclaimable and a stale holder's write is rejected by its own fence.\n\nState is `ready` → `claimed`: `ready` is a grant minted but not yet installed on the node; `claimed` is the live hold. There is no third value here — `done`/`blocked`/`parked` are the NODE's states in graph.schema.json, not the attempt's. The record is ISSUED by `scripts/execution_authority.py` (PF-01.02) — a durable single-writer SQLite coordinator whose `BEGIN IMMEDIATE` makes ready→claimed atomic, so two racing `graph.py claim` runs yield one winner; the `fence` here is that coordinator's monotonic lease generation, and `expiry` bounds the run in place of a held OS lock. Local filesystem only; a Fabric adapter replaces the coordinator for distributed execution.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"schema_version",
|
|
10
|
+
"node",
|
|
11
|
+
"owner",
|
|
12
|
+
"attempt",
|
|
13
|
+
"revision",
|
|
14
|
+
"fence",
|
|
15
|
+
"expiry",
|
|
16
|
+
"state"
|
|
17
|
+
],
|
|
18
|
+
"properties": {
|
|
19
|
+
"schema_version": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"pattern": "^execution-attempt/[0-9]+$",
|
|
22
|
+
"description": "Contract version. A consumer that does not know the major REJECTS the grant."
|
|
23
|
+
},
|
|
24
|
+
"node": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^N-[0-9]{3,}$",
|
|
27
|
+
"description": "The graph node this attempt claims."
|
|
28
|
+
},
|
|
29
|
+
"owner": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"minLength": 1,
|
|
32
|
+
"description": "The SESSION/ATTEMPT identity that holds the claim — never a role name. Two `next` runs of the same role are two owners; that is the whole point. `graph.schema.json`'s node `owner` stays the ROLE; this is who is actually running it right now."
|
|
33
|
+
},
|
|
34
|
+
"attempt": {
|
|
35
|
+
"type": "integer",
|
|
36
|
+
"minimum": 1,
|
|
37
|
+
"description": "Which attempt on this node this is. A recovered node's next claim increments it, so a retry is distinguishable from the run it replaced."
|
|
38
|
+
},
|
|
39
|
+
"revision": {
|
|
40
|
+
"type": "integer",
|
|
41
|
+
"minimum": 0,
|
|
42
|
+
"description": "The node revision this claim was taken against. `start`/`renew`/`release` must present the revision they read; a write against a stale revision is refused — the compare in compare-and-swap."
|
|
43
|
+
},
|
|
44
|
+
"fence": {
|
|
45
|
+
"type": "integer",
|
|
46
|
+
"minimum": 1,
|
|
47
|
+
"description": "A monotonic fence token, strictly increasing across the node's lifetime. A held-then-lost owner that wakes up and writes carries an OLD fence, and the store rejects it — the guarantee that a zombie cannot clobber the run that reclaimed its node."
|
|
48
|
+
},
|
|
49
|
+
"expiry": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?Z$",
|
|
52
|
+
"description": "ISO-8601 UTC. Past it, `recover` may reclaim the node for a new attempt. UNKNOWN is not a value — a grant with no expiry is an orphan waiting to happen, so the field is required."
|
|
53
|
+
},
|
|
54
|
+
"state": {
|
|
55
|
+
"enum": [
|
|
56
|
+
"ready",
|
|
57
|
+
"claimed",
|
|
58
|
+
"completed"
|
|
59
|
+
],
|
|
60
|
+
"description": "`ready` — minted, not yet installed on the node; `claimed` — the live hold. The node's own lifecycle (pending/running/done/blocked/parked) lives in graph.schema.json, not here."
|
|
61
|
+
},
|
|
62
|
+
"installed_at": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?Z$",
|
|
65
|
+
"description": "When the claim went `claimed`. Optional — a `ready` grant has none yet."
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "execution-packet/1",
|
|
3
|
+
"id": "FIX-EX-01.01",
|
|
4
|
+
"parent_id": "FIX-EX-01",
|
|
5
|
+
"module": "example-module",
|
|
6
|
+
"intent": "Split received from completed in the webhook reference so a crash between them stops losing the event.",
|
|
7
|
+
"inputs": [
|
|
8
|
+
{
|
|
9
|
+
"address": "docs/evidence/audits/example/leaves/FIX-EX-01.01.md",
|
|
10
|
+
"sha256": "9b64e93e16025c61cce840b5facbeed619927a20c07f6f919ac92816d6ddc3b6",
|
|
11
|
+
"role": "primary packet brief"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"decision_refs": [
|
|
15
|
+
{
|
|
16
|
+
"id": "DEC-0007",
|
|
17
|
+
"address": "docs/decisions.md#dec-0007",
|
|
18
|
+
"sha256": "276e15892305979ae04a402971c6632a53c249412d99fbea1cf49b4795dbf622"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"source_scope": {
|
|
22
|
+
"edit_targets": [
|
|
23
|
+
{
|
|
24
|
+
"address": "plugins/example/skills/example/SKILL.md",
|
|
25
|
+
"mode": "Edit",
|
|
26
|
+
"baseline_sha256": "a0dcc36937f50a8da38261c1c39afe6caeb0f31674cdf3baaac48c4c81defe32"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"address": "test/audit_regressions/fix-ex-01.01.py",
|
|
30
|
+
"mode": "Create_or_extend"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"claim": "FIX-EX-01.01"
|
|
34
|
+
},
|
|
35
|
+
"budgets": {
|
|
36
|
+
"context_bytes": 24576,
|
|
37
|
+
"token_note": "estimate: utf8 bytes / 3.9 chars-per-token (the family's measured divisor)"
|
|
38
|
+
},
|
|
39
|
+
"acceptance": [
|
|
40
|
+
"A crash after the receipt admits a repeat worker; a duplicate of a completed event never grants again."
|
|
41
|
+
]
|
|
42
|
+
}
|