hermes-taskflow 0.3.0-beta.1.1 → 1.0.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/README.md CHANGED
@@ -11,23 +11,23 @@
11
11
 
12
12
  **English** · [简体中文](https://github.com/heggria/taskflow/blob/main/README.zh-CN.md)
13
13
 
14
- [0.3 overview](#taskflow-03-trusted-effects) · [Quickstart](#quickstart) · [Docs](https://heggria.github.io/taskflow/en/docs) · [Examples](https://github.com/heggria/taskflow/blob/main/examples) · [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md)
14
+ [1.0 overview](#taskflow-10-declarative-coding-agent-workflows) · [Quickstart](#quickstart) · [Docs](https://heggria.github.io/taskflow/en/docs) · [Examples](https://github.com/heggria/taskflow/blob/main/examples) · [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md)
15
15
 
16
16
  </div>
17
17
 
18
18
  ---
19
19
 
20
- # taskflow 0.3: make agent side effects inspectable
20
+ # taskflow 1.0: declarative coding-agent workflows
21
21
 
22
- **taskflow is a declarative runtime for coding-agent workflows.** It turns a graph into a verifiable execution contract, runs phases in isolation, and keeps intermediate work out of the host conversation. In the 0.3 candidate, the contract also describes the effects a phase is allowed to propose.
22
+ **taskflow is a declarative runtime for coding-agent workflows.** It turns a graph into a verifiable execution contract, runs phases in isolation, and keeps intermediate work out of the host conversation. In Taskflow 1.0, the contract also describes the effects a phase is allowed to propose.
23
23
 
24
- > **Status: 0.3.0-beta.1.1 Trusted Effects beta — beta channel, not GA.** This release candidate is prepared for npm's `beta` channel; the beta ships the Trusted Effects MVP described below. The 0.3-C Control Plane remains a follow-on candidate track; it is not a shipped beta surface.
24
+ > **Taskflow 1.0.0** includes the DAG runtime, trusted filesystem effects and complete Control Plane (CLI/MCP/WebUI). [GitHub Releases](https://github.com/heggria/taskflow/releases) and npm establish publication; see the [acceptance scoreboard](https://github.com/heggria/taskflow/blob/main/docs/internal/1.0.0-ga-scoreboard.md) for verified scope and limits.
25
25
 
26
- ## The 0.3 idea
26
+ ## The declared-effect contract
27
27
 
28
28
  An agent can propose content. It should not become the mutation authority merely because it can run a command.
29
29
 
30
- For admitted, declared filesystem-write targets, taskflow 0.3 makes the path explicit and routes the final mutation through the resources transaction:
30
+ For admitted, declared filesystem-write targets, taskflow 1.0 makes the path explicit and routes the final mutation through the resources transaction:
31
31
 
32
32
  ```text
33
33
  flow / .tf.ts
@@ -47,39 +47,40 @@ flow / .tf.ts
47
47
 
48
48
  This is **not** an OS sandbox. Resolve-only hosts cannot prevent every write to an undeclared path. Secret and service references are typed and fail closed in this cut; they do not imply a vault or network backend.
49
49
 
50
- ## What is in the candidate
50
+ ## The 1.0 target and current implementation
51
51
 
52
- | Layer | What it does | Candidate status |
52
+ | Layer | What it does | Support boundary |
53
53
  |---|---|---|
54
- | **Taskflow runtime** | Declarative DAGs, 12 phase types, budgets, retries, approvals, isolation, resume, replay, trace, and recompute | Existing 0.2 foundation |
55
- | **Trusted Effects** | Closed `EffectIR`, `PathRef` / `SecretRef` / `ServiceRef`, confidentiality/integrity labels, effect validation, overlap checks, and ledger-backed `why-*` explainers | 0.3 MVP implementation |
56
- | **Resource transaction** | Snapshot → lease → durable intent/permit → stage → commit, or restore and reject | 0.3 MVP implementation |
54
+ | **Taskflow runtime** | Declarative DAGs, 12 phase types, budgets, retries, approvals, isolation, resume, replay, trace, and recompute | Stable runtime contract |
55
+ | **Trusted Effects** | Closed `EffectIR`, `PathRef` / `SecretRef` / `ServiceRef`, confidentiality/integrity labels, effect validation, overlap checks, and ledger-backed `why-*` explainers | Declared-target contract |
56
+ | **Resource transaction** | Snapshot → lease → durable intent/permit → stage → commit, or restore and reject | Declared-target contract |
57
57
  | **Host adapters** | Pi, Codex, Claude Code, OpenCode, Grok Build, and Hermes Agent use the same flow contract | Existing host surface; support remains host-specific |
58
- | **Control Plane** | ControlHost scaffold, proposed wire contracts, singleton/fencing, and hello negotiation; future stores, approvals, receipts, and coordination | Active 0.3-C track; not shipped and not the 0.3 MVP GA claim |
59
- | **WebUI** | Runs, approvals, receipts, and evidence browsing | Planned in the 0.3-C sequence; not shipped in this candidate |
58
+ | **Control Plane** | Authenticated multi-project admission, global concurrency, durable replay, approvals/CAS, Receipts and operator CLI/MCP | Bundled in public `taskflow-mcp-core`; Unix UDS, Windows pipes non-GA |
59
+ | **WebUI** | Runs, approval edits, Receipts and evidence browsing | Local token login, live authorization and project isolation |
60
60
 
61
- The normative MVP definition is [`docs/internal/0.3.0-trusted-effects-mvp.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3.0-trusted-effects-mvp.md). The 0.3-C Control Plane plan is [`docs/internal/0.3-c-control-plane-plan.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3-c-control-plane-plan.md).
61
+ The [1.0 release plan](https://github.com/heggria/taskflow/blob/main/docs/internal/1.0.0-release-plan.md) defines the stable scope and acceptance gates. The filesystem-transaction details are in [`docs/internal/0.3.0-trusted-effects-mvp.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3.0-trusted-effects-mvp.md). The 0.3-C Control Plane plan is [`docs/internal/0.3-c-control-plane-plan.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3-c-control-plane-plan.md).
62
62
 
63
63
  ## Quickstart
64
64
 
65
- The 0.3 beta can be installed from npm, or exercised from a clean source checkout. Use Node.js **≥ 22.19.0**:
65
+ Use Node.js **≥ 22.19.0**. To run from the 1.0 source checkout:
66
66
 
67
67
  ```bash
68
68
  git clone https://github.com/heggria/taskflow.git
69
69
  cd taskflow
70
- git checkout rc/0.3.0-trusted-effects
70
+ git checkout v1.0.0
71
71
  pnpm install
72
72
  pnpm run typecheck
73
73
  pnpm test
74
74
  ```
75
75
 
76
- The beta commands below become usable after the tag workflow completes; until then they are release-target examples, not proof of registry availability.
76
+ Install the matching 1.0.0 package set after confirming the release is available:
77
+
77
78
  ```bash
78
- npm install --global pi-taskflow@beta
79
- npm install --global codex-taskflow@beta
79
+ npm install --global pi-taskflow@1.0.0
80
+ npm install --global codex-taskflow@1.0.0
80
81
  ```
81
82
 
82
- The host-specific plugin and MCP commands remain in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/). Stable 0.2.x installs remain available through exact stable pins.
83
+ The host-specific plugin and MCP commands remain in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/).
83
84
 
84
85
  Run the no-LLM Trusted Effects vertical-slice fixture:
85
86
 
@@ -88,7 +89,15 @@ pnpm exec node --conditions=development --experimental-strip-types --test \
88
89
  packages/taskflow-core/test/effects-e2e-fixture.test.ts
89
90
  ```
90
91
 
91
- This exercises the checked-in `examples/trusted-effects-write.json` path without a live LLM. For an interactive run, use the host guide for the adapter you already run. The stable 0.2 installation path remains documented separately in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/).
92
+ This exercises the checked-in `examples/trusted-effects-write.json` path without a live LLM. For an interactive run, use the host guide for the adapter you already run. The [release guide](https://github.com/heggria/taskflow/blob/main/RELEASE.md) covers packed-consumer validation and release gates.
93
+
94
+ ### Local Control Console
95
+
96
+ In Pi, run `/tf web` to start the bundled local Control Console and open the default browser. If browser opening fails, the command shows a manual loopback URL. Use the one-use token in the reported private (0600) handoff file to log in; tokens are never included in the URL or command notifications.
97
+
98
+ The console shows Control Plane runs, approvals, Receipts and existing evidence. Legacy Pi run transcripts are outside this view. Repeating the command in the same project reuses its service; changing projects or leaving the Pi session stops only the console process started by that session. Unix local transport is required. If another host already owns the Control home, stop that owner explicitly before launching this console.
99
+
100
+ See [Pi compatibility](https://github.com/heggria/taskflow/blob/main/docs/pi-compatibility.md) for the tested SDK matrix and the distinction between real-process fixtures and live-provider acceptance.
92
101
 
93
102
  ## Declare an effect
94
103
 
@@ -191,7 +200,7 @@ Host support is not a blanket security guarantee. Read the [host support baselin
191
200
  - Writes to undeclared paths remain host-policy dependent under resolve-only execution.
192
201
  - `SecretRef` and `ServiceRef` are typed handles only; no vault or live service adapter ships in this cut.
193
202
  - There is no FileBroker or full OS sandbox claim in 0.3 MVP.
194
- - Control Plane stores, approvals, receipts, and WebUI are future 0.3-C stages, not proof that 0.3 is released or GA.
203
+ - Control Plane admission, authorized replay, durable approvals, Receipts, global coordination and WebUI are implemented. Public `taskflow-mcp-core` provides the control binaries; operator actions require an explicitly provisioned separate credential. Request audit fields never grant authority.
195
204
 
196
205
  ## Development
197
206
 
@@ -210,13 +219,13 @@ The monorepo contains the host-neutral `taskflow-core`, Trusted Effects and reso
210
219
 
211
220
  | Start here | Use it for |
212
221
  |---|---|
213
- | [0.3 overview](https://heggria.github.io/taskflow/en/docs) | Candidate scope, status, and the honest security boundary |
222
+ | [1.0 overview](https://heggria.github.io/taskflow/en/docs) | 1.0 scope, support, and the security boundary |
214
223
  | [Getting Started](https://heggria.github.io/taskflow/en/docs/getting-started) | First flow and host setup |
215
224
  | [Core Concepts](https://heggria.github.io/taskflow/en/docs/concepts/) | DAGs, isolation, verification, resume, and evidence |
216
225
  | [Compiler & Runtime](https://heggria.github.io/taskflow/en/docs/compiler-runtime/) | JSON, TypeScript DSL, FlowIR, replay, and recompute |
217
226
  | [Host Guides](https://heggria.github.io/taskflow/en/docs/guides/) | Pi, Codex, Claude Code, OpenCode, Grok, and Hermes |
218
227
  | [Examples](https://github.com/heggria/taskflow/blob/main/examples) | Runnable flow definitions, including Trusted Effects |
219
- | [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md) | Release history and candidate notes |
228
+ | [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md) | Release history and version notes |
220
229
 
221
230
  ## License
222
231
 
@@ -226,6 +235,6 @@ The monorepo contains the host-neutral `taskflow-core`, Trusted Effects and reso
226
235
 
227
236
  **Declare the effect. Verify the path. Commit through one authority.**
228
237
 
229
- [Read the docs](https://heggria.github.io/taskflow/en/docs) · [Try the candidate](#quickstart) · [View releases](https://github.com/heggria/taskflow/releases)
238
+ [Read the docs](https://heggria.github.io/taskflow/en/docs) · [Install Taskflow 1.0](#quickstart) · [View releases](https://github.com/heggria/taskflow/releases)
230
239
 
231
240
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hermes-taskflow",
3
- "version": "0.3.0-beta.1.1",
3
+ "version": "1.0.0",
4
4
  "description": "Run taskflow on Hermes Agent: a Hermes subagent runner plus an MCP server (and a config scaffold) that exposes the taskflow_* tools to Hermes users.",
5
5
  "keywords": [
6
6
  "hermes",
@@ -50,9 +50,9 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "taskflow-core": "0.3.0-beta.1.1",
54
- "taskflow-hosts": "0.3.0-beta.1.1",
55
- "taskflow-mcp-core": "0.3.0-beta.1.1"
53
+ "taskflow-core": "1.0.0",
54
+ "taskflow-hosts": "1.0.0",
55
+ "taskflow-mcp-core": "1.0.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "rm -rf dist && tsc -p tsconfig.build.json && node ../../scripts/copy-readme.mjs hermes-taskflow"
@@ -14,7 +14,7 @@
14
14
 
15
15
  taskflow:
16
16
  command: "npx"
17
- args: ["-y", "-p", "hermes-taskflow@0.3.0-beta.1.1", "hermes-taskflow-mcp"]
17
+ args: ["-y", "-p", "hermes-taskflow@1.0.0", "hermes-taskflow-mcp"]
18
18
  env:
19
19
  # Uncomment for mutating agent phases (terminal / file write).
20
20
  # Leave unset for verify/plan/script-only flows.
@@ -147,9 +147,9 @@ For a non-trivial flow you'll iterate on, **write the definition to a file**
147
147
  (typically in the OS tmp dir) and point every call at it with `defineFile`:
148
148
 
149
149
  ```jsonc
150
- // 1. write /tmp/audit.json with the `write` tool (a full {name, phases:[…]} object)
150
+ // 1. write /tmp/audit.json with the `write` tool (a full {name, phases:[...]} object)
151
151
  // 2. verify, iterate, run — all reference the SAME file by path:
152
- { "name": "taskflow_plan", "arguments": { "defineFile": "/tmp/audit.json", "args": { … } } } // zero tokens: bind + plan + budget bound
152
+ { "name": "taskflow_plan", "arguments": { "defineFile": "/tmp/audit.json", "args": { ... } } } // zero tokens: bind + plan + budget bound
153
153
  { "name": "taskflow_verify", "arguments": { "defineFile": "/tmp/audit.json" } } // zero tokens
154
154
  { "name": "taskflow_compile", "arguments": { "defineFile": "/tmp/audit.json" } } // diagram
155
155
  { "name": "taskflow_lint", "arguments": { "defineFile": "/tmp/audit.json" } } // script-lint + custom verifiers
@@ -163,6 +163,24 @@ large definition on every call and keeps a durable draft you can diff. Falls
163
163
  back cleanly: precedence is `define` (inline) > `defineFile` (disk) > `name`
164
164
  (saved flow).
165
165
 
166
+ ### Long instructions: `taskFile` (load-time include, not `context`)
167
+
168
+ A phase or parallel branch may set `taskFile` **instead of** `task`. Trusted
169
+ loaders (`defineFile` / saved flow) resolve the **literal** path against the
170
+ definition directory — same class of source as `scriptCwd: "flow"` — inline the
171
+ UTF-8 body into `task`, and **delete** `taskFile` before validate / interpolate
172
+ / cache / FlowIR. Runtime never sees `taskFile`.
173
+
174
+ - XOR with `task`. Path is a static import: **not interpolated**, no `..`, no
175
+ symlink leaf, must stay physically inside the flow directory. Cap 256 KiB.
176
+ - Inline leftover → `TF_TASKFILE_NO_PROVENANCE`. Generated sub-flows →
177
+ `TF_DYNAMIC_RESOURCE_FORBIDDEN`.
178
+ - Do **not** put durable instructions in `context`. `context` is cwd-relative,
179
+ default-truncated at 8k, wrapped as `## File:`, marked unreplayable, and
180
+ forbidden in dynamic sub-flows.
181
+ - TS DSL: `agent({ taskFile: "prompts/x.md" })`. `taskflow-dsl check` / erase
182
+ emit the field and do **not** read the file.
183
+
166
184
  ### DSL shape
167
185
 
168
186
  ```jsonc
@@ -554,7 +572,7 @@ Each effect:
554
572
  **Phase output is the payload.** With one declared `fs.write`, the phase's
555
573
  output becomes the staged file content (see the example: `process.stdout.write`
556
574
  = the report). With several `fs.write` effects, the phase must emit JSON
557
- mapping each effect id to its content (`{ "report": "…", "backup": "…" }`).
575
+ mapping each effect id to its content (`{ "report": "...", "backup": "..." }`).
558
576
  Commit promotes each file atomically; a later failure restores every admitted
559
577
  file to its durable pre-state, and a direct write by the agent/script to a
560
578
  **declared final path** is detected and restored — only the resource
@@ -606,8 +624,8 @@ more than comparing every approach.
606
624
  {
607
625
  "id": "quick", "type": "race",
608
626
  "branches": [
609
- { "task": "Answer with a short heuristic…", "agent": "executor" },
610
- { "task": "Answer with a thorough search…", "agent": "researcher" }
627
+ { "task": "Answer with a short heuristic...", "agent": "executor" },
628
+ { "task": "Answer with a thorough search...", "agent": "researcher" }
611
629
  ],
612
630
  "final": true
613
631
  }
@@ -47,9 +47,9 @@ Top-level keys of the taskflow definition object.
47
47
  | `concurrency` | number | `8` | Default fan-out / same-layer parallelism cap. See §4. |
48
48
  | `idleTimeout` | number | host default (`300000`) | Flow-level idle watchdog in ms (≥ 1000, or `0` to disable) for all agent-running phases that don't set their own. `0` disables the watchdog but then **every** agent-running phase MUST declare a finite wall `timeout` (≥ 1000) so the flow can never hang. A per-phase `idleTimeout` overrides this. |
49
49
  | `agentScope` | `user`\|`project`\|`both` | `user` | Which agent dirs to load. See §6. |
50
- | `scriptCwd` | `invocation`\|`flow` | `invocation` | Default cwd policy for `script` phases. `flow` requires trusted saved-flow/`defineFile` provenance; explicit phase `cwd` wins, and inherited cwd-bridge boundaries still constrain the resolved source directory. |
50
+ | `scriptCwd` | `invocation`\|`flow` | `invocation` | Default cwd policy for `script` phases. `flow` requires trusted saved-flow/`defineFile` provenance; explicit phase `cwd` wins, and inherited cwd-bridge boundaries still constrain the resolved source directory. `taskFile` is the same class of load-time trusted source (see §2). |
51
51
  | `args` | record | `{}` | Declared invocation arguments. See §3. |
52
- | `hooks` | object | — | **0.2.7.** Terminal fire-and-forget notifications: `onComplete` / `onFail` / `onBlocked` arrays of `{type:"webhook"\|"file"\|"command", …}`. Payload is summary-only (`taskflow.hook.v1`) — never transcripts. Hook failure never changes run status. `https` or `http://127.0.0.1\|localhost` for webhooks; `command.run` is argv-only (no shell string). |
52
+ | `hooks` | object | — | **0.2.7.** Terminal fire-and-forget notifications: `onComplete` / `onFail` / `onBlocked` arrays of `{type:"webhook"\|"file"\|"command", ...}`. Payload is summary-only (`taskflow.hook.v1`) — never transcripts. Hook failure never changes run status. `https` or `http://127.0.0.1\|localhost` for webhooks; `command.run` is argv-only (no shell string). |
53
53
  | `phases` | array | — | **Required.** The phase DAG. See §2. |
54
54
  | `version` | number | `1` | Informational metadata in 0.2.x; it does not select runtime semantics or migrate a flow. |
55
55
 
@@ -66,11 +66,11 @@ Keys of each object in `phases[]`. Some only apply to specific `type`s.
66
66
  "id": "audit", // required, unique — referenced via {steps.audit.output}
67
67
  "type": "map", // agent | parallel | map | gate | reduce | approval | flow | loop | tournament | script | race | expand (default: agent)
68
68
  "agent": "analyst", // agent name to run this phase
69
- "task": "Audit {item.route}…",
69
+ "task": "Audit {item.route}...",
70
70
  "dependsOn": ["discover"],// DAG edges
71
71
  "over": "{steps.discover.json}", // [map] array to fan out over
72
72
  "as": "item", // [map] loop var name (default: item)
73
- "branches": [ /* … */ ], // [parallel|race] static task list
73
+ "branches": [ /* ... */ ], // [parallel|race] static task list
74
74
  "from": ["audit"], // [reduce] phase ids to aggregate
75
75
  "def": "{steps.plan.json}", // [expand|flow] inline fragment / dynamic sub-flow
76
76
  "expandMode": "nested", // [expand] nested | graft
@@ -86,13 +86,14 @@ Keys of each object in `phases[]`. Some only apply to specific `type`s.
86
86
 
87
87
  | Key | Applies to | Default | Notes |
88
88
  |-----|-----------|---------|-------|
89
- | `id` | all | — | **Required, unique.** Used in `{steps.<id>…}`. |
89
+ | `id` | all | — | **Required, unique.** Used in `{steps.<id>...}`. |
90
90
  | `type` | all | `agent` | One of the **12** phase types (agent, parallel, map, gate, reduce, approval, flow, loop, tournament, script, **race**, **expand**). |
91
91
  | `agent` | all | first available | Agent name; resolved from the scoped pool. |
92
- | `task` | agent, gate, map, reduce | — | Prompt; supports interpolation. Required for these types. |
92
+ | `task` | agent, gate, map, reduce | — | Prompt; supports interpolation. Required for these types unless `taskFile` is set. |
93
+ | `taskFile` | agent, gate, map, reduce, parallel/race branch | — | Load-time include. Literal path relative to the flow definition directory. Trusted loaders inline UTF-8 into `task` and delete the field. XOR with `task`. Path is **not** interpolated. Cap 256 KiB. Not `context`. |
93
94
  | `over` | map | — | **Required for map.** Must resolve to an array. |
94
95
  | `as` | map | `item` | Loop variable bound per item. |
95
- | `branches` | parallel, race | — | **Required** (≥1 for parallel; ≥2 for race). `[{task, agent?}]`. |
96
+ | `branches` | parallel, race | — | **Required** (≥1 for parallel; ≥2 for race). `[{task, agent?}]` or `{taskFile, agent?}`. |
96
97
  | `cancelLosers` | race | `true` | Abort in-flight losers after first **success** (best-effort AbortSignal). |
97
98
  | `from` | reduce | — | **Required for reduce.** Phase ids whose outputs are aggregated. `{previous.output}` resolves to **all completed `from[]` outputs** in from-array order (one → raw; many → `### <id>\n\n<output>` sections joined by `\n\n---\n\n`). |
98
99
  | `reduceStrategy` | reduce | `one-shot` | `one-shot` = a single reducer call over all aggregated inputs. `tree` = batched intermediate reducer rounds (see `batchSize`); useful when aggregated input would exceed one prompt. `tree` forces the imperative runtime (event kernel falls back). |
@@ -267,8 +268,8 @@ There are **two independent concurrency limits**:
267
268
  "concurrency": 6, // ≤6 sibling phases run at once
268
269
  "phases": [
269
270
  { "id": "scan", "type": "map", "over": "{steps.list.json}",
270
- "concurrency": 3, // …but this map only fans out 3 at a time
271
- "task": "…", "dependsOn": ["list"] }
271
+ "concurrency": 3, // ...but this map only fans out 3 at a time
272
+ "task": "...", "dependsOn": ["list"] }
272
273
  ]
273
274
  }
274
275
  ```
@@ -434,7 +435,7 @@ fingerprint folds **“did the world change?”** signals into that key, so an
434
435
  external change becomes a cache **miss** even when the task text is identical.
435
436
  Each entry is one of:
436
437
 
437
- | Entry | Becomes a miss when… | Resolves to |
438
+ | Entry | Becomes a miss when... | Resolves to |
438
439
  |-------|----------------------|-------------|
439
440
  | `git:HEAD` / `git:<ref>` | the commit moves | the resolved SHA (30s timeout → `<timeout>`; no git → `<no-git>`) |
440
441
  | `glob:<pattern>` | the **set of matching paths** or their metadata changes | sorted path list with size + mtime (content-hashed globs use `glob!:` instead, which is mtime-independent) |
@@ -496,7 +497,7 @@ Each entry is one of:
496
497
  ```jsonc
497
498
  { "id": "review", "type": "gate", "agent": "reviewer",
498
499
  "model": "claude-opus-4", "thinking": "high",
499
- "task": "…\nVERDICT:", "dependsOn": ["audit"] }
500
+ "task": "...\nVERDICT:", "dependsOn": ["audit"] }
500
501
  ```
501
502
 
502
503
  **Sandbox a phase to read-only in a subdirectory:**
@@ -515,7 +516,7 @@ Each entry is one of:
515
516
 
516
517
  **Project-only agents:**
517
518
  ```jsonc
518
- { "name": "ci-audit", "agentScope": "project", "phases": [ /* … */ ] }
519
+ { "name": "ci-audit", "agentScope": "project", "phases": [ /* ... */ ] }
519
520
  ```
520
521
 
521
522
  ---
@@ -554,22 +555,22 @@ symlinks, and commit atomically; `--emit both` preflights both destinations.
554
555
 
555
556
  **Authoring notes (kinds ↔ runes)**
556
557
 
557
- Import: `import { flow, agent, map, … } from "taskflow-dsl"`. Runes erase to Taskflow
558
+ Import: `import { flow, agent, map, ... } from "taskflow-dsl"`. Runes erase to Taskflow
558
559
  JSON kinds (single source: `PHASE_TYPES` in core + `erase/kinds/*` registry).
559
560
 
560
561
  | JSON `type` | DSL rune(s) | Notes |
561
562
  |-------------|-------------|--------|
562
563
  | `agent` | `agent(task, opts?)` | templates → `{steps.*}` / `{item.*}` |
563
- | `parallel` | `parallel([agent…])` | waits for all branches |
564
- | `map` | `map(source, item => agent…)` | `over` + `as` |
564
+ | `parallel` | `parallel([agent...])` | waits for all branches |
565
+ | `map` | `map(source, item => agent...)` | `over` + `as` |
565
566
  | `gate` | `gate(up, opts?, task?)` · `gate.automated` · `gate.scored` | sugar → `eval` / `score` |
566
- | `reduce` | `reduce([…], () => agent…)` | `from` |
567
+ | `reduce` | `reduce([...], () => agent...)` | `from` |
567
568
  | `approval` | `approval({ request })` | |
568
569
  | `flow` | `subflow("name")` · `subflow.def(plan)` | use vs def |
569
- | `loop` | `loop({ task, until?, … })` | |
570
- | `tournament` | `tournament({ branches/variants, judge, … })` | |
570
+ | `loop` | `loop({ task, until?, ... })` | |
571
+ | `tournament` | `tournament({ branches/variants, judge, ... })` | |
571
572
  | `script` | `script(run, opts?)` | string or argv array |
572
- | `race` | `race([agent…], { cancelLosers? })` | first **success** wins; cooperative loser usage is counted |
573
+ | `race` | `race([agent...], { cancelLosers? })` | first **success** wins; cooperative loser usage is counted |
573
574
  | `expand` | `expand` / `expand.nested` / `expand.graft` | `def` + `expandMode` |
574
575
 
575
576
  - `const [a,b] = parallel([agent(...), agent(...)])` desugars to **two real agent phases** (`a`, `b`) that run concurrently (no `dependsOn` between them). Prefer this when you need `{steps.a.output}`.