cool-workflow 0.1.87 → 0.1.89

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.
Files changed (75) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +111 -71
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +1 -1
  6. package/apps/end-to-end-golden-path/app.json +1 -1
  7. package/apps/pr-review-fix-ci/app.json +1 -1
  8. package/apps/release-cut/app.json +1 -1
  9. package/apps/research-synthesis/app.json +1 -1
  10. package/dist/agent-config.js +42 -1
  11. package/dist/capability-core.js +16 -4
  12. package/dist/capability-registry.js +24 -0
  13. package/dist/cli/command-surface.js +105 -2
  14. package/dist/cli.js +2 -1
  15. package/dist/doctor.js +14 -1
  16. package/dist/drive.js +222 -16
  17. package/dist/execution-backend.js +4 -4
  18. package/dist/loop-expansion.js +60 -0
  19. package/dist/onramp.js +25 -0
  20. package/dist/orchestrator/lifecycle-operations.js +134 -3
  21. package/dist/orchestrator.js +48 -77
  22. package/dist/run-export.js +106 -2
  23. package/dist/state-node.js +13 -3
  24. package/dist/state.js +21 -0
  25. package/dist/telemetry-attestation.js +30 -6
  26. package/dist/telemetry-demo.js +29 -1
  27. package/dist/telemetry-ledger.js +6 -0
  28. package/dist/version.js +1 -1
  29. package/dist/worker-accept/telemetry-ledger.js +12 -2
  30. package/dist/workflow-api.js +33 -0
  31. package/dist/workflow-app-framework.js +20 -0
  32. package/docs/agent-delegation-drive.7.md +8 -0
  33. package/docs/capability-topology-registry.7.md +69 -46
  34. package/docs/cli-mcp-parity.7.md +16 -2
  35. package/docs/contract-migration-tooling.7.md +8 -0
  36. package/docs/control-plane-scheduling.7.md +8 -0
  37. package/docs/durable-state-and-locking.7.md +8 -0
  38. package/docs/evidence-adoption-reasoning-chain.7.md +8 -0
  39. package/docs/execution-backends.7.md +8 -0
  40. package/docs/launch/launch-kit.md +9 -9
  41. package/docs/multi-agent-cli-mcp-surface.7.md +8 -0
  42. package/docs/multi-agent-eval-replay-harness.7.md +8 -0
  43. package/docs/multi-agent-operator-ux.7.md +8 -0
  44. package/docs/node-snapshot-diff-replay.7.md +8 -0
  45. package/docs/observability-cost-accounting.7.md +8 -0
  46. package/docs/project-index.md +22 -5
  47. package/docs/readme-v0.1.87-full.md +301 -0
  48. package/docs/real-execution-backends.7.md +8 -0
  49. package/docs/release-and-migration.7.md +8 -0
  50. package/docs/release-tooling.7.md +8 -0
  51. package/docs/report-verifiable-bundle.7.md +34 -2
  52. package/docs/run-registry-control-plane.7.md +18 -0
  53. package/docs/run-retention-reclamation.7.md +8 -0
  54. package/docs/state-explosion-management.7.md +8 -0
  55. package/docs/team-collaboration.7.md +8 -0
  56. package/docs/trust-model.md +6 -4
  57. package/docs/web-desktop-workbench.7.md +8 -0
  58. package/manifest/plugin.manifest.json +1 -1
  59. package/manifest/source-context-profiles.json +1 -1
  60. package/package.json +8 -5
  61. package/scripts/agents/agent-adapter-core.js +1 -1
  62. package/scripts/agents/builtin-templates.json +2 -1
  63. package/scripts/agents/claude-p-agent.js +7 -33
  64. package/scripts/agents/codex-agent.js +1 -1
  65. package/scripts/agents/cw-attest-wrap.js +9 -1
  66. package/scripts/agents/gemini-agent.js +1 -1
  67. package/scripts/agents/opencode-agent.js +1 -1
  68. package/scripts/canonical-apps.js +4 -4
  69. package/scripts/coverage-gate.js +15 -1
  70. package/scripts/cw.js +0 -0
  71. package/scripts/dogfood-release.js +1 -1
  72. package/scripts/golden-path.js +4 -4
  73. package/scripts/release-flow.js +49 -2
  74. package/scripts/release-gate.sh +11 -2
  75. package/tsconfig.json +3 -1
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.workflow = workflow;
4
4
  exports.phase = phase;
5
5
  exports.parallel = parallel;
6
+ exports.loop = loop;
6
7
  exports.createWorkflowApi = createWorkflowApi;
7
8
  exports.agent = agent;
9
+ exports.subWorkflow = subWorkflow;
8
10
  exports.artifact = artifact;
9
11
  exports.input = input;
10
12
  exports.slugify = slugify;
@@ -46,19 +48,50 @@ function phase(name, tasks, options = {}) {
46
48
  function parallel(name, tasks, options = {}) {
47
49
  return phase(name, tasks, { mode: "parallel", ...options });
48
50
  }
51
+ /** A BOUNDED DYNAMIC LOOP phase: `tasks` are a per-round template. After each round
52
+ * completes, the registered `until` predicate decides whether to run another round
53
+ * (a fresh appended phase with the same tasks, round-suffixed ids) or stop; capped
54
+ * at `maxRounds`. Sugar over phase() that sets `loop`; plain phases are unaffected. */
55
+ function loop(name, tasks, spec, options = {}) {
56
+ if (!spec || typeof spec.maxRounds !== "number" || spec.maxRounds < 1) {
57
+ throw new Error(`loop ${name} requires a positive integer maxRounds`);
58
+ }
59
+ const until = spec.until;
60
+ const valid = until
61
+ && ((until.kind === "predicate" && Boolean(until.ref))
62
+ || (until.kind === "budget-target" && typeof until.target === "number" && until.target > 0));
63
+ if (!valid) {
64
+ throw new Error(`loop ${name} requires until: { kind: "predicate", ref } or { kind: "budget-target", target }`);
65
+ }
66
+ return phase(name, tasks, { loop: { maxRounds: Math.floor(spec.maxRounds), until }, ...options });
67
+ }
49
68
  function createWorkflowApi() {
50
69
  return {
51
70
  workflow,
52
71
  phase,
53
72
  parallel,
73
+ loop,
54
74
  agent,
55
75
  artifact,
76
+ subWorkflow,
56
77
  input
57
78
  };
58
79
  }
59
80
  function agent(id, prompt, options = {}) {
60
81
  return task("agent", id, prompt, options);
61
82
  }
83
+ /** A task fulfilled by an inline SUB-WORKFLOW: instead of spawning an agent, the
84
+ * drive plans + drives the child `appId` and binds its report back as this task's
85
+ * result. The prompt is recorded for provenance but is not sent to an agent. */
86
+ function subWorkflow(id, appId, options = {}) {
87
+ if (!appId)
88
+ throw new Error(`subWorkflow task ${id} requires an appId`);
89
+ const { inputs, bindResult, prompt, ...rest } = options;
90
+ return task("agent", id, prompt || `Delegate to sub-workflow app: ${appId}`, {
91
+ ...rest,
92
+ subWorkflow: { appId, ...(inputs ? { inputs } : {}), ...(bindResult ? { bindResult } : {}) }
93
+ });
94
+ }
62
95
  function artifact(id, prompt, options = {}) {
63
96
  return task("artifact", id, prompt, options);
64
97
  }
@@ -522,6 +522,26 @@ function validatePhase(phaseDefinition, issues, pathName, seenPhaseIds) {
522
522
  if (!Array.isArray(phaseValue.tasks) || !phaseValue.tasks.length) {
523
523
  issues.push(issue("workflow-phase-tasks", `Workflow phase ${String(phaseValue.id || phaseValue.name || "")} must have tasks`, joinPath(pathName, "tasks")));
524
524
  }
525
+ // Bounded dynamic loop spec (fail-closed shape check; the predicate ref need not be
526
+ // registered at validation time — the expander stops fail-closed if it is missing).
527
+ if (phaseValue.loop !== undefined) {
528
+ const loop = phaseValue.loop;
529
+ if (!isRecord(loop)) {
530
+ issues.push(issue("workflow-phase-loop", "Workflow phase loop must be an object", joinPath(pathName, "loop")));
531
+ }
532
+ else {
533
+ if (typeof loop.maxRounds !== "number" || !Number.isInteger(loop.maxRounds) || loop.maxRounds < 1) {
534
+ issues.push(issue("workflow-phase-loop-maxrounds", "loop.maxRounds must be a positive integer", joinPath(pathName, "loop.maxRounds")));
535
+ }
536
+ const until = loop.until;
537
+ const validUntil = isRecord(until)
538
+ && ((until.kind === "predicate" && isNonEmptyString(until.ref))
539
+ || (until.kind === "budget-target" && typeof until.target === "number" && until.target > 0));
540
+ if (!validUntil) {
541
+ issues.push(issue("workflow-phase-loop-until", 'loop.until must be { kind: "predicate", ref } or { kind: "budget-target", target }', joinPath(pathName, "loop.until")));
542
+ }
543
+ }
544
+ }
525
545
  }
526
546
  function validateTask(taskDefinition, issues, pathName, seenTaskIds, options) {
527
547
  if (!isRecord(taskDefinition)) {
@@ -309,3 +309,11 @@ No other change to this page in v0.1.84.
309
309
  ## 0.1.87 (v0.1.87)
310
310
 
311
311
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
312
+
313
+ ## 0.1.88 (v0.1.88)
314
+
315
+ Orchestration-parity for the agent drive: `run --drive --incremental` step-level resume (unchanged-input tasks replay from a content-addressed cache, zero re-spawns), inline `subWorkflow()` nesting (a task runs a child app and binds its verified report back, bounded depth + cycle guard, no telemetry fabricated), bounded dynamic `loop()` phases that expand at runtime under a static replay-stable cap, and a `claude -p` wrapper now on the canonical result contract.
316
+
317
+ ## 0.1.89 (v0.1.89)
318
+
319
+ The one-command `cw -q` headline now routes the question and defaults the repo to the caller cwd before driving the agent; the delegation contract, drive, and accept path are unchanged.
@@ -2,69 +2,92 @@
2
2
 
3
3
  ## Name
4
4
 
5
- `capability-dispatcher`, `registerCapabilityHandler`, `registerTopology` — open registries for agent-driven CW extension
5
+ `capability-registry`, `registerTopology` — the declared capability contract and the open topology registry for agent-driven CW extension
6
6
 
7
7
  ## Description
8
8
 
9
- v0.1.53 adds two open registries. They let agents grow CW at runtime
10
- with no need to wire things by hand in many files. New capabilities put
11
- themselves in the registry and then work by themselves across CLI, MCP, and Workbench. New topologies put
12
- themselves in the registry too and then come up by themselves in `topology list`, `topology validate`, and `topology apply`.
13
-
14
- BSD way: keep **mechanism** (Map / pipe) apart from **policy** (entries).
15
- Fail-closed on unknown ids.
9
+ CW keeps two layers here. The **capability registry**
10
+ (`src/capability-registry.ts`) is the one declared source of truth for every
11
+ capability CW exposes; it is read at build/check time, not written to at
12
+ runtime. The **topology registry** (`src/topology.ts`) is an open runtime
13
+ registry: new topologies put themselves in it with `registerTopology()` and
14
+ then come up by themselves in `topology list`, `topology validate`, and
15
+ `topology apply`.
16
+
17
+ > History: v0.1.53 also shipped a dynamic *capability* dispatcher
18
+ > (`capability-dispatcher.ts`, `registerCapabilityHandler`,
19
+ > `dispatchCapability`, `resolveCliPath`, `resolveMcpTool`) meant to let
20
+ > capabilities register handlers and be routed at runtime. It had zero call
21
+ > sites — the handler map was always empty and every dispatch path was
22
+ > unreachable — so it was removed as dead code in v0.1.81 (#131). Capabilities
23
+ > are **declared**, not runtime-registered; see below. (The unrelated
24
+ > `cw dispatch` command, which writes a subagent dispatch manifest, is a normal
25
+ > declared capability, not that dispatcher.)
26
+
27
+ BSD way: keep **mechanism** (the registry / the open Map) apart from **policy**
28
+ (the entries). Fail-closed on unknown ids.
16
29
 
17
30
  ## Capability Registry
18
31
 
19
- ### Interface
32
+ The capability registry, `src/capability-registry.ts`, is the SINGLE declared
33
+ source of truth for every capability CW exposes — and the contract both front
34
+ doors (CLI and MCP) are checked against. It is a static, read-only array of
35
+ descriptors, `CAPABILITY_REGISTRY`. There is no runtime "register a handler"
36
+ seam and no dynamic dispatcher: capabilities are data here, not code that wires
37
+ itself in.
20
38
 
21
- ```typescript
22
- interface CapabilityHandler {
23
- descriptor: CapabilityDescriptor;
24
- run(args: Record<string, unknown>, ctx: CapabilityContext): unknown | Promise<unknown>;
25
- }
39
+ ### Descriptor
26
40
 
27
- interface CapabilityContext {
28
- runner: CoolWorkflowRunner;
29
- cwd: string;
41
+ ```typescript
42
+ interface CapabilityDescriptor {
43
+ capability: string; // canonical dot-namespaced id, e.g. "worker.list"
44
+ summary: string; // one-line description
45
+ entry: string; // the ONE shared core entry both surfaces route through
46
+ surface: "both" | "cli-only" | "mcp-only";
47
+ cli?: { path: string[]; jsonMode: "default" | "flag" | "human" };
48
+ mcp?: { tool: string; requiredArgs?: string[] };
49
+ payloadIdentical?: boolean; // CLI --json === MCP result (default true for "both")
50
+ reason?: string; // required when surface !== "both" or payloadIdentical === false
30
51
  }
31
52
  ```
32
53
 
33
- ### Registering a new capability
54
+ ### Adding a capability
55
+
56
+ A capability is declared once, as data, in `CAPABILITY_REGISTRY`, against one
57
+ shared core `entry`:
34
58
 
35
59
  ```typescript
36
- import { registerCapabilityHandler } from "./capability-registry";
37
-
38
- registerCapabilityHandler({
39
- descriptor: {
40
- capability: "my.new.tool", // canonical dot-namespaced id
41
- summary: "Does something useful.", // one-line description
42
- entry: "myNewTool", // core entry name
43
- surface: "both", // "both" | "cli-only" | "mcp-only"
44
- cli: { path: ["my", "new-tool"], jsonMode: "default" },
45
- mcp: { tool: "cw_my_new_tool" }
46
- },
47
- run: async (args, ctx) => {
48
- // ctx.runner exposes all orchestrator methods
49
- return ctx.runner.listWorkflows();
50
- }
51
- });
60
+ {
61
+ capability: "my.new.tool",
62
+ summary: "Does something useful.",
63
+ entry: "myNewTool",
64
+ surface: "both",
65
+ cli: { path: ["my", "new-tool"], jsonMode: "default" },
66
+ mcp: { tool: "cw_my_new_tool" }
67
+ }
52
68
  ```
53
69
 
70
+ `cli.ts` and `mcp-server.ts` each route their surface to the shared `entry` with
71
+ their own explicit `switch` routing (plus a few `if (action === …)` branches).
72
+ The registry is what those switches are validated against, not something they
73
+ call into — there is no fallback dynamic dispatch.
74
+
54
75
  ### How it works
55
76
 
56
- 1. `registerCapabilityHandler()` keeps the handler in a `Map<string, CapabilityHandler>`
57
- 2. CLI: `resolveCliPath(["my", "new-tool"])` turns the CLI path into the capability id
58
- 3. MCP: `resolveMcpTool("cw_my_new_tool")` turns the tool name into the capability id
59
- 4. `dispatchCapability(id, args, ctx)` calls `handler.run(args, ctx)`
60
- 5. Both the CLI and MCP surfaces drop through to the dynamic dispatcher when
61
- their hardcoded switch statements do not match an unknown command/tool
77
+ 1. `CAPABILITY_REGISTRY` declares every capability once one row per capability.
78
+ 2. CLI: `cli.ts` matches the command in its explicit `switch` and calls the core `entry`.
79
+ 3. MCP: `mcp-server.ts` matches the tool name in its explicit `switch` and calls the same `entry`.
80
+ 4. The parity gate (`scripts/parity-check.js --check`) fails closed on any drift:
81
+ a CLI command or MCP tool live on one surface but absent on the other or
82
+ undeclared, an undeclared payload divergence, or a surface-specific capability
83
+ with no recorded `reason`.
62
84
 
63
- ### Existing capabilities
85
+ ### How many capabilities
64
86
 
65
- All 182 capabilities that are there now keep working through their hardcoded switch
66
- cases in `cli.ts` and `mcp-server.ts`. The dynamic dispatch is a **fallback**
67
- it turns on only for commands/tools not found in the old switches.
87
+ Run `node plugins/cool-workflow/scripts/parity-check.js --check` and read
88
+ `registrySize` for the live count (199 at the time of writing). The full
89
+ CLI <-> MCP matrix lives in `docs/cli-mcp-parity.7.md`, which is generated from
90
+ the same registry.
68
91
 
69
92
  ## Topology Registry
70
93
 
@@ -160,8 +183,8 @@ expansion. Now it reads `role.count` on each role spec:
160
183
 
161
184
  ## See Also
162
185
 
163
- - `capability-registry.ts` — the one true source for all capabilities
164
- - `capability-dispatcher.ts` — the thin Map-based dispatch pipe
186
+ - `capability-registry.ts` — the one declared source for all capabilities
187
+ - `capability-core.ts` — the shared core entries both surfaces route through
165
188
  - `topology.ts` — topology definitions and the registry
166
189
  - `types/topology.ts` — topology type definitions
167
190
  - `docs/cli-mcp-parity.7.md` — CLI <-> MCP parity gate
@@ -82,13 +82,16 @@ relationship. `identical` means `cw <cmd> --json` is equal to the `cw_<tool>`
82
82
  payload; `projected` means a declared divergence with a reason; `cli-only` marks
83
83
  a surface-specific capability with a recorded reason. The matrix is
84
84
  <!-- gen:parity:count -->
85
- machine-complete by design: 196 capabilities, 186 MCP tools.
85
+ machine-complete by design: 199 capabilities, 186 MCP tools.
86
86
  <!-- /gen:parity:count -->
87
87
 
88
88
  <!-- gen:parity:table -->
89
89
  | Capability | CLI command | MCP tool | Core entry | Surface | Payload |
90
90
  | --- | --- | --- | --- | --- | --- |
91
91
  | `help` | `cw help` | `—` | `formatHelp` | cli-only | cli-only |
92
+ | `version` | `cw version` | `—` | `CURRENT_COOL_WORKFLOW_VERSION` | cli-only | cli-only |
93
+ | `update` | `cw update` | `—` | `npmUpdate` | cli-only | cli-only |
94
+ | `fix` | `cw fix` | `—` | `runDoctor` | cli-only | cli-only |
92
95
  | `list` | `cw list` | `cw_list` | `listWorkflows` | both | identical |
93
96
  | `info` | `cw info` | `—` | `showApp` | cli-only | cli-only |
94
97
  | `search` | `cw search` | `—` | `listApps` | cli-only | cli-only |
@@ -298,9 +301,12 @@ A capability may be on one surface only, but never without word of it — it mus
298
301
  carry a recorded reason in the registry.
299
302
 
300
303
  <!-- gen:parity:cliOnly -->
301
- Ten capabilities are CLI-only:
304
+ 13 capabilities are CLI-only:
302
305
 
303
306
  - `help` — Human help text. MCP hosts enumerate capabilities via tools/list, not a help command.
307
+ - `version` — Version string — no structured data contract.
308
+ - `update` — Self-update via npm — inherently local shell operation, no MCP surface.
309
+ - `fix` — Environment fix commands are local diagnostics, same reasoning as doctor.
304
310
  - `info` — Human-focused workflow discovery tool (like Homebrew's `brew info`). MCP agents discover workflows via cw_list and cw_app_show tools.
305
311
  - `search` — Human-focused workflow discovery (like Homebrew's `brew search`). MCP agents discover workflows via cw_list tool.
306
312
  - `man` — Human documentation viewer. MCP agents read docs/ directly via file tools.
@@ -507,3 +513,11 @@ No other change to this page in v0.1.84.
507
513
  ## 0.1.87 (v0.1.87)
508
514
 
509
515
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
516
+
517
+ ## 0.1.88 (v0.1.88)
518
+
519
+ CLI surface simplified to 6 commands with agent stderr streaming on by default and vendor agent flags; the drive gains a `--incremental` flag (added to DRIVE_RUNTIME_KEYS so it never poisons run.inputs or the cache key). MCP tools stay the derived mirror of the same capabilities.
520
+
521
+ ## 0.1.89 (v0.1.89)
522
+
523
+ CLI golden-path fixes: `cw -q "…"` routes the question (was read as an app id → "Workflow app not found"), auto-detects the cwd as the repo (run anywhere, no `--repo`), and `cw help` wraps its command list with a trailing newline; the CLI↔MCP parity contract and the help-token parser are unchanged.
@@ -149,3 +149,11 @@ No other change to this page in v0.1.84.
149
149
  ## 0.1.87 (v0.1.87)
150
150
 
151
151
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
152
+
153
+ ## 0.1.88 (v0.1.88)
154
+
155
+ _No behavioral change in v0.1.88 (no schema-migration edge was added; the incremental result cache uses a self-contained schemaVersion:2 key that never collides with the opt-in v1 cache and is not a run-state or app-schema migration)._
156
+
157
+ ## 0.1.89 (v0.1.89)
158
+
159
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -133,3 +133,11 @@ No other change to this page in v0.1.84.
133
133
  ## 0.1.87 (v0.1.87)
134
134
 
135
135
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
136
+
137
+ ## 0.1.88 (v0.1.88)
138
+
139
+ _No behavioral change in v0.1.88 (the `sched` priority/readiness selection, concurrency ceiling, leases, backoff retry, and fail-closed park state are unchanged)._
140
+
141
+ ## 0.1.89 (v0.1.89)
142
+
143
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -132,3 +132,11 @@ No other change to this page in v0.1.84.
132
132
  ## 0.1.87 (v0.1.87)
133
133
 
134
134
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
135
+
136
+ ## 0.1.88 (v0.1.88)
137
+
138
+ _No behavioral change in v0.1.88 (atomic writes, fsync-durability for audit-essential state, and lock-serialized cross-process stores are unchanged; the in-place `appendRunNode` optimization keeps `writeRunNode` and the persisted bytes identical)._
139
+
140
+ ## 0.1.89 (v0.1.89)
141
+
142
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -293,3 +293,11 @@ No other change to this page in v0.1.84.
293
293
  ## 0.1.87 (v0.1.87)
294
294
 
295
295
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
296
+
297
+ ## 0.1.88 (v0.1.88)
298
+
299
+ _No behavioral change in v0.1.88 (the evidence adoption reasoning chain and its fingerprinted, fail-closed derivation are unchanged)._
300
+
301
+ ## 0.1.89 (v0.1.89)
302
+
303
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -323,3 +323,11 @@ No other change to this page in v0.1.84.
323
323
  ## 0.1.87 (v0.1.87)
324
324
 
325
325
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
326
+
327
+ ## 0.1.88 (v0.1.88)
328
+
329
+ Agent stderr live-streaming is now on by default when stderr is a TTY (CW_AGENT_STREAM=0 / CW_NO_STREAM=1 force it off; CI and pipes stay silent); stdout is still always captured as data and the driver model / sandbox contract are unchanged.
330
+
331
+ ## 0.1.89 (v0.1.89)
332
+
333
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -41,9 +41,9 @@ to trust or breach.
41
41
 
42
42
  npx cool-workflow demo tamper
43
43
 
44
- It builds a real signed ledger, forges it two ways (flip a verdict + re-seal its
45
- hash; inflate reported tokens + reuse the signature), and catches both offline with
46
- only the public key. On a real run, `cw telemetry verify <run>` re-proves the
44
+ It builds a real signed ledger, forges it three ways (flip a verdict + re-seal its
45
+ hash; inflate reported tokens + reuse the signature; edit a signed finding), and
46
+ catches all three offline with only the public key. On a real run, `cw telemetry verify <run>` re-proves the
47
47
  recorded ledger on disk — recomputing the chain so any later edit to a verdict or
48
48
  usage digest is caught; add `--pubkey <public.pem>` to re-run each attested hop's
49
49
  signature check offline too. I keep an
@@ -111,9 +111,9 @@ npm: https://www.npmjs.com/package/cool-workflow
111
111
  > npx cool-workflow demo tamper
112
112
  > ```
113
113
  >
114
- > It builds a real signed ledger, forges it two ways (flip a verdict + re-seal its
115
- > hash; inflate reported tokens + reuse the signature), and catches both offline with
116
- > only the public key. On a real run, `cw telemetry verify <run>` re-proves the
114
+ > It builds a real signed ledger, forges it three ways (flip a verdict + re-seal its
115
+ > hash; inflate reported tokens + reuse the signature; edit a signed finding), and
116
+ > catches all three offline with only the public key. On a real run, `cw telemetry verify <run>` re-proves the
117
117
  > recorded ledger on disk — recomputing the chain so any later edit to a verdict or
118
118
  > usage digest is caught; add `--pubkey <public.pem>` to re-run each attested hop's
119
119
  > signature check offline too. I keep an
@@ -142,9 +142,9 @@ npm: https://www.npmjs.com/package/cool-workflow
142
142
  1/ Your agent pipeline trusts what the model *says* it did. Cool Workflow proves
143
143
  it instead. `npx cool-workflow demo tamper` — 30s, no install:
144
144
 
145
- 2/ It builds a real ed25519-signed telemetry ledger, forges it two ways, and
146
- catches both offline with only the public key. A control-plane that delegates
147
- model execution but can still prove the bill is real.
145
+ 2/ It builds a real ed25519-signed telemetry ledger, forges it three ways (incl.
146
+ editing a signed finding), and catches all three offline with only the public key.
147
+ A control-plane that delegates model execution but can still prove the bill is real.
148
148
 
149
149
  3/ Also: concurrent batches that don't deadlock when an agent hangs, schema-gated
150
150
  outputs, token budgets vs the host's recorded usage (attested-telemetry gate is
@@ -291,3 +291,11 @@ No other change to this page in v0.1.84.
291
291
  ## 0.1.87 (v0.1.87)
292
292
 
293
293
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
294
+
295
+ ## 0.1.88 (v0.1.88)
296
+
297
+ The host-facing surface tracks the CLI simplification to 6 commands (streaming on by default, vendor agent flags); the multi-agent control loop verbs and their MCP-tool mirrors are otherwise unchanged.
298
+
299
+ ## 0.1.89 (v0.1.89)
300
+
301
+ The host-facing surface tracks the CLI golden-path fixes (`cw -q` routing + repo auto-detect + clean help); the multi-agent verbs and their MCP-tool mirrors are unchanged.
@@ -325,3 +325,11 @@ No other change to this page in v0.1.84.
325
325
  ## 0.1.87 (v0.1.87)
326
326
 
327
327
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
328
+
329
+ ## 0.1.88 (v0.1.88)
330
+
331
+ _No change in behavior in v0.1.88 (no harness code changed; the new `loop-control` state node and loop result nodes replay byte-identically through the existing normalize/replay machinery, and pre-0.1.88 snapshots load unchanged)._
332
+
333
+ ## 0.1.89 (v0.1.89)
334
+
335
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -337,3 +337,11 @@ No other change to this page in v0.1.84.
337
337
  ## 0.1.87 (v0.1.87)
338
338
 
339
339
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
340
+
341
+ ## 0.1.88 (v0.1.88)
342
+
343
+ _No behavioral change in v0.1.88 (no operator-view code changed; the new sub-workflow `subRunId`/`subRunDir` and `loopRound` run-state fields surface read-only through the existing derived graph/dependency/evidence views, which neither fabricate state nor guess success)._
344
+
345
+ ## 0.1.89 (v0.1.89)
346
+
347
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -158,3 +158,11 @@ No other change to this page in v0.1.84.
158
158
  ## 0.1.87 (v0.1.87)
159
159
 
160
160
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
161
+
162
+ ## 0.1.88 (v0.1.88)
163
+
164
+ A new `loop-control` StateNodeKind now flows through per-node snapshot/diff/replay (loop decisions are recorded as deterministic, replay-stable nodes); `appendRunNode` was optimized to mutate `run.nodes` in place (O(1) per append vs O(N^2) churn) with byte-identical persisted state, so snapshot/replay digests are unchanged.
165
+
166
+ ## 0.1.89 (v0.1.89)
167
+
168
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -217,3 +217,11 @@ No other change to this page in v0.1.84.
217
217
  ## 0.1.87 (v0.1.87)
218
218
 
219
219
  npm test parallel, 4-vendor wrappers (Claude/Codex/Gemini/OpenCode), Homebrew-style CLI UX (colors/did-you-mean/categorized help/error tips/cw info/cw search/cw man/doctor --fix), post-success summaries, agent execution timing
220
+
221
+ ## 0.1.88 (v0.1.88)
222
+
223
+ Attestation now signs the agent's RESULT, not just its usage: `TelemetryAttestationRecord.resultDigest` hash-binds sha256(result.md) into the ed25519-signed, hash-chained ledger so an offline re-verifier reconstructs the exact signed payload. Budget-aware loop scaling reads the SAME recorded usage total (`deriveUsageTotals`) the fail-closed cost cap reads, so a `until:{kind:"budget-target"}` loop stops on a token target while the cap stays the absolute backstop.
224
+
225
+ ## 0.1.89 (v0.1.89)
226
+
227
+ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes only; this subsystem is unchanged)._
@@ -1,15 +1,15 @@
1
1
  # Cool Workflow Project Index
2
2
 
3
- Generated from the current repository code on 2026-06-19 by `npm run sync:project-index`.
3
+ Generated from the current repository code on 2026-06-21 by `npm run sync:project-index`.
4
4
 
5
5
  ## Snapshot
6
6
 
7
7
  - Package: `cool-workflow`
8
- - Version: `0.1.87`
9
- - Source modules: `64`
8
+ - Version: `0.1.89`
9
+ - Source modules: `65`
10
10
  - Workflow apps: `7`
11
- - Docs: `51`
12
- - Smoke tests: `115`
11
+ - Docs: `52`
12
+ - Smoke tests: `130`
13
13
  - Repository: https://github.com/coo1white/cool-workflow
14
14
 
15
15
  ## Architecture
@@ -92,6 +92,7 @@ multi-agent host -> topology -> blackboard/coordinator
92
92
  - [evidence-reasoning.ts](../src/evidence-reasoning.ts)
93
93
  - [execution-backend.ts](../src/execution-backend.ts)
94
94
  - [gates.ts](../src/gates.ts)
95
+ - [loop-expansion.ts](../src/loop-expansion.ts)
95
96
  - [mcp-surface.ts](../src/mcp-surface.ts)
96
97
  - [multi-agent-eval.ts](../src/multi-agent-eval.ts)
97
98
  - [multi-agent-operator-ux.ts](../src/multi-agent-operator-ux.ts)
@@ -160,6 +161,7 @@ multi-agent host -> topology -> blackboard/coordinator
160
161
  - [Operator UX](operator-ux.7.md)
161
162
  - [PIPELINE-RUNNER(7)](pipeline-runner.7.md)
162
163
  - [Cool Workflow Project Index](project-index.md)
164
+ - [Cool Workflow](readme-v0.1.87-full.md)
163
165
  - [Real Execution Backend Integrations](real-execution-backends.7.md)
164
166
  - [Release And Migration Discipline](release-and-migration.7.md)
165
167
  - [Cool Workflow Release History](release-history.md)
@@ -188,6 +190,7 @@ multi-agent host -> topology -> blackboard/coordinator
188
190
  Smoke tests mirror the public contracts. The high-signal suites are:
189
191
 
190
192
  - [agent-delegation-drive-smoke.js](../test/agent-delegation-drive-smoke.js)
193
+ - [append-run-node-no-realloc-smoke.js](../test/append-run-node-no-realloc-smoke.js)
191
194
  - [architecture-review-fast-automation-smoke.js](../test/architecture-review-fast-automation-smoke.js)
192
195
  - [architecture-review-fast-smoke.js](../test/architecture-review-fast-smoke.js)
193
196
  - [artifact-integrity-smoke.js](../test/artifact-integrity-smoke.js)
@@ -195,6 +198,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
195
198
  - [backend-registry-smoke.js](../test/backend-registry-smoke.js)
196
199
  - [blackboard-state-explosion-management-smoke.js](../test/blackboard-state-explosion-management-smoke.js)
197
200
  - [block-unapproved-tag-smoke.js](../test/block-unapproved-tag-smoke.js)
201
+ - [budget-scaling-loop-smoke.js](../test/budget-scaling-loop-smoke.js)
198
202
  - [bump-version-idempotent-smoke.js](../test/bump-version-idempotent-smoke.js)
199
203
  - [candidate-scoring-smoke.js](../test/candidate-scoring-smoke.js)
200
204
  - [canonical-workflow-apps-smoke.js](../test/canonical-workflow-apps-smoke.js)
@@ -221,10 +225,15 @@ Smoke tests mirror the public contracts. The high-signal suites are:
221
225
  - [error-feedback-smoke.js](../test/error-feedback-smoke.js)
222
226
  - [evidence-adoption-reasoning-smoke.js](../test/evidence-adoption-reasoning-smoke.js)
223
227
  - [evidence-content-extraction-smoke.js](../test/evidence-content-extraction-smoke.js)
228
+ - [execution-backend-agent-smoke.js](../test/execution-backend-agent-smoke.js)
229
+ - [execution-backend-ci-smoke.js](../test/execution-backend-ci-smoke.js)
224
230
  - [execution-backends-smoke.js](../test/execution-backends-smoke.js)
225
231
  - [freebsd-audit-fixes-smoke.js](../test/freebsd-audit-fixes-smoke.js)
226
232
  - [gemini-agent-wrapper-smoke.js](../test/gemini-agent-wrapper-smoke.js)
227
233
  - [h7-custom-profile-persist-smoke.js](../test/h7-custom-profile-persist-smoke.js)
234
+ - [headline-commands-smoke.js](../test/headline-commands-smoke.js)
235
+ - [incremental-resume-smoke.js](../test/incremental-resume-smoke.js)
236
+ - [loop-bounded-expansion-smoke.js](../test/loop-bounded-expansion-smoke.js)
228
237
  - [mcp-app-surface-smoke.js](../test/mcp-app-surface-smoke.js)
229
238
  - [mcp-surface-registry-smoke.js](../test/mcp-surface-registry-smoke.js)
230
239
  - [multi-agent-cli-mcp-surface-smoke.js](../test/multi-agent-cli-mcp-surface-smoke.js)
@@ -239,6 +248,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
239
248
  - [multi-agent-trust-policy-audit-smoke.js](../test/multi-agent-trust-policy-audit-smoke.js)
240
249
  - [no-false-green-smoke.js](../test/no-false-green-smoke.js)
241
250
  - [node-snapshot-diff-replay-smoke.js](../test/node-snapshot-diff-replay-smoke.js)
251
+ - [npm-global-install-smoke.js](../test/npm-global-install-smoke.js)
242
252
  - [npm-trusted-publish-smoke.js](../test/npm-trusted-publish-smoke.js)
243
253
  - [observability-cost-accounting-smoke.js](../test/observability-cost-accounting-smoke.js)
244
254
  - [one-way-boundary-smoke.js](../test/one-way-boundary-smoke.js)
@@ -253,8 +263,10 @@ Smoke tests mirror the public contracts. The high-signal suites are:
253
263
  - [project-index-sync-smoke.js](../test/project-index-sync-smoke.js)
254
264
  - [quickstart-bundle-smoke.js](../test/quickstart-bundle-smoke.js)
255
265
  - [quickstart-check-smoke.js](../test/quickstart-check-smoke.js)
266
+ - [quickstart-no-agent-smoke.js](../test/quickstart-no-agent-smoke.js)
256
267
  - [quickstart-readme-path-smoke.js](../test/quickstart-readme-path-smoke.js)
257
268
  - [quickstart-smoke.js](../test/quickstart-smoke.js)
269
+ - [readme-trust-claim-smoke.js](../test/readme-trust-claim-smoke.js)
258
270
  - [real-execution-backends-smoke.js](../test/real-execution-backends-smoke.js)
259
271
  - [registry-corrupt-fail-closed-smoke.js](../test/registry-corrupt-fail-closed-smoke.js)
260
272
  - [release-flow-smoke.js](../test/release-flow-smoke.js)
@@ -265,16 +277,20 @@ Smoke tests mirror the public contracts. The high-signal suites are:
265
277
  - [result-normalize-smoke.js](../test/result-normalize-smoke.js)
266
278
  - [robustness-failclosed-smoke.js](../test/robustness-failclosed-smoke.js)
267
279
  - [robustness-hardening-smoke.js](../test/robustness-hardening-smoke.js)
280
+ - [run-all-agent-env-hermetic-smoke.js](../test/run-all-agent-env-hermetic-smoke.js)
268
281
  - [run-all-json-summary-smoke.js](../test/run-all-json-summary-smoke.js)
282
+ - [run-export-cross-machine-smoke.js](../test/run-export-cross-machine-smoke.js)
269
283
  - [run-export-import-smoke.js](../test/run-export-import-smoke.js)
270
284
  - [run-export-restore-rerun-smoke.js](../test/run-export-restore-rerun-smoke.js)
271
285
  - [run-export-restore-resume-smoke.js](../test/run-export-restore-resume-smoke.js)
272
286
  - [run-fixture-compat-smoke.js](../test/run-fixture-compat-smoke.js)
287
+ - [run-import-path-traversal-smoke.js](../test/run-import-path-traversal-smoke.js)
273
288
  - [run-import-tamper-failclosed-smoke.js](../test/run-import-tamper-failclosed-smoke.js)
274
289
  - [run-inspect-archive-smoke.js](../test/run-inspect-archive-smoke.js)
275
290
  - [run-registry-control-plane-smoke.js](../test/run-registry-control-plane-smoke.js)
276
291
  - [run-resume-drive-smoke.js](../test/run-resume-drive-smoke.js)
277
292
  - [run-retention-reclamation-smoke.js](../test/run-retention-reclamation-smoke.js)
293
+ - [sample-determinism-smoke.js](../test/sample-determinism-smoke.js)
278
294
  - [sandbox-profile-smoke.js](../test/sandbox-profile-smoke.js)
279
295
  - [sched-policy-validation-smoke.js](../test/sched-policy-validation-smoke.js)
280
296
  - [schedule-routine-daemon-smoke.js](../test/schedule-routine-daemon-smoke.js)
@@ -284,6 +300,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
284
300
  - [source-context-batch-smoke.js](../test/source-context-batch-smoke.js)
285
301
  - [source-context-profile-smoke.js](../test/source-context-profile-smoke.js)
286
302
  - [state-node-smoke.js](../test/state-node-smoke.js)
303
+ - [sub-workflow-nesting-smoke.js](../test/sub-workflow-nesting-smoke.js)
287
304
  - [surface-explicit-cwd-smoke.js](../test/surface-explicit-cwd-smoke.js)
288
305
  - [tamper-evidence-demo-smoke.js](../test/tamper-evidence-demo-smoke.js)
289
306
  - [team-collaboration-smoke.js](../test/team-collaboration-smoke.js)