cool-workflow 0.1.82 → 0.1.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +4 -4
  3. package/README.md +124 -120
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +1 -1
  6. package/apps/end-to-end-golden-path/app.json +1 -1
  7. package/apps/pr-review-fix-ci/app.json +1 -1
  8. package/apps/release-cut/app.json +1 -1
  9. package/apps/research-synthesis/app.json +1 -1
  10. package/dist/capability-core.js +16 -8
  11. package/dist/capability-registry.js +8 -0
  12. package/dist/cli.js +12 -1
  13. package/dist/commit.js +5 -1
  14. package/dist/doctor.js +153 -0
  15. package/dist/mcp-server.js +11 -0
  16. package/dist/orchestrator.js +13 -0
  17. package/dist/reclamation/hash.js +72 -0
  18. package/dist/reclamation.js +25 -78
  19. package/dist/run-registry/queue.js +6 -7
  20. package/dist/run-registry.js +35 -24
  21. package/dist/scheduler.js +78 -53
  22. package/dist/version.js +1 -1
  23. package/dist/worker-isolation.js +22 -2
  24. package/docs/agent-delegation-drive.7.md +90 -86
  25. package/docs/agent-framework.md +33 -32
  26. package/docs/candidate-scoring.7.md +26 -24
  27. package/docs/canonical-workflow-apps.7.md +40 -40
  28. package/docs/capability-topology-registry.7.md +24 -24
  29. package/docs/cli-mcp-parity.7.md +226 -154
  30. package/docs/contract-migration-tooling.7.md +48 -41
  31. package/docs/control-plane-scheduling.7.md +45 -41
  32. package/docs/coordinator-blackboard.7.md +30 -30
  33. package/docs/dogfood-one-real-repo.7.md +44 -44
  34. package/docs/durable-state-and-locking.7.md +34 -30
  35. package/docs/end-to-end-golden-path.7.md +29 -29
  36. package/docs/error-feedback.7.md +27 -27
  37. package/docs/evidence-adoption-reasoning-chain.7.md +62 -58
  38. package/docs/execution-backends.7.md +84 -80
  39. package/docs/getting-started.md +35 -18
  40. package/docs/index.md +3 -3
  41. package/docs/mcp-app-surface.7.md +64 -64
  42. package/docs/multi-agent-cli-mcp-surface.7.md +82 -77
  43. package/docs/multi-agent-eval-replay-harness.7.md +59 -55
  44. package/docs/multi-agent-operator-ux.7.md +69 -65
  45. package/docs/multi-agent-runtime-core.7.md +39 -39
  46. package/docs/multi-agent-topologies.7.md +24 -24
  47. package/docs/multi-agent-trust-policy-audit.7.md +38 -38
  48. package/docs/node-snapshot-diff-replay.7.md +26 -22
  49. package/docs/observability-cost-accounting.7.md +49 -45
  50. package/docs/operator-ux.7.md +30 -30
  51. package/docs/pipeline-runner.7.md +31 -31
  52. package/docs/project-index.md +10 -5
  53. package/docs/real-execution-backends.7.md +47 -43
  54. package/docs/release-and-migration.7.md +42 -38
  55. package/docs/release-tooling.7.md +53 -49
  56. package/docs/routines.md +16 -16
  57. package/docs/run-registry-control-plane.7.md +120 -116
  58. package/docs/run-retention-reclamation.7.md +45 -41
  59. package/docs/sandbox-profiles.7.md +32 -32
  60. package/docs/scheduled-tasks.md +14 -14
  61. package/docs/security-trust-hardening.7.md +29 -29
  62. package/docs/source-context-profiles.7.md +28 -28
  63. package/docs/state-explosion-management.7.md +63 -59
  64. package/docs/state-node.7.md +8 -8
  65. package/docs/team-collaboration.7.md +62 -58
  66. package/docs/trust-model.md +126 -126
  67. package/docs/unix-principles.md +80 -80
  68. package/docs/vendor-manifest-loadability.7.md +20 -20
  69. package/docs/verifier-gated-commit.7.md +16 -16
  70. package/docs/web-desktop-workbench.7.md +69 -65
  71. package/docs/worker-isolation.7.md +34 -37
  72. package/docs/workflow-app-framework.7.md +38 -38
  73. package/manifest/plugin.manifest.json +4 -4
  74. package/package.json +3 -2
  75. package/scripts/canonical-apps.js +4 -4
  76. package/scripts/dogfood-release.js +1 -1
  77. package/scripts/gen-parity-doc.js +106 -0
  78. package/scripts/golden-path.js +4 -4
  79. package/dist/verifier-registry.js +0 -46
@@ -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.1.82",
86
+ "Cool Workflow v0.1.83",
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.1.82");
120
+ assert.equal(summary.version, "0.1.83");
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.1.82");
127
+ assert.equal(shown.app.version, "0.1.83");
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.1.82");
138
+ assert.equal(state.workflow.app.version, "0.1.83");
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`);
@@ -5,7 +5,7 @@ const { spawnSync } = require("node:child_process");
5
5
  const fs = require("node:fs");
6
6
  const path = require("node:path");
7
7
 
8
- const TARGET_VERSION = "0.1.82";
8
+ const TARGET_VERSION = "0.1.83";
9
9
  const PREVIOUS_VERSION = "0.1.31";
10
10
  const pluginRoot = path.resolve(__dirname, "..");
11
11
  const repoRoot = path.resolve(pluginRoot, "..", "..");
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // gen-parity-doc.js — generate the CLI<->MCP parity matrix, counts, and the
5
+ // surface-specific (cli-only / projected) enumerations in
6
+ // docs/cli-mcp-parity.7.md DIRECTLY from the capability registry (the single
7
+ // source of truth). The matrix declares itself "machine-complete by design", so
8
+ // it must BE machine-generated — a hand-maintained table drifts (it did: 132
9
+ // rows vs a 190-capability registry). Mechanism, not policy.
10
+ //
11
+ // node scripts/gen-parity-doc.js # rewrite the generated regions
12
+ // node scripts/gen-parity-doc.js --check # fail closed if the doc drifted
13
+ //
14
+ // Idempotent: re-running with no registry change is a no-op. Only the four
15
+ // marker-delimited regions are touched; all surrounding prose (incl. the Basic
16
+ // English narrative and version trailers) is preserved byte-for-byte.
17
+
18
+ const fs = require("node:fs");
19
+ const path = require("node:path");
20
+
21
+ const pluginRoot = path.resolve(__dirname, "..");
22
+ const DOC = path.join(pluginRoot, "docs", "cli-mcp-parity.7.md");
23
+ const CHECK = process.argv.includes("--check");
24
+
25
+ const { CAPABILITY_REGISTRY } = require(path.join(pluginRoot, "dist", "capability-registry.js"));
26
+
27
+ const NUM_WORDS = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve"];
28
+ const numWord = (n) => NUM_WORDS[n] || String(n);
29
+
30
+ function cliCommand(cap) {
31
+ return cap.cli ? `cw ${cap.cli.path.join(" ")}` : "—";
32
+ }
33
+ function cliDisplay(cap) {
34
+ // Human form used in the prose bullets (e.g. "schedule daemon", "demo tamper").
35
+ return cap.cli ? cap.cli.path.join(" ") : cap.capability;
36
+ }
37
+ function mcpTool(cap) {
38
+ return cap.mcp ? cap.mcp.tool : "—";
39
+ }
40
+ function payload(cap) {
41
+ if (cap.surface !== "both") return cap.surface;
42
+ return cap.payloadIdentical === false ? "projected" : "identical";
43
+ }
44
+
45
+ function buildCount() {
46
+ const caps = CAPABILITY_REGISTRY.length;
47
+ const tools = CAPABILITY_REGISTRY.filter((c) => c.mcp && c.mcp.tool).length;
48
+ return `machine-complete by design: ${caps} capabilities, ${tools} MCP tools.`;
49
+ }
50
+
51
+ function buildTable() {
52
+ const lines = [
53
+ "| Capability | CLI command | MCP tool | Core entry | Surface | Payload |",
54
+ "| --- | --- | --- | --- | --- | --- |"
55
+ ];
56
+ for (const cap of CAPABILITY_REGISTRY) {
57
+ lines.push(`| \`${cap.capability}\` | \`${cliCommand(cap)}\` | \`${mcpTool(cap)}\` | \`${cap.entry}\` | ${payload(cap) === "cli-only" || cap.surface !== "both" ? cap.surface : "both"} | ${payload(cap)} |`);
58
+ }
59
+ return lines.join("\n");
60
+ }
61
+
62
+ function buildCliOnly() {
63
+ const caps = CAPABILITY_REGISTRY.filter((c) => c.surface === "cli-only");
64
+ const head = `${numWord(caps.length)} ${caps.length === 1 ? "capability is" : "capabilities are"} CLI-only:`;
65
+ const bullets = caps.map((c) => `- \`${cliDisplay(c)}\` — ${c.reason || "(reason recorded in the registry)"}`);
66
+ return [head, "", ...bullets].join("\n");
67
+ }
68
+
69
+ function buildProjected() {
70
+ const caps = CAPABILITY_REGISTRY.filter((c) => c.surface === "both" && c.payloadIdentical === false);
71
+ const head = `${numWord(caps.length)} ${caps.length === 1 ? "capability is" : "capabilities are"} payload-divergent on purpose (\`projected\`):`;
72
+ const bullets = caps.map((c) => `- \`${c.capability}\` — ${c.reason || "(reason recorded in the registry)"}`);
73
+ return [head, "", ...bullets].join("\n");
74
+ }
75
+
76
+ const REGIONS = {
77
+ count: buildCount(),
78
+ table: buildTable(),
79
+ cliOnly: buildCliOnly(),
80
+ projected: buildProjected()
81
+ };
82
+
83
+ function replaceRegion(text, name, body) {
84
+ const begin = `<!-- gen:parity:${name} -->`;
85
+ const end = `<!-- /gen:parity:${name} -->`;
86
+ const re = new RegExp(`${begin}[\\s\\S]*?${end}`);
87
+ if (!re.test(text)) {
88
+ throw new Error(`marker ${begin} … ${end} not found in cli-mcp-parity.7.md — add the markers once, then re-run.`);
89
+ }
90
+ return text.replace(re, `${begin}\n${body}\n${end}`);
91
+ }
92
+
93
+ const original = fs.readFileSync(DOC, "utf8");
94
+ let next = original;
95
+ for (const [name, body] of Object.entries(REGIONS)) next = replaceRegion(next, name, body);
96
+
97
+ if (CHECK) {
98
+ if (next !== original) {
99
+ process.stderr.write("gen-parity-doc: docs/cli-mcp-parity.7.md is OUT OF SYNC with the capability registry. Run `node scripts/gen-parity-doc.js` and commit.\n");
100
+ process.exit(1);
101
+ }
102
+ process.stdout.write("gen-parity-doc: cli-mcp-parity.7.md in sync with the registry.\n");
103
+ } else {
104
+ if (next !== original) fs.writeFileSync(DOC, next);
105
+ process.stdout.write(`gen-parity-doc: ${next !== original ? "updated" : "unchanged"} — ${CAPABILITY_REGISTRY.length} capabilities, ${CAPABILITY_REGISTRY.filter((c) => c.mcp).length} MCP tools.\n`);
106
+ }
@@ -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.1.82");
36
+ assert.equal(appValidation.summary.version, "0.1.83");
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.1.82 end-to-end golden path."
45
+ "Prove the deterministic v0.1.83 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.1.82");
55
+ assert.equal(state.workflow.app.version, "0.1.83");
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\.1\.82/);
198
+ assert.match(report, /Workflow App: end-to-end-golden-path@0\.1\.83/);
199
199
  assert.match(report, /## Candidates/);
200
200
  assert.match(report, /## Trust Audit/);
201
201
  assert.match(report, /## Acceptance Rationale/);
@@ -1,46 +0,0 @@
1
- "use strict";
2
- // Verifier Registry — open pluggability for commit-gate verifiers.
3
- //
4
- // BSD discipline (mechanism separate from policy):
5
- // - MECHANISM: a Map<string, Verifier> with register + resolve.
6
- // - POLICY: which verifiers exist is declared via registerVerifier() at load time.
7
- // - FAIL CLOSED: unknown verifier id → named refusal.
8
- // - COMPOSABLE: multiple verifiers can be chained; each runs in registration order.
9
- //
10
- // From v0.1.58: the built-in verifier (validateResultEnvelope, validateRunGates,
11
- // hasGroundedEvidence) remains the default. Registered verifiers run BEFORE the
12
- // default — they can block or add evidence but cannot override the default gate.
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.registerVerifier = registerVerifier;
15
- exports.getVerifier = getVerifier;
16
- exports.listVerifiers = listVerifiers;
17
- exports.runAllVerifiers = runAllVerifiers;
18
- const _verifierRegistry = new Map();
19
- function registerVerifier(verifier) {
20
- _verifierRegistry.set(verifier.id, verifier);
21
- }
22
- function getVerifier(id) {
23
- return _verifierRegistry.get(id);
24
- }
25
- function listVerifiers() {
26
- return [..._verifierRegistry.values()];
27
- }
28
- /** Run all registered verifiers against a run. Returns the aggregated verdict:
29
- * "pass" if all pass, "block" if any block (first block reason wins). */
30
- async function runAllVerifiers(input) {
31
- const reasons = [];
32
- const evidence = [];
33
- for (const verifier of _verifierRegistry.values()) {
34
- const result = await verifier.verify(input);
35
- if (result.evidence)
36
- evidence.push(...result.evidence);
37
- if (result.verdict === "block") {
38
- reasons.push(`[${verifier.id}] ${result.reason || "blocked by verifier"}`);
39
- }
40
- else if (result.verdict === "warn") {
41
- reasons.push(`[${verifier.id}] warn: ${result.reason || "warning"}`);
42
- }
43
- }
44
- const blocked = reasons.some((r) => !r.includes("warn:"));
45
- return { verdict: blocked ? "block" : "pass", reasons, evidence };
46
- }