cool-workflow 0.2.4 → 0.2.6

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 (155) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/.gemini-plugin/mcp.json +10 -0
  4. package/.gemini-plugin/plugin.json +40 -0
  5. package/.opencode-plugin/mcp.json +10 -0
  6. package/.opencode-plugin/plugin.json +40 -0
  7. package/README.md +204 -48
  8. package/apps/architecture-review/app.json +1 -1
  9. package/apps/architecture-review-fast/app.json +1 -1
  10. package/apps/end-to-end-golden-path/app.json +1 -1
  11. package/apps/pr-review-fix-ci/app.json +1 -1
  12. package/apps/release-cut/app.json +1 -1
  13. package/apps/research-synthesis/app.json +1 -1
  14. package/dist/cli/dispatch.js +32 -4
  15. package/dist/cli/entry.js +11 -19
  16. package/dist/cli/global-flags.js +113 -0
  17. package/dist/cli/parseargv.js +7 -1
  18. package/dist/core/capability-data.js +337 -8
  19. package/dist/core/format/help.js +73 -3
  20. package/dist/core/format/recovery-hint.js +32 -0
  21. package/dist/core/multi-agent/collaboration.js +35 -6
  22. package/dist/core/multi-agent/runtime.js +7 -0
  23. package/dist/core/multi-agent/trust-policy.js +7 -1
  24. package/dist/core/pipeline/contract.js +7 -0
  25. package/dist/core/pipeline/error-feedback.js +2 -2
  26. package/dist/core/state/run-paths.js +3 -30
  27. package/dist/core/trust/evidence-grounding.js +13 -1
  28. package/dist/core/util/cli-args.js +22 -0
  29. package/dist/core/version.js +1 -1
  30. package/dist/mcp/dispatch.js +22 -2
  31. package/dist/mcp/server.js +215 -36
  32. package/dist/mcp/tool-process.js +181 -0
  33. package/dist/mcp-server.js +28 -1
  34. package/dist/shell/agent-config.js +11 -2
  35. package/dist/shell/audit-cli.js +1 -1
  36. package/dist/shell/commit.js +8 -2
  37. package/dist/shell/coordinator-io.js +73 -1
  38. package/dist/shell/drive.js +195 -128
  39. package/dist/shell/error-feedback-io.js +6 -0
  40. package/dist/shell/execution-backend/agent.js +201 -26
  41. package/dist/shell/execution-backend/container.js +44 -10
  42. package/dist/shell/execution-backend/local.js +33 -0
  43. package/dist/shell/fs-atomic.js +96 -12
  44. package/dist/shell/ledger-cli.js +9 -2
  45. package/dist/shell/metrics-cli.js +1 -1
  46. package/dist/shell/multi-agent-cli.js +9 -2
  47. package/dist/shell/multi-agent-operator-ux.js +1 -1
  48. package/dist/shell/observability.js +7 -4
  49. package/dist/shell/onramp.js +48 -5
  50. package/dist/shell/operator-ux.js +1 -1
  51. package/dist/shell/perf-trace.js +136 -0
  52. package/dist/shell/pipeline.js +3 -2
  53. package/dist/shell/reclamation-io.js +10 -9
  54. package/dist/shell/report-view-cli.js +2 -0
  55. package/dist/shell/run-export-cli.js +5 -2
  56. package/dist/shell/run-export.js +293 -31
  57. package/dist/shell/run-registry-io.js +8 -0
  58. package/dist/shell/run-store.js +183 -3
  59. package/dist/shell/scheduler-io.js +101 -10
  60. package/dist/shell/state-explosion-cli.js +4 -1
  61. package/dist/shell/telemetry-demo.js +1 -1
  62. package/dist/shell/telemetry-ledger-io.js +36 -24
  63. package/dist/shell/trust-audit.js +178 -36
  64. package/dist/shell/workbench-host.js +121 -10
  65. package/dist/shell/workbench.js +83 -6
  66. package/dist/shell/worker-isolation.js +1 -1
  67. package/dist/wiring/capability-table/basics.js +5 -0
  68. package/dist/wiring/capability-table/exec-backend.js +40 -22
  69. package/dist/wiring/capability-table/parity.js +10 -5
  70. package/dist/wiring/capability-table/pipeline.js +32 -0
  71. package/dist/wiring/capability-table/registry-core.js +26 -3
  72. package/dist/wiring/capability-table/reporting.js +7 -1
  73. package/dist/wiring/capability-table/scheduling-registry.js +8 -2
  74. package/dist/wiring/capability-table/trust-ledger.js +54 -12
  75. package/docs/agent-delegation-drive.7.md +17 -0
  76. package/docs/cli-mcp-parity.7.md +46 -5
  77. package/docs/contract-migration-tooling.7.md +4 -0
  78. package/docs/control-plane-scheduling.7.md +38 -0
  79. package/docs/cross-agent-ledger.7.md +20 -8
  80. package/docs/durable-state-and-locking.7.md +4 -0
  81. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  82. package/docs/execution-backends.7.md +4 -0
  83. package/docs/fix.7.md +4 -4
  84. package/docs/getting-started.md +40 -32
  85. package/docs/index.md +17 -0
  86. package/docs/launch/demo.tape +4 -3
  87. package/docs/mcp-app-surface.7.md +27 -0
  88. package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
  89. package/docs/multi-agent-eval-replay-harness.7.md +4 -0
  90. package/docs/multi-agent-operator-ux.7.md +4 -0
  91. package/docs/node-snapshot-diff-replay.7.md +4 -0
  92. package/docs/observability-cost-accounting.7.md +4 -0
  93. package/docs/project-index.md +53 -9
  94. package/docs/real-execution-backends.7.md +4 -0
  95. package/docs/release-and-migration.7.md +4 -0
  96. package/docs/release-tooling.7.md +12 -0
  97. package/docs/routine.7.md +22 -0
  98. package/docs/run-registry-control-plane.7.md +37 -9
  99. package/docs/run-retention-reclamation.7.md +12 -4
  100. package/docs/state-explosion-management.7.md +4 -0
  101. package/docs/team-collaboration.7.md +4 -0
  102. package/docs/trust-audit-anchor.7.md +4 -0
  103. package/docs/web-desktop-workbench.7.md +72 -2
  104. package/docs/workflow-app-framework.7.md +31 -0
  105. package/manifest/plugin.manifest.json +1 -1
  106. package/manifest/source-context-profiles.json +4 -3
  107. package/package.json +6 -3
  108. package/scripts/agents/agent-adapter-core.js +26 -0
  109. package/scripts/agents/claude-p-agent.js +4 -1
  110. package/scripts/agents/codex-agent.js +4 -0
  111. package/scripts/agents/cw-attest-wrap.js +1 -1
  112. package/scripts/agents/gemini-agent.js +4 -0
  113. package/scripts/agents/opencode-agent.js +5 -0
  114. package/scripts/block-unapproved-tag.js +160 -0
  115. package/scripts/canonical-apps.js +4 -4
  116. package/scripts/children/batch-delegate-child.js +72 -4
  117. package/scripts/children/http-batch-delegate-child.js +132 -0
  118. package/scripts/children/http-delegate-child.js +8 -0
  119. package/scripts/dogfood-release.js +2 -2
  120. package/scripts/fake-date-for-reproduction.js +1 -1
  121. package/scripts/gen-manifests.js +32 -61
  122. package/scripts/golden-path.js +4 -4
  123. package/scripts/lang-policy-check.js +82 -0
  124. package/scripts/parity-check.js +42 -23
  125. package/scripts/purity-baseline.json +0 -3
  126. package/scripts/purity-gate.js +16 -3
  127. package/scripts/release-check.js +2 -1
  128. package/scripts/release-flow.js +169 -41
  129. package/scripts/release-gate.js +208 -0
  130. package/scripts/release-oneclick.js +38 -7
  131. package/scripts/release-tags.js +47 -0
  132. package/scripts/schema-version-inventory.json +31 -0
  133. package/scripts/validate-run-state-schema.js +95 -4
  134. package/scripts/verdict-keygen.js +2 -2
  135. package/scripts/verify-bump-reproduction.js +193 -0
  136. package/scripts/verify-release-verdict.js +139 -0
  137. package/scripts/verify-verdict-signature.js +1 -1
  138. package/ui/workbench/app.css +50 -10
  139. package/ui/workbench/app.js +269 -34
  140. package/ui/workbench/index.html +4 -2
  141. package/ui/workbench/inspection.js +51 -0
  142. package/ui/workbench/navigation.js +44 -0
  143. package/docs/agent-framework.md +0 -177
  144. package/docs/designs/handoff-ledger.md +0 -145
  145. package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +0 -40
  146. package/docs/launch/launch-kit.md +0 -195
  147. package/docs/launch/pre-launch-checklist.md +0 -53
  148. package/docs/readme-v0.1.87-full.md +0 -301
  149. package/docs/routines.md +0 -101
  150. package/docs/scheduled-tasks.md +0 -80
  151. package/scripts/agents/claude-p-agent.sh +0 -9
  152. package/scripts/block-unapproved-tag.sh +0 -75
  153. package/scripts/release-gate.sh +0 -94
  154. package/scripts/verify-bump-reproduction.sh +0 -148
  155. package/scripts/verify-container-selfref.js +0 -64
@@ -169,6 +169,14 @@ LLM step (the reviewer) is **delegated** through CW's agent backend, so whicheve
169
169
  model you set up does the review. CW starts the agent argv-style (`shell:false`),
170
170
  takes on the agent's own credentials, and pulls in no model SDK — the red line.
171
171
 
172
+ The control plane runs the deterministic gate once. It keeps a failed child
173
+ command's short tail on stderr for the operator, but never puts that tail in a
174
+ saved verdict. The reviewer does not run that gate again. It checks judgment
175
+ questions the gate cannot check. A reviewer rejection has exact `REJECTED`,
176
+ `kind: semantic-review`, and numbered facts with repo-relative `file:line`
177
+ places. Other rejection text is invalid reviewer output: the cut stops, no tag
178
+ is made, and it is not a verified code rejection.
179
+
172
180
  ```bash
173
181
  # the operator's one-command release (scripts/release-oneclick.js — preflight,
174
182
  # gated cut, tag-only push, CI wait, npm confirmation, verdict-record PR):
@@ -320,3 +328,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
320
328
  0.2.3
321
329
 
322
330
  0.2.4
331
+
332
+ 0.2.5
333
+
334
+ 0.2.6
package/docs/routine.7.md CHANGED
@@ -67,6 +67,28 @@ and fills out the prompt.
67
67
  | 0 | Command done |
68
68
  | 1 | Error (bad arguments, missing trigger, etc.) |
69
69
 
70
+ ## EXAMPLES
71
+
72
+ Long architecture reviews as background routines: use
73
+ `architecture-review-fast` for the foreground user path, then put the full
74
+ `architecture-review` app in line as background work so a deep look-over does
75
+ not get in the way of a back-and-forth session:
76
+
77
+ ```bash
78
+ node scripts/architecture-review-fast.js \
79
+ --repo /path/to/repo \
80
+ --question "Is this architecture sound?" \
81
+ --metrics \
82
+ --schedule-full
83
+ ```
84
+
85
+ The wrapper makes a one-shot reminder schedule whose `workflowId` is
86
+ `architecture-review`. The schedule prompt carries the foreground fast run id,
87
+ fast report path, and source-context digest/profile, and asks the background
88
+ agent to give back the full review report path and digest. `--metrics` is
89
+ optional and reports foreground time plus agent-spawn and result-cache-hit
90
+ counts for the fast run.
91
+
70
92
  ## SEE ALSO
71
93
 
72
94
  cw sched — durable run-queue scheduling for workflow runs
@@ -123,6 +123,11 @@ adds the drive outcome to the result under a `drive` field. The default (no
123
123
  gives `drive.status="blocked"` (fail-closed, never a made-up completion); CW
124
124
  hands worker execution to your agent and never runs a model itself.
125
125
 
126
+ Human output with `--drive` or `--once` prints the drive status, worker counts,
127
+ each drive step, and the terminal commit id when there is one. This makes a
128
+ blocked or failed drive clear without `--json`. Bare `run resume` keeps its old
129
+ text as it is.
130
+
126
131
  ## Queue
127
132
 
128
133
  `queue add` adds a durable entry to the end of `$CW_HOME/registry/queue.json` with an
@@ -177,6 +182,15 @@ whose top-level integrity block is *absent* — closing the legacy fail-open sea
177
182
  where a stripped-integrity archive imported unverified. Unset (the default) keeps
178
183
  legacy integrity-less archives byte-identical; the flag is mechanism, not policy.
179
184
 
185
+ An operator can also set `CW_MAX_RUN_ARCHIVE_BYTES`,
186
+ `CW_MAX_RUN_ARCHIVE_FILES`, or `CW_MAX_RUN_ARCHIVE_CONTENT_BYTES`. Each value
187
+ has to be a positive safe integer. The first sets a raw file byte limit before
188
+ the archive is read. The second sets a normalized file row limit. The last sets
189
+ the total decoded content byte limit, checked from declared sizes before decode
190
+ and again while content is decoded. A bad setting or over-limit archive stops
191
+ before a run directory is made. With all three unset, import, inspect, restore,
192
+ and offline bundle check keep their present behavior.
193
+
180
194
  The archive's run id becomes a directory name under `DIR/.cw/runs/`, so import
181
195
  also refuses any run id that is not a single safe path segment (`[A-Za-z0-9._-]`,
182
196
  with no separator and not the `.` or `..` component) and asserts the resolved run
@@ -216,11 +230,20 @@ before importing a bad archive. It is a true preview of import: under
216
230
  turn away) also inspects as `ok:false`; with the env unset (default) an absent integrity
217
231
  block is only reported, not failed.
218
232
 
233
+ The file table is checked before any write. Every row needs a known role, a
234
+ safe size, a sha256 value, and a relative path. Paths are made portable and
235
+ then have to be unique. `state.json`, `import-manifest.json`, and lock files
236
+ are made by the restore work and are not accepted from an archive. A bad row
237
+ or two rows with the same path make inspect, import, and restore fail closed.
238
+ No run directory is made for that input.
239
+
219
240
  **Restore in one fail-closed step.** `run restore PATH --target DIR [--json]`
220
- does the whole move-a-run-to-another-machine flow as ONE atomic, fail-closed
221
- step: it integrity-**inspects** the bundle first (writing nothing), **imports**
222
- it, then reuses the verification `import` already ran and reports `ok:true`
223
- ONLY when that verify passes. This closes a real gap: `run import` runs a
241
+ does the whole move-a-run-to-another-machine flow as one atomic, fail-closed
242
+ step. It integrity-**inspects** the bundle first, imports it into a same-disk
243
+ staging tree, and checks the file, telemetry, trust-audit, and run-state records there.
244
+ Only then does it put final paths into state and publish the run with one
245
+ directory rename. It reports `ok:true` only after a check of the published
246
+ tree. This closes a real gap: `run import` runs a
224
247
  verification (it re-proves restored file digests, the **telemetry ledger**, and
225
248
  the **trust-audit hash chain**) and reports it, but does NOT fail on it — it
226
249
  exits `0` even when that chain does not verify. So a run whose telemetry or
@@ -229,13 +252,14 @@ made-up success. `run restore` refuses exactly that: it fails closed on the same
229
252
  verification `import` only reports. A bundle that fails the up-front integrity
230
253
  inspect is refused **before any import**, so nothing is written and the run is
231
254
  never left part-restored; the result carries `imported:null` and `verify:null`.
232
- A bundle that imports but fails post-import verification is reported with
233
- `ok:false` too. It exits `1` whenever `ok:false`, so `cw run restore <path>` is a
255
+ A bundle that imports in staging but fails a chain check is reported with
256
+ `ok:false`, `imported:null`, and no final run. A final run with the same id is
257
+ never merged or replaced. A staging write fault is cleaned up. It exits `1`
258
+ whenever `ok:false`, so `cw run restore <path>` is a
234
259
  single command that either lands a fully-proven run or refuses with a non-zero
235
- exit — never a made-up success. The result is structured
260
+ exit — never a made-up success or a half-written final run. The result is structured
236
261
  (`{ schemaVersion, ok, target, inspect, imported, verify, registry }`) so it is
237
- scriptable. `run import` and `run inspect-archive` are unchanged; restore is a
238
- thin composition of `inspectArchive` + `importRun` (reusing its verification).
262
+ scriptable. `run import` and `run inspect-archive` are unchanged.
239
263
 
240
264
  MCP gives the same mechanisms as `cw_run_export`, `cw_run_import`,
241
265
  `cw_run_verify_import`, `cw_run_inspect_archive`, and `cw_run_restore`; the CLI
@@ -482,3 +506,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
482
506
  0.2.3
483
507
 
484
508
  0.2.4
509
+
510
+ 0.2.5
511
+
512
+ 0.2.6
@@ -109,16 +109,20 @@ node points to a freed path. Opt out with `--keep-scratch`.
109
109
 
110
110
  ## Commit snapshots — never reconstructable, always downgrades to verify-only
111
111
 
112
- `commitState` embeds the FULL run into `commits/<id>.json` on every commit, so
113
- these grow unbounded in both count and per-file size with no cap. Reclaiming them
112
+ `commitState` writes only the commit's own (small, bounded) record into
113
+ `commits/<id>.json` on every commit it no longer embeds the whole run, so
114
+ these files stay small and do not grow with the run's size. Reclaiming them
114
115
  frees the run's superseded, non-`verifierGated` "checkpoint" commit snapshots —
115
116
  the run's LATEST commit and every `verifierGated` commit (the actual
116
117
  audit-significant milestones) are always kept. `run.commits`' own lightweight
117
118
  metadata (id, `verifierGated`, evidence digests, acceptance rationale — everything
118
119
  `extractSkeleton` seals) lives in `state.json`, not the snapshot file, so it stays
119
- fully intact and queryable regardless. Unlike a node snapshot, a commit snapshot is
120
- a genuine point-in-time capture with no `ReconstructionRecipe` — reclaiming even
120
+ fully intact and queryable regardless. A commit snapshot is treated as never
121
+ reconstructable there is no `ReconstructionRecipe` for it so reclaiming even
121
122
  one downgrades capability to `verify-only`, never `re-runnable-by-reconstruction`.
123
+ This is left conservative on purpose: even though the snapshot file's content is
124
+ now a strict subset of what `state.json` already keeps durably, the reclaim
125
+ classification does not (yet) treat that as a basis for reconstruction.
122
126
  Each reclaimed commit's own `StateNode` had its `snapshot` artifact stripped (not
123
127
  re-pointed — there is no retained alternative) before the free, so `prepareFree`'s
124
128
  dangling-reference proof covers this kind too. Opt out with `--keep-commits`.
@@ -288,3 +292,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
288
292
  0.2.3
289
293
 
290
294
  0.2.4
295
+
296
+ 0.2.5
297
+
298
+ 0.2.6
@@ -328,3 +328,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
328
328
  0.2.3
329
329
 
330
330
  0.2.4
331
+
332
+ 0.2.5
333
+
334
+ 0.2.6
@@ -264,3 +264,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
264
264
  0.2.3
265
265
 
266
266
  0.2.4
267
+
268
+ 0.2.5
269
+
270
+ 0.2.6
@@ -71,3 +71,7 @@ security-trust-hardening(7), cli-mcp-parity(7), report-verifiable-bundle(7)
71
71
  0.2.3
72
72
 
73
73
  0.2.4
74
+
75
+ 0.2.5
76
+
77
+ 0.2.6
@@ -10,6 +10,28 @@ speed and the MCP server (JSON-RPC over stdio) showed things for machine context
10
10
  Workbench lets a person look at a run quickly — and adds NOTHING else. It works out,
11
11
  decides, and keeps nothing that the CLI/MCP cannot already make.
12
12
 
13
+ ## Simple UI rules
14
+
15
+ The Workbench follows three public sets of rules:
16
+
17
+ - FreeBSD [style(9)](https://man.freebsd.org/cgi/man.cgi?query=style&sektion=9)
18
+ says that usage text has to agree with the man page and that error text has
19
+ to be easy to find. CW keeps command words and error words clear and fixed.
20
+ - FreeBSD [hier(7)](https://man.freebsd.org/cgi/man.cgi?query=hier&sektion=7)
21
+ gives each sort of file one place. The Workbench keeps no state; `.cw/`
22
+ stays the one state source.
23
+ - Homebrew [brew(1)](https://docs.brew.sh/Manpage) puts its essential commands
24
+ before its full command list, and gives `help`, `doctor`, `info`, and
25
+ `search`. CW gives one clear next command in place of a hidden recovery
26
+ action. Homebrew [External Commands](https://docs.brew.sh/External-Commands)
27
+ also shows how a front door may be added without a change to the tool's
28
+ inside parts. The Workbench stays a view over present CW capabilities.
29
+ - Codex [Best practices](https://learn.chatgpt.com/guides/best-practices.md)
30
+ puts context, checks, and review in the work path. Its
31
+ [app commands](https://learn.chatgpt.com/docs/reference/commands.md) keep
32
+ search, key movement, and Back/Forward movement close at hand. The
33
+ Workbench keeps the run and panel in the page address for the same reason.
34
+
13
35
  ## The third front door (mechanism vs policy)
14
36
 
15
37
  The kernel and the durable `.cw/` state are the MECHANISM. The CLI, the MCP
@@ -85,6 +107,7 @@ The host has least privilege and is local by default:
85
107
 
86
108
  - it binds the loopback interface `127.0.0.1` ONLY — never a public address
87
109
  - it is READ-ONLY: every route is `GET`; any write verb is turned away with `405`
110
+ - a read view makes no audit, metrics, or other derived file under `.cw/`
88
111
  - it turns away non-localhost `Host` headers (a DNS-rebinding defense) with `403`
89
112
  - it turns away path traversal out of `ui/workbench/` with `403`
90
113
  - it serves nothing past the current user's `.cw/` scope and the Run Registry's
@@ -97,9 +120,16 @@ capability core entry that already exists — never a side code path — so it c
97
120
  CLI/MCP and is covered by the parity gate.
98
121
 
99
122
  Authentication is opt-in, not on by default: set `CW_WORKBENCH_TOKEN` and every
100
- request must carry it as `Authorization: Bearer <token>` or `?token=<token>`
123
+ `/api/*` request must carry it as `Authorization: Bearer <token>` or `?token=<token>`
101
124
  (timing-safe compare); left unset, the loopback/read-only/GET-only controls
102
- above are the only defense and any local process can read. Pass
125
+ above are the only defense and any local process can read. The static UI files
126
+ (`/ui/*`, and `/` when the UI is installed) are served without the token: they
127
+ are fixed code with no run data, and the browser needs them before the page can
128
+ say anything at all. The fallback `/` page (used when the UI is not installed)
129
+ stays behind the token, because it holds the serve descriptor with the repo
130
+ root path. Open the page as `/?token=<token>`: the UI reads the token from the
131
+ page address and adds it to every `/api/*` request; without it the page still
132
+ loads and tells you to reopen it with the token. Pass
103
133
  `--require-token` to `cw workbench serve` to fail closed instead: the server
104
134
  refuses to start at all unless `CW_WORKBENCH_TOKEN` is already set. This is a
105
135
  strict opt-in — leaving it off keeps today's default behavior unchanged.
@@ -113,6 +143,29 @@ cw workbench view <run-id> [--json] # five-panel WorkbenchRunView for on
113
143
  cw workbench serve [--port N] [--scope repo|home] [--once|--json] [--require-token]
114
144
  ```
115
145
 
146
+ The page address may name one run and one panel:
147
+
148
+ ```text
149
+ #run=<encoded-run-id>&tab=<graph|blackboard|worker|candidate|audit|metrics|collaboration>
150
+ ```
151
+
152
+ The `run` value is needed for a run view. With no `tab`, the page uses
153
+ `graph`. A bad tab name is changed to `graph`. Back, Forward, and page reload
154
+ keep the named view. The Workbench token stays in the page query and is never
155
+ put in this fragment.
156
+
157
+ The run list and panels work with a keyboard. Left and Right move through the
158
+ panel tabs; Home and End go to the first and last tab. The active tab and its
159
+ panel are joined with the standard ARIA tab and tabpanel links.
160
+
161
+ When a present panel payload has an `integrity`, `problems`,
162
+ `missingEvidence`, `nextAction`, or `nextActions` fact, the page puts a small
163
+ `What matters` block before the full panel record. It copies only source
164
+ values. It does not make a new state, rank, or action. An empty problem or
165
+ missing-evidence list is shown as `none`. A field with a shape the page does
166
+ not know is left out of the block. The full structured view or JSON stays
167
+ under the block.
168
+
116
169
  `cw workbench serve` with `--once`/`--json` prints the serve descriptor (bind
117
170
  host/port, scope, routes) and stops without starting a server; the default starts
118
171
  the localhost host (like `schedule daemon`). The MCP tools `cw_workbench_view` and
@@ -282,3 +335,20 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
282
335
  0.2.3
283
336
 
284
337
  0.2.4
338
+
339
+ ## Workbench UI/host round 2 (Unreleased)
340
+
341
+ - With `CW_WORKBENCH_TOKEN` set, the page now works: the static UI files are
342
+ open, and every `/api/*` request stays behind the token (see "Trust
343
+ boundary" above). The UI reads `?token=` from the page address, and a 401
344
+ answer tells you to reopen the page with the token.
345
+ - `cw workbench view --json` (and `/api/run/:runId`) gains a `lifecycle` key:
346
+ the run registry's own state for the run
347
+ (queued|running|blocked|completed|failed|archived|reclaimed). The key is
348
+ left out when the run cannot be classified, so those payloads keep their
349
+ old bytes. The UI shows it as a badge in the run header, with one
350
+ next-step line when a run is blocked or failed.
351
+
352
+ 0.2.5
353
+
354
+ 0.2.6
@@ -32,6 +32,37 @@ runner owns state transitions, dispatch, result recording, verifier gates,
32
32
  commits, and reports. A workflow app owns its own inputs, phases, task
33
33
  prompts, evidence needs, and sandbox profile hints.
34
34
 
35
+ Every CW workflow keeps to one loop, and the loop maps to real framework
36
+ operations:
37
+
38
+ | Loop stage | framework operation | Responsibility |
39
+ | --- | --- | --- |
40
+ | Interpret | `plan()` | Load workflow, check inputs, make tasks |
41
+ | Act | `dispatch()` | Move tasks that can run from pending to running |
42
+ | Observe | `recordResult()` | Read Markdown/JSON-RPC result evidence |
43
+ | Adjust | verifier gates | Check evidence and pick the next phase |
44
+ | Checkpoint | `commitState()` | Take a snapshot of state after important changes |
45
+
46
+ The language split is on purpose: the platform is TypeScript
47
+ (`src/*.ts -> dist/*.js`, strongly typed so it is simple to keep up), while
48
+ workflow apps are plain JavaScript modules (`apps/<app-id>/workflow.js`,
49
+ legacy `workflows/*.workflow.js`) so workflow scripts run without `ts-node`.
50
+
51
+ Verification and verdict tasks give back a `cw:result` JSON fence:
52
+
53
+ ````text
54
+ ```cw:result
55
+ {
56
+ "summary": "short summary",
57
+ "findings": [],
58
+ "evidence": ["/absolute/path/file.ts:42"]
59
+ }
60
+ ```
61
+ ````
62
+
63
+ CW says no to high-priority findings without evidence. This keeps agent work
64
+ nearer to engineering output you can look into than to free talk.
65
+
35
66
  The framework is kept small on purpose. The public app helpers are:
36
67
 
37
68
  - `defineWorkflowApp(definition)`
@@ -2,7 +2,7 @@
2
2
  "_comment": "SINGLE SOURCE OF TRUTH for every vendor manifest. Edit THIS file, then run `npm run gen:manifests`. Do NOT hand-edit the generated vendor manifests (.claude-plugin/, .codex-plugin/, .agents/, .mcp.json) — `npm run gen:manifests -- --check` (run by release:check) will fail if they drift from this source.",
3
3
  "identity": {
4
4
  "name": "cool-workflow",
5
- "version": "0.2.4",
5
+ "version": "0.2.6",
6
6
  "license": "BSD-2-Clause",
7
7
  "homepage": "https://github.com/coo1white/cool-workflow",
8
8
  "author": {
@@ -3,7 +3,7 @@
3
3
  "profiles": {
4
4
  "core": {
5
5
  "description": "Default AI source context: runtime source, apps, package metadata, and agent wrappers; generated artifacts, tests, docs, release records, and long logs are manifest-only.",
6
- "maxLines": 50000,
6
+ "maxLines": 52000,
7
7
  "include": [
8
8
  "plugins/cool-workflow/src/**",
9
9
  "plugins/cool-workflow/apps/**",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "runtime": {
27
27
  "description": "Runtime-kernel source context for state, orchestration, scheduling, execution, and shared types.",
28
- "maxLines": 48000,
28
+ "maxLines": 49000,
29
29
  "include": [
30
30
  "plugins/cool-workflow/src/**",
31
31
  "plugins/cool-workflow/package.json",
@@ -95,7 +95,8 @@
95
95
  "include": [
96
96
  "AGENTS.md",
97
97
  "plugins/cool-workflow/scripts/release-flow.js",
98
- "plugins/cool-workflow/scripts/release-gate.sh",
98
+ "plugins/cool-workflow/scripts/release-gate.js",
99
+ "plugins/cool-workflow/scripts/release-tags.js",
99
100
  "plugins/cool-workflow/scripts/dogfood-release.js",
100
101
  "plugins/cool-workflow/scripts/gen-manifests.js",
101
102
  "plugins/cool-workflow/scripts/version-sync-check.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cool-workflow",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "bin": {
5
5
  "cool-workflow": "scripts/cw.js",
6
6
  "cw": "scripts/cw.js"
@@ -26,6 +26,8 @@
26
26
  "files": [
27
27
  ".claude-plugin/",
28
28
  ".codex-plugin/",
29
+ ".gemini-plugin/",
30
+ ".opencode-plugin/",
29
31
  ".mcp.json",
30
32
  "manifest/",
31
33
  "README.md",
@@ -44,6 +46,7 @@
44
46
  "check": "tsc -p tsconfig.json --noEmit",
45
47
  "dist:check": "node scripts/dist-drift-check.js",
46
48
  "purity:check": "node scripts/purity-gate.js",
49
+ "lang:check": "node scripts/lang-policy-check.js",
47
50
  "golden-path": "node scripts/golden-path.js",
48
51
  "dogfood:release": "node scripts/dogfood-release.js",
49
52
  "canonical-apps": "node scripts/canonical-apps.js",
@@ -55,7 +58,6 @@
55
58
  "bump:version": "node scripts/bump-version.js",
56
59
  "new:feature": "node scripts/new-feature.js",
57
60
  "forward-ref": "node scripts/forward-ref-docs.js",
58
- "verify:container": "node scripts/verify-container-selfref.js",
59
61
  "gen:manifests": "node scripts/gen-manifests.js",
60
62
  "gen:parity": "node scripts/gen-parity-doc.js",
61
63
  "manifest:load-check": "node test/vendor-manifest-load-smoke.js",
@@ -73,7 +75,8 @@
73
75
  "test:unit": "node dist/cli.js version > /dev/null && node test/run-unit.js",
74
76
  "eval:replay": "tsc -p tsconfig.json && node test/multi-agent-eval-replay-harness-smoke.js",
75
77
  "ci": "npm run build && npm run check && npm run test && npm run release:check",
76
- "validate:schema": "node scripts/validate-run-state-schema.js"
78
+ "validate:schema": "node scripts/validate-run-state-schema.js",
79
+ "bench:workbench:deep": "node ../../scripts/bench/workbench-load.js"
77
80
  },
78
81
  "devDependencies": {
79
82
  "@types/node": "^26.1.1",
@@ -490,8 +490,34 @@ function buildFailureDetail({ label, code, childStderr, partialText }) {
490
490
  return codeText;
491
491
  }
492
492
 
493
+ // CW may set CW_AGENT_VENDOR_PIDFILE when it runs a shipped wrapper. We write
494
+ // the vendor child's PID there so CW can reap the vendor if it has to SIGKILL
495
+ // this wrapper on a timeout: a SIGKILL is uncatchable, so the wrapper cannot
496
+ // forward the stop to its vendor child itself, and the vendor would otherwise
497
+ // live on as an orphan and keep spending (see execution-backend/agent.ts). The
498
+ // file is removed as soon as the vendor exits, so a stale PID is never reaped.
499
+ // Best-effort: fs errors are ignored -- reaping is a safety net, not a
500
+ // correctness dependency -- and an arbitrary CW_AGENT_COMMAND that never calls
501
+ // this is simply not covered.
502
+ function recordVendorPid(child, env = process.env) {
503
+ const pidfile = env.CW_AGENT_VENDOR_PIDFILE;
504
+ if (!pidfile || !child || !child.pid) return child;
505
+ try { fs.writeFileSync(pidfile, String(child.pid), "utf8"); } catch { /* best-effort */ }
506
+ let cleared = false;
507
+ const clear = () => {
508
+ if (cleared) return;
509
+ cleared = true;
510
+ try { fs.unlinkSync(pidfile); } catch { /* already gone */ }
511
+ };
512
+ child.once("close", clear);
513
+ child.once("exit", clear);
514
+ process.once("exit", clear);
515
+ return child;
516
+ }
517
+
493
518
  module.exports = {
494
519
  RESULT_CONTRACT,
520
+ recordVendorPid, // write the vendor child's PID to CW_AGENT_VENDOR_PIDFILE so cw can reap it on a timeout
495
521
  buildPrompt,
496
522
  streamEnabled,
497
523
  traceEnabled,
@@ -34,7 +34,7 @@ const { spawn, spawnSync } = require("node:child_process");
34
34
  // wrappers instead of carrying a private copy. A drifted inline copy (ASCII
35
35
  // hyphens silently became em-dashes here) meant claude was sent a different
36
36
  // instruction text than the other providers for the same contract.
37
- const { buildPrompt, createRenderer, persistStderr, toolLabel, summarizeToolResult, buildFailureDetail } = require("./agent-adapter-core");
37
+ const { buildPrompt, createRenderer, persistStderr, toolLabel, summarizeToolResult, buildFailureDetail, recordVendorPid } = require("./agent-adapter-core");
38
38
 
39
39
  const inputPath = process.argv[2];
40
40
  const resultPath = process.argv[3];
@@ -103,6 +103,9 @@ const child = spawn(
103
103
  ["-p", prompt, "--output-format", "stream-json", "--verbose", "--allowedTools", "Read,Grep,Glob"],
104
104
  { stdio: ["ignore", "pipe", "pipe"] }
105
105
  );
106
+ // Record the vendor PID so cw can reap this claude process if it SIGKILLs the
107
+ // wrapper on a timeout (see agent-adapter-core recordVendorPid).
108
+ recordVendorPid(child);
106
109
 
107
110
  let model;
108
111
  let usage;
@@ -43,6 +43,7 @@ const {
43
43
  flushJsonLines,
44
44
  parseJsonLines,
45
45
  persistStderr,
46
+ recordVendorPid,
46
47
  writeResult
47
48
  } = require("./agent-adapter-core");
48
49
 
@@ -133,6 +134,9 @@ const child = spawn("codex", args, {
133
134
  stdio: ["pipe", "pipe", "pipe"],
134
135
  shell: false
135
136
  });
137
+ // Record the vendor PID so cw can reap this codex process if it SIGKILLs the
138
+ // wrapper on a timeout (see agent-adapter-core recordVendorPid).
139
+ recordVendorPid(child);
136
140
 
137
141
  child.stdin.setDefaultEncoding("utf8");
138
142
  child.stdin.end(prompt);
@@ -20,7 +20,7 @@
20
20
  // Point CW at it (from plugins/cool-workflow/), keeping your inner agent intact:
21
21
  // CW_AGENT_ATTEST_PRIVKEY=$PWD/cw-attest.key \
22
22
  // CW_AGENT_COMMAND="node $PWD/scripts/agents/cw-attest-wrap.js --manifest {{manifest}} -- \
23
- // bash $PWD/scripts/agents/claude-p-agent.sh {{input}} {{result}}"
23
+ // node $PWD/scripts/agents/claude-p-agent.js {{input}} {{result}}"
24
24
  // and configure CW's verify side: CW_AGENT_ATTEST_PUBKEY=$PWD/cw-attest.pub
25
25
  //
26
26
  // Honest posture: if no private key is set, or the agent reports no usage, the
@@ -24,6 +24,7 @@ const {
24
24
  flushJsonLines,
25
25
  parseJsonLines,
26
26
  persistStderr,
27
+ recordVendorPid,
27
28
  writeResult
28
29
  } = require("./agent-adapter-core");
29
30
 
@@ -71,6 +72,9 @@ const child = spawn("gemini", args, {
71
72
  stdio: ["ignore", "pipe", "pipe"],
72
73
  shell: false
73
74
  });
75
+ // Record the vendor PID so cw can reap this gemini process if it SIGKILLs the
76
+ // wrapper on a timeout (see agent-adapter-core recordVendorPid).
77
+ recordVendorPid(child);
74
78
 
75
79
  child.stdout.setEncoding("utf8");
76
80
  child.stdout.on("data", (chunk) => {
@@ -29,6 +29,7 @@ const {
29
29
  flushJsonLines,
30
30
  parseJsonLines,
31
31
  persistStderr,
32
+ recordVendorPid,
32
33
  writeResult
33
34
  } = require("./agent-adapter-core");
34
35
 
@@ -124,6 +125,10 @@ const child = spawn("opencode", args, {
124
125
  stdio: ["ignore", "pipe", "pipe"],
125
126
  shell: false
126
127
  });
128
+ // Record the vendor PID so cw can reap this opencode process (also used by the
129
+ // deepseek wrapper, which re-exports this file) if it SIGKILLs the wrapper on a
130
+ // timeout (see agent-adapter-core recordVendorPid).
131
+ recordVendorPid(child);
127
132
 
128
133
  child.stdout.setEncoding("utf8");
129
134
  child.stdout.on("data", (chunk) => {