cool-workflow 0.1.82 → 0.1.84

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 (92) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/.codex-plugin/plugin.json +4 -4
  3. package/README.md +128 -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 +270 -0
  12. package/dist/cli/command-surface.js +1320 -0
  13. package/dist/cli.js +2 -1307
  14. package/dist/commit.js +5 -1
  15. package/dist/doctor.js +153 -0
  16. package/dist/mcp-server.js +15 -1451
  17. package/dist/mcp-surface.js +1441 -0
  18. package/dist/orchestrator.js +13 -0
  19. package/dist/reclamation/hash.js +72 -0
  20. package/dist/reclamation.js +25 -78
  21. package/dist/run-registry/queue.js +6 -7
  22. package/dist/run-registry.js +35 -24
  23. package/dist/scheduler.js +78 -53
  24. package/dist/version.js +1 -1
  25. package/dist/worker-accept/acceptance.js +114 -0
  26. package/dist/worker-accept/blackboard-fanout.js +80 -0
  27. package/dist/worker-accept/blackboard-linkage.js +19 -0
  28. package/dist/worker-accept/context.js +2 -0
  29. package/dist/worker-accept/telemetry-ledger.js +116 -0
  30. package/dist/worker-accept/validation.js +77 -0
  31. package/dist/worker-accept/verifier-completion.js +73 -0
  32. package/dist/worker-isolation.js +41 -446
  33. package/docs/agent-delegation-drive.7.md +94 -86
  34. package/docs/agent-framework.md +33 -32
  35. package/docs/candidate-scoring.7.md +26 -24
  36. package/docs/canonical-workflow-apps.7.md +40 -40
  37. package/docs/capability-topology-registry.7.md +24 -24
  38. package/docs/cli-mcp-parity.7.md +230 -154
  39. package/docs/contract-migration-tooling.7.md +52 -41
  40. package/docs/control-plane-scheduling.7.md +49 -41
  41. package/docs/coordinator-blackboard.7.md +30 -30
  42. package/docs/dogfood-one-real-repo.7.md +44 -44
  43. package/docs/durable-state-and-locking.7.md +38 -30
  44. package/docs/end-to-end-golden-path.7.md +29 -29
  45. package/docs/error-feedback.7.md +27 -27
  46. package/docs/evidence-adoption-reasoning-chain.7.md +66 -58
  47. package/docs/execution-backends.7.md +88 -80
  48. package/docs/getting-started.md +35 -18
  49. package/docs/index.md +3 -3
  50. package/docs/mcp-app-surface.7.md +64 -64
  51. package/docs/multi-agent-cli-mcp-surface.7.md +86 -77
  52. package/docs/multi-agent-eval-replay-harness.7.md +63 -55
  53. package/docs/multi-agent-operator-ux.7.md +73 -65
  54. package/docs/multi-agent-runtime-core.7.md +39 -39
  55. package/docs/multi-agent-topologies.7.md +24 -24
  56. package/docs/multi-agent-trust-policy-audit.7.md +38 -38
  57. package/docs/node-snapshot-diff-replay.7.md +30 -22
  58. package/docs/observability-cost-accounting.7.md +53 -45
  59. package/docs/operator-ux.7.md +30 -30
  60. package/docs/pipeline-runner.7.md +31 -31
  61. package/docs/project-index.md +16 -5
  62. package/docs/real-execution-backends.7.md +51 -43
  63. package/docs/release-and-migration.7.md +46 -38
  64. package/docs/release-tooling.7.md +67 -50
  65. package/docs/routines.md +16 -16
  66. package/docs/run-registry-control-plane.7.md +124 -116
  67. package/docs/run-retention-reclamation.7.md +49 -41
  68. package/docs/sandbox-profiles.7.md +32 -32
  69. package/docs/scheduled-tasks.md +14 -14
  70. package/docs/security-trust-hardening.7.md +29 -29
  71. package/docs/source-context-profiles.7.md +28 -28
  72. package/docs/state-explosion-management.7.md +67 -59
  73. package/docs/state-node.7.md +8 -8
  74. package/docs/team-collaboration.7.md +66 -58
  75. package/docs/trust-model.md +126 -126
  76. package/docs/unix-principles.md +80 -80
  77. package/docs/vendor-manifest-loadability.7.md +20 -20
  78. package/docs/verifier-gated-commit.7.md +16 -16
  79. package/docs/web-desktop-workbench.7.md +73 -65
  80. package/docs/worker-isolation.7.md +34 -37
  81. package/docs/workflow-app-framework.7.md +38 -38
  82. package/manifest/plugin.manifest.json +4 -4
  83. package/package.json +3 -2
  84. package/scripts/bump-version.js +9 -1
  85. package/scripts/canonical-apps.js +4 -4
  86. package/scripts/dogfood-release.js +1 -1
  87. package/scripts/gen-parity-doc.js +106 -0
  88. package/scripts/golden-path.js +4 -4
  89. package/scripts/parity-check.js +27 -57
  90. package/scripts/release-flow.js +7 -6
  91. package/scripts/sync-project-index.js +1 -1
  92. package/dist/verifier-registry.js +0 -46
@@ -3,7 +3,7 @@
3
3
  "id": "pr-review-fix-ci",
4
4
  "title": "PR Review Fix CI",
5
5
  "summary": "Review a pull request or branch, inspect CI failures, diagnose actionable issues, optionally patch, verify, and summarize with evidence.",
6
- "version": "0.1.82",
6
+ "version": "0.1.84",
7
7
  "author": "COOLWHITE LLC",
8
8
  "inputs": [
9
9
  {
@@ -3,7 +3,7 @@
3
3
  "id": "release-cut",
4
4
  "title": "Release Cut",
5
5
  "summary": "Prepare a release with checklist discipline: version checks, changelog, tests, packaging, release notes, and final verification.",
6
- "version": "0.1.82",
6
+ "version": "0.1.84",
7
7
  "author": "COOLWHITE LLC",
8
8
  "inputs": [
9
9
  {
@@ -3,7 +3,7 @@
3
3
  "id": "research-synthesis",
4
4
  "title": "Research Synthesis",
5
5
  "summary": "Split a research question into claims, investigate sources, cross-check evidence, verify claims, and synthesize a concise answer.",
6
- "version": "0.1.82",
6
+ "version": "0.1.84",
7
7
  "author": "COOLWHITE LLC",
8
8
  "inputs": [
9
9
  {
@@ -333,13 +333,12 @@ function queueShow(reg, id) {
333
333
  // ---- control-plane scheduling (v0.1.37) -----------------------------------
334
334
  function loadSchedulingPolicy(reg) {
335
335
  const file = reg.schedulingPolicyPath();
336
+ // Absent policy => conservative DEFAULT (an unconfigured backend, which §4
337
+ // permits). But a PRESENT-but-corrupt policy must fail closed: silently
338
+ // substituting defaults would schedule under settings the operator never
339
+ // chose while their broken file sits on disk. Let readJson's throw surface it.
336
340
  if (node_fs_1.default.existsSync(file)) {
337
- try {
338
- return { policy: (0, scheduling_1.normalizeSchedulingPolicy)((0, state_1.readJson)(file)), source: "file" };
339
- }
340
- catch {
341
- /* fall through to default */
342
- }
341
+ return { policy: (0, scheduling_1.normalizeSchedulingPolicy)((0, state_1.readJson)(file)), source: "file" };
343
342
  }
344
343
  return { policy: scheduling_1.DEFAULT_SCHEDULING_POLICY, source: "default" };
345
344
  }
@@ -400,8 +399,17 @@ function schedPolicySet(reg, args) {
400
399
  const current = loadSchedulingPolicy(reg).policy;
401
400
  const patch = {};
402
401
  for (const key of ["maxConcurrent", "maxAttempts", "leaseTtlMs", "backoffBaseMs", "backoffFactor", "backoffCapMs"]) {
403
- if (args[key] !== undefined)
404
- patch[key] = Number(args[key]);
402
+ if (args[key] === undefined)
403
+ continue;
404
+ // Fail closed on a non-numeric flag instead of letting normalizeSchedulingPolicy
405
+ // silently substitute the DEFAULT (which would report source:"file" + exit 0,
406
+ // so the operator believes they set a value they didn't). Matches the
407
+ // Number.isFinite guard the sibling reclaimPolicyFrom already uses.
408
+ const value = Number(args[key]);
409
+ if (!Number.isFinite(value)) {
410
+ throw new Error(`Invalid --${key} "${String(args[key])}": expected a number (e.g. --${key} 4)`);
411
+ }
412
+ patch[key] = value;
405
413
  }
406
414
  const policy = (0, scheduling_1.normalizeSchedulingPolicy)({ ...current, ...patch });
407
415
  (0, state_1.writeJson)(reg.schedulingPolicyPath(), policy);
@@ -26,10 +26,17 @@
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
27
  exports.CAPABILITY_REGISTRY = void 0;
28
28
  exports.declaredMcpTools = declaredMcpTools;
29
+ exports.mcpCapabilityForTool = mcpCapabilityForTool;
30
+ exports.mcpCapabilityForId = mcpCapabilityForId;
31
+ exports.mcpRequiredArgsForTool = mcpRequiredArgsForTool;
32
+ exports.mcpToolDefinition = mcpToolDefinition;
29
33
  exports.declaredCliTokens = declaredCliTokens;
30
34
  exports.requiresReason = requiresReason;
31
35
  exports.isPayloadProbeOptOut = isPayloadProbeOptOut;
32
36
  exports.payloadIdenticalCapabilities = payloadIdenticalCapabilities;
37
+ exports.payloadProbeTargets = payloadProbeTargets;
38
+ exports.deferredPayloadProbeCapabilities = deferredPayloadProbeCapabilities;
39
+ exports.payloadProbePlan = payloadProbePlan;
33
40
  exports.buildParityReport = buildParityReport;
34
41
  // ---------------------------------------------------------------------------
35
42
  // Builtin entries. Grouped to mirror the CLI dispatch and the MCP tool list.
@@ -52,6 +59,14 @@ const BUILTIN_CAPABILITIES = [
52
59
  cli: { path: ["list"], jsonMode: "default" },
53
60
  mcp: { tool: "cw_list" }
54
61
  },
62
+ {
63
+ capability: "doctor",
64
+ summary: "Diagnose the host for setup problems (Node version, agent backend, agent binary on PATH, git, writable home/repo state) and print an actionable fix per check.",
65
+ entry: "runDoctor",
66
+ surface: "cli-only",
67
+ cli: { path: ["doctor"], jsonMode: "flag" },
68
+ reason: "Environment diagnostics are inherently local to the CLI host — Node version, $PATH, $CW_HOME/cwd writability. An MCP client diagnosing the server process's environment is not meaningful; agents already receive the same readiness facts in their typed results (e.g. status: blocked, agentConfigured). Inspired by `brew doctor`."
69
+ },
55
70
  {
56
71
  capability: "init",
57
72
  summary: "Scaffold a new workflow definition.",
@@ -404,12 +419,236 @@ const BUILTIN_CAPABILITIES = [
404
419
  * silently-dead duplicate the way the old snapshot-then-register design allowed. */
405
420
  exports.CAPABILITY_REGISTRY = Array.from(new Map(BUILTIN_CAPABILITIES.map((cap) => [cap.capability, cap])).values());
406
421
  // ---------------------------------------------------------------------------
422
+ // Payload probe classification.
423
+ // ---------------------------------------------------------------------------
424
+ const GLOBAL_PAYLOAD_PROBE_CAPABILITIES = [
425
+ "list",
426
+ "app.list",
427
+ "topology.list",
428
+ "sandbox.list",
429
+ "backend.list",
430
+ "backend.agent.config.show",
431
+ "metrics.summary"
432
+ ];
433
+ const RUN_PAYLOAD_PROBE_CAPABILITIES = [
434
+ "status",
435
+ "operator.status",
436
+ "operator.report",
437
+ "graph",
438
+ "report",
439
+ "next",
440
+ "state.check",
441
+ "contract.show",
442
+ "node.list",
443
+ "node.graph",
444
+ "worker.summary",
445
+ "candidate.summary",
446
+ "feedback.summary",
447
+ "commit.summary",
448
+ "audit.summary",
449
+ "multi-agent.summary",
450
+ "workbench.view",
451
+ "metrics.show",
452
+ "review.status",
453
+ "comment.list",
454
+ "run.drive",
455
+ "gc.plan",
456
+ "gc.verify"
457
+ ];
458
+ const PAYLOAD_PROBE_DEFERRED_GROUPS = [
459
+ {
460
+ reason: "Not safe for the deterministic bootstrap parity probe yet: this capability needs extra target ids/files, mutates durable state, depends on external state, or needs a dedicated fixture beyond cwd/runId.",
461
+ capabilities: [
462
+ "init",
463
+ "plan",
464
+ "dispatch",
465
+ "result",
466
+ "app.show",
467
+ "app.validate",
468
+ "app.init",
469
+ "app.package",
470
+ "app.run",
471
+ "node.show",
472
+ "node.snapshot",
473
+ "node.diff",
474
+ "node.replay",
475
+ "node.replay.verify",
476
+ "migration.list",
477
+ "migration.check",
478
+ "migration.prove",
479
+ "topology.show",
480
+ "topology.validate",
481
+ "topology.apply",
482
+ "topology.summary",
483
+ "topology.graph",
484
+ "summary.refresh",
485
+ "summary.show",
486
+ "multi-agent.run",
487
+ "multi-agent.status",
488
+ "multi-agent.step",
489
+ "multi-agent.blackboard",
490
+ "multi-agent.score",
491
+ "multi-agent.select",
492
+ "multi-agent.summarize",
493
+ "multi-agent.graph",
494
+ "multi-agent.graph.compact",
495
+ "multi-agent.dependencies",
496
+ "multi-agent.failures",
497
+ "multi-agent.evidence",
498
+ "multi-agent.reasoning",
499
+ "multi-agent.reasoning.refresh",
500
+ "multi-agent.run.create",
501
+ "multi-agent.run.transition",
502
+ "multi-agent.run.show",
503
+ "multi-agent.role.create",
504
+ "multi-agent.role.show",
505
+ "multi-agent.group.create",
506
+ "multi-agent.group.show",
507
+ "multi-agent.membership.create",
508
+ "multi-agent.membership.show",
509
+ "multi-agent.fanout.create",
510
+ "multi-agent.fanout.show",
511
+ "multi-agent.fanin.collect",
512
+ "multi-agent.fanin.show",
513
+ "eval.snapshot",
514
+ "eval.replay",
515
+ "eval.compare",
516
+ "eval.score",
517
+ "eval.gate",
518
+ "eval.report",
519
+ "blackboard.summary",
520
+ "blackboard.summarize",
521
+ "blackboard.graph",
522
+ "blackboard.resolve",
523
+ "blackboard.topic.create",
524
+ "blackboard.message.post",
525
+ "blackboard.message.list",
526
+ "blackboard.context.put",
527
+ "blackboard.artifact.add",
528
+ "blackboard.artifact.list",
529
+ "blackboard.snapshot",
530
+ "coordinator.summary",
531
+ "coordinator.decision",
532
+ "audit.verify",
533
+ "audit.worker",
534
+ "audit.provenance",
535
+ "audit.multi-agent",
536
+ "audit.policy",
537
+ "audit.role",
538
+ "audit.blackboard",
539
+ "audit.judge",
540
+ "audit.attest",
541
+ "audit.decision",
542
+ "sandbox.show",
543
+ "sandbox.validate",
544
+ "sandbox.choose",
545
+ "sandbox.resolve",
546
+ "backend.show",
547
+ "backend.probe",
548
+ "worker.list",
549
+ "worker.show",
550
+ "worker.manifest",
551
+ "worker.output",
552
+ "worker.fail",
553
+ "worker.validate",
554
+ "candidate.list",
555
+ "candidate.show",
556
+ "candidate.register",
557
+ "candidate.score",
558
+ "candidate.rank",
559
+ "candidate.select",
560
+ "candidate.reject",
561
+ "feedback.list",
562
+ "feedback.show",
563
+ "feedback.collect",
564
+ "feedback.task",
565
+ "feedback.resolve",
566
+ "schedule.create",
567
+ "schedule.list",
568
+ "schedule.delete",
569
+ "schedule.due",
570
+ "schedule.complete",
571
+ "schedule.pause",
572
+ "schedule.resume",
573
+ "schedule.run-now",
574
+ "schedule.history",
575
+ "routine.create",
576
+ "routine.list",
577
+ "routine.delete",
578
+ "routine.fire",
579
+ "routine.events",
580
+ "registry.refresh",
581
+ "registry.show",
582
+ "run.search",
583
+ "run.list",
584
+ "run.show",
585
+ "run.resume",
586
+ "run.archive",
587
+ "run.rerun",
588
+ "run.export",
589
+ "run.import",
590
+ "run.verify-import",
591
+ "run.inspect-archive",
592
+ "queue.add",
593
+ "queue.list",
594
+ "queue.drain",
595
+ "queue.show",
596
+ "sched.plan",
597
+ "sched.lease",
598
+ "sched.release",
599
+ "sched.complete",
600
+ "sched.reclaim",
601
+ "sched.reset",
602
+ "sched.policy.show",
603
+ "sched.policy.set",
604
+ "telemetry.verify",
605
+ "history",
606
+ "approve",
607
+ "reject",
608
+ "comment.add",
609
+ "handoff",
610
+ "review.policy"
611
+ ]
612
+ }
613
+ ];
614
+ // ---------------------------------------------------------------------------
407
615
  // Derivations + the fail-closed parity report builder.
408
616
  // ---------------------------------------------------------------------------
409
617
  /** The MCP tool names this registry declares. */
410
618
  function declaredMcpTools() {
411
619
  return exports.CAPABILITY_REGISTRY.filter((cap) => cap.mcp).map((cap) => cap.mcp.tool);
412
620
  }
621
+ /** The descriptor for a registry-declared MCP tool name. */
622
+ function mcpCapabilityForTool(tool) {
623
+ return exports.CAPABILITY_REGISTRY.find((capability) => capability.mcp?.tool === tool);
624
+ }
625
+ /** The descriptor for a registry-declared capability id. */
626
+ function mcpCapabilityForId(capabilityId) {
627
+ const descriptor = exports.CAPABILITY_REGISTRY.find((capability) => capability.capability === capabilityId);
628
+ return descriptor?.mcp ? descriptor : undefined;
629
+ }
630
+ /** Required MCP argument groups for a registry-declared tool. */
631
+ function mcpRequiredArgsForTool(tool) {
632
+ return mcpCapabilityForTool(tool)?.mcp?.requiredArgs ?? [];
633
+ }
634
+ function mcpToolDefinition(capabilityId, descriptionOrProperties, maybeProperties) {
635
+ const descriptor = mcpCapabilityForId(capabilityId);
636
+ if (!descriptor?.mcp)
637
+ throw new Error(`MCP capability not declared: ${capabilityId}`);
638
+ const description = typeof descriptionOrProperties === "string" ? descriptionOrProperties : descriptor.summary;
639
+ const properties = typeof descriptionOrProperties === "string" ? maybeProperties : descriptionOrProperties;
640
+ if (!properties)
641
+ throw new Error(`MCP capability ${capabilityId} missing input schema properties.`);
642
+ return {
643
+ name: descriptor.mcp.tool,
644
+ description,
645
+ inputSchema: {
646
+ type: "object",
647
+ properties,
648
+ additionalProperties: true
649
+ }
650
+ };
651
+ }
413
652
  /** The CLI `case` tokens this registry declares (deduped). */
414
653
  function declaredCliTokens() {
415
654
  const tokens = new Set();
@@ -452,6 +691,30 @@ function isPayloadProbeOptOut(cap) {
452
691
  function payloadIdenticalCapabilities() {
453
692
  return exports.CAPABILITY_REGISTRY.filter((cap) => cap.surface === "both" && cap.cli && cap.mcp && !isPayloadProbeOptOut(cap));
454
693
  }
694
+ function payloadProbeTargets() {
695
+ return [
696
+ ...GLOBAL_PAYLOAD_PROBE_CAPABILITIES.map((capability) => ({ capability, kind: "global" })),
697
+ ...RUN_PAYLOAD_PROBE_CAPABILITIES.map((capability) => ({ capability, kind: "run" }))
698
+ ];
699
+ }
700
+ function deferredPayloadProbeCapabilities() {
701
+ return PAYLOAD_PROBE_DEFERRED_GROUPS.flatMap((group) => group.capabilities.map((capability) => ({ capability, reason: group.reason })));
702
+ }
703
+ function payloadProbePlan() {
704
+ const candidateIds = new Set(payloadIdenticalCapabilities().map((cap) => cap.capability));
705
+ const counts = new Map();
706
+ const classified = [...payloadProbeTargets().map((entry) => entry.capability), ...deferredPayloadProbeCapabilities().map((entry) => entry.capability)];
707
+ for (const capability of classified)
708
+ counts.set(capability, (counts.get(capability) || 0) + 1);
709
+ const classifiedIds = new Set(classified);
710
+ return {
711
+ targets: payloadProbeTargets(),
712
+ deferred: deferredPayloadProbeCapabilities(),
713
+ unclassified: [...candidateIds].filter((capability) => !classifiedIds.has(capability)).sort(),
714
+ duplicateClassifications: [...counts.entries()].filter(([, count]) => count > 1).map(([capability]) => capability).sort(),
715
+ invalidClassifications: [...classifiedIds].filter((capability) => !candidateIds.has(capability)).sort()
716
+ };
717
+ }
455
718
  function lintRegistry() {
456
719
  const issues = [];
457
720
  const seenCaps = new Set();
@@ -494,12 +757,16 @@ function buildParityReport(input) {
494
757
  const reasonlessExceptions = exports.CAPABILITY_REGISTRY.filter((cap) => requiresReason(cap) && !(cap.reason && cap.reason.trim()))
495
758
  .map((cap) => cap.capability)
496
759
  .sort();
760
+ const payloadPlan = payloadProbePlan();
497
761
  const registryLint = lintRegistry();
498
762
  const ok = missingMcpTools.length === 0 &&
499
763
  undeclaredMcpTools.length === 0 &&
500
764
  missingCliTokens.length === 0 &&
501
765
  undeclaredCliTokens.length === 0 &&
502
766
  reasonlessExceptions.length === 0 &&
767
+ payloadPlan.unclassified.length === 0 &&
768
+ payloadPlan.duplicateClassifications.length === 0 &&
769
+ payloadPlan.invalidClassifications.length === 0 &&
503
770
  registryLint.length === 0;
504
771
  return {
505
772
  ok,
@@ -509,6 +776,9 @@ function buildParityReport(input) {
509
776
  missingCliTokens,
510
777
  undeclaredCliTokens,
511
778
  reasonlessExceptions,
779
+ payloadProbeUnclassified: payloadPlan.unclassified,
780
+ payloadProbeDuplicateClassifications: payloadPlan.duplicateClassifications,
781
+ payloadProbeInvalidClassifications: payloadPlan.invalidClassifications,
512
782
  registryLint
513
783
  };
514
784
  }