cool-workflow 0.1.78
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 +20 -0
- package/.codex-plugin/mcp.json +10 -0
- package/.codex-plugin/plugin.json +38 -0
- package/.mcp.json +10 -0
- package/LICENSE +24 -0
- package/README.md +638 -0
- package/apps/architecture-review/app.json +51 -0
- package/apps/architecture-review/workflow.js +116 -0
- package/apps/end-to-end-golden-path/app.json +30 -0
- package/apps/end-to-end-golden-path/workflow.js +33 -0
- package/apps/pr-review-fix-ci/app.json +59 -0
- package/apps/pr-review-fix-ci/workflow.js +90 -0
- package/apps/release-cut/app.json +54 -0
- package/apps/release-cut/workflow.js +82 -0
- package/apps/research-synthesis/app.json +50 -0
- package/apps/research-synthesis/workflow.js +76 -0
- package/apps/workflow-app-framework-demo/app.json +29 -0
- package/apps/workflow-app-framework-demo/workflow.js +44 -0
- package/dist/agent-config.js +223 -0
- package/dist/candidate-scoring.js +715 -0
- package/dist/capability-core.js +630 -0
- package/dist/capability-dispatcher.js +86 -0
- package/dist/capability-registry.js +523 -0
- package/dist/cli.js +1276 -0
- package/dist/collaboration.js +727 -0
- package/dist/commit.js +570 -0
- package/dist/contract-migration.js +234 -0
- package/dist/coordinator.js +1163 -0
- package/dist/daemon.js +44 -0
- package/dist/dispatch.js +201 -0
- package/dist/drive.js +503 -0
- package/dist/error-feedback.js +415 -0
- package/dist/evidence-grounding.js +179 -0
- package/dist/evidence-reasoning.js +733 -0
- package/dist/execution-backend.js +1279 -0
- package/dist/harness.js +61 -0
- package/dist/mcp-server.js +1615 -0
- package/dist/multi-agent-eval.js +857 -0
- package/dist/multi-agent-host.js +764 -0
- package/dist/multi-agent-operator-ux.js +537 -0
- package/dist/multi-agent-trust.js +366 -0
- package/dist/multi-agent.js +1173 -0
- package/dist/node-snapshot.js +270 -0
- package/dist/observability.js +922 -0
- package/dist/operator-ux.js +971 -0
- package/dist/orchestrator/audit-operations.js +182 -0
- package/dist/orchestrator/candidate-operations.js +117 -0
- package/dist/orchestrator/cli-options.js +288 -0
- package/dist/orchestrator/collaboration-operations.js +86 -0
- package/dist/orchestrator/feedback-operations.js +81 -0
- package/dist/orchestrator/host-operations.js +78 -0
- package/dist/orchestrator/lifecycle-operations.js +462 -0
- package/dist/orchestrator/migration-operations.js +44 -0
- package/dist/orchestrator/multi-agent-operations.js +362 -0
- package/dist/orchestrator/report.js +369 -0
- package/dist/orchestrator/topology-operations.js +84 -0
- package/dist/orchestrator.js +874 -0
- package/dist/pipeline-contract.js +92 -0
- package/dist/pipeline-runner.js +285 -0
- package/dist/reclamation.js +882 -0
- package/dist/result-normalize.js +194 -0
- package/dist/run-export.js +64 -0
- package/dist/run-registry.js +1347 -0
- package/dist/run-state-schema.js +67 -0
- package/dist/sandbox-profile.js +471 -0
- package/dist/scheduler.js +266 -0
- package/dist/scheduling.js +184 -0
- package/dist/schema-validate.js +98 -0
- package/dist/state-explosion.js +1213 -0
- package/dist/state-migrations.js +463 -0
- package/dist/state-node.js +301 -0
- package/dist/state.js +308 -0
- package/dist/telemetry-attestation.js +156 -0
- package/dist/telemetry-ledger.js +145 -0
- package/dist/topology.js +527 -0
- package/dist/triggers.js +159 -0
- package/dist/trust-audit.js +475 -0
- package/dist/types/blackboard.js +2 -0
- package/dist/types/boundary.js +29 -0
- package/dist/types/candidate.js +2 -0
- package/dist/types/collaboration.js +2 -0
- package/dist/types/core.js +2 -0
- package/dist/types/drive.js +10 -0
- package/dist/types/error-feedback.js +2 -0
- package/dist/types/evidence-reasoning.js +2 -0
- package/dist/types/execution-backend.js +2 -0
- package/dist/types/multi-agent.js +2 -0
- package/dist/types/observability.js +2 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/reclamation.js +8 -0
- package/dist/types/result.js +2 -0
- package/dist/types/run-registry.js +2 -0
- package/dist/types/run.js +2 -0
- package/dist/types/sandbox.js +2 -0
- package/dist/types/schedule.js +2 -0
- package/dist/types/state-node.js +2 -0
- package/dist/types/topology.js +2 -0
- package/dist/types/trust.js +2 -0
- package/dist/types/workbench.js +2 -0
- package/dist/types/worker.js +2 -0
- package/dist/types/workflow-app.js +2 -0
- package/dist/types.js +43 -0
- package/dist/verifier-registry.js +46 -0
- package/dist/verifier.js +78 -0
- package/dist/version.js +8 -0
- package/dist/workbench-host.js +172 -0
- package/dist/workbench.js +190 -0
- package/dist/worker-isolation.js +1028 -0
- package/dist/workflow-api.js +98 -0
- package/dist/workflow-app-framework.js +626 -0
- package/docs/agent-delegation-drive.7.md +190 -0
- package/docs/agent-framework.md +176 -0
- package/docs/candidate-scoring.7.md +106 -0
- package/docs/canonical-workflow-apps.7.md +137 -0
- package/docs/capability-topology-registry.7.md +168 -0
- package/docs/cli-mcp-parity.7.md +373 -0
- package/docs/contract-migration-tooling.7.md +123 -0
- package/docs/control-plane-scheduling.7.md +110 -0
- package/docs/coordinator-blackboard.7.md +183 -0
- package/docs/dogfood/architecture-review-cool-workflow.md +16 -0
- package/docs/dogfood-one-real-repo.7.md +168 -0
- package/docs/durable-state-and-locking.7.md +107 -0
- package/docs/end-to-end-golden-path.7.md +117 -0
- package/docs/error-feedback.7.md +153 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +270 -0
- package/docs/execution-backends.7.md +300 -0
- package/docs/getting-started.md +99 -0
- package/docs/index.md +41 -0
- package/docs/mcp-app-surface.7.md +235 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +265 -0
- package/docs/multi-agent-eval-replay-harness.7.md +302 -0
- package/docs/multi-agent-operator-ux.7.md +314 -0
- package/docs/multi-agent-runtime-core.7.md +231 -0
- package/docs/multi-agent-topologies.7.md +103 -0
- package/docs/multi-agent-trust-policy-audit.7.md +154 -0
- package/docs/node-snapshot-diff-replay.7.md +135 -0
- package/docs/observability-cost-accounting.7.md +194 -0
- package/docs/operator-ux.7.md +180 -0
- package/docs/pipeline-runner.7.md +136 -0
- package/docs/project-index.md +261 -0
- package/docs/real-execution-backends.7.md +142 -0
- package/docs/release-and-migration.7.md +280 -0
- package/docs/release-tooling.7.md +159 -0
- package/docs/routines.md +48 -0
- package/docs/run-registry-control-plane.7.md +312 -0
- package/docs/run-retention-reclamation.7.md +191 -0
- package/docs/sandbox-profiles.7.md +137 -0
- package/docs/scheduled-tasks.md +80 -0
- package/docs/security-trust-hardening.7.md +117 -0
- package/docs/state-explosion-management.7.md +264 -0
- package/docs/state-node.7.md +96 -0
- package/docs/team-collaboration.7.md +207 -0
- package/docs/unix-principles.md +192 -0
- package/docs/verifier-gated-commit.7.md +140 -0
- package/docs/web-desktop-workbench.7.md +215 -0
- package/docs/worker-isolation.7.md +167 -0
- package/docs/workflow-app-framework.7.md +274 -0
- package/manifest/README.md +43 -0
- package/manifest/plugin.manifest.json +316 -0
- package/manifest/pricing.policy.json +14 -0
- package/package.json +79 -0
- package/scripts/agents/claude-p-agent.js +104 -0
- package/scripts/agents/claude-p-agent.sh +9 -0
- package/scripts/agents/cw-attest-keygen.js +55 -0
- package/scripts/agents/cw-attest-wrap.js +143 -0
- package/scripts/block-unapproved-tag.sh +39 -0
- package/scripts/bump-version.js +249 -0
- package/scripts/canonical-apps.js +171 -0
- package/scripts/cw.js +4 -0
- package/scripts/dist-drift-check.js +79 -0
- package/scripts/dogfood-architecture-review.js +237 -0
- package/scripts/dogfood-release.js +624 -0
- package/scripts/forward-ref-docs.js +73 -0
- package/scripts/gen-manifests.js +232 -0
- package/scripts/golden-path.js +300 -0
- package/scripts/mcp-server.js +4 -0
- package/scripts/new-feature.js +121 -0
- package/scripts/parity-check.js +213 -0
- package/scripts/release-check.js +118 -0
- package/scripts/release-flow.js +272 -0
- package/scripts/release-gate.sh +85 -0
- package/scripts/sync-project-index.js +387 -0
- package/scripts/validate-run-state-schema.js +126 -0
- package/scripts/verify-container-selfref.js +64 -0
- package/scripts/version-sync-check.js +237 -0
- package/skills/cool-workflow/SKILL.md +162 -0
- package/skills/cool-workflow/references/commands.md +282 -0
- package/tsconfig.json +16 -0
- package/ui/workbench/app.css +76 -0
- package/ui/workbench/app.js +159 -0
- package/ui/workbench/index.html +32 -0
- package/workflows/architecture-review.workflow.js +84 -0
- package/workflows/research-synthesis.workflow.js +47 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# CAPABILITY-TOPOLOGY-REGISTRY(7) — Cool Workflow Agent-Driven Self-Evolution
|
|
2
|
+
|
|
3
|
+
## Name
|
|
4
|
+
|
|
5
|
+
`capability-dispatcher`, `registerCapabilityHandler`, `registerTopology` — open registries for agent-driven CW extension
|
|
6
|
+
|
|
7
|
+
## Description
|
|
8
|
+
|
|
9
|
+
v0.1.53 introduces two open registries that let agents extend CW at runtime
|
|
10
|
+
without manual wiring in multiple files. New capabilities self-register and
|
|
11
|
+
auto-work across CLI, MCP, and Workbench. New topologies self-register and
|
|
12
|
+
auto-appear in `topology list`, `topology validate`, and `topology apply`.
|
|
13
|
+
|
|
14
|
+
BSD discipline: **mechanism** (Map / pipe) separate from **policy** (entries).
|
|
15
|
+
Fail-closed on unknown ids.
|
|
16
|
+
|
|
17
|
+
## Capability Registry
|
|
18
|
+
|
|
19
|
+
### Interface
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
interface CapabilityHandler {
|
|
23
|
+
descriptor: CapabilityDescriptor;
|
|
24
|
+
run(args: Record<string, unknown>, ctx: CapabilityContext): unknown | Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface CapabilityContext {
|
|
28
|
+
runner: CoolWorkflowRunner;
|
|
29
|
+
cwd: string;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Registering a new capability
|
|
34
|
+
|
|
35
|
+
```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
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### How it works
|
|
55
|
+
|
|
56
|
+
1. `registerCapabilityHandler()` stores the handler in a `Map<string, CapabilityHandler>`
|
|
57
|
+
2. CLI: `resolveCliPath(["my", "new-tool"])` resolves the CLI path to the capability id
|
|
58
|
+
3. MCP: `resolveMcpTool("cw_my_new_tool")` resolves the tool name to the capability id
|
|
59
|
+
4. `dispatchCapability(id, args, ctx)` invokes `handler.run(args, ctx)`
|
|
60
|
+
5. Both the CLI and MCP surfaces fall through to the dynamic dispatcher when
|
|
61
|
+
their hardcoded switch statements don't match an unknown command/tool
|
|
62
|
+
|
|
63
|
+
### Existing capabilities
|
|
64
|
+
|
|
65
|
+
All existing 182 capabilities continue to work through their hardcoded switch
|
|
66
|
+
cases in `cli.ts` and `mcp-server.ts`. The dynamic dispatch is a **fallback**
|
|
67
|
+
— it only activates for commands/tools not found in the legacy switches.
|
|
68
|
+
|
|
69
|
+
## Topology Registry
|
|
70
|
+
|
|
71
|
+
### Interface
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface MultiAgentTopologyDefinition {
|
|
75
|
+
schemaVersion: 1;
|
|
76
|
+
id: string; // open string namespace (was closed union)
|
|
77
|
+
title: string;
|
|
78
|
+
summary: string;
|
|
79
|
+
roles: TopologyRoleSpec[];
|
|
80
|
+
groups: Array<{ id: string; title: string; roleIds: string[] }>;
|
|
81
|
+
blackboardTopics: Array<{ id: string; title: string; description: string }>;
|
|
82
|
+
phases: TopologyPhaseSpec[];
|
|
83
|
+
fanoutStrategy: string;
|
|
84
|
+
faninStrategy: string;
|
|
85
|
+
requiredEvidence: string[];
|
|
86
|
+
coordinatorDecisions: CoordinatorDecisionKind[];
|
|
87
|
+
candidateExpectations: string[];
|
|
88
|
+
verifierGates: string[];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface TopologyRoleSpec {
|
|
92
|
+
id: string;
|
|
93
|
+
title: string;
|
|
94
|
+
responsibilities: string[];
|
|
95
|
+
count?: number; // NEW: materialize N instances of this role
|
|
96
|
+
requiredEvidence: string[];
|
|
97
|
+
expectedArtifacts: string[];
|
|
98
|
+
faninObligations: string[];
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Registering a new topology
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { registerTopology } from "./topology";
|
|
106
|
+
|
|
107
|
+
registerTopology({
|
|
108
|
+
schemaVersion: 1,
|
|
109
|
+
id: "swarm",
|
|
110
|
+
title: "Swarm",
|
|
111
|
+
summary: "Parallel swarm agents with consensus voting.",
|
|
112
|
+
roles: [
|
|
113
|
+
{ id: "swarm-agent", title: "Swarm Agent",
|
|
114
|
+
responsibilities: ["Produce shard result with evidence."],
|
|
115
|
+
requiredEvidence: ["swarm output artifact"],
|
|
116
|
+
expectedArtifacts: ["swarm result"],
|
|
117
|
+
faninObligations: ["indexed swarm artifact"],
|
|
118
|
+
count: 5 }
|
|
119
|
+
],
|
|
120
|
+
groups: [{ id: "swarm", title: "Swarm Group", roleIds: ["swarm-agent"] }],
|
|
121
|
+
blackboardTopics: [
|
|
122
|
+
{ id: "swarm-outputs", title: "Swarm Outputs", description: "Agent results." }
|
|
123
|
+
],
|
|
124
|
+
phases: [
|
|
125
|
+
{ id: "execute", title: "Execute", roleIds: ["swarm-agent"],
|
|
126
|
+
fanout: true, fanin: false,
|
|
127
|
+
requiredEvidence: ["swarm output artifact"],
|
|
128
|
+
coordinatorDecisionKinds: ["artifact-index"] },
|
|
129
|
+
{ id: "consensus", title: "Consensus", roleIds: ["synthesizer"],
|
|
130
|
+
fanout: false, fanin: true,
|
|
131
|
+
requiredEvidence: ["all swarm evidence"],
|
|
132
|
+
coordinatorDecisionKinds: ["candidate-synthesis"] }
|
|
133
|
+
],
|
|
134
|
+
fanoutStrategy: "one membership per swarm agent role",
|
|
135
|
+
faninStrategy: "consensus requires all swarm agent evidence",
|
|
136
|
+
requiredEvidence: ["swarm output artifact", "consensus synthesis"],
|
|
137
|
+
coordinatorDecisions: ["artifact-index", "candidate-synthesis"],
|
|
138
|
+
candidateExpectations: ["Synthesis cites swarm agent provenance."],
|
|
139
|
+
verifierGates: ["Swarm fanin must be ready before commit."]
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### How it works
|
|
144
|
+
|
|
145
|
+
1. `registerTopology()` stores the definition in a `Map<string, MultiAgentTopologyDefinition>`
|
|
146
|
+
2. `listTopologyDefinitions()` returns official + registered, registered wins on id collision
|
|
147
|
+
3. `getTopologyDefinition(id)` checks registered first, then official
|
|
148
|
+
4. `materializedRoles()` uses `role.count` for replication — no more hardcoded
|
|
149
|
+
mapper/judge switch logic
|
|
150
|
+
5. `applyTopology()` works identically for official and registered topologies
|
|
151
|
+
|
|
152
|
+
### Data-driven role expansion
|
|
153
|
+
|
|
154
|
+
Before v0.1.53, `materializedRoles()` hardcoded "mapper" and "judge" role
|
|
155
|
+
expansion. Now it checks `role.count` on each role spec:
|
|
156
|
+
- `role.count > 1`: creates `role-1`, `role-2`, ... `role-N`
|
|
157
|
+
- `role.count` undefined or 1: creates a single role instance
|
|
158
|
+
- For backward compat with official topologies, `mapperCount` and `judgeCount`
|
|
159
|
+
input overrides still apply
|
|
160
|
+
|
|
161
|
+
## See Also
|
|
162
|
+
|
|
163
|
+
- `capability-registry.ts` — the single source of truth for all capabilities
|
|
164
|
+
- `capability-dispatcher.ts` — the thin Map-based dispatch pipe
|
|
165
|
+
- `topology.ts` — topology definitions and the registry
|
|
166
|
+
- `types/topology.ts` — topology type definitions
|
|
167
|
+
- `docs/cli-mcp-parity.7.md` — CLI <-> MCP parity gate
|
|
168
|
+
- `docs/multi-agent-topologies.7.md` — official topology recipes
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# CLI ↔ MCP Parity
|
|
2
|
+
|
|
3
|
+
CW v0.1.27 adds CLI ↔ MCP Parity. CW has two front doors. The CLI
|
|
4
|
+
(`node scripts/cw.js ...`, `dist/cli.js`) serves human speed: terse, scannable
|
|
5
|
+
text with meaningful exit codes. The MCP server (`cw_*` JSON-RPC tools) serves
|
|
6
|
+
machine context: complete, stable, structured JSON. This release makes the two
|
|
7
|
+
doors two renderings of one data source — declared, derived, and enforced — so
|
|
8
|
+
the same capability cannot drift between surfaces.
|
|
9
|
+
|
|
10
|
+
The design follows a base-system discipline that separates mechanism from
|
|
11
|
+
policy:
|
|
12
|
+
|
|
13
|
+
- one source of truth: the capability registry, not two hand-maintained lists
|
|
14
|
+
- mechanism (shared core) is separate from policy (per-surface rendering)
|
|
15
|
+
- one source, two renderings; no undeclared divergence
|
|
16
|
+
- principle of least astonishment: matching names, flags, order, and defaults
|
|
17
|
+
across surfaces
|
|
18
|
+
- the surfaces do not interfere: human formatting never leaks into machine
|
|
19
|
+
output, machine completeness never bloats the default human view
|
|
20
|
+
- fail closed on drift; a surface mismatch is a release-blocking error
|
|
21
|
+
- stable interfaces, backward compatible; old names remain aliases or wrappers
|
|
22
|
+
- it is not done until it is documented and tested
|
|
23
|
+
|
|
24
|
+
## Mechanism vs Policy
|
|
25
|
+
|
|
26
|
+
The mechanism is the capability registry at `src/capability-registry.ts`
|
|
27
|
+
(compiled to `dist/capability-registry.js`). It is the single source of truth.
|
|
28
|
+
Every capability declares one shared core `entry` — the mechanism both surfaces
|
|
29
|
+
route through — plus its CLI command, its MCP tool, the surface it lives on, and
|
|
30
|
+
whether its payload is identical across surfaces.
|
|
31
|
+
|
|
32
|
+
No business logic is stranded in `cli.ts` or `mcp-server.ts`. Composite
|
|
33
|
+
capabilities live in `src/capability-core.ts` (`planSummary`, `appRun`,
|
|
34
|
+
`sandboxChoose`, `commitEnvelope`), so both surfaces call the same core entry
|
|
35
|
+
and differ only in how they render its result. The CLI renders for a human; the
|
|
36
|
+
MCP tool renders for a machine; neither owns the logic.
|
|
37
|
+
|
|
38
|
+
A new runtime capability is added once, in the registry, against one core entry.
|
|
39
|
+
The CLI command and the MCP tool are then two policies over that one mechanism —
|
|
40
|
+
which is exactly what the parity gate checks.
|
|
41
|
+
|
|
42
|
+
## Human vs Machine Contract
|
|
43
|
+
|
|
44
|
+
The two surfaces have different contracts and must not interfere:
|
|
45
|
+
|
|
46
|
+
- CLI = human speed. The default output is terse, scannable text with meaningful
|
|
47
|
+
exit codes. The canonical payload is available on demand via `--json` or
|
|
48
|
+
`--format json`. Human formatting is never emitted on the machine path.
|
|
49
|
+
- MCP = machine context. The result is always complete, stable, structured
|
|
50
|
+
JSON. Machine completeness is never forced into the default human view.
|
|
51
|
+
|
|
52
|
+
A capability marked `payloadIdentical` returns the same canonical JSON from
|
|
53
|
+
`cw <cmd> --json` and from the `cw_<tool>` MCP result — whitespace and
|
|
54
|
+
generation-moment ISO timestamps aside. The `--json` payload is the contract,
|
|
55
|
+
and it is the same bytes the MCP tool returns. The human text view is policy
|
|
56
|
+
layered on top; it never changes the payload.
|
|
57
|
+
|
|
58
|
+
## The Parity Matrix
|
|
59
|
+
|
|
60
|
+
The matrix below is derived from the live registry — one row per capability,
|
|
61
|
+
showing its CLI command, MCP tool, shared core entry, surface, and payload
|
|
62
|
+
relationship. `identical` means `cw <cmd> --json` equals the `cw_<tool>`
|
|
63
|
+
payload; `projected` means a declared, reasoned divergence; `cli-only` marks a
|
|
64
|
+
surface-specific capability with a recorded reason. The matrix is
|
|
65
|
+
machine-complete by design: 132 capabilities, 129 MCP tools.
|
|
66
|
+
|
|
67
|
+
| Capability | CLI command | MCP tool | Core entry | Surface | Payload |
|
|
68
|
+
| --- | --- | --- | --- | --- | --- |
|
|
69
|
+
| `help` | `cw help` | `—` | `formatHelp` | cli-only | cli-only |
|
|
70
|
+
| `list` | `cw list` | `cw_list` | `listWorkflows` | both | identical |
|
|
71
|
+
| `init` | `cw init` | `cw_init` | `init` | both | identical |
|
|
72
|
+
| `plan` | `cw plan` | `cw_plan` | `planSummary` | both | identical |
|
|
73
|
+
| `status` | `cw status --json` | `cw_status` | `status` | both | identical |
|
|
74
|
+
| `next` | `cw next` | `cw_next` | `next` | both | identical |
|
|
75
|
+
| `dispatch` | `cw dispatch` | `cw_dispatch` | `dispatch` | both | identical |
|
|
76
|
+
| `result` | `cw result` | `cw_result` | `recordResult` | both | identical |
|
|
77
|
+
| `commit` | `cw commit` | `cw_commit` | `commit` | both | projected |
|
|
78
|
+
| `commit.summary` | `cw commit summary --json` | `cw_commit_summary` | `summarizeCommitRecords` | both | identical |
|
|
79
|
+
| `report` | `cw report --json` | `cw_report` | `report` | both | identical |
|
|
80
|
+
| `graph` | `cw graph --json` | `cw_operator_graph` | `operatorGraph` | both | identical |
|
|
81
|
+
| `loop` | `cw loop` | `—` | `scheduler.create` | cli-only | cli-only |
|
|
82
|
+
| `operator.status` | `cw operator status --json` | `cw_operator_status` | `operatorStatus` | both | identical |
|
|
83
|
+
| `operator.report` | `cw operator report --json` | `cw_operator_report` | `operatorReport` | both | identical |
|
|
84
|
+
| `app.list` | `cw app list` | `cw_app_list` | `listApps` | both | identical |
|
|
85
|
+
| `app.show` | `cw app show` | `cw_app_show` | `showApp` | both | identical |
|
|
86
|
+
| `app.validate` | `cw app validate` | `cw_app_validate` | `validateApp` | both | identical |
|
|
87
|
+
| `app.init` | `cw app init` | `cw_app_init` | `initApp` | both | identical |
|
|
88
|
+
| `app.package` | `cw app package` | `cw_app_package` | `packageApp` | both | identical |
|
|
89
|
+
| `app.run` | `cw app run` | `cw_app_run` | `appRun` | both | identical |
|
|
90
|
+
| `state.check` | `cw state check` | `cw_state_check` | `checkState` | both | identical |
|
|
91
|
+
| `contract.show` | `cw contract show` | `cw_contract_show` | `showContract` | both | identical |
|
|
92
|
+
| `node.list` | `cw node list` | `cw_node_list` | `listNodes` | both | identical |
|
|
93
|
+
| `node.show` | `cw node show` | `cw_node_show` | `showNode` | both | identical |
|
|
94
|
+
| `node.graph` | `cw node graph --json` | `cw_node_graph` | `graphNodes` | both | identical |
|
|
95
|
+
| `topology.list` | `cw topology list` | `cw_topology_list` | `listTopologies` | both | identical |
|
|
96
|
+
| `topology.show` | `cw topology show` | `cw_topology_show` | `showTopology` | both | identical |
|
|
97
|
+
| `topology.validate` | `cw topology validate` | `cw_topology_validate` | `validateTopology` | both | identical |
|
|
98
|
+
| `topology.apply` | `cw topology apply` | `cw_topology_apply` | `applyTopology` | both | identical |
|
|
99
|
+
| `topology.summary` | `cw topology summary --json` | `cw_topology_summary` | `topologySummary` | both | identical |
|
|
100
|
+
| `topology.graph` | `cw topology graph --json` | `cw_topology_graph` | `topologyGraph` | both | identical |
|
|
101
|
+
| `summary.refresh` | `cw summary refresh --json` | `cw_summary_refresh` | `summaryRefresh` | both | identical |
|
|
102
|
+
| `summary.show` | `cw summary show --json` | `cw_summary_show` | `summaryShow` | both | identical |
|
|
103
|
+
| `multi-agent.run` | `cw multi-agent run` | `cw_multi_agent_run` | `hostMultiAgentRun` | both | identical |
|
|
104
|
+
| `multi-agent.status` | `cw multi-agent status --json` | `cw_multi_agent_status` | `hostMultiAgentStatus` | both | identical |
|
|
105
|
+
| `multi-agent.step` | `cw multi-agent step` | `cw_multi_agent_step` | `hostMultiAgentStep` | both | identical |
|
|
106
|
+
| `multi-agent.blackboard` | `cw multi-agent blackboard` | `cw_multi_agent_blackboard` | `hostMultiAgentBlackboard` | both | identical |
|
|
107
|
+
| `multi-agent.score` | `cw multi-agent score` | `cw_multi_agent_score` | `hostMultiAgentScore` | both | identical |
|
|
108
|
+
| `multi-agent.select` | `cw multi-agent select` | `cw_multi_agent_select` | `hostMultiAgentSelect` | both | identical |
|
|
109
|
+
| `multi-agent.summary` | `cw multi-agent summary --json` | `cw_multi_agent_summary` | `multiAgentSummary` | both | identical |
|
|
110
|
+
| `multi-agent.summarize` | `cw multi-agent summarize --json` | `cw_multi_agent_summarize` | `multiAgentSummarize` | both | identical |
|
|
111
|
+
| `multi-agent.graph` | `cw multi-agent graph --json` | `cw_multi_agent_graph` | `multiAgentOperatorGraph` | both | identical |
|
|
112
|
+
| `multi-agent.graph.compact` | `cw multi-agent graph --json` | `cw_multi_agent_graph_compact` | `multiAgentGraphView` | both | identical |
|
|
113
|
+
| `multi-agent.dependencies` | `cw multi-agent dependencies --json` | `cw_multi_agent_dependencies` | `multiAgentDependencies` | both | identical |
|
|
114
|
+
| `multi-agent.failures` | `cw multi-agent failures --json` | `cw_multi_agent_failures` | `multiAgentFailures` | both | identical |
|
|
115
|
+
| `multi-agent.evidence` | `cw multi-agent evidence --json` | `cw_multi_agent_evidence` | `multiAgentEvidence` | both | identical |
|
|
116
|
+
| `multi-agent.reasoning` | `cw multi-agent reasoning --json` | `cw_evidence_reasoning` | `multiAgentReasoning` | both | identical |
|
|
117
|
+
| `multi-agent.reasoning.refresh` | `cw multi-agent reasoning` | `cw_evidence_reasoning_refresh` | `multiAgentReasoningRefresh` | both | identical |
|
|
118
|
+
| `multi-agent.run.create` | `cw multi-agent run` | `cw_multi_agent_run_create` | `createMultiAgentRun` | both | identical |
|
|
119
|
+
| `multi-agent.run.transition` | `cw multi-agent run` | `cw_multi_agent_run_transition` | `transitionMultiAgentRun` | both | identical |
|
|
120
|
+
| `multi-agent.run.show` | `cw multi-agent show` | `cw_multi_agent_run_show` | `showMultiAgentRun` | both | identical |
|
|
121
|
+
| `multi-agent.role.create` | `cw multi-agent role` | `cw_multi_agent_role_create` | `createAgentRole` | both | identical |
|
|
122
|
+
| `multi-agent.role.show` | `cw multi-agent role` | `cw_multi_agent_role_show` | `showAgentRole` | both | identical |
|
|
123
|
+
| `multi-agent.group.create` | `cw multi-agent group` | `cw_multi_agent_group_create` | `createAgentGroup` | both | identical |
|
|
124
|
+
| `multi-agent.group.show` | `cw multi-agent group` | `cw_multi_agent_group_show` | `showAgentGroup` | both | identical |
|
|
125
|
+
| `multi-agent.membership.create` | `cw multi-agent membership` | `cw_multi_agent_membership_create` | `assignAgentMembership` | both | identical |
|
|
126
|
+
| `multi-agent.membership.show` | `cw multi-agent membership` | `cw_multi_agent_membership_show` | `showAgentMembership` | both | identical |
|
|
127
|
+
| `multi-agent.fanout.create` | `cw multi-agent fanout` | `cw_multi_agent_fanout_create` | `createAgentFanout` | both | identical |
|
|
128
|
+
| `multi-agent.fanout.show` | `cw multi-agent fanout` | `cw_multi_agent_fanout_show` | `showAgentFanout` | both | identical |
|
|
129
|
+
| `multi-agent.fanin.collect` | `cw multi-agent fanin` | `cw_multi_agent_fanin_collect` | `collectAgentFanin` | both | identical |
|
|
130
|
+
| `multi-agent.fanin.show` | `cw multi-agent fanin` | `cw_multi_agent_fanin_show` | `showAgentFanin` | both | identical |
|
|
131
|
+
| `eval.snapshot` | `cw eval snapshot --json` | `cw_eval_snapshot` | `evalSnapshot` | both | identical |
|
|
132
|
+
| `eval.replay` | `cw eval replay --json` | `cw_eval_replay` | `evalReplay` | both | identical |
|
|
133
|
+
| `eval.compare` | `cw eval compare --json` | `cw_eval_compare` | `evalCompare` | both | identical |
|
|
134
|
+
| `eval.score` | `cw eval score --json` | `cw_eval_score` | `evalScore` | both | identical |
|
|
135
|
+
| `eval.gate` | `cw eval gate --json` | `cw_eval_gate` | `evalGate` | both | identical |
|
|
136
|
+
| `eval.report` | `cw eval report --json` | `cw_eval_report` | `evalReport` | both | identical |
|
|
137
|
+
| `blackboard.summary` | `cw blackboard summary` | `cw_blackboard_summary` | `blackboardSummary` | both | identical |
|
|
138
|
+
| `blackboard.summarize` | `cw blackboard summarize --json` | `cw_blackboard_summarize` | `blackboardSummarize` | both | identical |
|
|
139
|
+
| `blackboard.graph` | `cw blackboard graph` | `cw_blackboard_graph` | `blackboardGraph` | both | identical |
|
|
140
|
+
| `blackboard.resolve` | `cw blackboard resolve` | `cw_blackboard_resolve` | `resolveRunBlackboard` | both | identical |
|
|
141
|
+
| `blackboard.topic.create` | `cw blackboard topic create` | `cw_blackboard_topic_create` | `createBlackboardTopic` | both | identical |
|
|
142
|
+
| `blackboard.message.post` | `cw blackboard message post` | `cw_blackboard_message_post` | `postBlackboardMessage` | both | identical |
|
|
143
|
+
| `blackboard.message.list` | `cw blackboard message list` | `cw_blackboard_message_list` | `listBlackboardMessages` | both | identical |
|
|
144
|
+
| `blackboard.context.put` | `cw blackboard context put` | `cw_blackboard_context_put` | `putBlackboardContext` | both | identical |
|
|
145
|
+
| `blackboard.artifact.add` | `cw blackboard artifact add` | `cw_blackboard_artifact_add` | `addBlackboardArtifact` | both | identical |
|
|
146
|
+
| `blackboard.artifact.list` | `cw blackboard artifact list` | `cw_blackboard_artifact_list` | `listBlackboardArtifacts` | both | identical |
|
|
147
|
+
| `blackboard.snapshot` | `cw blackboard snapshot` | `cw_blackboard_snapshot` | `snapshotBlackboard` | both | identical |
|
|
148
|
+
| `coordinator.summary` | `cw coordinator summary` | `cw_coordinator_summary` | `coordinatorSummary` | both | identical |
|
|
149
|
+
| `coordinator.decision` | `cw coordinator decision` | `cw_coordinator_decision` | `recordCoordinatorDecision` | both | identical |
|
|
150
|
+
| `audit.summary` | `cw audit summary` | `cw_audit_summary` | `auditSummary` | both | identical |
|
|
151
|
+
| `audit.worker` | `cw audit worker` | `cw_audit_worker` | `workerAudit` | both | identical |
|
|
152
|
+
| `audit.provenance` | `cw audit provenance` | `cw_audit_provenance` | `evidenceProvenance` | both | identical |
|
|
153
|
+
| `audit.multi-agent` | `cw audit multi-agent --json` | `cw_audit_multi_agent` | `auditMultiAgent` | both | identical |
|
|
154
|
+
| `audit.policy` | `cw audit policy --json` | `cw_audit_policy` | `auditPolicy` | both | identical |
|
|
155
|
+
| `audit.role` | `cw audit role --json` | `cw_audit_role` | `auditRole` | both | identical |
|
|
156
|
+
| `audit.blackboard` | `cw audit blackboard --json` | `cw_audit_blackboard` | `auditBlackboard` | both | identical |
|
|
157
|
+
| `audit.judge` | `cw audit judge --json` | `cw_audit_judge` | `auditJudge` | both | identical |
|
|
158
|
+
| `audit.attest` | `cw audit attest` | `cw_audit_attest` | `recordAuditAttestation` | both | identical |
|
|
159
|
+
| `audit.decision` | `cw audit decision` | `cw_audit_decision` | `recordAuditDecision` | both | identical |
|
|
160
|
+
| `sandbox.list` | `cw sandbox list` | `cw_sandbox_list` | `listSandboxProfiles` | both | identical |
|
|
161
|
+
| `sandbox.show` | `cw sandbox show` | `cw_sandbox_show` | `showSandboxProfile` | both | identical |
|
|
162
|
+
| `sandbox.validate` | `cw sandbox validate` | `cw_sandbox_validate` | `validateSandboxProfile` | both | identical |
|
|
163
|
+
| `sandbox.choose` | `cw sandbox choose` | `cw_sandbox_choose` | `sandboxChoose` | both | identical |
|
|
164
|
+
| `sandbox.resolve` | `cw sandbox resolve` | `cw_sandbox_resolve` | `sandboxChoose` | both | identical |
|
|
165
|
+
| `worker.list` | `cw worker list` | `cw_worker_list` | `listWorkers` | both | identical |
|
|
166
|
+
| `worker.summary` | `cw worker summary --json` | `cw_worker_summary` | `summarizeWorkerRecords` | both | identical |
|
|
167
|
+
| `worker.show` | `cw worker show` | `cw_worker_show` | `showWorker` | both | identical |
|
|
168
|
+
| `worker.manifest` | `cw worker manifest` | `cw_worker_manifest` | `showWorkerManifest` | both | identical |
|
|
169
|
+
| `worker.output` | `cw worker output` | `cw_worker_output` | `recordWorkerOutput` | both | identical |
|
|
170
|
+
| `worker.fail` | `cw worker fail` | `cw_worker_fail` | `recordWorkerFailure` | both | identical |
|
|
171
|
+
| `worker.validate` | `cw worker validate` | `cw_worker_validate` | `validateWorker` | both | identical |
|
|
172
|
+
| `candidate.list` | `cw candidate list` | `cw_candidate_list` | `listCandidates` | both | identical |
|
|
173
|
+
| `candidate.show` | `cw candidate show` | `cw_candidate_show` | `showCandidate` | both | identical |
|
|
174
|
+
| `candidate.register` | `cw candidate register` | `cw_candidate_register` | `registerCandidate` | both | identical |
|
|
175
|
+
| `candidate.score` | `cw candidate score` | `cw_candidate_score` | `scoreCandidate` | both | identical |
|
|
176
|
+
| `candidate.rank` | `cw candidate rank` | `cw_candidate_rank` | `rankCandidates` | both | identical |
|
|
177
|
+
| `candidate.select` | `cw candidate select` | `cw_candidate_select` | `selectCandidate` | both | identical |
|
|
178
|
+
| `candidate.reject` | `cw candidate reject` | `cw_candidate_reject` | `rejectCandidate` | both | identical |
|
|
179
|
+
| `candidate.summary` | `cw candidate summary --json` | `cw_candidate_summary` | `summarizeCandidateOperatorRecords` | both | identical |
|
|
180
|
+
| `feedback.list` | `cw feedback list` | `cw_feedback_list` | `listFeedback` | both | identical |
|
|
181
|
+
| `feedback.show` | `cw feedback show` | `cw_feedback_show` | `showFeedback` | both | identical |
|
|
182
|
+
| `feedback.collect` | `cw feedback collect` | `cw_feedback_collect` | `collectFeedback` | both | identical |
|
|
183
|
+
| `feedback.summary` | `cw feedback summary --json` | `cw_feedback_summary` | `summarizeFeedbackRecords` | both | identical |
|
|
184
|
+
| `feedback.task` | `cw feedback task` | `cw_feedback_task` | `createFeedbackTask` | both | identical |
|
|
185
|
+
| `feedback.resolve` | `cw feedback resolve` | `cw_feedback_resolve` | `resolveFeedback` | both | identical |
|
|
186
|
+
| `schedule.create` | `cw schedule create` | `cw_schedule_create` | `scheduler.create` | both | identical |
|
|
187
|
+
| `schedule.list` | `cw schedule list` | `cw_schedule_list` | `scheduler.list` | both | identical |
|
|
188
|
+
| `schedule.delete` | `cw schedule delete` | `cw_schedule_delete` | `scheduler.delete` | both | identical |
|
|
189
|
+
| `schedule.due` | `cw schedule due` | `cw_schedule_due` | `scheduler.due` | both | identical |
|
|
190
|
+
| `schedule.complete` | `cw schedule complete` | `cw_schedule_complete` | `scheduler.complete` | both | identical |
|
|
191
|
+
| `schedule.pause` | `cw schedule pause` | `cw_schedule_pause` | `scheduler.pause` | both | identical |
|
|
192
|
+
| `schedule.resume` | `cw schedule resume` | `cw_schedule_resume` | `scheduler.resume` | both | identical |
|
|
193
|
+
| `schedule.run-now` | `cw schedule run-now` | `cw_schedule_run_now` | `scheduler.runNow` | both | identical |
|
|
194
|
+
| `schedule.history` | `cw schedule history` | `cw_schedule_history` | `scheduler.history` | both | identical |
|
|
195
|
+
| `schedule.daemon` | `cw schedule daemon` | `—` | `DesktopSchedulerDaemon.run` | cli-only | cli-only |
|
|
196
|
+
| `routine.create` | `cw routine create` | `cw_routine_create` | `triggers.create` | both | identical |
|
|
197
|
+
| `routine.list` | `cw routine list` | `cw_routine_list` | `triggers.list` | both | identical |
|
|
198
|
+
| `routine.delete` | `cw routine delete` | `cw_routine_delete` | `triggers.delete` | both | identical |
|
|
199
|
+
| `routine.fire` | `cw routine fire` | `cw_routine_fire` | `triggers.fire` | both | identical |
|
|
200
|
+
| `routine.events` | `cw routine events` | `cw_routine_events` | `triggers.events` | both | identical |
|
|
201
|
+
|
|
202
|
+
v0.1.27 closed the historical gaps. It added MCP peers `cw_init`, `cw_next`,
|
|
203
|
+
`cw_state_check`, `cw_contract_show`, `cw_node_list`, `cw_node_show`, and
|
|
204
|
+
`cw_node_graph`; and CLI peers `app run`, `operator status`, `operator report`,
|
|
205
|
+
`sandbox choose`, `sandbox resolve`, and `report --json`. Everything else is on
|
|
206
|
+
both surfaces.
|
|
207
|
+
|
|
208
|
+
## Surface-Specific Capabilities
|
|
209
|
+
|
|
210
|
+
A capability may live on one surface only, but never silently — it must carry a
|
|
211
|
+
recorded reason in the registry. Three capabilities are CLI-only:
|
|
212
|
+
|
|
213
|
+
- `help` — human help text. MCP hosts enumerate capabilities via `tools/list`,
|
|
214
|
+
not a help command.
|
|
215
|
+
- `loop` — a convenience alias of `schedule create` with `kind=loop`. MCP hosts
|
|
216
|
+
use `cw_schedule_create` with `kind=loop`.
|
|
217
|
+
- `schedule daemon` — a long-running desktop daemon process, not a
|
|
218
|
+
request/response tool. MCP hosts drive ticks via `cw_schedule_due` and
|
|
219
|
+
`cw_schedule_run_now`.
|
|
220
|
+
|
|
221
|
+
One capability is intentionally payload-divergent (`projected`):
|
|
222
|
+
|
|
223
|
+
- `commit` — both surfaces route through the single core entry `runner.commit`.
|
|
224
|
+
The CLI emits the raw `StateCommitResult` for scripting (`commit.id`,
|
|
225
|
+
`commit.evidence`, `commit.gate`, `commit.acceptanceRationale`); `cw_commit`
|
|
226
|
+
emits the operator commit envelope (`commitId`, `verifierGated`, `checkpoint`,
|
|
227
|
+
`evidenceCount`, `snapshotPath`, `nextActions`, plus the raw result under
|
|
228
|
+
`commit`). This is a declared projection via `capability-core.commitEnvelope`,
|
|
229
|
+
not drift.
|
|
230
|
+
|
|
231
|
+
## Fail-Closed Rules
|
|
232
|
+
|
|
233
|
+
The parity gate fails closed. Any of the following is a release-blocking error:
|
|
234
|
+
|
|
235
|
+
- a capability present on one surface but missing from the other
|
|
236
|
+
- an MCP tool that is live but not declared in the registry
|
|
237
|
+
- a CLI command or token that is live but not declared in the registry
|
|
238
|
+
- a surface-specific or payload-divergent capability with no recorded `reason`
|
|
239
|
+
- a payload divergence on a capability marked `payloadIdentical` — that is,
|
|
240
|
+
`cw <cmd> --json` and `cw_<tool>` returning different canonical JSON
|
|
241
|
+
|
|
242
|
+
There is no "fix it later" path. A surface mismatch blocks the release until the
|
|
243
|
+
registry, the surfaces, and the recorded reasons agree.
|
|
244
|
+
|
|
245
|
+
## Enforcement & Smoke Coverage
|
|
246
|
+
|
|
247
|
+
Parity is checked by `scripts/parity-check.js --check`, run by
|
|
248
|
+
`npm run parity:check` and wired into `npm run release:check`. The check loads
|
|
249
|
+
the registry, enumerates the live CLI commands and MCP tools, and fails closed on
|
|
250
|
+
any of the rules above.
|
|
251
|
+
|
|
252
|
+
`test/cli-mcp-parity-smoke.js` proves the contract end to end. It verifies
|
|
253
|
+
registry ⇄ CLI ⇄ MCP coverage (every declared capability resolves on its
|
|
254
|
+
declared surfaces and nothing live is undeclared), confirms `--json` output
|
|
255
|
+
equals the MCP payload for every `payloadIdentical` capability, confirms the
|
|
256
|
+
declared `commit` projection, and confirms fail-closed behavior by injecting
|
|
257
|
+
drift — a removed peer, an undeclared tool, a reasonless exception, a mutated
|
|
258
|
+
payload — and asserting the gate rejects each one. It is included in `npm test`
|
|
259
|
+
and `npm run release:check`.
|
|
260
|
+
|
|
261
|
+
In CW, parity is not a convention; it is a derived, declared, and enforced
|
|
262
|
+
property of the build. It is not done until it is documented and tested.
|
|
263
|
+
|
|
264
|
+
## Run Registry / Control Plane (v0.1.28)
|
|
265
|
+
|
|
266
|
+
v0.1.28 adds 13 control-plane capabilities — `registry refresh|show`, `run
|
|
267
|
+
search|list|show|resume|archive|rerun`, `queue add|list|drain|show`, and
|
|
268
|
+
`history` — declared once in the capability registry and validated by the same
|
|
269
|
+
fail-closed parity gate, so each `cw <cmd> --json` is schema-identical to its
|
|
270
|
+
`cw_<tool>`. See [run-registry-control-plane.7.md](run-registry-control-plane.7.md).
|
|
271
|
+
|
|
272
|
+
## Execution Backends (v0.1.29)
|
|
273
|
+
|
|
274
|
+
v0.1.29 lifts execution into a pluggable driver layer: one narrow `ExecutionBackend`
|
|
275
|
+
contract with interchangeable `node`/`bun`/`shell`/`container`/`remote`/`ci`
|
|
276
|
+
drivers, selected by `--backend` (parallel to `--sandbox`) and inspected via
|
|
277
|
+
`backend list|show|probe`. The result/evidence envelope is schema-identical across
|
|
278
|
+
backends; the backend id + sandbox attestation are recorded as provenance, so this
|
|
279
|
+
surface is unchanged regardless of which backend executed a run. See
|
|
280
|
+
[execution-backends.7.md](execution-backends.7.md).
|
|
281
|
+
## Web / Desktop Workbench (v0.1.30)
|
|
282
|
+
|
|
283
|
+
v0.1.30 adds the Web / Desktop Workbench: a read-only, localhost-only human
|
|
284
|
+
console that renders this surface (and the other four operator panels — run
|
|
285
|
+
graph, blackboard, worker logs, candidate compare, audit timeline) for any run,
|
|
286
|
+
reading the SAME capability `--json` payloads. It is a THIRD FRONT DOOR alongside
|
|
287
|
+
the CLI and MCP that holds no authoritative state and forks no schema: each panel
|
|
288
|
+
equals its `cw <cmd> --json` payload byte-for-byte (parity-gated), and refresh
|
|
289
|
+
re-derives everything from disk. See
|
|
290
|
+
[web-desktop-workbench.7.md](web-desktop-workbench.7.md).
|
|
291
|
+
|
|
292
|
+
## Observability + Cost Accounting (v0.1.31)
|
|
293
|
+
|
|
294
|
+
v0.1.31 adds Observability + Cost Accounting: `metrics show`/`metrics summary`
|
|
295
|
+
derive durations, failure/verifier/acceptance rates (with sample counts and
|
|
296
|
+
fail-closed `n/a`), and host-attested token/cost from existing durable run state
|
|
297
|
+
— no metrics database, no collector daemon, no hidden counter. Usage is additive
|
|
298
|
+
and optional (absent ⇒ `unreported`, never 0); cost is `attested` (attested usage
|
|
299
|
+
× a recorded pricing policy) or clearly `estimated`, with pricing as policy. Both
|
|
300
|
+
verbs are parity-gated and render read-only in the v0.1.30 Workbench. See
|
|
301
|
+
[observability-cost-accounting.7.md](observability-cost-accounting.7.md).
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
## Team Collaboration (v0.1.32)
|
|
305
|
+
|
|
306
|
+
v0.1.32 adds Team Collaboration: a host-attested actor and append-only
|
|
307
|
+
approvals/rejections/comments/handoffs provenance-linked to a durable target,
|
|
308
|
+
plus a review gate that STACKS ON the verifier gate — required approvals from
|
|
309
|
+
authorized roles, enforced inside `resolveCommitGate` AFTER the verifier checks
|
|
310
|
+
and never instead of them, failing closed on quorum/authority/self-approval and
|
|
311
|
+
recording who approved the very artifact that shipped. Policy (required approvals,
|
|
312
|
+
authorized roles, self-approval) is data, default off (pre-v0.1.32 behavior
|
|
313
|
+
unchanged). The verbs are parity-gated and render read-only in the v0.1.30
|
|
314
|
+
Workbench. See [Team Collaboration](team-collaboration.7.md).
|
|
315
|
+
|
|
316
|
+
## Release Tooling (v0.1.33)
|
|
317
|
+
|
|
318
|
+
the per-tag mechanical surfaces (version bump across 17 surfaces, feature scaffold, and the forward-reference docs) become deterministic scripts, with a de-duplicated release gate. See release-tooling(7).
|
|
319
|
+
|
|
320
|
+
## Real Execution Backend Integrations (v0.1.34)
|
|
321
|
+
|
|
322
|
+
container/remote/ci backends really execute (docker/podman run, remote/CI POST-and-poll) under the sandbox contract, with byte-stable evidence vs node and fail-closed refusal when a runtime/endpoint is unavailable. See real-execution-backends(7).
|
|
323
|
+
|
|
324
|
+
## Node Snapshot / Diff / Replay (v0.1.35)
|
|
325
|
+
|
|
326
|
+
per-node snapshot, structural diff, and isolated deterministic replay over StateNode, reusing the v0.1.23 eval harness; fail-closed on source drift (valid|stale|absent). See node-snapshot-diff-replay(7).
|
|
327
|
+
|
|
328
|
+
## Contract Migration Tooling (v0.1.36)
|
|
329
|
+
|
|
330
|
+
first-class declared migration registry (run-state + workflow-app) with per-edge compatibility proofs, fail-closed reachability, and a round-trip/non-destruction prover. See contract-migration-tooling(7).
|
|
331
|
+
|
|
332
|
+
## Control-Plane Scheduling (v0.1.37)
|
|
333
|
+
|
|
334
|
+
priority + concurrency limits + lease lifecycle + retry/backoff + fail-closed park over the v0.1.28 Run Registry queue; policy-as-data, deterministic. See control-plane-scheduling(7).
|
|
335
|
+
|
|
336
|
+
## Agent Delegation Drive (v0.1.38)
|
|
337
|
+
|
|
338
|
+
spawn an external agent process per worker, capture result.md + attestation, auto-drive plan->dispatch->fulfill->accept->commit
|
|
339
|
+
|
|
340
|
+
## Run Retention & Provable Reclamation (v0.1.39)
|
|
341
|
+
|
|
342
|
+
tiered, append-only, cryptographically-verifiable run reclamation: seal the audit skeleton, free the reconstructable bulk, prove it
|
|
343
|
+
|
|
344
|
+
## Durable State & Locking (v0.1.40)
|
|
345
|
+
|
|
346
|
+
atomic temp->rename writes + fsync-durability for authoritative stores; portable stale-stealing file lock serializing the cross-process read-modify-write stores
|
|
347
|
+
|
|
348
|
+
## Self-Audit Hardening & Pure-Router Decomposition (v0.1.41)
|
|
349
|
+
|
|
350
|
+
evidence grounding + durable audit append + symlink-hardened containment + deterministic worker ids + recursive redaction; BackendRegistry self-describing drivers (no per-id switches); orchestrator god-object decomposed into per-domain operation modules (pure loadRun->delegate router)
|
|
351
|
+
|
|
352
|
+
## Robust Result Ingest (v0.1.42)
|
|
353
|
+
|
|
354
|
+
capture findings/evidence from any reasonable agent shape (alt keys + prose), CW derives grounded evidence itself, warn on empty capture — closes the v0.1.41 live-drive 'accepted with 0 captured' failure
|
|
355
|
+
|
|
356
|
+
## No-False-Green Gate & Launch Prep (v0.1.43)
|
|
357
|
+
|
|
358
|
+
Hard gate blocking empty-capture verifier-gated commits, plus quickstart and launch-prep docs.
|
|
359
|
+
|
|
360
|
+
## Release-Gate Determinism & Agents Vendor (v0.1.44)
|
|
361
|
+
|
|
362
|
+
Release-readiness checks now validate the committed blob (`git show HEAD:<path>`) instead of the mutable working tree — eliminating false-red/false-green from concurrent working-tree writes (iCloud/Spotlight/editor). Adds the `agents` vendor manifest target: a generated `.agents/plugins/cool-workflow/` adapter giving any non-Claude AI agent one common interface to CW.
|
|
363
|
+
|
|
364
|
+
## P1-P2 Fixes & CI Content Surfaces (v0.1.49)
|
|
365
|
+
|
|
366
|
+
Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.46), vendor-adapter registry (v0.1.47), state auto-compaction and P2 fixes (v0.1.48), plus CI content-surface determinism hardening (v0.1.49).
|
|
367
|
+
0.1.51
|
|
368
|
+
|
|
369
|
+
0.1.76
|
|
370
|
+
|
|
371
|
+
0.1.77
|
|
372
|
+
|
|
373
|
+
0.1.78
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Contract Migration Tooling
|
|
2
|
+
|
|
3
|
+
CW v0.1.36 makes schema migration a first-class, declared subsystem. Before
|
|
4
|
+
v0.1.36 migration was ad-hoc and run-state-only: `RUN_STATE_MIGRATIONS` was an
|
|
5
|
+
inline step array walked by `migrateRunState`, with no declared `up`-transform
|
|
6
|
+
registry, no recorded compatibility PROOF, no round-trip/non-destruction
|
|
7
|
+
guarantee, and NOTHING covering the workflow-app schema (an old app schema was
|
|
8
|
+
flatly rejected, never migrated). v0.1.36 adds a declared registry, per-edge
|
|
9
|
+
compatibility proofs, fail-closed reachability, and a round-trip prover — reusing
|
|
10
|
+
the existing `migrateRunState` transform (no logic forked).
|
|
11
|
+
|
|
12
|
+
## The declared registry
|
|
13
|
+
|
|
14
|
+
`migration list` is the single declared source for "what versions exist and how
|
|
15
|
+
to advance them": one `MigrationContract` per schema (`run-state`,
|
|
16
|
+
`workflow-app`), each with `currentVersion`, `minVersion`, and an array of
|
|
17
|
+
`MigrationEdge { from, to, description, proof }`. The run-state edges ARE
|
|
18
|
+
`RUN_STATE_MIGRATIONS` (the transform is not duplicated). Each edge carries a
|
|
19
|
+
mechanically-checkable `MigrationCompatibilityProof` — the invariant it preserves
|
|
20
|
+
(`addsDefaulted`, `dropsNothing`), as data, not prose.
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
migration list [--json]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Fail closed on reachability
|
|
27
|
+
|
|
28
|
+
Before transforming, the chain `detected -> current` is resolved. If a contract's
|
|
29
|
+
detected version is below `minVersion`, above `currentVersion`, or has no chained
|
|
30
|
+
path, the verdict is `unsupported` with a named reason and NO write — never a
|
|
31
|
+
best-effort partial migration. (An older workflow-app, for which no edge exists
|
|
32
|
+
yet, fails closed with a precise reason instead of being silently accepted.)
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
migration check <target> [--contract run-state|workflow-app] [--json]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`<target>` is a run id (resolves to `.cw/runs/<id>/state.json`) or a path to a
|
|
39
|
+
`state.json` / app manifest. The verdict reports `status`
|
|
40
|
+
(`current|migrated|normalized|unsupported`), the detected/current versions, the
|
|
41
|
+
resolved `chain`, the change count, and any errors.
|
|
42
|
+
|
|
43
|
+
## Round-trip / non-destruction proof
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
migration prove <target> [--contract run-state|workflow-app] [--json]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`migration prove` runs the chain and PROVES four properties, emitting a
|
|
50
|
+
deterministic, sha256-fingerprinted `MigrationProof`:
|
|
51
|
+
|
|
52
|
+
- **validatesAtCurrent** — the result validates at `currentVersion`.
|
|
53
|
+
- **appendOnly** — every source record/key survives into the output (recursive);
|
|
54
|
+
nothing is destroyed.
|
|
55
|
+
- **idempotent** — re-running migration on the output yields no further change.
|
|
56
|
+
- **sourceImmutable** — `sourceHash == resultHash`-of-source: the original
|
|
57
|
+
snapshot is byte-unchanged (`migrateRunState` clones; the source `state.json` is
|
|
58
|
+
never mutated).
|
|
59
|
+
|
|
60
|
+
`pass` is the conjunction. An `unsupported` verdict never transforms and never
|
|
61
|
+
claims a positive proof.
|
|
62
|
+
|
|
63
|
+
## Append-only proof storage
|
|
64
|
+
|
|
65
|
+
`migration prove` persists the `MigrationProof` beside the target under
|
|
66
|
+
`migration/<fingerprint>.json` — a NEW file, never overwriting `state.json` or the
|
|
67
|
+
source manifest. Re-deriving from disk reproduces the same fingerprint.
|
|
68
|
+
|
|
69
|
+
## Surfaces & Compatibility
|
|
70
|
+
|
|
71
|
+
`migration.list`/`check`/`prove` are declared `surface: "both"`, so
|
|
72
|
+
`cw migration <verb> --json` and the `cw_migration_*` MCP tools render one core
|
|
73
|
+
(`src/contract-migration.ts`). Additive: the run-state and workflow-app schema
|
|
74
|
+
versions and `migrateRunState` are unchanged; the registry declares and proves
|
|
75
|
+
over the existing transform. Pre-0.1.36 runs and apps load unchanged.
|
|
76
|
+
|
|
77
|
+
## See Also
|
|
78
|
+
|
|
79
|
+
release-and-migration(7), state-explosion-management(7), workflow-app-framework(7),
|
|
80
|
+
cli-mcp-parity(7)
|
|
81
|
+
|
|
82
|
+
## Control-Plane Scheduling (v0.1.37)
|
|
83
|
+
|
|
84
|
+
priority + concurrency limits + lease lifecycle + retry/backoff + fail-closed park over the v0.1.28 Run Registry queue; policy-as-data, deterministic. See control-plane-scheduling(7).
|
|
85
|
+
|
|
86
|
+
## Agent Delegation Drive (v0.1.38)
|
|
87
|
+
|
|
88
|
+
spawn an external agent process per worker, capture result.md + attestation, auto-drive plan->dispatch->fulfill->accept->commit
|
|
89
|
+
|
|
90
|
+
## Run Retention & Provable Reclamation (v0.1.39)
|
|
91
|
+
|
|
92
|
+
tiered, append-only, cryptographically-verifiable run reclamation: seal the audit skeleton, free the reconstructable bulk, prove it
|
|
93
|
+
|
|
94
|
+
## Durable State & Locking (v0.1.40)
|
|
95
|
+
|
|
96
|
+
atomic temp->rename writes + fsync-durability for authoritative stores; portable stale-stealing file lock serializing the cross-process read-modify-write stores
|
|
97
|
+
|
|
98
|
+
## Self-Audit Hardening & Pure-Router Decomposition (v0.1.41)
|
|
99
|
+
|
|
100
|
+
evidence grounding + durable audit append + symlink-hardened containment + deterministic worker ids + recursive redaction; BackendRegistry self-describing drivers (no per-id switches); orchestrator god-object decomposed into per-domain operation modules (pure loadRun->delegate router)
|
|
101
|
+
|
|
102
|
+
## Robust Result Ingest (v0.1.42)
|
|
103
|
+
|
|
104
|
+
capture findings/evidence from any reasonable agent shape (alt keys + prose), CW derives grounded evidence itself, warn on empty capture — closes the v0.1.41 live-drive 'accepted with 0 captured' failure
|
|
105
|
+
|
|
106
|
+
## No-False-Green Gate & Launch Prep (v0.1.43)
|
|
107
|
+
|
|
108
|
+
Hard gate blocking empty-capture verifier-gated commits, plus quickstart and launch-prep docs.
|
|
109
|
+
|
|
110
|
+
## Release-Gate Determinism & Agents Vendor (v0.1.44)
|
|
111
|
+
|
|
112
|
+
Release-readiness checks now validate the committed blob (`git show HEAD:<path>`) instead of the mutable working tree — eliminating false-red/false-green from concurrent working-tree writes (iCloud/Spotlight/editor). Adds the `agents` vendor manifest target: a generated `.agents/plugins/cool-workflow/` adapter giving any non-Claude AI agent one common interface to CW.
|
|
113
|
+
|
|
114
|
+
## P1-P2 Fixes & CI Content Surfaces (v0.1.49)
|
|
115
|
+
|
|
116
|
+
Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.46), vendor-adapter registry (v0.1.47), state auto-compaction and P2 fixes (v0.1.48), plus CI content-surface determinism hardening (v0.1.49).
|
|
117
|
+
0.1.51
|
|
118
|
+
|
|
119
|
+
0.1.76
|
|
120
|
+
|
|
121
|
+
0.1.77
|
|
122
|
+
|
|
123
|
+
0.1.78
|