cool-workflow 0.1.79 → 0.1.81

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 (131) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +51 -3
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +64 -0
  6. package/apps/architecture-review-fast/workflow.js +153 -0
  7. package/apps/end-to-end-golden-path/app.json +1 -1
  8. package/apps/pr-review-fix-ci/app.json +1 -1
  9. package/apps/release-cut/app.json +1 -1
  10. package/apps/research-synthesis/app.json +1 -1
  11. package/dist/agent-config.js +21 -7
  12. package/dist/candidate-scoring.js +42 -22
  13. package/dist/capability-core.js +132 -17
  14. package/dist/capability-registry.js +138 -168
  15. package/dist/cli.js +97 -98
  16. package/dist/collaboration.js +5 -6
  17. package/dist/commit.js +20 -6
  18. package/dist/compare.js +18 -0
  19. package/dist/coordinator/classify.js +45 -0
  20. package/dist/coordinator/paths.js +42 -0
  21. package/dist/coordinator/util.js +129 -0
  22. package/dist/coordinator.js +127 -300
  23. package/dist/dispatch.js +35 -0
  24. package/dist/drive.js +79 -6
  25. package/dist/error-feedback.js +8 -4
  26. package/dist/evidence-reasoning.js +3 -3
  27. package/dist/execution-backend/agent.js +331 -0
  28. package/dist/execution-backend/probes.js +96 -0
  29. package/dist/execution-backend/util.js +47 -0
  30. package/dist/execution-backend.js +73 -421
  31. package/dist/mcp-server.js +79 -183
  32. package/dist/multi-agent/graph.js +84 -0
  33. package/dist/multi-agent/helpers.js +145 -0
  34. package/dist/multi-agent/paths.js +22 -0
  35. package/dist/multi-agent-eval/format.js +194 -0
  36. package/dist/multi-agent-eval/normalize.js +51 -0
  37. package/dist/multi-agent-eval.js +39 -244
  38. package/dist/multi-agent-host.js +0 -19
  39. package/dist/multi-agent.js +125 -314
  40. package/dist/node-snapshot.js +3 -3
  41. package/dist/observability/format.js +61 -0
  42. package/dist/observability/intake.js +98 -0
  43. package/dist/observability.js +14 -160
  44. package/dist/operator-ux/format.js +364 -0
  45. package/dist/operator-ux.js +22 -363
  46. package/dist/orchestrator/lifecycle-operations.js +2 -1
  47. package/dist/orchestrator/report.js +8 -0
  48. package/dist/orchestrator.js +26 -9
  49. package/dist/reclamation.js +26 -21
  50. package/dist/run-export.js +494 -25
  51. package/dist/run-registry/derive.js +172 -0
  52. package/dist/run-registry/format.js +124 -0
  53. package/dist/run-registry/gc.js +251 -0
  54. package/dist/run-registry/policy.js +16 -0
  55. package/dist/run-registry/queue.js +116 -0
  56. package/dist/run-registry.js +89 -597
  57. package/dist/run-state-schema.js +1 -0
  58. package/dist/sandbox-profile.js +43 -2
  59. package/dist/state-explosion/format.js +159 -0
  60. package/dist/state-explosion/helpers.js +82 -0
  61. package/dist/state-explosion.js +165 -304
  62. package/dist/state-node.js +19 -4
  63. package/dist/telemetry-attestation.js +55 -0
  64. package/dist/telemetry-demo.js +15 -3
  65. package/dist/telemetry-ledger.js +60 -15
  66. package/dist/topology.js +25 -8
  67. package/dist/triggers.js +33 -14
  68. package/dist/trust-audit.js +145 -33
  69. package/dist/version.js +1 -1
  70. package/dist/worker-isolation/helpers.js +51 -0
  71. package/dist/worker-isolation/paths.js +46 -0
  72. package/dist/worker-isolation.js +39 -115
  73. package/docs/agent-delegation-drive.7.md +71 -0
  74. package/docs/canonical-workflow-apps.7.md +37 -0
  75. package/docs/cli-mcp-parity.7.md +16 -0
  76. package/docs/contract-migration-tooling.7.md +6 -0
  77. package/docs/control-plane-scheduling.7.md +6 -0
  78. package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +40 -0
  79. package/docs/durable-state-and-locking.7.md +8 -0
  80. package/docs/evidence-adoption-reasoning-chain.7.md +6 -0
  81. package/docs/execution-backends.7.md +6 -0
  82. package/docs/index.md +2 -0
  83. package/docs/launch/demo.tape +28 -0
  84. package/docs/launch/launch-kit.md +96 -17
  85. package/docs/launch/pre-launch-checklist.md +53 -0
  86. package/docs/multi-agent-cli-mcp-surface.7.md +8 -0
  87. package/docs/multi-agent-eval-replay-harness.7.md +6 -0
  88. package/docs/multi-agent-operator-ux.7.md +6 -0
  89. package/docs/multi-agent-trust-policy-audit.7.md +27 -0
  90. package/docs/node-snapshot-diff-replay.7.md +6 -0
  91. package/docs/observability-cost-accounting.7.md +6 -0
  92. package/docs/project-index.md +27 -6
  93. package/docs/real-execution-backends.7.md +6 -0
  94. package/docs/release-and-migration.7.md +8 -0
  95. package/docs/release-tooling.7.md +6 -0
  96. package/docs/routines.md +23 -0
  97. package/docs/run-registry-control-plane.7.md +89 -2
  98. package/docs/run-retention-reclamation.7.md +8 -0
  99. package/docs/source-context-profiles.7.md +119 -0
  100. package/docs/state-explosion-management.7.md +13 -0
  101. package/docs/team-collaboration.7.md +6 -0
  102. package/docs/trust-model.md +267 -0
  103. package/docs/unix-principles.md +49 -1
  104. package/docs/vendor-manifest-loadability.7.md +43 -0
  105. package/docs/web-desktop-workbench.7.md +6 -0
  106. package/manifest/plugin.manifest.json +1 -1
  107. package/manifest/source-context-profiles.json +142 -0
  108. package/package.json +4 -1
  109. package/scripts/agents/builtin-templates.json +7 -0
  110. package/scripts/agents/claude-p-agent.js +129 -43
  111. package/scripts/architecture-review-fast.js +362 -0
  112. package/scripts/bump-version.js +5 -10
  113. package/scripts/canonical-apps-list.js +64 -0
  114. package/scripts/canonical-apps.js +36 -4
  115. package/scripts/coverage-gate.js +211 -0
  116. package/scripts/dogfood-release.js +1 -1
  117. package/scripts/golden-path.js +4 -4
  118. package/scripts/parity-check.js +5 -0
  119. package/scripts/release-check.js +5 -1
  120. package/scripts/source-context.js +291 -0
  121. package/scripts/version-sync-check.js +5 -7
  122. package/skills/ci-triage/SKILL.md +50 -0
  123. package/skills/ci-triage/agents/openai.yaml +4 -0
  124. package/skills/cool-workflow/SKILL.md +4 -1
  125. package/skills/deploy-check/SKILL.md +55 -0
  126. package/skills/deploy-check/agents/openai.yaml +4 -0
  127. package/skills/design-qa/SKILL.md +49 -0
  128. package/skills/design-qa/agents/openai.yaml +4 -0
  129. package/skills/pr-review/SKILL.md +45 -0
  130. package/skills/pr-review/agents/openai.yaml +4 -0
  131. package/dist/capability-dispatcher.js +0 -86
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.GRAPH_VIEWS = exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS = exports.STATE_EXPLOSION_SCHEMA_VERSION = void 0;
6
+ exports.stateExplosionReportLines = exports.formatBlackboardDigest = exports.formatCompactGraph = exports.formatStateExplosionReport = exports.fingerprintStrings = exports.GRAPH_VIEWS = exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS = exports.STATE_EXPLOSION_SCHEMA_VERSION = void 0;
7
7
  exports.computeStateSize = computeStateSize;
8
8
  exports.summarizeBlackboardDigest = summarizeBlackboardDigest;
9
9
  exports.buildCompactGraph = buildCompactGraph;
@@ -13,13 +13,7 @@ exports.maybeCompactRun = maybeCompactRun;
13
13
  exports.refreshStateExplosionSummaries = refreshStateExplosionSummaries;
14
14
  exports.loadStateExplosionSummaryIndex = loadStateExplosionSummaryIndex;
15
15
  exports.showStateExplosionSummary = showStateExplosionSummary;
16
- exports.formatStateExplosionReport = formatStateExplosionReport;
17
- exports.formatCompactGraph = formatCompactGraph;
18
- exports.formatBlackboardDigest = formatBlackboardDigest;
19
- exports.stateExplosionReportLines = stateExplosionReportLines;
20
16
  exports.normalizeStateExplosionForEval = normalizeStateExplosionForEval;
21
- exports.fingerprintStrings = fingerprintStrings;
22
- const node_crypto_1 = __importDefault(require("node:crypto"));
23
17
  const node_fs_1 = __importDefault(require("node:fs"));
24
18
  const node_path_1 = __importDefault(require("node:path"));
25
19
  const state_1 = require("./state");
@@ -27,6 +21,7 @@ const coordinator_1 = require("./coordinator");
27
21
  const multi_agent_operator_ux_1 = require("./multi-agent-operator-ux");
28
22
  const trust_audit_1 = require("./trust-audit");
29
23
  const evidence_reasoning_1 = require("./evidence-reasoning");
24
+ const helpers_1 = require("./state-explosion/helpers");
30
25
  exports.STATE_EXPLOSION_SCHEMA_VERSION = 1;
31
26
  exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS = {
32
27
  graphNodes: 40,
@@ -48,13 +43,55 @@ exports.GRAPH_VIEWS = [
48
43
  "candidate",
49
44
  "commit-gate"
50
45
  ];
46
+ function createStateExplosionBuildContext() {
47
+ return {
48
+ stateSizes: new Map(),
49
+ blackboardDigests: new Map(),
50
+ graphRecords: new Map()
51
+ };
52
+ }
53
+ function fullGraphFor(run, context) {
54
+ if (!context.fullGraph)
55
+ context.fullGraph = (0, multi_agent_operator_ux_1.buildMultiAgentOperatorGraph)(run);
56
+ return context.fullGraph;
57
+ }
58
+ function operatorFor(run, context) {
59
+ if (!context.operator)
60
+ context.operator = (0, multi_agent_operator_ux_1.summarizeMultiAgentOperator)(run);
61
+ return context.operator;
62
+ }
63
+ function reasoningCriticalIdsFor(run, context) {
64
+ if (!context.reasoningCriticalIds)
65
+ context.reasoningCriticalIds = (0, evidence_reasoning_1.reasoningCriticalNodeIds)(run, operatorFor(run, context));
66
+ return context.reasoningCriticalIds;
67
+ }
68
+ function thresholdsKey(thresholds) {
69
+ return [
70
+ thresholds.graphNodes,
71
+ thresholds.graphEdges,
72
+ thresholds.blackboardMessages,
73
+ thresholds.blackboardRecords,
74
+ thresholds.collapseBucket,
75
+ thresholds.totalRecords
76
+ ].join(":");
77
+ }
78
+ function graphKey(view, options) {
79
+ return [
80
+ view,
81
+ options.focus || "",
82
+ options.depth === undefined ? "" : String(options.depth),
83
+ thresholdsKey(options.thresholds || exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS)
84
+ ].join("\0");
85
+ }
51
86
  // ---------------------------------------------------------------------------
52
87
  // State size
53
88
  // ---------------------------------------------------------------------------
54
89
  function computeStateSize(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS) {
90
+ return computeStateSizeWithGraph(run, thresholds, (0, multi_agent_operator_ux_1.buildMultiAgentOperatorGraph)(run));
91
+ }
92
+ function computeStateSizeWithGraph(run, thresholds, graph) {
55
93
  const ma = run.multiAgent || { runs: [], roles: [], groups: [], memberships: [], fanouts: [], fanins: [] };
56
94
  const bb = run.blackboard || { topics: [], messages: [], contexts: [], artifacts: [], snapshots: [], decisions: [] };
57
- const graph = (0, multi_agent_operator_ux_1.buildMultiAgentOperatorGraph)(run);
58
95
  const counts = {
59
96
  multiAgentRuns: (ma.runs || []).length,
60
97
  roles: (ma.roles || []).length,
@@ -97,6 +134,15 @@ function computeStateSize(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_THRE
97
134
  reasons.push(`run has ${total} multi-agent records (> ${thresholds.totalRecords})`);
98
135
  return { ...counts, total, compactionRecommended: reasons.length > 0, reasons: reasons.sort() };
99
136
  }
137
+ function stateSizeFor(run, thresholds, context) {
138
+ const key = thresholdsKey(thresholds);
139
+ let size = context.stateSizes.get(key);
140
+ if (!size) {
141
+ size = computeStateSizeWithGraph(run, thresholds, fullGraphFor(run, context));
142
+ context.stateSizes.set(key, size);
143
+ }
144
+ return size;
145
+ }
100
146
  // ---------------------------------------------------------------------------
101
147
  // Blackboard digest (deterministic structural summary)
102
148
  // ---------------------------------------------------------------------------
@@ -127,11 +173,11 @@ function summarizeBlackboardDigest(run, blackboardId) {
127
173
  label: `${topic.title} (${topicMessages.length} messages, ${topic.contextIds.length} contexts, ${topic.artifactRefIds.length} artifacts)`,
128
174
  status: topic.status,
129
175
  sourceIds: [topic.id, ...topicMessages.map((m) => m.id)],
130
- evidenceRefs: unique(topicMessages.flatMap((m) => m.linkedEvidenceRefs || [])),
176
+ evidenceRefs: (0, helpers_1.unique)(topicMessages.flatMap((m) => m.linkedEvidenceRefs || [])),
131
177
  expansionCommand: `node scripts/cw.js blackboard message list ${run.id} --topic ${topic.id}`
132
178
  };
133
179
  })
134
- .sort(byId);
180
+ .sort(helpers_1.byId);
135
181
  const threadSummaries = topics
136
182
  .map((topic) => {
137
183
  const topicMessages = messages
@@ -143,23 +189,23 @@ function summarizeBlackboardDigest(run, blackboardId) {
143
189
  label: `${topic.title}: ${topicMessages.length} messages${last ? `; latest by ${last.author.kind}:${last.author.id}` : ""}`,
144
190
  status: topic.status,
145
191
  sourceIds: topicMessages.map((m) => m.id),
146
- evidenceRefs: unique(topicMessages.flatMap((m) => m.linkedEvidenceRefs || [])),
192
+ evidenceRefs: (0, helpers_1.unique)(topicMessages.flatMap((m) => m.linkedEvidenceRefs || [])),
147
193
  expansionCommand: `node scripts/cw.js blackboard message list ${run.id} --topic ${topic.id}`
148
194
  };
149
195
  })
150
196
  .filter((entry) => entry.sourceIds.length)
151
- .sort(byId);
197
+ .sort(helpers_1.byId);
152
198
  const unresolvedQuestions = contexts
153
199
  .filter((c) => c.kind === "question" && c.status === "open")
154
200
  .map((c) => ({
155
201
  id: c.id,
156
- label: `${c.key}: ${truncate(c.value)}`,
202
+ label: `${c.key}: ${(0, helpers_1.truncate)(c.value)}`,
157
203
  status: c.status,
158
204
  sourceIds: [c.id],
159
- evidenceRefs: unique([...(c.evidenceRefs || []), ...(c.artifactRefIds || [])]),
205
+ evidenceRefs: (0, helpers_1.unique)([...(c.evidenceRefs || []), ...(c.artifactRefIds || [])]),
160
206
  expansionCommand: `node scripts/cw.js blackboard message post ${run.id} --topic ${c.topicId} --body "<answer with evidence>"`
161
207
  }))
162
- .sort(byId);
208
+ .sort(helpers_1.byId);
163
209
  const conflicts = contexts
164
210
  .filter((c) => c.status === "conflicting" || (c.conflictingContextIds || []).length)
165
211
  .map((c) => ({
@@ -167,30 +213,30 @@ function summarizeBlackboardDigest(run, blackboardId) {
167
213
  label: `${c.key} conflicts with ${(c.conflictingContextIds || []).join(", ") || "another value"}`,
168
214
  status: c.status,
169
215
  sourceIds: [c.id, ...(c.conflictingContextIds || [])],
170
- evidenceRefs: unique([...(c.evidenceRefs || []), ...(c.artifactRefIds || [])]),
216
+ evidenceRefs: (0, helpers_1.unique)([...(c.evidenceRefs || []), ...(c.artifactRefIds || [])]),
171
217
  expansionCommand: `node scripts/cw.js coordinator decision ${run.id} --kind conflict-resolution --outcome accepted --subject ${c.id} --reason "<reason>"`
172
218
  }))
173
- .sort(byId);
219
+ .sort(helpers_1.byId);
174
220
  const decisionEntries = decisions
175
221
  .map((d) => ({
176
222
  id: d.id,
177
- label: `${d.kind}:${d.outcome} ${truncate(d.reason)}`,
223
+ label: `${d.kind}:${d.outcome} ${(0, helpers_1.truncate)(d.reason)}`,
178
224
  status: d.status,
179
225
  sourceIds: [d.id, ...(d.subjectIds || [])],
180
- evidenceRefs: unique([...(d.evidenceRefs || []), ...(d.artifactRefIds || [])]),
226
+ evidenceRefs: (0, helpers_1.unique)([...(d.evidenceRefs || []), ...(d.artifactRefIds || [])]),
181
227
  expansionCommand: `node scripts/cw.js node show ${run.id} ${run.id}:coordinator:decision:${d.id}`
182
228
  }))
183
- .sort(byId);
229
+ .sort(helpers_1.byId);
184
230
  const artifactEntries = artifacts
185
231
  .map((a) => ({
186
232
  id: a.id,
187
233
  label: `${a.kind} ${a.locator || a.path || a.id}`,
188
234
  status: a.status,
189
235
  sourceIds: [a.id],
190
- evidenceRefs: unique(a.evidenceRefs || []),
236
+ evidenceRefs: (0, helpers_1.unique)(a.evidenceRefs || []),
191
237
  expansionCommand: `node scripts/cw.js blackboard artifact list ${run.id}`
192
238
  }))
193
- .sort(byId);
239
+ .sort(helpers_1.byId);
194
240
  const adoptedEvidence = artifacts
195
241
  .filter((a) => a.status === "active")
196
242
  .map((a) => ({
@@ -198,42 +244,42 @@ function summarizeBlackboardDigest(run, blackboardId) {
198
244
  label: `${a.kind} ${a.locator || a.path || a.id}`,
199
245
  status: a.status,
200
246
  sourceIds: [a.id],
201
- evidenceRefs: unique([a.locator || a.path || a.id, ...(a.evidenceRefs || [])]),
247
+ evidenceRefs: (0, helpers_1.unique)([a.locator || a.path || a.id, ...(a.evidenceRefs || [])]),
202
248
  expansionCommand: `node scripts/cw.js audit blackboard ${run.id} --json`
203
249
  }))
204
- .sort(byId);
250
+ .sort(helpers_1.byId);
205
251
  const missingEvidence = (summary.missingEvidence || [])
206
252
  .map((reason, index) => ({
207
- id: `missing:${index}:${slug(reason)}`,
253
+ id: `missing:${index}:${(0, helpers_1.slug)(reason)}`,
208
254
  label: reason,
209
255
  status: "missing",
210
256
  sourceIds: [],
211
257
  evidenceRefs: [],
212
258
  expansionCommand: `node scripts/cw.js multi-agent failures ${run.id}`
213
259
  }))
214
- .sort(byId);
260
+ .sort(helpers_1.byId);
215
261
  const policyViolations = decisions
216
262
  .filter((d) => d.outcome === "rejected" || d.outcome === "blocked" || d.outcome === "conflicting")
217
263
  .map((d) => ({
218
264
  id: `policy:${d.id}`,
219
- label: `${d.kind}:${d.outcome} ${truncate(d.reason)}`,
265
+ label: `${d.kind}:${d.outcome} ${(0, helpers_1.truncate)(d.reason)}`,
220
266
  status: d.status,
221
267
  sourceIds: [d.id],
222
- evidenceRefs: unique(d.evidenceRefs || []),
268
+ evidenceRefs: (0, helpers_1.unique)(d.evidenceRefs || []),
223
269
  expansionCommand: `node scripts/cw.js audit policy ${run.id} --json`
224
270
  }))
225
- .sort(byId);
271
+ .sort(helpers_1.byId);
226
272
  const judgeRationale = messages
227
273
  .filter((m) => (m.tags || []).includes("judge-rationale") || Boolean(m.metadata?.judgeRationale))
228
274
  .map((m) => ({
229
275
  id: `judge:${m.id}`,
230
- label: `${m.author.kind}:${m.author.id} ${truncate(m.body)}`,
276
+ label: `${m.author.kind}:${m.author.id} ${(0, helpers_1.truncate)(m.body)}`,
231
277
  status: m.status,
232
278
  sourceIds: [m.id],
233
- evidenceRefs: unique(m.linkedEvidenceRefs || []),
279
+ evidenceRefs: (0, helpers_1.unique)(m.linkedEvidenceRefs || []),
234
280
  expansionCommand: `node scripts/cw.js audit judge ${run.id} --json`
235
281
  }))
236
- .sort(byId);
282
+ .sort(helpers_1.byId);
237
283
  const recentChanges = [...messages, ...contexts, ...artifacts, ...decisions]
238
284
  .map((record) => ({
239
285
  id: record.id,
@@ -251,30 +297,30 @@ function summarizeBlackboardDigest(run, blackboardId) {
251
297
  evidenceRefs: [],
252
298
  expansionCommand: `node scripts/cw.js node show ${run.id} ${record.id}`
253
299
  }))
254
- .sort(byId);
300
+ .sort(helpers_1.byId);
255
301
  const highSignal = [
256
302
  ...conflicts,
257
303
  ...unresolvedQuestions,
258
304
  ...policyViolations,
259
305
  ...missingEvidence
260
- ].sort(byId);
261
- const sourceRecordIds = unique([
306
+ ].sort(helpers_1.byId);
307
+ const sourceRecordIds = (0, helpers_1.unique)([
262
308
  ...topics.map((t) => t.id),
263
309
  ...messages.map((m) => m.id),
264
310
  ...contexts.map((c) => c.id),
265
311
  ...artifacts.map((a) => a.id),
266
312
  ...decisions.map((d) => d.id)
267
313
  ]);
268
- const evidenceRefs = unique([
314
+ const evidenceRefs = (0, helpers_1.unique)([
269
315
  ...messages.flatMap((m) => m.linkedEvidenceRefs || []),
270
316
  ...artifacts.flatMap((a) => [a.locator || a.path || a.id, ...(a.evidenceRefs || [])]),
271
317
  ...contexts.flatMap((c) => c.evidenceRefs || [])
272
318
  ]);
273
- const trustAuditEventRefs = unique([
319
+ const trustAuditEventRefs = (0, helpers_1.unique)([
274
320
  ...messages.flatMap((m) => m.linkedAuditEventIds || []),
275
321
  ...artifacts.flatMap((a) => a.trustAuditEventIds || [])
276
322
  ]);
277
- const fingerprint = fingerprintRecords([...topics, ...messages, ...contexts, ...artifacts, ...decisions]);
323
+ const fingerprint = (0, helpers_1.fingerprintRecords)([...topics, ...messages, ...contexts, ...artifacts, ...decisions]);
278
324
  return {
279
325
  schemaVersion: exports.STATE_EXPLOSION_SCHEMA_VERSION,
280
326
  runId: run.id,
@@ -285,7 +331,7 @@ function summarizeBlackboardDigest(run, blackboardId) {
285
331
  sourceFingerprint: fingerprint,
286
332
  includedCount: topicRollups.length + conflicts.length + unresolvedQuestions.length + decisionEntries.length + artifactEntries.length,
287
333
  omittedCount: Math.max(0, messages.length - threadSummaries.length),
288
- importantRefs: unique([
334
+ importantRefs: (0, helpers_1.unique)([
289
335
  ...conflicts.map((c) => c.id),
290
336
  ...unresolvedQuestions.map((q) => q.id),
291
337
  ...policyViolations.map((p) => p.id)
@@ -310,27 +356,43 @@ function summarizeBlackboardDigest(run, blackboardId) {
310
356
  highSignal
311
357
  };
312
358
  }
359
+ function blackboardDigestFor(run, context, blackboardId) {
360
+ const key = blackboardId || "";
361
+ let digest = context.blackboardDigests.get(key);
362
+ if (!digest) {
363
+ digest = summarizeBlackboardDigest(run, blackboardId);
364
+ context.blackboardDigests.set(key, digest);
365
+ }
366
+ return digest;
367
+ }
313
368
  function buildCompactGraph(run, view = "compact", options = {}) {
369
+ return buildCompactGraphWithContext(run, view, options, createStateExplosionBuildContext());
370
+ }
371
+ function buildCompactGraphWithContext(run, view, options, context) {
314
372
  const thresholds = options.thresholds || exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS;
315
- const full = (0, multi_agent_operator_ux_1.buildMultiAgentOperatorGraph)(run);
316
- const operator = (0, multi_agent_operator_ux_1.summarizeMultiAgentOperator)(run);
373
+ const key = graphKey(view, { ...options, thresholds });
374
+ const cached = context.graphRecords.get(key);
375
+ if (cached)
376
+ return cached;
377
+ const full = fullGraphFor(run, context);
378
+ const operator = operatorFor(run, context);
317
379
  const critical = criticalPathNodeIds(run, operator);
318
380
  const protectedIds = new Set(critical);
319
381
  // Failures, blocked, rejected, conflicting nodes are always preserved.
320
382
  for (const node of full.nodes) {
321
- if (isProtectedStatus(node.status))
383
+ if ((0, helpers_1.isProtectedStatus)(node.status))
322
384
  protectedIds.add(node.id);
323
385
  }
324
386
  // v0.1.26: reasoning steps are on the critical path and must never be collapsed
325
387
  // into a synthetic summary node — protect every decision-gate node backing an
326
388
  // adopted reasoning chain (notably score nodes, which are otherwise collapsed).
327
- for (const id of (0, evidence_reasoning_1.reasoningCriticalNodeIds)(run))
389
+ for (const id of reasoningCriticalIdsFor(run, context))
328
390
  protectedIds.add(id);
329
391
  for (const failure of operator.failures) {
330
392
  if (failure.linked)
331
393
  protectedIds.add(failure.linked);
332
394
  }
333
- const parents = parentMap(full.edges);
395
+ const parents = (0, helpers_1.parentMap)(full.edges);
334
396
  const parentOf = (id) => parents.get(id);
335
397
  let scopeNodes = full.nodes;
336
398
  let scopeEdges = full.edges;
@@ -349,13 +411,15 @@ function buildCompactGraph(run, view = "compact", options = {}) {
349
411
  const collapseEnabled = view === "compact" || view === "critical-path" || Boolean(options.focus);
350
412
  if (view === "full" || !collapseEnabled) {
351
413
  // No collapse: emit scoped graph verbatim (still records provenance + critical path).
352
- return finalizeGraphRecord(run, view, options, full, {
414
+ const record = finalizeGraphRecord(run, view, options, full, {
353
415
  nodes: scopeNodes.map((node) => ({ ...node })),
354
416
  edges: scopeEdges.map((edge) => ({ ...edge })),
355
417
  syntheticNodes: [],
356
418
  critical,
357
419
  operator
358
420
  });
421
+ context.graphRecords.set(key, record);
422
+ return record;
359
423
  }
360
424
  // Determine collapse buckets per node.
361
425
  const rule = collapseRuleFor(view);
@@ -390,9 +454,9 @@ function buildCompactGraph(run, view = "compact", options = {}) {
390
454
  }
391
455
  const members = scopeNodes.filter((node) => ids.includes(node.id));
392
456
  const internalEdges = scopeEdges.filter((edge) => ids.includes(edge.from) && ids.includes(edge.to));
393
- const syntheticId = `${run.id}:summary:${slug(key)}`;
394
- const dominant = dominantStatus(members.map((m) => m.status));
395
- const blocked = members.find((m) => isProtectedStatus(m.status));
457
+ const syntheticId = `${run.id}:summary:${(0, helpers_1.slug)(key)}`;
458
+ const dominant = (0, helpers_1.dominantStatus)(members.map((m) => m.status));
459
+ const blocked = members.find((m) => (0, helpers_1.isProtectedStatus)(m.status));
396
460
  synthetic.push({
397
461
  id: syntheticId,
398
462
  kind: "summary",
@@ -436,25 +500,27 @@ function buildCompactGraph(run, view = "compact", options = {}) {
436
500
  edgeSeen.add(key);
437
501
  edges.push({ from, to, label: edge.label });
438
502
  }
439
- return finalizeGraphRecord(run, view, options, full, {
503
+ const record = finalizeGraphRecord(run, view, options, full, {
440
504
  nodes: nodes.sort((a, b) => a.kind.localeCompare(b.kind) || a.id.localeCompare(b.id)),
441
505
  edges: edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || (a.label || "").localeCompare(b.label || "")),
442
506
  syntheticNodes: synthetic.sort((a, b) => a.id.localeCompare(b.id)),
443
507
  critical,
444
508
  operator
445
509
  });
510
+ context.graphRecords.set(key, record);
511
+ return record;
446
512
  }
447
513
  function finalizeGraphRecord(run, view, options, full, built) {
448
514
  const collapsedNodeCount = built.syntheticNodes.reduce((acc, syn) => acc + syn.collapsedNodeCount, 0);
449
515
  const collapsedEdgeCount = built.syntheticNodes.reduce((acc, syn) => acc + syn.collapsedEdgeCount, 0);
450
- const blockedReasons = unique([
516
+ const blockedReasons = (0, helpers_1.unique)([
451
517
  ...built.operator.failures.map((f) => `${f.kind} ${f.id}: ${f.reason}`),
452
518
  ...built.syntheticNodes.filter((s) => s.blockedReason).map((s) => s.blockedReason)
453
519
  ]);
454
520
  return {
455
521
  schemaVersion: exports.STATE_EXPLOSION_SCHEMA_VERSION,
456
522
  runId: run.id,
457
- id: `graph-${view}${options.focus ? `:focus:${slug(options.focus)}` : ""}`,
523
+ id: `graph-${view}${options.focus ? `:focus:${(0, helpers_1.slug)(options.focus)}` : ""}`,
458
524
  scope: "run",
459
525
  view,
460
526
  focus: options.focus,
@@ -471,7 +537,7 @@ function finalizeGraphRecord(run, view, options, full, built) {
471
537
  nodes: built.nodes,
472
538
  edges: built.edges,
473
539
  sourceRecordIds: full.nodes.map((n) => n.id).sort(),
474
- sourceFingerprint: fingerprintStrings(full.nodes.map((n) => `${n.id}:${n.status}`)),
540
+ sourceFingerprint: (0, helpers_1.fingerprintStrings)(full.nodes.map((n) => `${n.id}:${n.status}`)),
475
541
  includedCount: built.nodes.length,
476
542
  omittedCount: collapsedNodeCount,
477
543
  importantRefs: built.critical,
@@ -487,7 +553,6 @@ function finalizeGraphRecord(run, view, options, full, built) {
487
553
  }
488
554
  function collapseRuleFor(view) {
489
555
  return {
490
- collapse: true,
491
556
  bucketBy: (node, parentOf) => {
492
557
  switch (node.kind) {
493
558
  case "blackboard-message":
@@ -542,7 +607,7 @@ function filterByView(run, view, full, operator, protectedIds) {
542
607
  ids.add(failure.linked);
543
608
  }
544
609
  for (const node of full.nodes)
545
- if (isProtectedStatus(node.status))
610
+ if ((0, helpers_1.isProtectedStatus)(node.status))
546
611
  ids.add(node.id);
547
612
  ids.add(`${run.id}:run`);
548
613
  break;
@@ -632,7 +697,7 @@ function criticalPathNodeIds(run, operator) {
632
697
  if (failure.linked)
633
698
  ids.push(failure.linked);
634
699
  }
635
- return unique(ids);
700
+ return (0, helpers_1.unique)(ids);
636
701
  }
637
702
  function bfsNeighborhood(focus, nodes, edges, depth) {
638
703
  const adjacency = new Map();
@@ -671,10 +736,13 @@ function expansionCommandFor(run, view, key) {
671
736
  // Operator digest
672
737
  // ---------------------------------------------------------------------------
673
738
  function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS) {
674
- const stateSize = computeStateSize(run, thresholds);
675
- const operator = (0, multi_agent_operator_ux_1.summarizeMultiAgentOperator)(run);
676
- const compact = buildCompactGraph(run, "compact", { thresholds });
677
- const blackboard = summarizeBlackboardDigest(run);
739
+ return buildOperatorDigestWithContext(run, thresholds, createStateExplosionBuildContext());
740
+ }
741
+ function buildOperatorDigestWithContext(run, thresholds, context) {
742
+ const stateSize = stateSizeFor(run, thresholds, context);
743
+ const operator = operatorFor(run, context);
744
+ const compact = buildCompactGraphWithContext(run, "compact", { thresholds }, context);
745
+ const blackboard = blackboardDigestFor(run, context);
678
746
  const evidence = operator.evidence;
679
747
  const adopted = evidence.filter((e) => e.status === "adopted");
680
748
  const missing = evidence.filter((e) => e.status === "missing" || e.status === "pending" || e.status === "conflicting");
@@ -685,7 +753,7 @@ function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_T
685
753
  count: syn.collapsedNodeCount,
686
754
  expansionCommand: syn.expansionCommand
687
755
  }));
688
- const expansionCommands = unique([
756
+ const expansionCommands = (0, helpers_1.unique)([
689
757
  `node scripts/cw.js multi-agent graph ${run.id} --view full --json`,
690
758
  `node scripts/cw.js blackboard message list ${run.id} --topic <topic-id>`,
691
759
  `node scripts/cw.js multi-agent graph ${run.id} --view critical-path`,
@@ -698,7 +766,7 @@ function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_T
698
766
  id: "operator-digest",
699
767
  scope: "run",
700
768
  sourceRecordIds: compact.sourceRecordIds,
701
- sourceFingerprint: fingerprintStrings([
769
+ sourceFingerprint: (0, helpers_1.fingerprintStrings)([
702
770
  compact.sourceFingerprint,
703
771
  blackboard.sourceFingerprint,
704
772
  String(stateSize.total)
@@ -706,8 +774,8 @@ function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_T
706
774
  includedCount: compact.compactNodeCount,
707
775
  omittedCount: compact.collapsedNodeCount,
708
776
  importantRefs: compact.criticalPath,
709
- evidenceRefs: unique(adopted.map((e) => e.ref || e.id)),
710
- trustAuditEventRefs: [],
777
+ evidenceRefs: (0, helpers_1.unique)(adopted.map((e) => e.ref || e.id)),
778
+ trustAuditEventRefs: (0, helpers_1.unique)(blackboard.trustAuditEventRefs),
711
779
  generatedAt: new Date().toISOString(),
712
780
  status: "valid",
713
781
  deterministic: true,
@@ -740,7 +808,7 @@ function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_T
740
808
  events: trust?.totalEvents || 0,
741
809
  policyViolations: blackboard.policyViolations.length,
742
810
  judgeRationales: blackboard.judgeRationale.length,
743
- entries: unique([
811
+ entries: (0, helpers_1.unique)([
744
812
  ...blackboard.policyViolations.map((p) => p.id),
745
813
  ...blackboard.judgeRationale.map((j) => j.id)
746
814
  ])
@@ -753,13 +821,16 @@ function buildOperatorDigest(run, thresholds = exports.DEFAULT_STATE_EXPLOSION_T
753
821
  // State explosion report (combines all derived indexes)
754
822
  // ---------------------------------------------------------------------------
755
823
  function buildStateExplosionReport(run, options = {}) {
824
+ return buildStateExplosionReportWithContext(run, options, createStateExplosionBuildContext());
825
+ }
826
+ function buildStateExplosionReportWithContext(run, options, context) {
756
827
  const thresholds = options.thresholds || exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS;
757
- const stateSize = computeStateSize(run, thresholds);
758
- const compactGraph = buildCompactGraph(run, "compact", { thresholds });
759
- const criticalPathGraph = buildCompactGraph(run, "critical-path", { thresholds });
760
- const blackboardDigest = summarizeBlackboardDigest(run);
761
- const operatorDigest = buildOperatorDigest(run, thresholds);
762
- const currentFingerprint = fingerprintStrings([
828
+ const stateSize = stateSizeFor(run, thresholds, context);
829
+ const compactGraph = buildCompactGraphWithContext(run, "compact", { thresholds }, context);
830
+ const criticalPathGraph = buildCompactGraphWithContext(run, "critical-path", { thresholds }, context);
831
+ const blackboardDigest = blackboardDigestFor(run, context);
832
+ const operatorDigest = buildOperatorDigestWithContext(run, thresholds, context);
833
+ const currentFingerprint = (0, helpers_1.fingerprintStrings)([
763
834
  compactGraph.sourceFingerprint,
764
835
  blackboardDigest.sourceFingerprint,
765
836
  operatorDigest.sourceFingerprint,
@@ -837,12 +908,13 @@ function summariesDir(run) {
837
908
  }
838
909
  function refreshStateExplosionSummaries(run, options = {}) {
839
910
  const thresholds = options.thresholds || exports.DEFAULT_STATE_EXPLOSION_THRESHOLDS;
911
+ const context = createStateExplosionBuildContext();
840
912
  const dir = summariesDir(run);
841
913
  node_fs_1.default.mkdirSync(dir, { recursive: true });
842
914
  const views = options.views || ["full", "compact", "critical-path", "failures", "evidence", "trust", "topology", "blackboard", "candidate", "commit-gate"];
843
- const blackboardDigest = summarizeBlackboardDigest(run);
844
- const operatorDigest = buildOperatorDigest(run, thresholds);
845
- const graphRecords = views.map((view) => buildCompactGraph(run, view, { thresholds }));
915
+ const blackboardDigest = blackboardDigestFor(run, context);
916
+ const operatorDigest = buildOperatorDigestWithContext(run, thresholds, context);
917
+ const graphRecords = views.map((view) => buildCompactGraphWithContext(run, view, { thresholds }, context));
846
918
  const entries = [];
847
919
  const writeRecord = (id, record, scope, fingerprint, included, omitted) => {
848
920
  const file = node_path_1.default.join(dir, `${(0, state_1.safeFileName)(id)}.json`);
@@ -854,22 +926,17 @@ function refreshStateExplosionSummaries(run, options = {}) {
854
926
  for (const record of graphRecords) {
855
927
  writeRecord(record.id, record, "run", record.sourceFingerprint, record.compactNodeCount, record.collapsedNodeCount);
856
928
  }
857
- const stateSize = computeStateSize(run, thresholds);
858
- const indexFingerprint = fingerprintStrings([
859
- operatorDigest.sourceFingerprint,
860
- blackboardDigest.sourceFingerprint,
861
- ...graphRecords.map((r) => r.sourceFingerprint),
862
- String(stateSize.total)
863
- ]);
929
+ const stateSize = stateSizeFor(run, thresholds, context);
930
+ const compactGraph = buildCompactGraphWithContext(run, "compact", { thresholds }, context);
864
931
  const reportPath = node_path_1.default.join(dir, "state-explosion-report.json");
865
932
  const index = {
866
933
  schemaVersion: exports.STATE_EXPLOSION_SCHEMA_VERSION,
867
934
  runId: run.id,
868
935
  id: "multi-agent-summary-index",
869
936
  scope: "run",
870
- sourceRecordIds: unique([...blackboardDigest.sourceRecordIds, ...operatorDigest.sourceRecordIds]),
871
- sourceFingerprint: fingerprintStrings([
872
- buildCompactGraph(run, "compact", { thresholds }).sourceFingerprint,
937
+ sourceRecordIds: (0, helpers_1.unique)([...blackboardDigest.sourceRecordIds, ...operatorDigest.sourceRecordIds]),
938
+ sourceFingerprint: (0, helpers_1.fingerprintStrings)([
939
+ compactGraph.sourceFingerprint,
873
940
  blackboardDigest.sourceFingerprint,
874
941
  operatorDigest.sourceFingerprint,
875
942
  String(stateSize.total)
@@ -891,9 +958,8 @@ function refreshStateExplosionSummaries(run, options = {}) {
891
958
  reportPath
892
959
  }
893
960
  };
894
- void indexFingerprint;
895
961
  (0, state_1.writeJson)(index.paths.indexPath, index);
896
- const report = buildStateExplosionReport(run, { thresholds, index });
962
+ const report = buildStateExplosionReportWithContext(run, { thresholds, index }, context);
897
963
  (0, state_1.writeJson)(reportPath, report);
898
964
  (0, trust_audit_1.recordTrustAuditEvent)(run, {
899
965
  kind: "summary.refresh",
@@ -944,175 +1010,19 @@ function showStateExplosionSummary(run, options = {}) {
944
1010
  }
945
1011
  return report;
946
1012
  }
947
- // ---------------------------------------------------------------------------
948
- // Human formatting
949
- // ---------------------------------------------------------------------------
950
- function formatStateExplosionReport(report) {
951
- const lines = [];
952
- const size = report.stateSize;
953
- lines.push(`State Explosion Report: ${report.runId}`);
954
- lines.push(`Freshness: ${report.freshness.status}${report.freshness.staleScopes.length ? ` (stale: ${report.freshness.staleScopes.join(", ")})` : ""}`);
955
- lines.push("");
956
- lines.push("State Size");
957
- lines.push(` records=${size.total}; graph nodes=${size.graphNodes}; graph edges=${size.graphEdges}; messages=${size.messages}; compaction=${size.compactionRecommended ? "recommended" : "not needed"}`);
958
- for (const reason of size.reasons)
959
- lines.push(` - ${reason}`);
960
- lines.push("");
961
- lines.push("Compact Graph");
962
- lines.push(` full=${report.compactGraph.fullNodeCount} nodes/${report.compactGraph.fullEdgeCount} edges -> compact=${report.compactGraph.compactNodeCount} nodes/${report.compactGraph.compactEdgeCount} edges`);
963
- if (report.compactGraph.collapsedNodeCount > 0) {
964
- lines.push(` Graph compacted: ${report.compactGraph.collapsedNodeCount} nodes collapsed into ${report.compactGraph.syntheticNodes.length} summary nodes`);
965
- }
966
- for (const syn of report.compactGraph.syntheticNodes) {
967
- lines.push(` [${syn.dominantStatus}] ${syn.id} collapses ${syn.collapsedNodeCount} nodes/${syn.collapsedEdgeCount} edges${syn.blockedReason ? ` blocked=${syn.blockedReason}` : ""}; expand: ${syn.expansionCommand}`);
968
- }
969
- lines.push("");
970
- lines.push("Blackboard Digest");
971
- lines.push(` topics=${report.blackboardDigest.topicRollups.length}; threads=${report.blackboardDigest.threadSummaries.length}; unresolved=${report.blackboardDigest.unresolvedQuestions.length}; conflicts=${report.blackboardDigest.conflicts.length}; decisions=${report.blackboardDigest.decisions.length}; artifacts=${report.blackboardDigest.artifacts.length}`);
972
- for (const topic of report.blackboardDigest.topicRollups.slice(0, 20))
973
- lines.push(` - ${topic.label}; expand: ${topic.expansionCommand}`);
974
- lines.push("");
975
- lines.push("Critical Path");
976
- if (!report.criticalPathGraph.criticalPath.length)
977
- lines.push(" none");
978
- for (const id of report.criticalPathGraph.criticalPath.slice(0, 40))
979
- lines.push(` -> ${id}`);
980
- lines.push("");
981
- lines.push("Failures / Blockers");
982
- if (!report.operatorDigest.failures.length)
983
- lines.push(" none");
984
- for (const failure of report.operatorDigest.failures.slice(0, 30))
985
- lines.push(` [${failure.status}] ${failure.kind} ${failure.id}: ${failure.reason}; next=${failure.nextCommand}`);
986
- lines.push("");
987
- lines.push("Evidence Digest");
988
- lines.push(` adopted=${report.operatorDigest.evidenceDigest.adopted}; missing=${report.operatorDigest.evidenceDigest.missing}; rejected=${report.operatorDigest.evidenceDigest.rejected}`);
989
- lines.push("");
990
- lines.push("Trust / Policy Digest");
991
- lines.push(` events=${report.operatorDigest.trustDigest.events}; policyViolations=${report.operatorDigest.trustDigest.policyViolations}; judgeRationales=${report.operatorDigest.trustDigest.judgeRationales}`);
992
- for (const violation of report.blackboardDigest.policyViolations.slice(0, 20))
993
- lines.push(` [policy] ${violation.label}; expand: ${violation.expansionCommand}`);
994
- lines.push("");
995
- lines.push("Hidden Source Records");
996
- if (!report.hiddenSourceRecords.length)
997
- lines.push(" none (all records shown)");
998
- for (const hidden of report.hiddenSourceRecords)
999
- lines.push(` ${hidden.kind}: ${hidden.count} records hidden; expand: ${hidden.expansionCommand}`);
1000
- lines.push("");
1001
- lines.push("Expansion Commands");
1002
- for (const command of report.expansionCommands)
1003
- lines.push(` ${command}`);
1004
- lines.push("");
1005
- lines.push("Next Action");
1006
- lines.push(` ${report.nextAction}`);
1007
- return lines.join("\n");
1008
- }
1009
- function formatCompactGraph(graph) {
1010
- const lines = [];
1011
- lines.push(`Compact Graph (${graph.view}): ${graph.runId}`);
1012
- lines.push(` full=${graph.fullNodeCount} nodes/${graph.fullEdgeCount} edges -> view=${graph.compactNodeCount} nodes/${graph.compactEdgeCount} edges`);
1013
- if (graph.collapsedNodeCount > 0) {
1014
- lines.push(` Graph compacted: ${graph.collapsedNodeCount} nodes collapsed into ${graph.syntheticNodes.length} summary nodes`);
1015
- }
1016
- lines.push("");
1017
- lines.push("Critical Path");
1018
- if (!graph.criticalPath.length)
1019
- lines.push(" none");
1020
- for (const id of graph.criticalPath.slice(0, 40))
1021
- lines.push(` -> ${id}`);
1022
- lines.push("");
1023
- lines.push("Summary Nodes");
1024
- if (!graph.syntheticNodes.length)
1025
- lines.push(" none");
1026
- for (const syn of graph.syntheticNodes) {
1027
- lines.push(` [${syn.dominantStatus}] ${syn.id}: ${syn.collapsedNodeCount} nodes / ${syn.collapsedEdgeCount} edges${syn.blockedReason ? ` blocked=${syn.blockedReason}` : ""}`);
1028
- lines.push(` expand: ${syn.expansionCommand}`);
1029
- }
1030
- lines.push("");
1031
- lines.push("Blockers");
1032
- if (!graph.blockedReasons.length)
1033
- lines.push(" none");
1034
- for (const reason of graph.blockedReasons.slice(0, 20))
1035
- lines.push(` ${reason}`);
1036
- lines.push("");
1037
- lines.push("Nodes");
1038
- for (const node of graph.nodes.slice(0, 80)) {
1039
- lines.push(` [${node.status}] ${node.kind} ${node.id}${node.synthetic ? ` (summary of ${node.synthetic.collapsedNodeCount})` : ""}`);
1040
- }
1041
- if (graph.nodes.length > 80)
1042
- lines.push(` ... ${graph.nodes.length - 80} more`);
1043
- lines.push("");
1044
- lines.push("Next Action");
1045
- lines.push(` ${graph.nextAction}`);
1046
- return lines.join("\n");
1047
- }
1048
- function formatBlackboardDigest(record) {
1049
- const lines = [];
1050
- lines.push(`Blackboard Digest: ${record.runId}${record.blackboardId ? ` (${record.blackboardId})` : ""}`);
1051
- lines.push(` freshness=${record.status}; included=${record.includedCount}; omitted=${record.omittedCount}`);
1052
- const section = (title, entries) => {
1053
- lines.push("");
1054
- lines.push(title);
1055
- if (!entries.length) {
1056
- lines.push(" none");
1057
- return;
1058
- }
1059
- for (const entry of entries.slice(0, 25))
1060
- lines.push(` [${entry.status}] ${entry.label}; expand: ${entry.expansionCommand}`);
1061
- if (entries.length > 25)
1062
- lines.push(` ... ${entries.length - 25} more`);
1063
- };
1064
- section("Topic Rollups", record.topicRollups);
1065
- section("Thread Summaries", record.threadSummaries);
1066
- section("Unresolved Questions", record.unresolvedQuestions);
1067
- section("Conflicts", record.conflicts);
1068
- section("Decisions", record.decisions);
1069
- section("Artifacts", record.artifacts);
1070
- section("Adopted Evidence", record.adoptedEvidence);
1071
- section("Missing Evidence", record.missingEvidence);
1072
- section("Policy Violations", record.policyViolations);
1073
- section("Judge Rationale", record.judgeRationale);
1074
- section("Recent Changes", record.recentChanges);
1075
- section("High-Signal Records", record.highSignal);
1076
- lines.push("");
1077
- lines.push("Next Action");
1078
- lines.push(` ${record.nextAction}`);
1079
- return lines.join("\n");
1080
- }
1081
- function stateExplosionReportLines(report) {
1082
- // Markdown lines for inclusion in the run report.md State Size section.
1083
- const size = report.stateSize;
1084
- const lines = [
1085
- `- Records: ${size.total}; graph nodes: ${size.graphNodes}; graph edges: ${size.graphEdges}; messages: ${size.messages}`,
1086
- `- Compaction: ${size.compactionRecommended ? "recommended" : "not needed"}`,
1087
- `- Summary freshness: ${report.freshness.status}`
1088
- ];
1089
- for (const reason of size.reasons)
1090
- lines.push(` - ${reason}`);
1091
- if (report.compactGraph.collapsedNodeCount > 0) {
1092
- lines.push(`- Graph compacted: ${report.compactGraph.collapsedNodeCount} nodes collapsed into ${report.compactGraph.syntheticNodes.length} summary nodes`);
1093
- lines.push(` - Use: \`node scripts/cw.js multi-agent graph ${report.runId} --view full --json\``);
1094
- }
1095
- if (report.hiddenSourceRecords.length) {
1096
- for (const hidden of report.hiddenSourceRecords) {
1097
- lines.push(`- Hidden ${hidden.kind}: ${hidden.count} records; expand: \`${hidden.expansionCommand}\``);
1098
- }
1099
- }
1100
- lines.push(`- Next: \`${report.nextAction}\``);
1101
- return lines;
1102
- }
1103
1013
  function normalizeStateExplosionForEval(run) {
1104
1014
  const report = buildStateExplosionReport(run);
1105
1015
  const graph = report.compactGraph;
1106
1016
  return {
1107
1017
  summaryFreshness: [
1108
- stableLine({
1018
+ (0, helpers_1.stableLine)({
1109
1019
  compactionRecommended: report.stateSize.compactionRecommended,
1110
1020
  total: report.stateSize.total,
1111
1021
  deterministic: graph.deterministic
1112
1022
  })
1113
1023
  ],
1114
1024
  compactGraphShape: [
1115
- stableLine({
1025
+ (0, helpers_1.stableLine)({
1116
1026
  view: graph.view,
1117
1027
  fullNodeCount: graph.fullNodeCount,
1118
1028
  fullEdgeCount: graph.fullEdgeCount,
@@ -1128,7 +1038,7 @@ function normalizeStateExplosionForEval(run) {
1128
1038
  })
1129
1039
  ],
1130
1040
  blackboardDigest: [
1131
- stableLine({
1041
+ (0, helpers_1.stableLine)({
1132
1042
  topics: report.blackboardDigest.topicRollups.length,
1133
1043
  threads: report.blackboardDigest.threadSummaries.length,
1134
1044
  unresolved: report.blackboardDigest.unresolvedQuestions.map((q) => q.id),
@@ -1140,9 +1050,9 @@ function normalizeStateExplosionForEval(run) {
1140
1050
  missingEvidence: report.blackboardDigest.missingEvidence.map((m) => m.label)
1141
1051
  })
1142
1052
  ],
1143
- criticalPath: graph.criticalPath.map((id) => stripRunId(run, id)).sort(),
1053
+ criticalPath: graph.criticalPath.map((id) => (0, helpers_1.stripRunId)(run, id)).sort(),
1144
1054
  evidenceDigest: [
1145
- stableLine({
1055
+ (0, helpers_1.stableLine)({
1146
1056
  adopted: report.operatorDigest.evidenceDigest.adopted,
1147
1057
  missing: report.operatorDigest.evidenceDigest.missing,
1148
1058
  rejected: report.operatorDigest.evidenceDigest.rejected
@@ -1152,62 +1062,13 @@ function normalizeStateExplosionForEval(run) {
1152
1062
  };
1153
1063
  }
1154
1064
  // ---------------------------------------------------------------------------
1155
- // Helpers
1065
+ // Helpers + human formatting now live in sibling modules (FreeBSD-audit carve).
1066
+ // Re-exported below so every importer of this module stays byte-unchanged.
1156
1067
  // ---------------------------------------------------------------------------
1157
- function isProtectedStatus(status) {
1158
- return ["failed", "blocked", "rejected", "conflicting"].includes(status);
1159
- }
1160
- function dominantStatus(statuses) {
1161
- for (const priority of ["failed", "blocked", "rejected", "conflicting", "running", "pending"]) {
1162
- if (statuses.includes(priority))
1163
- return priority;
1164
- }
1165
- return statuses[0] || "completed";
1166
- }
1167
- function parentMap(edges) {
1168
- const parents = new Map();
1169
- for (const edge of edges) {
1170
- if (!parents.has(edge.to))
1171
- parents.set(edge.to, edge.from);
1172
- }
1173
- return parents;
1174
- }
1175
- function fingerprintRecords(records) {
1176
- return fingerprintStrings(records.map((r) => `${r.id}:${r.status || ""}`).sort());
1177
- }
1178
- function fingerprintStrings(values) {
1179
- const hash = node_crypto_1.default.createHash("sha256");
1180
- hash.update(JSON.stringify([...values].sort()));
1181
- return `sha256:${hash.digest("hex").slice(0, 32)}`;
1182
- }
1183
- function stableLine(value) {
1184
- return JSON.stringify(sortKeys(value));
1185
- }
1186
- function sortKeys(value) {
1187
- if (Array.isArray(value))
1188
- return value.map(sortKeys);
1189
- if (value && typeof value === "object") {
1190
- const record = value;
1191
- const result = {};
1192
- for (const key of Object.keys(record).sort())
1193
- result[key] = sortKeys(record[key]);
1194
- return result;
1195
- }
1196
- return value;
1197
- }
1198
- function stripRunId(run, id) {
1199
- return id.startsWith(`${run.id}:`) ? id.slice(run.id.length + 1) : id;
1200
- }
1201
- function unique(values) {
1202
- return Array.from(new Set(values.filter(Boolean))).sort();
1203
- }
1204
- function byId(a, b) {
1205
- return a.id.localeCompare(b.id);
1206
- }
1207
- function truncate(value) {
1208
- const single = value.replace(/\s+/g, " ").trim();
1209
- return single.length > 80 ? `${single.slice(0, 77)}...` : single;
1210
- }
1211
- function slug(value) {
1212
- return value.replace(/[^a-zA-Z0-9._:-]/g, "-");
1213
- }
1068
+ var helpers_2 = require("./state-explosion/helpers");
1069
+ Object.defineProperty(exports, "fingerprintStrings", { enumerable: true, get: function () { return helpers_2.fingerprintStrings; } });
1070
+ var format_1 = require("./state-explosion/format");
1071
+ Object.defineProperty(exports, "formatStateExplosionReport", { enumerable: true, get: function () { return format_1.formatStateExplosionReport; } });
1072
+ Object.defineProperty(exports, "formatCompactGraph", { enumerable: true, get: function () { return format_1.formatCompactGraph; } });
1073
+ Object.defineProperty(exports, "formatBlackboardDigest", { enumerable: true, get: function () { return format_1.formatBlackboardDigest; } });
1074
+ Object.defineProperty(exports, "stateExplosionReportLines", { enumerable: true, get: function () { return format_1.stateExplosionReportLines; } });