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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +51 -3
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +64 -0
- package/apps/architecture-review-fast/workflow.js +153 -0
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/agent-config.js +21 -7
- package/dist/candidate-scoring.js +42 -22
- package/dist/capability-core.js +132 -17
- package/dist/capability-registry.js +138 -168
- package/dist/cli.js +97 -98
- package/dist/collaboration.js +5 -6
- package/dist/commit.js +20 -6
- package/dist/compare.js +18 -0
- package/dist/coordinator/classify.js +45 -0
- package/dist/coordinator/paths.js +42 -0
- package/dist/coordinator/util.js +129 -0
- package/dist/coordinator.js +127 -300
- package/dist/dispatch.js +35 -0
- package/dist/drive.js +79 -6
- package/dist/error-feedback.js +8 -4
- package/dist/evidence-reasoning.js +3 -3
- package/dist/execution-backend/agent.js +331 -0
- package/dist/execution-backend/probes.js +96 -0
- package/dist/execution-backend/util.js +47 -0
- package/dist/execution-backend.js +73 -421
- package/dist/mcp-server.js +79 -183
- package/dist/multi-agent/graph.js +84 -0
- package/dist/multi-agent/helpers.js +145 -0
- package/dist/multi-agent/paths.js +22 -0
- package/dist/multi-agent-eval/format.js +194 -0
- package/dist/multi-agent-eval/normalize.js +51 -0
- package/dist/multi-agent-eval.js +39 -244
- package/dist/multi-agent-host.js +0 -19
- package/dist/multi-agent.js +125 -314
- package/dist/node-snapshot.js +3 -3
- package/dist/observability/format.js +61 -0
- package/dist/observability/intake.js +98 -0
- package/dist/observability.js +14 -160
- package/dist/operator-ux/format.js +364 -0
- package/dist/operator-ux.js +22 -363
- package/dist/orchestrator/lifecycle-operations.js +2 -1
- package/dist/orchestrator/report.js +8 -0
- package/dist/orchestrator.js +26 -9
- package/dist/reclamation.js +26 -21
- package/dist/run-export.js +494 -25
- package/dist/run-registry/derive.js +172 -0
- package/dist/run-registry/format.js +124 -0
- package/dist/run-registry/gc.js +251 -0
- package/dist/run-registry/policy.js +16 -0
- package/dist/run-registry/queue.js +116 -0
- package/dist/run-registry.js +89 -597
- package/dist/run-state-schema.js +1 -0
- package/dist/sandbox-profile.js +43 -2
- package/dist/state-explosion/format.js +159 -0
- package/dist/state-explosion/helpers.js +82 -0
- package/dist/state-explosion.js +165 -304
- package/dist/state-node.js +19 -4
- package/dist/telemetry-attestation.js +55 -0
- package/dist/telemetry-demo.js +15 -3
- package/dist/telemetry-ledger.js +60 -15
- package/dist/topology.js +25 -8
- package/dist/triggers.js +33 -14
- package/dist/trust-audit.js +145 -33
- package/dist/version.js +1 -1
- package/dist/worker-isolation/helpers.js +51 -0
- package/dist/worker-isolation/paths.js +46 -0
- package/dist/worker-isolation.js +39 -115
- package/docs/agent-delegation-drive.7.md +71 -0
- package/docs/canonical-workflow-apps.7.md +37 -0
- package/docs/cli-mcp-parity.7.md +16 -0
- package/docs/contract-migration-tooling.7.md +6 -0
- package/docs/control-plane-scheduling.7.md +6 -0
- package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +40 -0
- package/docs/durable-state-and-locking.7.md +8 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +6 -0
- package/docs/execution-backends.7.md +6 -0
- package/docs/index.md +2 -0
- package/docs/launch/demo.tape +28 -0
- package/docs/launch/launch-kit.md +96 -17
- package/docs/launch/pre-launch-checklist.md +53 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +8 -0
- package/docs/multi-agent-eval-replay-harness.7.md +6 -0
- package/docs/multi-agent-operator-ux.7.md +6 -0
- package/docs/multi-agent-trust-policy-audit.7.md +27 -0
- package/docs/node-snapshot-diff-replay.7.md +6 -0
- package/docs/observability-cost-accounting.7.md +6 -0
- package/docs/project-index.md +27 -6
- package/docs/real-execution-backends.7.md +6 -0
- package/docs/release-and-migration.7.md +8 -0
- package/docs/release-tooling.7.md +6 -0
- package/docs/routines.md +23 -0
- package/docs/run-registry-control-plane.7.md +89 -2
- package/docs/run-retention-reclamation.7.md +8 -0
- package/docs/source-context-profiles.7.md +119 -0
- package/docs/state-explosion-management.7.md +13 -0
- package/docs/team-collaboration.7.md +6 -0
- package/docs/trust-model.md +267 -0
- package/docs/unix-principles.md +49 -1
- package/docs/vendor-manifest-loadability.7.md +43 -0
- package/docs/web-desktop-workbench.7.md +6 -0
- package/manifest/plugin.manifest.json +1 -1
- package/manifest/source-context-profiles.json +142 -0
- package/package.json +4 -1
- package/scripts/agents/builtin-templates.json +7 -0
- package/scripts/agents/claude-p-agent.js +129 -43
- package/scripts/architecture-review-fast.js +362 -0
- package/scripts/bump-version.js +5 -10
- package/scripts/canonical-apps-list.js +64 -0
- package/scripts/canonical-apps.js +36 -4
- package/scripts/coverage-gate.js +211 -0
- package/scripts/dogfood-release.js +1 -1
- package/scripts/golden-path.js +4 -4
- package/scripts/parity-check.js +5 -0
- package/scripts/release-check.js +5 -1
- package/scripts/source-context.js +291 -0
- package/scripts/version-sync-check.js +5 -7
- package/skills/ci-triage/SKILL.md +50 -0
- package/skills/ci-triage/agents/openai.yaml +4 -0
- package/skills/cool-workflow/SKILL.md +4 -1
- package/skills/deploy-check/SKILL.md +55 -0
- package/skills/deploy-check/agents/openai.yaml +4 -0
- package/skills/design-qa/SKILL.md +49 -0
- package/skills/design-qa/agents/openai.yaml +4 -0
- package/skills/pr-review/SKILL.md +45 -0
- package/skills/pr-review/agents/openai.yaml +4 -0
- package/dist/capability-dispatcher.js +0 -86
package/dist/state-explosion.js
CHANGED
|
@@ -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
|
|
316
|
-
const
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
const
|
|
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 =
|
|
758
|
-
const compactGraph =
|
|
759
|
-
const criticalPathGraph =
|
|
760
|
-
const blackboardDigest =
|
|
761
|
-
const operatorDigest =
|
|
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 =
|
|
844
|
-
const operatorDigest =
|
|
845
|
-
const graphRecords = views.map((view) =>
|
|
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 =
|
|
858
|
-
const
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
function
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
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; } });
|