cool-workflow 0.2.0 → 0.2.2
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +7 -5
- package/apps/architecture-review/app.json +2 -2
- package/apps/architecture-review/workflow.js +12 -12
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/cli/dispatch.js +20 -88
- package/dist/cli/parseargv.js +6 -3
- package/dist/core/capability-data.js +270 -0
- package/dist/core/capability-table.js +15 -3519
- package/dist/core/format/help.js +30 -7
- package/dist/core/hash.js +1 -1
- package/dist/core/multi-agent/candidate-scoring.js +1 -1
- package/dist/core/multi-agent/collaboration.js +3 -2
- package/dist/core/multi-agent/coordinator.js +4 -3
- package/dist/core/multi-agent/eval-replay.js +1 -1
- package/dist/core/multi-agent/runtime.js +2 -2
- package/dist/core/multi-agent/trust-policy.js +1 -1
- package/dist/core/pipeline/commit-gate.js +2 -1
- package/dist/core/pipeline/contract.js +1 -1
- package/dist/core/pipeline/drive-decide.js +1 -1
- package/dist/core/state/contract-migration.js +1 -1
- package/dist/core/state/migrations.js +2 -2
- package/dist/core/state/node-snapshot.js +1 -1
- package/dist/core/state/state-explosion/digest.js +3 -2
- package/dist/core/state/state-explosion/graph.js +13 -12
- package/dist/core/state/state-explosion/helpers.js +5 -4
- package/dist/core/state/state-explosion/report.js +1 -1
- package/dist/core/state/state-explosion/size.js +1 -1
- package/dist/core/state/state-node.js +2 -2
- package/dist/core/state/types.js +1 -1
- package/dist/core/trust/ledger.js +3 -2
- package/dist/core/trust/telemetry-attestation.js +3 -3
- package/dist/core/trust/telemetry-ledger.js +2 -2
- package/dist/core/types/execution-backend.js +18 -0
- package/dist/core/types/observability.js +7 -0
- package/dist/core/util/collate.js +23 -0
- package/dist/core/version.js +1 -1
- package/dist/core/workflow-apps/app-schema.js +1 -1
- package/dist/mcp/dispatch.js +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/shell/agent-config.js +1 -1
- package/dist/shell/audit-cli.js +46 -2
- package/dist/shell/commit-summary.js +2 -1
- package/dist/shell/doctor.js +17 -4
- package/dist/shell/drive.js +47 -19
- package/dist/shell/evidence-reasoning.js +4 -3
- package/dist/shell/execution-backend/agent.js +42 -10
- package/dist/shell/execution-backend/ci.js +1 -1
- package/dist/shell/execution-backend/container.js +1 -1
- package/dist/shell/execution-backend/envelopes.js +1 -1
- package/dist/shell/execution-backend/local.js +1 -1
- package/dist/shell/execution-backend/probes.js +1 -1
- package/dist/shell/execution-backend/registry.js +3 -2
- package/dist/shell/execution-backend/remote.js +1 -1
- package/dist/shell/execution-backend/types.js +0 -9
- package/dist/shell/fs-atomic.js +15 -2
- package/dist/shell/ledger-io.js +1 -1
- package/dist/shell/metrics-cli.js +4 -2
- package/dist/shell/multi-agent-host.js +1 -1
- package/dist/shell/multi-agent-operator-ux.js +4 -3
- package/dist/shell/observability.js +12 -11
- package/dist/shell/onramp.js +17 -1
- package/dist/shell/operator-ux-text.js +2 -1
- package/dist/shell/operator-ux.js +7 -6
- package/dist/shell/pipeline-cli.js +82 -72
- package/dist/shell/reclamation-io.js +3 -2
- package/dist/shell/registry-cli.js +15 -0
- package/dist/shell/report.js +2 -1
- package/dist/shell/run-registry-io.js +1 -1
- package/dist/shell/run-store.js +17 -0
- package/dist/shell/sandbox-profile.js +1 -1
- package/dist/shell/scheduler-io.js +46 -37
- package/dist/shell/scheduling-io.js +32 -22
- package/dist/shell/state-explosion-cli.js +2 -1
- package/dist/shell/telemetry-ledger-io.js +1 -1
- package/dist/shell/term.js +1 -1
- package/dist/shell/topology-io.js +2 -1
- package/dist/shell/trust-audit.js +45 -5
- package/dist/shell/workbench-host.js +9 -1
- package/dist/shell/workbench.js +6 -11
- package/dist/shell/worker-cli.js +9 -1
- package/dist/shell/worker-isolation.js +34 -9
- package/dist/shell/workflow-app-loader.js +3 -2
- package/dist/wiring/capability-table/basics.js +66 -0
- package/dist/wiring/capability-table/exec-backend.js +162 -0
- package/dist/wiring/capability-table/index.js +42 -0
- package/dist/wiring/capability-table/multi-agent.js +623 -0
- package/dist/wiring/capability-table/parity.js +466 -0
- package/dist/wiring/capability-table/pipeline.js +280 -0
- package/dist/wiring/capability-table/registry-core.js +189 -0
- package/dist/wiring/capability-table/reporting.js +394 -0
- package/dist/wiring/capability-table/scheduling-registry.js +558 -0
- package/dist/wiring/capability-table/state.js +173 -0
- package/dist/wiring/capability-table/trust-ledger.js +134 -0
- package/dist/wiring/capability-table/workflow-apps.js +366 -0
- package/docs/agent-delegation-drive.7.md +4 -0
- package/docs/cli-mcp-parity.7.md +9 -2
- package/docs/contract-migration-tooling.7.md +4 -0
- package/docs/control-plane-scheduling.7.md +4 -0
- package/docs/durable-state-and-locking.7.md +24 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
- package/docs/execution-backends.7.md +4 -0
- package/docs/index.md +1 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
- package/docs/multi-agent-eval-replay-harness.7.md +4 -0
- package/docs/multi-agent-operator-ux.7.md +4 -0
- package/docs/node-snapshot-diff-replay.7.md +4 -0
- package/docs/observability-cost-accounting.7.md +6 -1
- package/docs/project-index.md +30 -5
- package/docs/real-execution-backends.7.md +4 -0
- package/docs/release-and-migration.7.md +4 -0
- package/docs/release-tooling.7.md +4 -0
- package/docs/remote-source-review.7.md +4 -4
- package/docs/report-verifiable-bundle.7.md +1 -1
- package/docs/run-registry-control-plane.7.md +4 -0
- package/docs/run-retention-reclamation.7.md +4 -0
- package/docs/security-trust-hardening.7.md +33 -1
- package/docs/state-explosion-management.7.md +4 -0
- package/docs/team-collaboration.7.md +4 -0
- package/docs/trust-audit-anchor.7.md +69 -0
- package/docs/web-desktop-workbench.7.md +15 -1
- package/manifest/plugin.manifest.json +1 -1
- package/package.json +3 -1
- package/scripts/agents/agent-adapter-core.js +22 -2
- package/scripts/agents/claude-p-agent.js +8 -3
- package/scripts/agents/gemini-agent.js +5 -1
- package/scripts/agents/opencode-agent.js +5 -1
- package/scripts/bump-version.js +24 -2
- package/scripts/canonical-apps.js +4 -4
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/purity-baseline.json +68 -0
- package/scripts/purity-gate.js +239 -0
- package/scripts/release-check.js +8 -1
- package/scripts/version-sync-check.js +33 -12
- package/workflows/README.md +19 -0
package/docs/project-index.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Cool Workflow Project Index
|
|
2
2
|
|
|
3
|
-
Generated from the current repository code on 2026-07-
|
|
3
|
+
Generated from the current repository code on 2026-07-08 by `npm run sync:project-index`.
|
|
4
4
|
|
|
5
5
|
## Snapshot
|
|
6
6
|
|
|
7
7
|
- Package: `cool-workflow`
|
|
8
|
-
- Version: `0.2.
|
|
9
|
-
- Source modules: `
|
|
8
|
+
- Version: `0.2.2`
|
|
9
|
+
- Source modules: `145`
|
|
10
10
|
- Workflow apps: `8`
|
|
11
|
-
- Docs: `
|
|
12
|
-
- Smoke tests: `
|
|
11
|
+
- Docs: `62`
|
|
12
|
+
- Smoke tests: `181`
|
|
13
13
|
- Repository: https://github.com/coo1white/cool-workflow
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
@@ -82,6 +82,7 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
82
82
|
- [cli/entry.ts](../src/cli/entry.ts)
|
|
83
83
|
- [cli/io.ts](../src/cli/io.ts)
|
|
84
84
|
- [cli/parseargv.ts](../src/cli/parseargv.ts)
|
|
85
|
+
- [core/capability-data.ts](../src/core/capability-data.ts)
|
|
85
86
|
- [core/capability-table.ts](../src/core/capability-table.ts)
|
|
86
87
|
- [core/format/help.ts](../src/core/format/help.ts)
|
|
87
88
|
- [core/format/state-explosion-text.ts](../src/core/format/state-explosion-text.ts)
|
|
@@ -113,6 +114,9 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
113
114
|
- [core/trust/telemetry-ledger.ts](../src/core/trust/telemetry-ledger.ts)
|
|
114
115
|
- [core/types.ts](../src/core/types.ts)
|
|
115
116
|
- [core/types/boundary.ts](../src/core/types/boundary.ts)
|
|
117
|
+
- [core/types/execution-backend.ts](../src/core/types/execution-backend.ts)
|
|
118
|
+
- [core/types/observability.ts](../src/core/types/observability.ts)
|
|
119
|
+
- [core/util/collate.ts](../src/core/util/collate.ts)
|
|
116
120
|
- [mcp/dispatch.ts](../src/mcp/dispatch.ts)
|
|
117
121
|
- [mcp/server.ts](../src/mcp/server.ts)
|
|
118
122
|
- [shell/agent-config.ts](../src/shell/agent-config.ts)
|
|
@@ -181,6 +185,18 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
181
185
|
- [shell/workbench-text.ts](../src/shell/workbench-text.ts)
|
|
182
186
|
- [shell/workbench.ts](../src/shell/workbench.ts)
|
|
183
187
|
- [shell/worker-cli.ts](../src/shell/worker-cli.ts)
|
|
188
|
+
- [wiring/capability-table/basics.ts](../src/wiring/capability-table/basics.ts)
|
|
189
|
+
- [wiring/capability-table/exec-backend.ts](../src/wiring/capability-table/exec-backend.ts)
|
|
190
|
+
- [wiring/capability-table/index.ts](../src/wiring/capability-table/index.ts)
|
|
191
|
+
- [wiring/capability-table/multi-agent.ts](../src/wiring/capability-table/multi-agent.ts)
|
|
192
|
+
- [wiring/capability-table/parity.ts](../src/wiring/capability-table/parity.ts)
|
|
193
|
+
- [wiring/capability-table/pipeline.ts](../src/wiring/capability-table/pipeline.ts)
|
|
194
|
+
- [wiring/capability-table/registry-core.ts](../src/wiring/capability-table/registry-core.ts)
|
|
195
|
+
- [wiring/capability-table/reporting.ts](../src/wiring/capability-table/reporting.ts)
|
|
196
|
+
- [wiring/capability-table/scheduling-registry.ts](../src/wiring/capability-table/scheduling-registry.ts)
|
|
197
|
+
- [wiring/capability-table/state.ts](../src/wiring/capability-table/state.ts)
|
|
198
|
+
- [wiring/capability-table/trust-ledger.ts](../src/wiring/capability-table/trust-ledger.ts)
|
|
199
|
+
- [wiring/capability-table/workflow-apps.ts](../src/wiring/capability-table/workflow-apps.ts)
|
|
184
200
|
|
|
185
201
|
## Workflow Apps
|
|
186
202
|
|
|
@@ -251,6 +267,7 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
251
267
|
- [State Explosion Management](state-explosion-management.7.md)
|
|
252
268
|
- [STATE-NODE(7)](state-node.7.md)
|
|
253
269
|
- [Team Collaboration](team-collaboration.7.md)
|
|
270
|
+
- [Trust Audit Anchor](trust-audit-anchor.7.md)
|
|
254
271
|
- [Trust Model & Limitations](trust-model.md)
|
|
255
272
|
- [Unix-Inspired Workflow Principles](unix-principles.md)
|
|
256
273
|
- [Vendor Manifest Loadability](vendor-manifest-loadability.7.md)
|
|
@@ -263,6 +280,8 @@ multi-agent host -> topology -> blackboard/coordinator
|
|
|
263
280
|
|
|
264
281
|
Smoke tests mirror the public contracts. The high-signal suites are:
|
|
265
282
|
|
|
283
|
+
- [agent-backend-concurrent-user-env-smoke.js](../test/agent-backend-concurrent-user-env-smoke.js)
|
|
284
|
+
- [agent-backend-user-env-smoke.js](../test/agent-backend-user-env-smoke.js)
|
|
266
285
|
- [agent-config-atomic-write-smoke.js](../test/agent-config-atomic-write-smoke.js)
|
|
267
286
|
- [agent-delegation-drive-smoke.js](../test/agent-delegation-drive-smoke.js)
|
|
268
287
|
- [agent-stream-gate-smoke.js](../test/agent-stream-gate-smoke.js)
|
|
@@ -270,6 +289,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
270
289
|
- [architecture-review-fast-automation-smoke.js](../test/architecture-review-fast-automation-smoke.js)
|
|
271
290
|
- [architecture-review-fast-phase-cache-smoke.js](../test/architecture-review-fast-phase-cache-smoke.js)
|
|
272
291
|
- [architecture-review-fast-smoke.js](../test/architecture-review-fast-smoke.js)
|
|
292
|
+
- [architecture-review-question-aware-smoke.js](../test/architecture-review-question-aware-smoke.js)
|
|
273
293
|
- [artifact-integrity-smoke.js](../test/artifact-integrity-smoke.js)
|
|
274
294
|
- [audit-verify-smoke.js](../test/audit-verify-smoke.js)
|
|
275
295
|
- [backend-registry-smoke.js](../test/backend-registry-smoke.js)
|
|
@@ -310,6 +330,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
310
330
|
- [deferred-checkpoint-batching-smoke.js](../test/deferred-checkpoint-batching-smoke.js)
|
|
311
331
|
- [demo-bundle-smoke.js](../test/demo-bundle-smoke.js)
|
|
312
332
|
- [det-ids-b-smoke.js](../test/det-ids-b-smoke.js)
|
|
333
|
+
- [dispatch-legacy-burndown-smoke.js](../test/dispatch-legacy-burndown-smoke.js)
|
|
313
334
|
- [doctor-smoke.js](../test/doctor-smoke.js)
|
|
314
335
|
- [dogfood-architecture-review-smoke.js](../test/dogfood-architecture-review-smoke.js)
|
|
315
336
|
- [dogfood-release-smoke.js](../test/dogfood-release-smoke.js)
|
|
@@ -339,6 +360,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
339
360
|
- [mcp-app-surface-smoke.js](../test/mcp-app-surface-smoke.js)
|
|
340
361
|
- [mcp-surface-registry-smoke.js](../test/mcp-surface-registry-smoke.js)
|
|
341
362
|
- [mcp-tool-call-coverage-smoke.js](../test/mcp-tool-call-coverage-smoke.js)
|
|
363
|
+
- [metrics-summary-limit-smoke.js](../test/metrics-summary-limit-smoke.js)
|
|
342
364
|
- [multi-agent-cli-mcp-surface-smoke.js](../test/multi-agent-cli-mcp-surface-smoke.js)
|
|
343
365
|
- [multi-agent-eval-determinism-regression-smoke.js](../test/multi-agent-eval-determinism-regression-smoke.js)
|
|
344
366
|
- [multi-agent-eval-replay-harness-smoke.js](../test/multi-agent-eval-replay-harness-smoke.js)
|
|
@@ -405,11 +427,13 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
405
427
|
- [run-restore-failclosed-smoke.js](../test/run-restore-failclosed-smoke.js)
|
|
406
428
|
- [run-resume-drive-smoke.js](../test/run-resume-drive-smoke.js)
|
|
407
429
|
- [run-retention-reclamation-smoke.js](../test/run-retention-reclamation-smoke.js)
|
|
430
|
+
- [run-state-lock-concurrency-smoke.js](../test/run-state-lock-concurrency-smoke.js)
|
|
408
431
|
- [sample-determinism-smoke.js](../test/sample-determinism-smoke.js)
|
|
409
432
|
- [sandbox-env-batch-hardening-smoke.js](../test/sandbox-env-batch-hardening-smoke.js)
|
|
410
433
|
- [sandbox-profile-smoke.js](../test/sandbox-profile-smoke.js)
|
|
411
434
|
- [sched-policy-validation-smoke.js](../test/sched-policy-validation-smoke.js)
|
|
412
435
|
- [schedule-routine-daemon-smoke.js](../test/schedule-routine-daemon-smoke.js)
|
|
436
|
+
- [scheduling-routine-lock-concurrency-smoke.js](../test/scheduling-routine-lock-concurrency-smoke.js)
|
|
413
437
|
- [schema-validation-smoke.js](../test/schema-validation-smoke.js)
|
|
414
438
|
- [security-trust-hardening-smoke.js](../test/security-trust-hardening-smoke.js)
|
|
415
439
|
- [self-audit-hardening-smoke.js](../test/self-audit-hardening-smoke.js)
|
|
@@ -427,6 +451,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
|
|
|
427
451
|
- [telemetry-metrics-coverage-smoke.js](../test/telemetry-metrics-coverage-smoke.js)
|
|
428
452
|
- [telemetry-verify-signatures-smoke.js](../test/telemetry-verify-signatures-smoke.js)
|
|
429
453
|
- [token-budget-enforcement-smoke.js](../test/token-budget-enforcement-smoke.js)
|
|
454
|
+
- [trust-audit-anchor-smoke.js](../test/trust-audit-anchor-smoke.js)
|
|
430
455
|
- [vendor-manifest-load-smoke.js](../test/vendor-manifest-load-smoke.js)
|
|
431
456
|
- [vendor-preflight-smoke.js](../test/vendor-preflight-smoke.js)
|
|
432
457
|
- [verifier-gated-commit-smoke.js](../test/verifier-gated-commit-smoke.js)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Remote-Source Review (`--link`)
|
|
2
2
|
|
|
3
3
|
CW v0.1.91 lets you point a review at **any repository on the internet** instead
|
|
4
|
-
of only a local path: `cw -q "
|
|
4
|
+
of only a local path: `cw -q "how does this work?" --link <url>`. CW materializes
|
|
5
5
|
the remote into a local checkout and runs the **existing** review pipeline against
|
|
6
6
|
it — identical downstream to reviewing a folder. A URL passed to `-dir`/`--repo`
|
|
7
7
|
is auto-detected, so `--link <url>` and `-dir <url>` are equivalent.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
cw -q "
|
|
11
|
-
cw -q "What are the risks?" --link git@gitlab.com:owner/repo.git --ref v1.2.0
|
|
12
|
-
cw -q "
|
|
10
|
+
cw -q "How does auth work end-to-end here?" --link https://github.com/owner/repo
|
|
11
|
+
cw -q "What are the security risks?" --link git@gitlab.com:owner/repo.git --ref v1.2.0
|
|
12
|
+
cw -q "Is it safe to swap this queue for Redis?" --link https://github.com/owner/repo/archive/refs/heads/main.tar.gz
|
|
13
13
|
cw -q "..." --link <url> --check # validate the URL + tooling WITHOUT fetching
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -127,7 +127,7 @@ npx cool-workflow demo bundle
|
|
|
127
127
|
# catching both offline with only the embedded public key.
|
|
128
128
|
|
|
129
129
|
# Run the review AND get a shippable, client-verifiable bundle from ONE command:
|
|
130
|
-
cw quickstart architecture-review --repo . --question "
|
|
130
|
+
cw quickstart architecture-review --repo . --question "How does auth work end-to-end here?" \
|
|
131
131
|
--agent-command "claude -p" --bundle --with-trust-key ./trust-pub.pem
|
|
132
132
|
# -> after the drive COMPLETES, the run is sealed into a self-verified bundle and
|
|
133
133
|
# the verdict is folded into the quickstart JSON (result.bundle). Exits non-zero
|
|
@@ -37,7 +37,9 @@ Event sources are clear:
|
|
|
37
37
|
- `runtime-derived`: CW got the event from run state.
|
|
38
38
|
|
|
39
39
|
CW does not keep secrets or raw environment values. Environment audit records
|
|
40
|
-
keep names only.
|
|
40
|
+
keep names only — for example, `worker.agent-env` records which provider-namespace
|
|
41
|
+
env var NAMES (`CW_`, `ANTHROPIC_`, `OPENAI_`, and similar) were forwarded from
|
|
42
|
+
the host process to a delegated agent child, queryable via `cw audit summary`/`cw audit`.
|
|
41
43
|
|
|
42
44
|
## Enforcement Boundary
|
|
43
45
|
|
|
@@ -49,6 +51,34 @@ The agent host must still make certain of OS-level read isolation, write isolati
|
|
|
49
51
|
limits on process execution, limits on network, and environment filtering.
|
|
50
52
|
The audit layer lets you look at that boundary; it is not a kernel.
|
|
51
53
|
|
|
54
|
+
## Requiring Attested Telemetry
|
|
55
|
+
|
|
56
|
+
`CW_REQUIRE_ATTESTED_TELEMETRY=1` (or `--require-attested-telemetry`, or a
|
|
57
|
+
durable `agent-config.json` field) is an opt-in, off-by-default gate: once
|
|
58
|
+
on, CW refuses to accept ANY worker result whose usage telemetry is not
|
|
59
|
+
cryptographically `attested` — a delegated hop whose signature does not
|
|
60
|
+
verify, and now also a MANUAL accept (`cw worker output`, `cw result`) that
|
|
61
|
+
carries no delegation telemetry at all. The manual shape used to slip past
|
|
62
|
+
the gate silently; it is now blocked the same way, with its own code
|
|
63
|
+
(`telemetry-missing-blocked`, distinct from a present-but-unverified hop's
|
|
64
|
+
`telemetry-unattested-blocked`).
|
|
65
|
+
|
|
66
|
+
An operator who genuinely needs to accept an unattested manual result under
|
|
67
|
+
the require flag passes `--allow-unattested` (MCP: `allowUnattested`). This
|
|
68
|
+
is never silent: it writes a `telemetry.gate-override` trust-audit event
|
|
69
|
+
(`decision: "allowed"`, `source: "operator"`) into the same hash-chained log
|
|
70
|
+
every other audit decision goes through, so the override itself is part of
|
|
71
|
+
the auditable record, not a hole in it.
|
|
72
|
+
|
|
73
|
+
A result-cache hit (the drive loop replaying a previously accepted result) is
|
|
74
|
+
never re-blocked by this gate — the underlying result was already gated (or
|
|
75
|
+
overridden) at its first acceptance. When the require flag is on, a cache
|
|
76
|
+
accept still records a `telemetry.cache-accept` event, so the audit trail
|
|
77
|
+
shows which accepts came from a fresh hop and which from the cache.
|
|
78
|
+
|
|
79
|
+
With the require flag off (the default), none of this changes: a plain
|
|
80
|
+
`cw worker output` / `cw result` behaves exactly as before.
|
|
81
|
+
|
|
52
82
|
## CLI
|
|
53
83
|
|
|
54
84
|
```bash
|
|
@@ -65,6 +95,8 @@ node scripts/cw.js audit decision <run-id> <worker-id> --path <path>
|
|
|
65
95
|
node scripts/cw.js audit decision <run-id> <worker-id> --command "npm test"
|
|
66
96
|
node scripts/cw.js audit decision <run-id> <worker-id> --network example.com
|
|
67
97
|
node scripts/cw.js audit decision <run-id> <worker-id> --env SECRET_NAME
|
|
98
|
+
node scripts/cw.js worker output <run-id> <worker-id> <result-file> [--allow-unattested]
|
|
99
|
+
node scripts/cw.js result <run-id> <task-id> <result-file> [--allow-unattested]
|
|
68
100
|
```
|
|
69
101
|
|
|
70
102
|
Denied audit decisions are put into audit files and joined to feedback/error
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Trust Audit Anchor
|
|
2
|
+
|
|
3
|
+
CW v0.2.1 adds the Trust Audit Anchor: a way to see when the END of a run's
|
|
4
|
+
trust-audit log was cut off. The hash chain in `audit/events.jsonl` lets
|
|
5
|
+
`cw audit verify` see an edited event, a removed middle event, a bad line, and
|
|
6
|
+
a mixed-era forgery. But one tamper shape gets past a pure chain walk: take
|
|
7
|
+
the last N lines off the file, and what is left is a shorter but fully
|
|
8
|
+
consistent chain — verify stays green. The anchor closes that hole, and it
|
|
9
|
+
does so without changing any old output byte.
|
|
10
|
+
|
|
11
|
+
## Design Discipline
|
|
12
|
+
|
|
13
|
+
- Mechanism, not policy: the kernel gives you two small parts — a read of the
|
|
14
|
+
chain head, and a check against a head you saved earlier. WHEN you save a
|
|
15
|
+
head (after a run, before you publish, at export time) is your policy.
|
|
16
|
+
- Fail-closed: a saved head that is not on the chain, or an event count that
|
|
17
|
+
comes up short, makes verify exit non-zero with the distinct check code
|
|
18
|
+
`trust-audit-truncated`. A bad `--expect-head` / `--expect-count` value is
|
|
19
|
+
an error, never a check silently made weaker.
|
|
20
|
+
- POLA: with no anchor flags, `cw audit verify` output is byte-for-byte what
|
|
21
|
+
it was before this feature (no `anchor` key, same checks, same exit rules).
|
|
22
|
+
- Reuse: the anchor rides on the existing eventHash chain — no new file, no
|
|
23
|
+
new state, no new hash form. `cw audit head` is a read-only projection.
|
|
24
|
+
- Parity: `audit.head` is on both front doors (`cw audit head` and the MCP
|
|
25
|
+
tool `cw_audit_head`); the anchor args are on both `cw audit verify` and
|
|
26
|
+
`cw_audit_verify` (`expectHead` / `expectCount`).
|
|
27
|
+
|
|
28
|
+
## CLI
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
node dist/cli.js audit head <run-id>
|
|
32
|
+
# -> { "schemaVersion": 1, "runId": "...", "eventCount": 87,
|
|
33
|
+
# "headHash": "sha256:..." }
|
|
34
|
+
|
|
35
|
+
node dist/cli.js audit verify <run-id> --expect-head <hash> --expect-count <n>
|
|
36
|
+
# green: verified true, "anchor": { ..., "satisfied": true }, exit 0
|
|
37
|
+
# cut tail: verified false, checks carry trust-audit-truncated, exit 1
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The head is the hash the NEXT appended event will link from: the last event's
|
|
41
|
+
`eventHash`, or the run's genesis hash when the log is empty. Save the pair
|
|
42
|
+
`{headHash, eventCount}` somewhere the log's writer cannot reach — a CI
|
|
43
|
+
variable, a note in your PR, the output of `cw run export` (the export
|
|
44
|
+
manifest hashes the event log bytes, so an export IS an anchor in file form).
|
|
45
|
+
|
|
46
|
+
## How the check works
|
|
47
|
+
|
|
48
|
+
`verifyTrustAudit` walks the chain as before, and keeps the trail of head
|
|
49
|
+
hashes it saw (genesis, then the hash after each event). With an anchor:
|
|
50
|
+
|
|
51
|
+
- `expectCount`: the walked log must have at least that many events. Fewer =
|
|
52
|
+
`trust-audit-truncated` (check name `anchor-count`).
|
|
53
|
+
- `expectHead`: the saved head must be ON the trail. A log that was cut and
|
|
54
|
+
then padded back with new events reaches the old count, but the new events
|
|
55
|
+
link from an earlier point — the old head is no longer on the trail, so
|
|
56
|
+
this still fails (check name `anchor-head`).
|
|
57
|
+
|
|
58
|
+
## Compatibility
|
|
59
|
+
|
|
60
|
+
Trust Audit Anchor is introduced in CW v0.2.1. Fields are additive and
|
|
61
|
+
optional; older run state loads unchanged. A plain `cw audit verify` keeps
|
|
62
|
+
its exact old output. The `anchor` key appears in the JSON only when the
|
|
63
|
+
caller passed an anchor flag.
|
|
64
|
+
|
|
65
|
+
## See Also
|
|
66
|
+
|
|
67
|
+
security-trust-hardening(7), cli-mcp-parity(7), report-verifiable-bundle(7)
|
|
68
|
+
|
|
69
|
+
0.2.2
|
|
@@ -96,11 +96,21 @@ The console is read-only. It offers no actions. If a later release adds an actio
|
|
|
96
96
|
capability core entry that already exists — never a side code path — so it cannot drift from the
|
|
97
97
|
CLI/MCP and is covered by the parity gate.
|
|
98
98
|
|
|
99
|
+
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>`
|
|
101
|
+
(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
|
|
103
|
+
`--require-token` to `cw workbench serve` to fail closed instead: the server
|
|
104
|
+
refuses to start at all unless `CW_WORKBENCH_TOKEN` is already set. This is a
|
|
105
|
+
strict opt-in — leaving it off keeps today's default behavior unchanged.
|
|
106
|
+
(`--require-token` has no effect on `cw_workbench_serve`'s MCP path, which
|
|
107
|
+
never actually binds a listener.)
|
|
108
|
+
|
|
99
109
|
## Surfaces
|
|
100
110
|
|
|
101
111
|
```
|
|
102
112
|
cw workbench view <run-id> [--json] # five-panel WorkbenchRunView for one run
|
|
103
|
-
cw workbench serve [--port N] [--scope repo|home] [--once|--json]
|
|
113
|
+
cw workbench serve [--port N] [--scope repo|home] [--once|--json] [--require-token]
|
|
104
114
|
```
|
|
105
115
|
|
|
106
116
|
`cw workbench serve` with `--once`/`--json` prints the serve descriptor (bind
|
|
@@ -264,3 +274,7 @@ _No behavioral change in v0.1.89 (CLI-surface golden-path + help-output fixes on
|
|
|
264
274
|
0.1.98
|
|
265
275
|
|
|
266
276
|
0.2.0
|
|
277
|
+
|
|
278
|
+
0.2.1
|
|
279
|
+
|
|
280
|
+
0.2.2
|
|
@@ -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.
|
|
5
|
+
"version": "0.2.2",
|
|
6
6
|
"license": "BSD-2-Clause",
|
|
7
7
|
"homepage": "https://github.com/coo1white/cool-workflow",
|
|
8
8
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cool-workflow",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"bin": {
|
|
5
5
|
"cool-workflow": "scripts/cw.js",
|
|
6
6
|
"cw": "scripts/cw.js"
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"build": "tsc -p tsconfig.json",
|
|
44
44
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
45
45
|
"dist:check": "node scripts/dist-drift-check.js",
|
|
46
|
+
"purity:check": "node scripts/purity-gate.js",
|
|
46
47
|
"golden-path": "node scripts/golden-path.js",
|
|
47
48
|
"dogfood:release": "node scripts/dogfood-release.js",
|
|
48
49
|
"canonical-apps": "node scripts/canonical-apps.js",
|
|
@@ -68,6 +69,7 @@
|
|
|
68
69
|
"test:fast": "npm run build --if-present && node dist/cli.js version > /dev/null && node test/run-all.js --concurrency auto",
|
|
69
70
|
"test:ci": "npm run build && node dist/cli.js version > /dev/null && node test/run-all.js --sample 55",
|
|
70
71
|
"test:coverage": "node dist/cli.js version > /dev/null && node scripts/coverage-gate.js --concurrency auto",
|
|
72
|
+
"test:unit": "node dist/cli.js version > /dev/null && node test/run-unit.js",
|
|
71
73
|
"eval:replay": "tsc -p tsconfig.json && node test/multi-agent-eval-replay-harness-smoke.js",
|
|
72
74
|
"ci": "npm run build && npm run check && npm run test && npm run release:check",
|
|
73
75
|
"validate:schema": "node scripts/validate-run-state-schema.js"
|
|
@@ -18,7 +18,7 @@ cw:result block that EXACTLY follows this schema:
|
|
|
18
18
|
"findings": [
|
|
19
19
|
{
|
|
20
20
|
"id": "unique-kebab-id",
|
|
21
|
-
"title": "short
|
|
21
|
+
"title": "short finding title",
|
|
22
22
|
"severity": "P0",
|
|
23
23
|
"classification": "real",
|
|
24
24
|
"evidence": ["path/to/file.ts:42"]
|
|
@@ -471,6 +471,25 @@ function persistStderr(resultPath, text) {
|
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
+
// Build the failure-path diagnostic string for a non-zero exit. Real OS-level
|
|
475
|
+
// stderr wins when present (the common case: a crash, a killed process, a
|
|
476
|
+
// vendor CLI that DOES write to stderr) — byte-identical to before this
|
|
477
|
+
// helper existed. When stderr is EMPTY, fall back to whatever partial/
|
|
478
|
+
// structured text the wrapper already parsed from stdout before the child
|
|
479
|
+
// died (a stream-json `result` event with is_error:true is how claude
|
|
480
|
+
// reports terminal errors like an auth failure — that text was being parsed
|
|
481
|
+
// and then silently thrown away). If there is no partial text either, say so
|
|
482
|
+
// plainly instead of just repeating the bare exit code. Never throws; always
|
|
483
|
+
// returns a non-empty string.
|
|
484
|
+
function buildFailureDetail({ label, code, childStderr, partialText }) {
|
|
485
|
+
const stderrText = String(childStderr || "").trim();
|
|
486
|
+
if (stderrText) return stderrText;
|
|
487
|
+
const partial = String(partialText || "").trim();
|
|
488
|
+
const codeText = `${label} exited ${code === null ? "(timeout/killed)" : code}`;
|
|
489
|
+
if (partial) return `${codeText} — ${label} stdout (no stderr) said: ${partial}`;
|
|
490
|
+
return codeText;
|
|
491
|
+
}
|
|
492
|
+
|
|
474
493
|
module.exports = {
|
|
475
494
|
RESULT_CONTRACT,
|
|
476
495
|
buildPrompt,
|
|
@@ -485,5 +504,6 @@ module.exports = {
|
|
|
485
504
|
flushJsonLines,
|
|
486
505
|
writeResult,
|
|
487
506
|
emitReport,
|
|
488
|
-
persistStderr // save a failed agent's stderr to <workerDir>/logs/agent-stderr.log (shared by all wrappers)
|
|
507
|
+
persistStderr, // save a failed agent's stderr to <workerDir>/logs/agent-stderr.log (shared by all wrappers)
|
|
508
|
+
buildFailureDetail // fold in parsed partial stdout text when real stderr is empty (shared by all wrappers)
|
|
489
509
|
};
|
|
@@ -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 } = require("./agent-adapter-core");
|
|
37
|
+
const { buildPrompt, createRenderer, persistStderr, toolLabel, summarizeToolResult, buildFailureDetail } = require("./agent-adapter-core");
|
|
38
38
|
|
|
39
39
|
const inputPath = process.argv[2];
|
|
40
40
|
const resultPath = process.argv[3];
|
|
@@ -179,9 +179,14 @@ child.on("close", (code) => {
|
|
|
179
179
|
render.finishLive(); // stop the spinner + restore the cursor BEFORE any further output
|
|
180
180
|
render.writeTranscript(transcriptPath); // full narration + tool I/O always saved
|
|
181
181
|
if (code !== 0) {
|
|
182
|
-
const
|
|
182
|
+
const stderrText = childStderr.trim();
|
|
183
|
+
// childStderr is the OS-level stream; claude's real failure reason (auth,
|
|
184
|
+
// rate limit, relay error) is often reported as a stream-json `result`
|
|
185
|
+
// event on STDOUT instead, already parsed into `resultText` above — fold
|
|
186
|
+
// it in here so a silent-stderr failure still leaves a readable reason.
|
|
187
|
+
const detail = buildFailureDetail({ label: "claude", code, childStderr: stderrText, partialText: resultText });
|
|
183
188
|
persistStderr(resultPath, detail);
|
|
184
|
-
if (
|
|
189
|
+
if (stderrText) process.stderr.write(`${stderrText}\n`);
|
|
185
190
|
process.stderr.write(`claude exited ${code === null ? "(timeout/killed)" : code}\n`);
|
|
186
191
|
process.exit(code === null ? 1 : code);
|
|
187
192
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
const path = require("node:path");
|
|
18
18
|
const { spawn } = require("node:child_process");
|
|
19
19
|
const {
|
|
20
|
+
buildFailureDetail,
|
|
20
21
|
buildPrompt,
|
|
21
22
|
createRenderer,
|
|
22
23
|
emitReport,
|
|
@@ -94,7 +95,10 @@ child.on("close", (code) => {
|
|
|
94
95
|
render.finishLive();
|
|
95
96
|
render.writeTranscript(transcriptPath);
|
|
96
97
|
if (code !== 0) {
|
|
97
|
-
|
|
98
|
+
// gemini's real failure reason is often only in the NDJSON text/result
|
|
99
|
+
// fragments already parsed into `state`, not in raw OS-level stderr.
|
|
100
|
+
const partial = state.finalResult || state.textFragments.join("\n\n");
|
|
101
|
+
const detail = buildFailureDetail({ label: "gemini", code, childStderr: childStderr.trim(), partialText: partial });
|
|
98
102
|
persistStderr(resultPath, detail);
|
|
99
103
|
process.stderr.write(`${detail}\n`);
|
|
100
104
|
process.exit(code === null ? 1 : code);
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
const path = require("node:path");
|
|
23
23
|
const { spawn } = require("node:child_process");
|
|
24
24
|
const {
|
|
25
|
+
buildFailureDetail,
|
|
25
26
|
buildPrompt,
|
|
26
27
|
createRenderer,
|
|
27
28
|
emitReport,
|
|
@@ -147,7 +148,10 @@ child.on("close", (code) => {
|
|
|
147
148
|
render.finishLive();
|
|
148
149
|
render.writeTranscript(transcriptPath);
|
|
149
150
|
if (code !== 0) {
|
|
150
|
-
|
|
151
|
+
// opencode's real failure reason is often only in the JSONL text/result
|
|
152
|
+
// fragments already parsed into `state`, not in raw OS-level stderr.
|
|
153
|
+
const partial = state.finalResult || state.lastMessageText || state.textFragments.join("\n\n");
|
|
154
|
+
const detail = buildFailureDetail({ label: "opencode", code, childStderr: childStderr.trim(), partialText: partial });
|
|
151
155
|
persistStderr(resultPath, detail);
|
|
152
156
|
process.stderr.write(`${detail}\n`);
|
|
153
157
|
process.exit(code === null ? 1 : code);
|
package/scripts/bump-version.js
CHANGED
|
@@ -46,6 +46,23 @@ function replaceFirstVersionField(absPath, next) {
|
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
function replaceLockfileVersions(absPath, next) {
|
|
50
|
+
// Move BOTH lockfile version fields with targeted string swaps, so the byte
|
|
51
|
+
// formatting npm wrote is kept as it is: the top-level "version" (the first
|
|
52
|
+
// one in the file) and the root-package entry `"": { "name": ..., "version": ... }`.
|
|
53
|
+
// Dependency entries are not touched — the second swap is keyed on the
|
|
54
|
+
// `"": {` root-package opening, which is present only once.
|
|
55
|
+
const text = fs.readFileSync(absPath, "utf8");
|
|
56
|
+
let updated = text.replace(/"version":\s*"[^"]*"/, `"version": "${next}"`);
|
|
57
|
+
updated = updated.replace(
|
|
58
|
+
/("":\s*\{\s*"name":\s*"[^"]*",\s*"version":\s*)"[^"]*"/,
|
|
59
|
+
`$1"${next}"`
|
|
60
|
+
);
|
|
61
|
+
if (updated === text) return false;
|
|
62
|
+
fs.writeFileSync(absPath, updated);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
49
66
|
function setNestedVersion(absPath, next) {
|
|
50
67
|
// For files where the first `"version"` is NOT the right one, parse + set.
|
|
51
68
|
const json = JSON.parse(fs.readFileSync(absPath, "utf8"));
|
|
@@ -75,9 +92,13 @@ function main() {
|
|
|
75
92
|
// 1. package.json (the single source of truth version:sync now reads from)
|
|
76
93
|
if (replaceFirstVersionField(path.join(pluginRoot, "package.json"), next)) note("package.json");
|
|
77
94
|
|
|
78
|
-
// 2. package-lock.json (
|
|
95
|
+
// 2. package-lock.json (tracked; only if present). The lockfile keeps the
|
|
96
|
+
// version in TWO places: the top-level "version" and the root-package
|
|
97
|
+
// entry packages[""].version. The old code moved only the first one, so
|
|
98
|
+
// the root-package entry kept an old version till the next `npm install`
|
|
99
|
+
// (the v0.1.97 drift seen after the v0.2.0/v0.2.1 cuts). Move both here.
|
|
79
100
|
const lock = path.join(pluginRoot, "package-lock.json");
|
|
80
|
-
if (fs.existsSync(lock) &&
|
|
101
|
+
if (fs.existsSync(lock) && replaceLockfileVersions(lock, next)) note("package-lock.json");
|
|
81
102
|
|
|
82
103
|
// 2b. Official MCP Registry server metadata (top-level server version + npm package version).
|
|
83
104
|
const serverJson = path.join(pluginRoot, "server.json");
|
|
@@ -218,6 +239,7 @@ function contentSurfaceFiles(next) {
|
|
|
218
239
|
{ path: "plugins/cool-workflow/docs/run-retention-reclamation.7.md", needle: next, desc: "run retention doc" },
|
|
219
240
|
{ path: "plugins/cool-workflow/docs/durable-state-and-locking.7.md", needle: next, desc: "durable state doc" },
|
|
220
241
|
{ path: "plugins/cool-workflow/docs/release-and-migration.7.md", needle: next, desc: "release & migration doc" },
|
|
242
|
+
{ path: "plugins/cool-workflow/docs/trust-audit-anchor.7.md", needle: next, desc: "trust audit anchor doc" },
|
|
221
243
|
];
|
|
222
244
|
}
|
|
223
245
|
|
|
@@ -83,7 +83,7 @@ const canonicalApps = [
|
|
|
83
83
|
"--source",
|
|
84
84
|
"plugins/cool-workflow/docs/workflow-app-framework.7.md",
|
|
85
85
|
"--scope",
|
|
86
|
-
"Cool Workflow v0.2.
|
|
86
|
+
"Cool Workflow v0.2.2",
|
|
87
87
|
"--freshness",
|
|
88
88
|
"as of release preparation"
|
|
89
89
|
]
|
|
@@ -117,14 +117,14 @@ function main() {
|
|
|
117
117
|
assert.ok(summary, `${app.id} must appear in app list`);
|
|
118
118
|
assert.equal(summary.sourceKind, "app-directory");
|
|
119
119
|
assert.equal(summary.legacy, false);
|
|
120
|
-
assert.equal(summary.version, "0.2.
|
|
120
|
+
assert.equal(summary.version, "0.2.2");
|
|
121
121
|
|
|
122
122
|
const validation = runJson(["app", "validate", manifestPath]);
|
|
123
123
|
assert.equal(validation.valid, true, `${app.id} manifest must validate`);
|
|
124
124
|
|
|
125
125
|
const shown = runJson(["app", "show", app.id]);
|
|
126
126
|
assert.equal(shown.app.id, app.id);
|
|
127
|
-
assert.equal(shown.app.version, "0.2.
|
|
127
|
+
assert.equal(shown.app.version, "0.2.2");
|
|
128
128
|
assert.ok(shown.app.metadata.canonical, `${app.id} must be marked canonical`);
|
|
129
129
|
assert.ok(shown.app.sandboxProfiles.length > 0, `${app.id} must declare sandbox profiles`);
|
|
130
130
|
assertTaskIdsUnique(shown);
|
|
@@ -135,7 +135,7 @@ function main() {
|
|
|
135
135
|
const plan = runJson(["plan", app.id, ...app.args(workspace)]);
|
|
136
136
|
const state = JSON.parse(fs.readFileSync(plan.statePath, "utf8"));
|
|
137
137
|
assert.equal(state.workflow.app.id, app.id);
|
|
138
|
-
assert.equal(state.workflow.app.version, "0.2.
|
|
138
|
+
assert.equal(state.workflow.app.version, "0.2.2");
|
|
139
139
|
assert.equal(state.workflow.app.metadata.canonical, true);
|
|
140
140
|
assert.ok(state.tasks.some((task) => task.requiresEvidence), `${app.id} plan must include evidence gates`);
|
|
141
141
|
assert.ok(state.tasks.every((task) => task.sandboxProfileId), `${app.id} plan must include sandbox hints`);
|
|
@@ -6,7 +6,7 @@ const fs = require("node:fs");
|
|
|
6
6
|
const path = require("node:path");
|
|
7
7
|
const { CoolWorkflowRunner } = require("../dist/shell/orchestrator.js");
|
|
8
8
|
|
|
9
|
-
const TARGET_VERSION = "0.2.
|
|
9
|
+
const TARGET_VERSION = "0.2.2";
|
|
10
10
|
const PREVIOUS_VERSION = "0.1.31";
|
|
11
11
|
const pluginRoot = path.resolve(__dirname, "..");
|
|
12
12
|
const repoRoot = path.resolve(pluginRoot, "..", "..");
|
package/scripts/golden-path.js
CHANGED
|
@@ -33,7 +33,7 @@ function main() {
|
|
|
33
33
|
const appValidation = runJson(["app", "validate", "end-to-end-golden-path"], pluginRoot);
|
|
34
34
|
assert.equal(appValidation.valid, true);
|
|
35
35
|
assert.equal(appValidation.summary.id, "end-to-end-golden-path");
|
|
36
|
-
assert.equal(appValidation.summary.version, "0.2.
|
|
36
|
+
assert.equal(appValidation.summary.version, "0.2.2");
|
|
37
37
|
|
|
38
38
|
const plan = runJson(
|
|
39
39
|
[
|
|
@@ -42,7 +42,7 @@ function main() {
|
|
|
42
42
|
"--repo",
|
|
43
43
|
tmp,
|
|
44
44
|
"--question",
|
|
45
|
-
"Prove the deterministic v0.2.
|
|
45
|
+
"Prove the deterministic v0.2.2 end-to-end golden path."
|
|
46
46
|
],
|
|
47
47
|
pluginRoot
|
|
48
48
|
);
|
|
@@ -52,7 +52,7 @@ function main() {
|
|
|
52
52
|
|
|
53
53
|
let state = readJson(plan.statePath);
|
|
54
54
|
assert.equal(state.workflow.app.id, "end-to-end-golden-path");
|
|
55
|
-
assert.equal(state.workflow.app.version, "0.2.
|
|
55
|
+
assert.equal(state.workflow.app.version, "0.2.2");
|
|
56
56
|
assert.equal(state.loopStage, "interpret");
|
|
57
57
|
|
|
58
58
|
const dispatch = runJson(["dispatch", plan.runId, "--limit", "1", "--sandbox", "readonly"], tmp);
|
|
@@ -195,7 +195,7 @@ function main() {
|
|
|
195
195
|
assert.equal(reportPath, plan.reportPath);
|
|
196
196
|
assert.ok(fs.existsSync(reportPath));
|
|
197
197
|
const report = fs.readFileSync(reportPath, "utf8");
|
|
198
|
-
assert.match(report, /Workflow App: end-to-end-golden-path@0\.2\.
|
|
198
|
+
assert.match(report, /Workflow App: end-to-end-golden-path@0\.2\.2/);
|
|
199
199
|
assert.match(report, /## Candidates/);
|
|
200
200
|
assert.match(report, /## Trust Audit/);
|
|
201
201
|
assert.match(report, /## Acceptance Rationale/);
|