cool-workflow 0.1.81 → 0.1.82

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 (66) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +1 -1
  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/candidate-scoring.js +20 -26
  11. package/dist/capability-core.js +64 -85
  12. package/dist/capability-registry.js +22 -3
  13. package/dist/commit.js +212 -203
  14. package/dist/coordinator/util.js +6 -9
  15. package/dist/dispatch.js +11 -3
  16. package/dist/evidence-reasoning.js +4 -1
  17. package/dist/execution-backend/agent.js +11 -48
  18. package/dist/execution-backend.js +11 -31
  19. package/dist/gates.js +48 -0
  20. package/dist/multi-agent/helpers.js +6 -10
  21. package/dist/multi-agent/ids.js +20 -0
  22. package/dist/multi-agent-eval.js +27 -1
  23. package/dist/multi-agent-host.js +53 -21
  24. package/dist/multi-agent-operator-ux.js +2 -1
  25. package/dist/multi-agent-trust.js +5 -5
  26. package/dist/node-projection.js +59 -0
  27. package/dist/node-snapshot.js +8 -18
  28. package/dist/orchestrator/lifecycle-operations.js +22 -1
  29. package/dist/orchestrator.js +16 -2
  30. package/dist/reclamation.js +8 -36
  31. package/dist/scheduler.js +34 -4
  32. package/dist/topology.js +25 -4
  33. package/dist/trust-audit.js +70 -38
  34. package/dist/validation.js +328 -0
  35. package/dist/version.js +1 -1
  36. package/dist/worker-isolation.js +143 -58
  37. package/docs/agent-delegation-drive.7.md +1 -0
  38. package/docs/cli-mcp-parity.7.md +1 -0
  39. package/docs/contract-migration-tooling.7.md +1 -0
  40. package/docs/control-plane-scheduling.7.md +1 -0
  41. package/docs/durable-state-and-locking.7.md +1 -0
  42. package/docs/evidence-adoption-reasoning-chain.7.md +1 -0
  43. package/docs/execution-backends.7.md +1 -0
  44. package/docs/multi-agent-cli-mcp-surface.7.md +1 -0
  45. package/docs/multi-agent-eval-replay-harness.7.md +1 -0
  46. package/docs/multi-agent-operator-ux.7.md +1 -0
  47. package/docs/node-snapshot-diff-replay.7.md +1 -0
  48. package/docs/observability-cost-accounting.7.md +1 -0
  49. package/docs/project-index.md +8 -4
  50. package/docs/real-execution-backends.7.md +1 -0
  51. package/docs/release-and-migration.7.md +1 -0
  52. package/docs/release-tooling.7.md +33 -2
  53. package/docs/run-registry-control-plane.7.md +1 -0
  54. package/docs/run-retention-reclamation.7.md +1 -0
  55. package/docs/state-explosion-management.7.md +1 -0
  56. package/docs/team-collaboration.7.md +1 -0
  57. package/docs/web-desktop-workbench.7.md +1 -0
  58. package/manifest/plugin.manifest.json +1 -1
  59. package/manifest/source-context-profiles.json +1 -1
  60. package/package.json +1 -1
  61. package/scripts/canonical-apps.js +4 -4
  62. package/scripts/children/batch-delegate-child.js +58 -0
  63. package/scripts/children/http-delegate-child.js +39 -0
  64. package/scripts/dogfood-release.js +1 -1
  65. package/scripts/golden-path.js +4 -4
  66. package/scripts/release-flow.js +181 -5
@@ -34,6 +34,7 @@ const telemetry_ledger_1 = require("./telemetry-ledger");
34
34
  const coordinator_1 = require("./coordinator");
35
35
  const helpers_1 = require("./worker-isolation/helpers");
36
36
  const paths_1 = require("./worker-isolation/paths");
37
+ const validation_1 = require("./validation");
37
38
  exports.WORKER_ISOLATION_SCHEMA_VERSION = 1;
38
39
  function allocateWorkerScope(run, task, options = {}) {
39
40
  ensureWorkerState(run);
@@ -269,11 +270,31 @@ function getWorkerScope(run, workerId) {
269
270
  const file = node_path_1.default.join(workerRoot(run), (0, state_1.safeFileName)(workerId), paths_1.WORKER_SCOPE_FILE);
270
271
  if (!node_fs_1.default.existsSync(file))
271
272
  return undefined;
272
- const scope = JSON.parse(node_fs_1.default.readFileSync(file, "utf8"));
273
+ const scope = (0, validation_1.validateWorkerScope)(JSON.parse(node_fs_1.default.readFileSync(file, "utf8")));
273
274
  upsertWorkerScope(run, scope);
274
275
  return scope;
275
276
  }
276
277
  function recordWorkerOutput(run, workerId, resultPath, options = {}) {
278
+ // Accept-path orchestrator. The recorded order + side effects of these ordered
279
+ // steps are load-bearing (replay determinism + the hash-chained audit/telemetry
280
+ // ledgers cross-link by parent event ids), so each helper runs exactly where it
281
+ // did before and mutates the shared `accept` context in place. Do NOT reorder.
282
+ const accept = validateWorkerResult(run, workerId, resultPath, options);
283
+ const delegation = attestWorkerDelegation(accept);
284
+ acceptWorkerResult(accept, delegation);
285
+ recordWorkerDelegationLedger(accept, delegation);
286
+ runWorkerVerify(accept);
287
+ recordWorkerCompletion(accept, delegation);
288
+ fanOutWorkerOutput(accept);
289
+ if (options.persist !== false)
290
+ (0, state_1.saveCheckpoint)(run);
291
+ return accept.output;
292
+ }
293
+ /** Step 1 — validateResult: resolve scope/task, enforce the sandbox boundary, the
294
+ * result-file existence, the envelope contract, and (opt-in) resolvable evidence.
295
+ * Fail-closed: any guard records a worker failure and throws BEFORE accept-side
296
+ * state mutation. Returns the partially-filled accept context on success. */
297
+ function validateWorkerResult(run, workerId, resultPath, options) {
277
298
  const scope = requireWorkerScope(run, workerId);
278
299
  const task = requireWorkerTask(run, scope);
279
300
  const absoluteResultPath = node_path_1.default.resolve(resultPath);
@@ -316,6 +337,30 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
316
337
  throw new Error(error.message);
317
338
  }
318
339
  }
340
+ return {
341
+ run,
342
+ workerId,
343
+ options,
344
+ scope,
345
+ task,
346
+ absoluteResultPath,
347
+ rawResult,
348
+ parsedResult,
349
+ destination: "",
350
+ pathAuditId: "",
351
+ acceptedAuditId: "",
352
+ resultNode: undefined,
353
+ verifierNodeId: "",
354
+ verifierStatus: "",
355
+ output: undefined
356
+ };
357
+ }
358
+ /** Step 2 — attestSandbox/attestDelegation: verify the agent's signed telemetry
359
+ * BEFORE recording it, enforce the opt-in require-attested-telemetry gate (still
360
+ * fail-closed, pre-mutation), and build the agent-hop provenance. Non-agent hops
361
+ * return an empty delegation. */
362
+ function attestWorkerDelegation(accept) {
363
+ const { run, workerId, options, task, absoluteResultPath, rawResult } = accept;
319
364
  // Agent Delegation Drive (v0.1.38): if this worker's result.md was produced by an
320
365
  // EXTERNAL agent, record the agent-hop attestation AS PROVENANCE — the agent
321
366
  // (kind:process) handle, the agent-REPORTED model (never CW_AGENT_MODEL), the
@@ -355,6 +400,16 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
355
400
  ...(telemetry ? { usageAttestation: telemetry.status, usageAttestationReason: telemetry.reason } : {})
356
401
  }
357
402
  : undefined;
403
+ return { agentDelegation, telemetry };
404
+ }
405
+ /** Step 3 — recordStateNode/audit: the irreversible accept. Records the allowed
406
+ * path decision, copies the result into the run results dir, completes the task,
407
+ * builds + appends the result node, emits the accepted audit event, re-normalizes
408
+ * node evidence against both audit ids, and surfaces the empty-capture warning.
409
+ * Writes destination/pathAuditId/acceptedAuditId/resultNode back into `accept`. */
410
+ function acceptWorkerResult(accept, delegation) {
411
+ const { run, workerId, scope, task, absoluteResultPath, parsedResult } = accept;
412
+ const { agentDelegation } = delegation;
358
413
  const pathAudit = (0, trust_audit_1.recordSandboxPathDecision)(run, {
359
414
  workerId,
360
415
  taskId: task.id,
@@ -443,58 +498,75 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
443
498
  metadata: { reason: "no findings or evidence captured from result.md", resultPath: destination }
444
499
  });
445
500
  }
501
+ accept.destination = destination;
502
+ accept.pathAuditId = pathAudit.id;
503
+ accept.acceptedAuditId = acceptedAudit.id;
504
+ accept.resultNode = resultNode;
505
+ }
506
+ /** Step 4 — recordTelemetryLedger: the agent-hop attestation. Binds the telemetry
507
+ * verdict into the append-only hash-chained ledger BEFORE the audit event (so the
508
+ * event can cross-link the record hash), then emits the worker.agent-delegation
509
+ * audit event. No-op for non-agent hops. */
510
+ function recordWorkerDelegationLedger(accept, delegation) {
511
+ const { agentDelegation } = delegation;
446
512
  // The agent-hop attestation event — hung off worker.output, alongside
447
513
  // worker.backend. Recorded in trust-audit/provenance, NEVER in node evidence.
448
- if (agentDelegation) {
449
- // Track 1 (tamper-evidence): bind this verdict into the append-only,
450
- // hash-chained telemetry ledger BEFORE the audit event, so the event can
451
- // cross-link the record hash. Editing the recorded verdict/usage later breaks
452
- // the chain (verifyTelemetryLedger). Only when a verdict was computed.
453
- const ledgerRecord = agentDelegation.usageAttestation
454
- ? (0, telemetry_ledger_1.appendTelemetryAttestation)(run, {
455
- workerId,
456
- taskId: task.id,
457
- promptDigest: agentDelegation.promptDigest,
458
- reportedUsage: agentDelegation.reportedUsage,
459
- usageSignature: agentDelegation.usageSignature,
460
- attestation: agentDelegation.usageAttestation,
461
- attestationReason: agentDelegation.usageAttestationReason
462
- })
463
- : undefined;
464
- (0, trust_audit_1.recordTrustAuditEvent)(run, {
465
- kind: "worker.agent-delegation",
466
- decision: "recorded",
467
- source: "host-attested",
514
+ if (!agentDelegation)
515
+ return;
516
+ const { run, workerId, scope, task, resultNode, acceptedAuditId } = accept;
517
+ // Track 1 (tamper-evidence): bind this verdict into the append-only,
518
+ // hash-chained telemetry ledger BEFORE the audit event, so the event can
519
+ // cross-link the record hash. Editing the recorded verdict/usage later breaks
520
+ // the chain (verifyTelemetryLedger). Only when a verdict was computed.
521
+ const ledgerRecord = agentDelegation.usageAttestation
522
+ ? (0, telemetry_ledger_1.appendTelemetryAttestation)(run, {
468
523
  workerId,
469
524
  taskId: task.id,
470
- nodeId: resultNode.id,
471
- sandboxProfileId: scope.sandboxProfileId,
472
- policySnapshot: scope.sandboxPolicy,
473
- parentEventIds: [acceptedAudit.id],
474
- metadata: {
475
- backendId: agentDelegation.backendId,
476
- handleKind: agentDelegation.handle.kind,
477
- handleRef: agentDelegation.handle.ref,
478
- model: agentDelegation.model,
479
- promptDigest: agentDelegation.promptDigest,
480
- resultDigest: agentDelegation.resultDigest,
481
- command: agentDelegation.command,
482
- args: agentDelegation.args,
483
- exitCode: agentDelegation.exitCode,
484
- // Track 1: the telemetry verdict travels with the agent-hop event so the
485
- // audit report can surface `unattested` usage loudly. Absent ⇒ no usage.
486
- ...(agentDelegation.usageAttestation
487
- ? {
488
- telemetryAttestation: agentDelegation.usageAttestation,
489
- ...(agentDelegation.usageAttestationReason ? { telemetryAttestationReason: agentDelegation.usageAttestationReason } : {}),
490
- ...(agentDelegation.reportedUsage ? { reportedUsage: agentDelegation.reportedUsage } : {}),
491
- // Cross-link to the hash-chained ledger entry (tamper-evidence).
492
- ...(ledgerRecord ? { telemetryRecordId: ledgerRecord.recordId, telemetryRecordHash: ledgerRecord.recordHash, telemetryPrevHash: ledgerRecord.prevHash } : {})
493
- }
494
- : {})
495
- }
496
- });
497
- }
525
+ promptDigest: agentDelegation.promptDigest,
526
+ reportedUsage: agentDelegation.reportedUsage,
527
+ usageSignature: agentDelegation.usageSignature,
528
+ attestation: agentDelegation.usageAttestation,
529
+ attestationReason: agentDelegation.usageAttestationReason
530
+ })
531
+ : undefined;
532
+ (0, trust_audit_1.recordTrustAuditEvent)(run, {
533
+ kind: "worker.agent-delegation",
534
+ decision: "recorded",
535
+ source: "host-attested",
536
+ workerId,
537
+ taskId: task.id,
538
+ nodeId: resultNode.id,
539
+ sandboxProfileId: scope.sandboxProfileId,
540
+ policySnapshot: scope.sandboxPolicy,
541
+ parentEventIds: [acceptedAuditId],
542
+ metadata: {
543
+ backendId: agentDelegation.backendId,
544
+ handleKind: agentDelegation.handle.kind,
545
+ handleRef: agentDelegation.handle.ref,
546
+ model: agentDelegation.model,
547
+ promptDigest: agentDelegation.promptDigest,
548
+ resultDigest: agentDelegation.resultDigest,
549
+ command: agentDelegation.command,
550
+ args: agentDelegation.args,
551
+ exitCode: agentDelegation.exitCode,
552
+ // Track 1: the telemetry verdict travels with the agent-hop event so the
553
+ // audit report can surface `unattested` usage loudly. Absent ⇒ no usage.
554
+ ...(agentDelegation.usageAttestation
555
+ ? {
556
+ telemetryAttestation: agentDelegation.usageAttestation,
557
+ ...(agentDelegation.usageAttestationReason ? { telemetryAttestationReason: agentDelegation.usageAttestationReason } : {}),
558
+ ...(agentDelegation.reportedUsage ? { reportedUsage: agentDelegation.reportedUsage } : {}),
559
+ // Cross-link to the hash-chained ledger entry (tamper-evidence).
560
+ ...(ledgerRecord ? { telemetryRecordId: ledgerRecord.recordId, telemetryRecordHash: ledgerRecord.recordHash, telemetryPrevHash: ledgerRecord.prevHash } : {})
561
+ }
562
+ : {})
563
+ }
564
+ });
565
+ }
566
+ /** Step 5 — runVerify: drive the verify pipeline stage off the accepted result node
567
+ * and record the verifier node id on the task + accept context. */
568
+ function runWorkerVerify(accept) {
569
+ const { run, workerId, scope, task, parsedResult, destination, resultNode } = accept;
498
570
  const verifierResult = (0, pipeline_runner_1.createPipelineRunner)({ persist: false }).runPipelineStage(run, "verify", resultNode.id, {
499
571
  outputNodeId: `${run.id}:verifier:${task.id}`,
500
572
  outputStatus: "verified",
@@ -507,14 +579,24 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
507
579
  metadata: { taskId: task.id, workerId, resultNodeId: resultNode.id, sandboxProfileId: scope.sandboxProfileId }
508
580
  });
509
581
  task.verifierNodeId = verifierResult.outputNodeId;
582
+ accept.verifierNodeId = verifierResult.outputNodeId;
583
+ // Carry the verify verdict for the scope-status transition in recordWorkerCompletion.
584
+ accept.verifierStatus = verifierResult.status;
585
+ }
586
+ /** Step 6 — recordStateNode (worker record): assemble the worker output record +
587
+ * host-attested usage record, then persist the worker scope with the verify-derived
588
+ * status, output digest/size, and (when present) usage. */
589
+ function recordWorkerCompletion(accept, delegation) {
590
+ const { run, workerId, scope, task, absoluteResultPath, rawResult, resultNode, verifierNodeId, verifierStatus, pathAuditId, acceptedAuditId } = accept;
591
+ const { agentDelegation, telemetry } = delegation;
510
592
  const output = {
511
593
  workerId,
512
594
  taskId: task.id,
513
595
  resultPath: absoluteResultPath,
514
596
  recordedAt: new Date().toISOString(),
515
597
  stateNodeId: resultNode.id,
516
- verifierNodeId: verifierResult.outputNodeId,
517
- auditEventIds: [pathAudit.id, acceptedAudit.id]
598
+ verifierNodeId,
599
+ auditEventIds: [pathAuditId, acceptedAuditId]
518
600
  };
519
601
  // Host-attested usage rides on the worker record. Recorded when the agent
520
602
  // REPORTED a model OR token usage — `unreported`/absent stays ABSENT (never
@@ -537,7 +619,7 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
537
619
  updateWorkerScope(run, {
538
620
  ...scope,
539
621
  updatedAt: new Date().toISOString(),
540
- status: verifierResult.status === "advanced" ? "verified" : "completed",
622
+ status: verifierStatus === "advanced" ? "verified" : "completed",
541
623
  resultNodeId: resultNode.id,
542
624
  output,
543
625
  // Output integrity (v0.1.63): SHA256 digest + file size
@@ -545,20 +627,23 @@ function recordWorkerOutput(run, workerId, resultPath, options = {}) {
545
627
  outputSizeBytes: Buffer.byteLength(rawResult, "utf8"),
546
628
  ...(usageRecord ? { usage: usageRecord } : {})
547
629
  });
548
- const blackboardLinks = publishWorkerOutputToBlackboard(run, scope, task, parsedResult.summary, destination, absoluteResultPath, resultNode.evidence, acceptedAudit.id);
630
+ accept.output = output;
631
+ }
632
+ /** Step 7 — fanOut: publish the accepted output to the blackboard and record the
633
+ * multi-agent worker output (linking the blackboard message/artifact refs). */
634
+ function fanOutWorkerOutput(accept) {
635
+ const { run, workerId, scope, task, absoluteResultPath, parsedResult, destination, resultNode, verifierNodeId, acceptedAuditId } = accept;
636
+ const blackboardLinks = publishWorkerOutputToBlackboard(run, scope, task, parsedResult.summary, destination, absoluteResultPath, resultNode.evidence, acceptedAuditId);
549
637
  (0, multi_agent_1.recordMultiAgentWorkerOutput)(run, {
550
638
  workerId,
551
639
  taskId: task.id,
552
640
  resultNodeId: resultNode.id,
553
- verifierNodeId: verifierResult.outputNodeId,
641
+ verifierNodeId,
554
642
  evidence: resultNode.evidence,
555
643
  artifactPaths: [destination, absoluteResultPath],
556
644
  blackboardMessageIds: blackboardLinks.messageIds,
557
645
  blackboardArtifactRefIds: blackboardLinks.artifactRefIds
558
646
  });
559
- if (options.persist !== false)
560
- (0, state_1.saveCheckpoint)(run);
561
- return output;
562
647
  }
563
648
  function recordWorkerFailure(run, workerId, error, options = {}) {
564
649
  const scope = requireWorkerScope(run, workerId);
@@ -786,7 +871,7 @@ function loadWorkerScopesFromDisk(run) {
786
871
  .filter((entry) => entry.isDirectory())
787
872
  .map((entry) => node_path_1.default.join(workerRoot(run), entry.name, paths_1.WORKER_SCOPE_FILE))
788
873
  .filter((file) => node_fs_1.default.existsSync(file))
789
- .map((file) => JSON.parse(node_fs_1.default.readFileSync(file, "utf8")));
874
+ .map((file) => (0, validation_1.validateWorkerScope)(JSON.parse(node_fs_1.default.readFileSync(file, "utf8"))));
790
875
  }
791
876
  function requireWorkerScope(run, workerId) {
792
877
  const scope = getWorkerScope(run, workerId);
@@ -261,3 +261,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
261
261
  ## Resumable Drive & Resume Routing (v0.1.81)
262
262
 
263
263
  Adds `run resume <id> --drive/--once` alongside `quickstart --resume`: a stopped pipeline resumes in-place, advancing to completion (`--drive`) or one deterministic step (`--once`) over the same plan->dispatch->agent-fulfill->accept->commit lifecycle, echoing `resumedFrom: <id>`. Fixes the `run resume --drive` CLI routing so the drive flag reaches the resumed run instead of being read as an app name. Replay determinism and the agent evidence triple are unchanged.
264
+ _No behavioral change in v0.1.82 (drive/quickstart resolve the run repo via an explicit base directory rather than process.chdir; delegation behavior is unchanged)._
@@ -389,3 +389,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
389
389
  ## Re-Prove Verbs on Both Surfaces (v0.1.81)
390
390
 
391
391
  v0.1.81 grows the parity surface with two new both-surface, fail-closed verbs declared once in the capability registry: `cw audit verify` / `cw_audit_verify` re-proves the trust-audit chain and exits non-zero on any unverified or corrupt chain, and `cw run inspect-archive` / `cw_run_inspect_archive` is a read-only archive integrity check. Each `cw <cmd> --json` is schema-identical to its `cw_<tool>` and validated by the same parity gate.
392
+ _No changes in v0.1.82._
@@ -129,3 +129,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
129
129
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
130
130
 
131
131
  _No changes to the contract-migration subsystem in v0.1.81._
132
+ _No changes in v0.1.82._
@@ -116,3 +116,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
116
116
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
117
117
 
118
118
  _No changes to the control-plane scheduling surface in v0.1.81._
119
+ _No behavioral change in v0.1.82 (schedule/run ids are now deterministic-but-unique via a monotonic counter + pid instead of Math.random; ids stay collision-free)._
@@ -115,3 +115,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
115
115
  ## Deterministic Tombstone Hash (v0.1.81)
116
116
 
117
117
  The reclamation tombstone's freed-manifest is now path-sorted before it feeds `tombstoneHash`, so the same freed set always yields the same hash regardless of filesystem enumeration order. This removes a non-determinism from the write-ahead chain (v0.1.39/v0.1.40), keeping the per-run tombstone hash-chain replayable and stable across hosts. Atomicity, locking, and the durable re-point seam are unchanged. v0.1.81 also adds import-time refusal (`CW_REQUIRE_ARCHIVE_INTEGRITY=1`) and restore-time trust-audit re-proving — see run-registry-control-plane(7).
118
+ _No changes in v0.1.82._
@@ -276,3 +276,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
276
276
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
277
277
 
278
278
  _No changes to the Evidence Adoption Reasoning Chain surface in v0.1.81. The v0.1.81 trust-audit `computeEventHash` fix hardens the underlying audit records this chain links to by reference, but the derived reasoning view, its commands, and its eval gates are unchanged._
279
+ _No changes in v0.1.82._
@@ -306,3 +306,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
306
306
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
307
307
 
308
308
  _No changes to the execution-backends surface in v0.1.81._
309
+ _No behavioral change in v0.1.82 (the delegated child programs moved from inline `node -e` strings to `scripts/children/`; spawn argv and shell:false behavior are byte-identical)._
@@ -273,3 +273,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
273
273
  ## New Both-Surface Verbs (v0.1.81)
274
274
 
275
275
  v0.1.81 adds `audit verify` (`cw_audit_verify`) and `run inspect-archive` (`cw_run_inspect_archive`) — both declared once in the capability registry and exposed identically on the CLI and MCP, fail-closed (non-zero exit / `ok:false` on an unverified chain or a tampered archive).
276
+ _No changes in v0.1.82._
@@ -308,3 +308,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
308
308
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
309
309
 
310
310
  _No changes to the multi-agent eval/replay harness in v0.1.81 (the multi-agent-eval module was carved into behavior-preserving siblings; replay output is byte-identical)._
311
+ _v0.1.82 — replay now RE-DERIVES the projection from the raw captured state instead of copying the baseline, so a nondeterministic projection is caught instead of silently passing; a new regression smoke (including an intrinsic-nondeterminism case) proves the moat has teeth._
@@ -320,3 +320,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
320
320
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
321
321
 
322
322
  _No changes to the multi-agent operator UX surface in v0.1.81 (the operator-ux module was carved into behavior-preserving siblings; output is byte-identical)._
323
+ _No changes in v0.1.82._
@@ -141,3 +141,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
141
141
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
142
142
 
143
143
  _No changes to node-snapshot diff/replay in v0.1.81._
144
+ _No behavioral change in v0.1.82 (the node projection field set was unified into one source of truth; snapshot/replay digests are byte-identical)._
@@ -200,3 +200,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
200
200
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
201
201
 
202
202
  _No changes to the observability + cost-accounting surface in v0.1.81 (the observability module was carved into behavior-preserving siblings; output is byte-identical)._
203
+ _No changes in v0.1.82._
@@ -1,15 +1,15 @@
1
1
  # Cool Workflow Project Index
2
2
 
3
- Generated from the current repository code on 2026-06-14 by `npm run sync:project-index`.
3
+ Generated from the current repository code on 2026-06-15 by `npm run sync:project-index`.
4
4
 
5
5
  ## Snapshot
6
6
 
7
7
  - Package: `cool-workflow`
8
- - Version: `0.1.81`
9
- - Source modules: `58`
8
+ - Version: `0.1.82`
9
+ - Source modules: `61`
10
10
  - Workflow apps: `7`
11
11
  - Docs: `49`
12
- - Smoke tests: `86`
12
+ - Smoke tests: `87`
13
13
  - Repository: https://github.com/coo1white/cool-workflow
14
14
 
15
15
  ## Architecture
@@ -90,9 +90,11 @@ multi-agent host -> topology -> blackboard/coordinator
90
90
  - [evidence-grounding.ts](../src/evidence-grounding.ts)
91
91
  - [evidence-reasoning.ts](../src/evidence-reasoning.ts)
92
92
  - [execution-backend.ts](../src/execution-backend.ts)
93
+ - [gates.ts](../src/gates.ts)
93
94
  - [multi-agent-eval.ts](../src/multi-agent-eval.ts)
94
95
  - [multi-agent-operator-ux.ts](../src/multi-agent-operator-ux.ts)
95
96
  - [multi-agent-trust.ts](../src/multi-agent-trust.ts)
97
+ - [node-projection.ts](../src/node-projection.ts)
96
98
  - [node-snapshot.ts](../src/node-snapshot.ts)
97
99
  - [observability.ts](../src/observability.ts)
98
100
  - [reclamation.ts](../src/reclamation.ts)
@@ -107,6 +109,7 @@ multi-agent host -> topology -> blackboard/coordinator
107
109
  - [telemetry-attestation.ts](../src/telemetry-attestation.ts)
108
110
  - [telemetry-demo.ts](../src/telemetry-demo.ts)
109
111
  - [telemetry-ledger.ts](../src/telemetry-ledger.ts)
112
+ - [validation.ts](../src/validation.ts)
110
113
  - [verifier-registry.ts](../src/verifier-registry.ts)
111
114
  - [workbench-host.ts](../src/workbench-host.ts)
112
115
  - [workbench.ts](../src/workbench.ts)
@@ -210,6 +213,7 @@ Smoke tests mirror the public contracts. The high-signal suites are:
210
213
  - [h7-custom-profile-persist-smoke.js](../test/h7-custom-profile-persist-smoke.js)
211
214
  - [mcp-app-surface-smoke.js](../test/mcp-app-surface-smoke.js)
212
215
  - [multi-agent-cli-mcp-surface-smoke.js](../test/multi-agent-cli-mcp-surface-smoke.js)
216
+ - [multi-agent-eval-determinism-regression-smoke.js](../test/multi-agent-eval-determinism-regression-smoke.js)
213
217
  - [multi-agent-eval-replay-harness-smoke.js](../test/multi-agent-eval-replay-harness-smoke.js)
214
218
  - [multi-agent-eval-replay-smoke.js](../test/multi-agent-eval-replay-smoke.js)
215
219
  - [multi-agent-operator-ux-smoke.js](../test/multi-agent-operator-ux-smoke.js)
@@ -148,3 +148,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
148
148
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
149
149
 
150
150
  _No changes to the real execution backends in v0.1.81._
151
+ _No behavioral change in v0.1.82 (delegated child programs extracted to `scripts/children/`; spawn behavior byte-identical)._
@@ -288,3 +288,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
288
288
  ## Migration Compatibility (v0.1.81)
289
289
 
290
290
  v0.1.81 is additive: every change is a new flag/verb/env (`audit verify`, `run inspect-archive`, `verify-import --strict`, `CW_REQUIRE_ARCHIVE_INTEGRITY`, `quickstart --resume`, `run resume --drive`) or an internal behavior-preserving carve. Run-state schema, existing outputs, files, and exit codes are byte-identical, so runs and archives from prior versions load and verify unchanged. No migration action is required.
291
+ _No changes in v0.1.82._
@@ -133,8 +133,10 @@ inherits the agent's own credentials, and imports no model SDK — the red line.
133
133
  ```bash
134
134
  # check only (gate + independent review, no mutation):
135
135
  node plugins/cool-workflow/scripts/release-flow.js --check
136
- # cut a tag once review is green:
137
- node plugins/cool-workflow/scripts/release-flow.js --cut --version 0.1.77 [--push]
136
+ # cut a tag once review is green (when --push, also creates the GitHub Release):
137
+ node plugins/cool-workflow/scripts/release-flow.js --cut --version 0.1.77 [--push] [--no-release]
138
+ # backfill / re-create the GitHub Release for an already-pushed tag (no gate/cut):
139
+ node plugins/cool-workflow/scripts/release-flow.js --release --version 0.1.77 [--soft]
138
140
  ```
139
141
 
140
142
  The per-platform difference is config, not code — set the reviewer agent:
@@ -152,6 +154,34 @@ also get generated MCP manifests (`.gemini-plugin/`, `.opencode-plugin/`) so the
152
154
  `cw_*` tools are available as MCP tools in those hosts. The verdict path
153
155
  (`.cw-release/review-<sha>.verdict`) and the tag-push CI backstop are unchanged.
154
156
 
157
+ ### GitHub Release finishing step
158
+
159
+ A `--cut --push` finishes by creating the **GitHub Release** for the tag, and
160
+ `--release --version x.y.z` creates-or-skips one for an already-pushed tag
161
+ (backfill). The notes body is assembled from the `## x.y.z` CHANGELOG section as
162
+ shipped at the tag, the independent reviewer's one-line capability, and a
163
+ "Provenance & audit" footer linking the reviewed commit, the **committed** reviewer
164
+ verdict, the full diff, and the provenance-attested npm version.
165
+
166
+ This step is **distribution upside, not a correctness gate**: the load-bearing
167
+ artifacts (the tag and the provenance-attested npm publish) already exist when it
168
+ runs. Therefore `gh` is **not** part of the node/git portability floor — it runs
169
+ ONLY in the human `--cut --push` / `--release` paths (never a gate or CI path) and
170
+ is **idempotent** (skips if the Release already exists).
171
+
172
+ Failure semantics differ by mode: in the **`--cut --push` finishing step** an
173
+ absent/unauthenticated/erroring `gh` **skips with a stderr note and never fails the
174
+ cut** (the tag and npm publish stand) — opt out entirely with `--no-release`. In the
175
+ explicit **`--release` backfill** it **fails closed** (exit 1) with guidance, since
176
+ the operator asked for it directly; add `--soft` to downgrade `--release` to the same
177
+ best-effort skip-not-fail behavior.
178
+
179
+ Honesty: the notes claim the gated flow ("independent release-reviewer, verdict
180
+ above") **only when a committed `APPROVED` verdict is found at the tag**; backfilling
181
+ an ungated tag emits a neutral caveat instead and warns on stderr — the notes never
182
+ assert a review that isn't there. Test seam: `CW_RELEASE_FLOW_GH_CMD` swaps the `gh`
183
+ binary for a stub (spawned `shell:false`) so the smoke exercises it offline.
184
+
155
185
  0.1.51
156
186
 
157
187
  0.1.76
@@ -165,3 +195,4 @@ also get generated MCP manifests (`.gemini-plugin/`, `.opencode-plugin/`) so the
165
195
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
166
196
 
167
197
  _No changes to the release-flow tooling in v0.1.81; this release was cut through the existing gate->review->tag flow._
198
+ _No changes to the release-tooling contract in v0.1.82._
@@ -399,3 +399,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
399
399
  ## Resume Drive, Inspect-Archive & Restore Re-Prove (v0.1.81)
400
400
 
401
401
  v0.1.81 adds `run resume <id> --drive/--once` (continue an interrupted run via the agent-drive loop; default resume stays read-only and byte-identical), `run inspect-archive PATH` (read-only archive integrity check that names any offending file without importing), and restore-time hardening: `verify-import` now re-proves the trust-audit chain on restore and gains `--strict`, and `CW_REQUIRE_ARCHIVE_INTEGRITY=1` refuses a stripped-integrity archive before any write.
402
+ _No behavioral change in v0.1.82 (run resolution now threads an explicit base directory via CoolWorkflowRunner.withBaseDir instead of mutating process.cwd; the resolved run is unchanged)._
@@ -199,3 +199,4 @@ Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, dif
199
199
  ## Deterministic Freed Manifest (v0.1.81)
200
200
 
201
201
  The freed manifest is path-sorted before it feeds `tombstoneHash`, so reclamation's write-ahead tombstone hash-chain is reproducible across hosts regardless of filesystem enumeration order. Reclaimed tiers, the re-point seam, and the default (reclaim-nothing) policy are unchanged.
202
+ _No changes in v0.1.82._
@@ -277,3 +277,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
277
277
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
278
278
 
279
279
  _No changes to the state-explosion management surface in v0.1.81 (the module was carved into behavior-preserving siblings; output is byte-identical)._
280
+ _No changes in v0.1.82._
@@ -213,3 +213,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
213
213
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
214
214
 
215
215
  _No changes to the team-collaboration surface in v0.1.81._
216
+ _No changes in v0.1.82._
@@ -221,3 +221,4 @@ Migration DAG with reversible edges (v0.1.45), capability auto-discovery (v0.1.4
221
221
  Adds the opt-in fast architecture-review lane: scoped JSONL source contexts, diff-aware exports, reusable Map and Assess results, measurable wrapper metrics, actionable background full-review handoff, and userland model policy flags for routing fast/strong workers without changing the full review contract.
222
222
 
223
223
  _No changes to the Web / Desktop Workbench in v0.1.81._
224
+ _No changes in v0.1.82._
@@ -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.1.81",
5
+ "version": "0.1.82",
6
6
  "license": "BSD-2-Clause",
7
7
  "homepage": "https://github.com/coo1white/cool-workflow",
8
8
  "author": {
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "runtime": {
27
27
  "description": "Runtime-kernel source context for state, orchestration, scheduling, execution, and shared types.",
28
- "maxLines": 40000,
28
+ "maxLines": 42000,
29
29
  "include": [
30
30
  "plugins/cool-workflow/src/**",
31
31
  "plugins/cool-workflow/package.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cool-workflow",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "bin": {
5
5
  "cool-workflow": "scripts/cw.js",
6
6
  "cw": "scripts/cw.js"
@@ -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.81",
86
+ "Cool Workflow v0.1.82",
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.81");
120
+ assert.equal(summary.version, "0.1.82");
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.81");
127
+ assert.equal(shown.app.version, "0.1.82");
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.81");
138
+ assert.equal(state.workflow.app.version, "0.1.82");
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`);