vericify 0.1.0

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.
@@ -0,0 +1,809 @@
1
+ import { fingerprintText, similarityFromText } from "../similarity/semantic-hash.js";
2
+ import { asArray, firstDefined, hashText, isoNow, slugify, unique, workspaceRef } from "../core/util.js";
3
+ import {
4
+ checkpointTriggerFromHandoff,
5
+ checkpointTriggerFromLedgerEntry,
6
+ checkpointTriggerFromProcessPost,
7
+ checkpointTriggerFromStatusEvent,
8
+ checkpointTriggerFromWorkspaceSummary,
9
+ } from "../checkpoints/policy.js";
10
+
11
+ function sortByUpdatedDescending(items) {
12
+ return [...items].sort((left, right) => String(right.updated_at).localeCompare(String(left.updated_at)));
13
+ }
14
+
15
+ function laneStatusFromHandoffStatus(status, isRecipient) {
16
+ if (status === "blocked") return "blocked";
17
+ if (status === "completed") return "completed";
18
+ if (isRecipient) return "running";
19
+ return "idle";
20
+ }
21
+
22
+ function inferRunStatus(values) {
23
+ if (values.some((value) => value === "blocked" || value === "failed")) return "blocked";
24
+ if (values.some((value) => value === "running")) return "running";
25
+ if (values.some((value) => value === "completed")) return "completed";
26
+ if (values.some((value) => value === "planned")) return "planned";
27
+ return "planned";
28
+ }
29
+
30
+ function runStatusFromNodes(nodes) {
31
+ if (nodes.some((node) => node.status === "blocked")) return "blocked";
32
+ if (nodes.length > 0 && nodes.every((node) => node.status === "done")) return "completed";
33
+ if (nodes.some((node) => node.status === "in_progress" || node.status === "gated")) return "running";
34
+ if (nodes.length > 0) return "planned";
35
+ return "planned";
36
+ }
37
+
38
+ function runStatusFromHandoff(status) {
39
+ if (status === "blocked") return "blocked";
40
+ if (status === "completed") return "completed";
41
+ if (status === "accepted") return "running";
42
+ return "planned";
43
+ }
44
+
45
+ function statusFromEventStatus(status) {
46
+ if (status === "blocked" || status === "fail") return "blocked";
47
+ if (status === "done" || status === "pass") return "completed";
48
+ if (status === "in_progress" || status === "started") return "running";
49
+ return "planned";
50
+ }
51
+
52
+ function statusFromLedgerCategory(category) {
53
+ if (category === "regression") return "blocked";
54
+ if (category === "major_update") return "running";
55
+ return "planned";
56
+ }
57
+
58
+ function statusFromProcessPostKind(kind) {
59
+ if (kind === "blocker") return "blocked";
60
+ if (kind === "completion") return "completed";
61
+ return "running";
62
+ }
63
+
64
+ function humanizeToken(value) {
65
+ return String(value ?? "")
66
+ .replace(/[-_]+/g, " ")
67
+ .trim();
68
+ }
69
+
70
+ function activityItemFromProcessPost(post) {
71
+ return {
72
+ activity_id: post.process_post_id,
73
+ run_id: post.run_id,
74
+ branch_id: post.branch_id,
75
+ lane_id: post.lane_id,
76
+ timestamp: post.timestamp ?? isoNow(),
77
+ source_kind: "process_post",
78
+ actor_id: post.agent_id ?? "unknown",
79
+ label: post.kind,
80
+ status: statusFromProcessPostKind(post.kind),
81
+ summary: post.summary,
82
+ refs: unique([...asArray(post.evidence_refs), ...asArray(post.tool_refs)]),
83
+ };
84
+ }
85
+
86
+ function activityItemFromStatusEvent(runId, event) {
87
+ return {
88
+ activity_id: event.event_id ?? `${runId}:event:${hashText(`${event.timestamp}:${event.source_module}:${event.event_type}`).slice(0, 10)}`,
89
+ run_id: runId,
90
+ branch_id: explicitBranchId(runId, event),
91
+ lane_id: explicitLaneId(runId, event),
92
+ timestamp: event.timestamp ?? isoNow(),
93
+ source_kind: "status_event",
94
+ actor_id: event.source_module ?? "unknown",
95
+ label: event.event_type,
96
+ status: statusFromEventStatus(event.status),
97
+ summary: event.payload?.summary ?? event.event_type,
98
+ refs: asArray(event.payload?.evidence_ref),
99
+ };
100
+ }
101
+
102
+ function activityItemFromLedgerEntry(runId, entry) {
103
+ return {
104
+ activity_id: entry.id ?? `${runId}:ledger:${hashText(`${entry.timestamp_utc}:${entry.tool}:${entry.message}`).slice(0, 10)}`,
105
+ run_id: runId,
106
+ branch_id: explicitBranchId(runId, entry),
107
+ lane_id: explicitLaneId(runId, entry),
108
+ timestamp: entry.timestamp_utc ?? isoNow(),
109
+ source_kind: "run_ledger",
110
+ actor_id: entry.tool ?? "unknown",
111
+ label: entry.category,
112
+ status: statusFromLedgerCategory(entry.category),
113
+ summary: entry.message,
114
+ refs: asArray(entry.artifacts),
115
+ };
116
+ }
117
+
118
+ function summarizeLaneHeartbeat(lane, latestActivity) {
119
+ const node = lane.current_node_id ? humanizeToken(lane.current_node_id) : "";
120
+ const nodePart = node ? ` on ${node}` : "";
121
+ const latestPart = latestActivity
122
+ ? ` Latest ${latestActivity.label}: ${latestActivity.summary}`
123
+ : lane.status === "idle"
124
+ ? " Awaiting new work."
125
+ : " Awaiting next signal.";
126
+ return `${lane.status}${nodePart}.${latestPart}`;
127
+ }
128
+
129
+ function activityItemFromLaneHeartbeat(runDetail, lane, latestActivity) {
130
+ const branch = runDetail.branches.find((candidate) => candidate.lane_ids?.includes(lane.lane_id));
131
+ return {
132
+ activity_id: `${runDetail.run.run_id}:lane-heartbeat:${slugify(lane.lane_id) || hashText(lane.lane_id).slice(0, 10)}`,
133
+ run_id: runDetail.run.run_id,
134
+ branch_id: branch?.branch_id,
135
+ lane_id: lane.lane_id,
136
+ timestamp: lane.updated_at ?? isoNow(),
137
+ source_kind: "lane_heartbeat",
138
+ actor_id: lane.agent_id ?? "unknown",
139
+ label: "heartbeat",
140
+ status: lane.status,
141
+ summary: summarizeLaneHeartbeat(lane, latestActivity),
142
+ refs: latestActivity?.refs ?? [],
143
+ };
144
+ }
145
+
146
+ function checkpointFromSummary({
147
+ checkpointId,
148
+ runId,
149
+ branchId,
150
+ laneId,
151
+ handoffId,
152
+ nodeRef,
153
+ timestamp,
154
+ summary,
155
+ taskDelta,
156
+ evidenceRefs,
157
+ gitCommitSha,
158
+ checkpointMeta = {},
159
+ }) {
160
+ return {
161
+ checkpoint_id: checkpointId,
162
+ run_id: runId,
163
+ branch_id: branchId,
164
+ lane_id: laneId,
165
+ handoff_id: handoffId,
166
+ node_ref: nodeRef,
167
+ timestamp,
168
+ git_commit_sha: gitCommitSha,
169
+ checkpoint_policy_version: checkpointMeta.checkpoint_policy_version,
170
+ trigger_kind: checkpointMeta.trigger_kind,
171
+ trigger_reason: checkpointMeta.trigger_reason,
172
+ capture_mode: checkpointMeta.capture_mode,
173
+ semantic_fingerprint: fingerprintText(summary),
174
+ task_delta_summary: taskDelta,
175
+ evidence_refs: evidenceRefs ?? [],
176
+ process_summary: summary,
177
+ };
178
+ }
179
+
180
+ function sortByTimestamp(items, accessor) {
181
+ return [...items].sort((left, right) => String(accessor(left)).localeCompare(String(accessor(right))));
182
+ }
183
+
184
+ function explicitBranchId(runId, record) {
185
+ return firstDefined(record.branch_id, record.payload?.branch_id, record.metadata?.branch_id) ?? `${runId}:main`;
186
+ }
187
+
188
+ function explicitLaneId(runId, record) {
189
+ const direct = firstDefined(record.lane_id, record.payload?.lane_id, record.metadata?.lane_id);
190
+ if (direct) return direct;
191
+ const agent = firstDefined(record.agent_id, record.source_module, record.from_agent, record.from, "unknown");
192
+ const processId = firstDefined(record.process_id, record.payload?.process_id, record.metadata?.process_id);
193
+ const suffix = processId ? `${slugify(agent)}:${slugify(String(processId))}` : slugify(String(agent));
194
+ return `${runId}:lane:${suffix || "unknown"}`;
195
+ }
196
+
197
+ function runIdFromStatusEvent(event) {
198
+ return firstDefined(event.run_id, event.payload?.run_id) ??
199
+ (event.objective_id ? `objective:${event.objective_id}` : event.trace_id ? `trace:${event.trace_id}` : null);
200
+ }
201
+
202
+ function runIdFromLedgerEntry(entry) {
203
+ const metadata = entry.metadata ?? {};
204
+ return firstDefined(
205
+ metadata.run_id,
206
+ metadata.runId,
207
+ metadata.trace_id ? `trace:${metadata.trace_id}` : undefined,
208
+ metadata.objective_id ? `objective:${metadata.objective_id}` : undefined,
209
+ metadata.handoff_id ? `handoff:${metadata.handoff_id}` : undefined
210
+ );
211
+ }
212
+
213
+ function matchingRunIdsForHandoff(handoff) {
214
+ return unique([`handoff:${handoff.handoff_id}`, handoff.handoff_id]);
215
+ }
216
+
217
+ function deltaBetween(left, right, id) {
218
+ const layers = ["structural", "semantic", "operational"];
219
+ if (left?.git_commit_sha && right?.git_commit_sha) layers.unshift("exact");
220
+ return {
221
+ delta_id: id,
222
+ from_checkpoint_id: left.checkpoint_id,
223
+ to_checkpoint_id: right.checkpoint_id,
224
+ layers,
225
+ semantic_similarity: similarityFromText(left.process_summary, right.process_summary),
226
+ summary: `${left.process_summary.slice(0, 80)} -> ${right.process_summary.slice(0, 80)}`,
227
+ };
228
+ }
229
+
230
+ function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighbors) {
231
+ const latestCheckpoint = checkpoints[checkpoints.length - 1];
232
+ return {
233
+ run_id: run.run_id,
234
+ title: run.title,
235
+ status: run.status,
236
+ branch_count: branches.length,
237
+ lane_count: lanes.length,
238
+ current_node_labels: unique(nodes.filter((node) => node.status !== "done").map((node) => node.title)).slice(0, 5),
239
+ last_handoff_at: handoffs.length ? handoffs[handoffs.length - 1].updated_at ?? handoffs[handoffs.length - 1].created_at : run.updated_at,
240
+ completion_confidence: run.status === "completed" ? 1 : run.status === "blocked" ? 0.2 : Math.min(0.9, 0.35 + checkpoints.length * 0.08),
241
+ updated_at: run.updated_at,
242
+ similar_runs: neighbors,
243
+ latest_checkpoint: latestCheckpoint,
244
+ };
245
+ }
246
+
247
+ function evidenceRefsFor(workspaceState, key, fallback) {
248
+ const refs = workspaceState.sourceRefs?.[key];
249
+ return Array.isArray(refs) && refs.length ? refs : fallback;
250
+ }
251
+
252
+ function buildHandoffRun(handoff, workspace) {
253
+ const runId = `handoff:${handoff.handoff_id}`;
254
+ const branchId = `${runId}:main`;
255
+ const roleAgents = unique([handoff.from, handoff.to]);
256
+ const lanes = roleAgents.map((agent) => ({
257
+ lane_id: `${runId}:lane:${slugify(agent)}`,
258
+ agent_id: agent,
259
+ status: laneStatusFromHandoffStatus(handoff.status, agent === handoff.to),
260
+ current_node_id: handoff.task_type ? slugify(handoff.task_type) : undefined,
261
+ updated_at: handoff.updated_at ?? handoff.created_at,
262
+ }));
263
+ const history = Array.isArray(handoff.history) && handoff.history.length
264
+ ? handoff.history
265
+ : [{ timestamp_utc: handoff.created_at, status: handoff.status, actor: handoff.from, note: handoff.title }];
266
+ const checkpoints = history.map((entry, index) => checkpointFromSummary({
267
+ checkpointId: `${runId}:cp:${index + 1}`,
268
+ runId,
269
+ branchId,
270
+ laneId: lanes[0]?.lane_id,
271
+ handoffId: handoff.handoff_id,
272
+ nodeRef: handoff.task_type ?? handoff.title,
273
+ timestamp: entry.timestamp_utc ?? handoff.updated_at ?? handoff.created_at,
274
+ summary: `${handoff.title}\n${entry.status}\n${entry.note ?? ""}\nfrom:${handoff.from} to:${handoff.to}`,
275
+ taskDelta: entry.note ?? handoff.title,
276
+ evidenceRefs: handoff.source_file ? [handoff.source_file] : [],
277
+ checkpointMeta: checkpointTriggerFromHandoff(handoff, entry),
278
+ }));
279
+ const deltas = checkpoints.length > 1
280
+ ? checkpoints.slice(1).map((checkpoint, index) => deltaBetween(checkpoints[index], checkpoint, `${runId}:delta:${index + 1}`))
281
+ : [];
282
+ const branch = {
283
+ branch_id: branchId,
284
+ run_id: runId,
285
+ name: "main",
286
+ status: runStatusFromHandoff(handoff.status),
287
+ lane_ids: lanes.map((lane) => lane.lane_id),
288
+ };
289
+ const run = {
290
+ run_id: runId,
291
+ workspace,
292
+ title: handoff.title ?? handoff.handoff_id,
293
+ objective: handoff.task_type ?? handoff.priority,
294
+ status: runStatusFromHandoff(handoff.status),
295
+ created_at: handoff.created_at,
296
+ updated_at: handoff.updated_at ?? handoff.created_at,
297
+ branch_ids: [branchId],
298
+ lane_ids: lanes.map((lane) => lane.lane_id),
299
+ checkpoint_ids: checkpoints.map((checkpoint) => checkpoint.checkpoint_id),
300
+ };
301
+ const handoffView = {
302
+ handoff_id: handoff.handoff_id,
303
+ run_id: runId,
304
+ branch_id: branchId,
305
+ lane_id: lanes[0]?.lane_id,
306
+ status: handoff.status,
307
+ from_agent: handoff.from,
308
+ to_agent: handoff.to,
309
+ node_ref: handoff.task_type ?? handoff.title,
310
+ created_at: handoff.created_at,
311
+ updated_at: handoff.updated_at ?? handoff.created_at,
312
+ checkpoint_id: checkpoints[checkpoints.length - 1]?.checkpoint_id,
313
+ };
314
+ return {
315
+ run,
316
+ branches: [branch],
317
+ lanes,
318
+ nodes: [],
319
+ handoff_timeline: { run_id: runId, items: [handoffView] },
320
+ recent_checkpoints: checkpoints,
321
+ deltas,
322
+ process_posts: [],
323
+ activity_items: [],
324
+ similarity: { target_run_id: runId, neighbors: [] },
325
+ };
326
+ }
327
+
328
+ function buildWorkspaceRun(workspaceState, workspace) {
329
+ if (
330
+ workspaceState.todoNodes.length === 0 &&
331
+ workspaceState.statusEvents.length === 0 &&
332
+ workspaceState.ledgerEntries.length === 0 &&
333
+ workspaceState.processPosts.length === 0
334
+ ) return null;
335
+ const runId = "workspace:current";
336
+ const branchId = `${runId}:main`;
337
+ const activeEvents = workspaceState.statusEvents.slice(-25);
338
+ const activeLedger = workspaceState.ledgerEntries.slice(-12);
339
+ const activePosts = workspaceState.processPosts.slice(-12);
340
+ const laneMap = new Map();
341
+ for (const event of activeEvents) {
342
+ const laneId = explicitLaneId(runId, event);
343
+ laneMap.set(laneId, {
344
+ lane_id: laneId,
345
+ agent_id: event.source_module ?? "unknown",
346
+ process_id: firstDefined(event.process_id, event.payload?.process_id),
347
+ status: statusFromEventStatus(event.status),
348
+ current_node_id: slugify(event.objective_id ?? event.event_type ?? "activity"),
349
+ updated_at: event.timestamp ?? isoNow(),
350
+ });
351
+ }
352
+ for (const post of activePosts) {
353
+ const laneId = explicitLaneId(runId, post);
354
+ laneMap.set(laneId, {
355
+ lane_id: laneId,
356
+ agent_id: post.agent_id ?? "unknown",
357
+ process_id: post.process_id,
358
+ status: statusFromProcessPostKind(post.kind),
359
+ current_node_id: slugify(post.summary),
360
+ updated_at: post.timestamp ?? isoNow(),
361
+ });
362
+ }
363
+ const lanes = [...laneMap.values()];
364
+ const checkpoints = [
365
+ checkpointFromSummary({
366
+ checkpointId: `${runId}:cp:1`,
367
+ runId,
368
+ branchId,
369
+ laneId: lanes[0]?.lane_id,
370
+ timestamp: isoNow(),
371
+ summary: [
372
+ "Workspace current run",
373
+ ...workspaceState.todoNodes.slice(0, 12).map((node) => `${node.status}:${node.title}`),
374
+ ...activeEvents.slice(-8).map((event) => `${event.source_module}:${event.event_type}:${event.status}`),
375
+ ...activeLedger.slice(-4).map((entry) => `${entry.tool}:${entry.category}:${entry.message}`),
376
+ ...activePosts.slice(-4).map((post) => `${post.agent_id}:${post.kind}:${post.summary}`),
377
+ ].join("\n"),
378
+ taskDelta: workspaceState.todoNodes.filter((node) => node.status !== "done").map((node) => node.title).slice(0, 6).join(", "),
379
+ evidenceRefs: unique([
380
+ ...evidenceRefsFor(workspaceState, "todoState", [".vericify/todo-state.json", "agent-state/todo-state.json"]),
381
+ ...evidenceRefsFor(workspaceState, "statusEvents", [".vericify/status-events.ndjson", "agent-state/STATUS_EVENTS.ndjson"]),
382
+ ...evidenceRefsFor(workspaceState, "runLedger", [".vericify/run-ledger.json", "agent-state/run-ledger.json"]),
383
+ ...evidenceRefsFor(workspaceState, "processPosts", [".vericify/process-posts.json", "agent-state/vericify/process-posts.json"]),
384
+ ]),
385
+ checkpointMeta: checkpointTriggerFromWorkspaceSummary(),
386
+ }),
387
+ ];
388
+ const branch = {
389
+ branch_id: branchId,
390
+ run_id: runId,
391
+ name: "main",
392
+ status: inferRunStatus([
393
+ runStatusFromNodes(workspaceState.todoNodes),
394
+ ...activeEvents.map((event) => statusFromEventStatus(event.status)),
395
+ ...activePosts.map((post) => statusFromProcessPostKind(post.kind)),
396
+ ]),
397
+ lane_ids: lanes.map((lane) => lane.lane_id),
398
+ };
399
+ const run = {
400
+ run_id: runId,
401
+ workspace,
402
+ title: "Workspace Current",
403
+ objective: "Current workspace execution state",
404
+ status: branch.status,
405
+ created_at: workspaceState.statusEvents[0]?.timestamp ?? isoNow(),
406
+ updated_at: firstDefined(
407
+ workspaceState.processPosts[workspaceState.processPosts.length - 1]?.timestamp,
408
+ workspaceState.statusEvents[workspaceState.statusEvents.length - 1]?.timestamp,
409
+ workspaceState.ledgerEntries[workspaceState.ledgerEntries.length - 1]?.timestamp_utc,
410
+ isoNow()
411
+ ),
412
+ branch_ids: [branchId],
413
+ lane_ids: lanes.map((lane) => lane.lane_id),
414
+ checkpoint_ids: checkpoints.map((checkpoint) => checkpoint.checkpoint_id),
415
+ };
416
+ return {
417
+ run,
418
+ branches: [branch],
419
+ lanes,
420
+ nodes: workspaceState.todoNodes.map((node) => ({
421
+ node_id: node.id,
422
+ title: node.title,
423
+ status: node.status,
424
+ priority: node.priority,
425
+ })),
426
+ handoff_timeline: { run_id: runId, items: [] },
427
+ recent_checkpoints: checkpoints,
428
+ deltas: [],
429
+ process_posts: sortByTimestamp(activePosts, (post) => post.timestamp),
430
+ activity_items: [],
431
+ similarity: { target_run_id: runId, neighbors: [] },
432
+ };
433
+ }
434
+
435
+ function buildObjectiveRuns(workspaceState, workspace) {
436
+ const grouped = new Map();
437
+ for (const event of workspaceState.statusEvents) {
438
+ const key = runIdFromStatusEvent(event);
439
+ if (!key) continue;
440
+ if (!grouped.has(key)) grouped.set(key, []);
441
+ grouped.get(key).push(event);
442
+ }
443
+ return [...grouped.entries()].map(([runId, events]) => {
444
+ const sortedEvents = sortByTimestamp(events, (event) => event.timestamp ?? "");
445
+ const branchIds = unique(sortedEvents.map((event) => explicitBranchId(runId, event)));
446
+ const laneIds = unique(sortedEvents.map((event) => explicitLaneId(runId, event)));
447
+ const branches = branchIds.map((branchId) => ({
448
+ branch_id: branchId,
449
+ run_id: runId,
450
+ name: branchId === `${runId}:main` ? "main" : branchId.split(":").at(-1) ?? "branch",
451
+ status: statusFromEventStatus(sortedEvents[sortedEvents.length - 1]?.status),
452
+ lane_ids: laneIds.filter((laneId) => laneId.startsWith(branchId) || branchId === `${runId}:main`),
453
+ }));
454
+ const lanes = laneIds.map((laneId) => {
455
+ const related = sortedEvents.filter((event) => explicitLaneId(runId, event) === laneId);
456
+ const latest = related[related.length - 1];
457
+ return {
458
+ lane_id: laneId,
459
+ agent_id: latest.source_module ?? "unknown",
460
+ process_id: firstDefined(latest.process_id, latest.payload?.process_id),
461
+ status: statusFromEventStatus(latest.status),
462
+ current_node_id: slugify(latest.event_type ?? latest.objective_id ?? "event"),
463
+ updated_at: latest.timestamp ?? isoNow(),
464
+ };
465
+ });
466
+ const checkpoints = sortedEvents.map((event, index) => checkpointFromSummary({
467
+ checkpointId: `${runId}:cp:${index + 1}`,
468
+ runId,
469
+ branchId: explicitBranchId(runId, event),
470
+ laneId: explicitLaneId(runId, event),
471
+ timestamp: event.timestamp ?? isoNow(),
472
+ summary: `${event.event_type}\n${event.status}\n${event.payload?.summary ?? ""}`,
473
+ taskDelta: event.payload?.summary ?? event.event_type,
474
+ evidenceRefs: event.payload?.evidence_ref ? [event.payload.evidence_ref] : [],
475
+ gitCommitSha: firstDefined(event.git_commit_sha, event.payload?.git_commit_sha, event.metadata?.git_commit_sha),
476
+ checkpointMeta: checkpointTriggerFromStatusEvent(event, sortedEvents[index - 1]),
477
+ }));
478
+ const deltas = checkpoints.length > 1
479
+ ? checkpoints.slice(1).map((checkpoint, index) => deltaBetween(checkpoints[index], checkpoint, `${runId}:delta:${index + 1}`))
480
+ : [];
481
+ const run = {
482
+ run_id: runId,
483
+ workspace,
484
+ title: sortedEvents[sortedEvents.length - 1]?.payload?.summary ?? runId,
485
+ objective: sortedEvents[0]?.objective_id ?? sortedEvents[0]?.trace_id ?? runId,
486
+ status: statusFromEventStatus(sortedEvents[sortedEvents.length - 1]?.status),
487
+ created_at: sortedEvents[0]?.timestamp ?? isoNow(),
488
+ updated_at: sortedEvents[sortedEvents.length - 1]?.timestamp ?? isoNow(),
489
+ branch_ids: branches.map((branch) => branch.branch_id),
490
+ lane_ids: lanes.map((lane) => lane.lane_id),
491
+ checkpoint_ids: checkpoints.map((checkpoint) => checkpoint.checkpoint_id),
492
+ };
493
+ return {
494
+ run,
495
+ branches,
496
+ lanes,
497
+ nodes: [],
498
+ handoff_timeline: { run_id: runId, items: [] },
499
+ recent_checkpoints: checkpoints,
500
+ deltas,
501
+ process_posts: [],
502
+ activity_items: [],
503
+ similarity: { target_run_id: runId, neighbors: [] },
504
+ };
505
+ });
506
+ }
507
+
508
+ function ensureBranch(runDetail, branchId) {
509
+ if (!runDetail.branches.some((branch) => branch.branch_id === branchId)) {
510
+ runDetail.branches.push({
511
+ branch_id: branchId,
512
+ run_id: runDetail.run.run_id,
513
+ name: branchId === `${runDetail.run.run_id}:main` ? "main" : branchId.split(":").at(-1) ?? "branch",
514
+ status: runDetail.run.status,
515
+ lane_ids: [],
516
+ });
517
+ }
518
+ return runDetail.branches.find((branch) => branch.branch_id === branchId);
519
+ }
520
+
521
+ function ensureLane(runDetail, lane) {
522
+ const existing = runDetail.lanes.find((candidate) => candidate.lane_id === lane.lane_id);
523
+ if (existing) {
524
+ Object.assign(existing, lane);
525
+ return existing;
526
+ }
527
+ runDetail.lanes.push(lane);
528
+ return lane;
529
+ }
530
+
531
+ function attachProcessPosts(runs, workspaceState, workspace) {
532
+ const byId = new Map();
533
+ for (const run of runs) {
534
+ byId.set(run.run.run_id, run);
535
+ if (run.run.run_id.startsWith("handoff:")) {
536
+ byId.set(run.run.run_id.slice("handoff:".length), run);
537
+ }
538
+ }
539
+ const postsByRun = new Map();
540
+ for (const post of sortByTimestamp(workspaceState.processPosts, (post) => post.timestamp ?? "")) {
541
+ const key = post.run_id;
542
+ if (!postsByRun.has(key)) postsByRun.set(key, []);
543
+ postsByRun.get(key).push(post);
544
+ }
545
+ for (const [runId, posts] of postsByRun.entries()) {
546
+ let runDetail = byId.get(runId);
547
+ if (!runDetail) {
548
+ const branchId = explicitBranchId(runId, posts[0]);
549
+ const laneId = explicitLaneId(runId, posts[0]);
550
+ runDetail = {
551
+ run: {
552
+ run_id: runId,
553
+ workspace,
554
+ title: posts[posts.length - 1].summary,
555
+ objective: runId,
556
+ status: statusFromProcessPostKind(posts[posts.length - 1].kind),
557
+ created_at: posts[0].timestamp ?? isoNow(),
558
+ updated_at: posts[posts.length - 1].timestamp ?? isoNow(),
559
+ branch_ids: [branchId],
560
+ lane_ids: [laneId],
561
+ checkpoint_ids: [],
562
+ },
563
+ branches: [{
564
+ branch_id: branchId,
565
+ run_id: runId,
566
+ name: branchId === `${runId}:main` ? "main" : branchId.split(":").at(-1) ?? "branch",
567
+ status: statusFromProcessPostKind(posts[posts.length - 1].kind),
568
+ lane_ids: [laneId],
569
+ }],
570
+ lanes: [{
571
+ lane_id: laneId,
572
+ agent_id: posts[0].agent_id,
573
+ status: statusFromProcessPostKind(posts[posts.length - 1].kind),
574
+ updated_at: posts[posts.length - 1].timestamp ?? isoNow(),
575
+ }],
576
+ nodes: [],
577
+ handoff_timeline: { run_id: runId, items: [] },
578
+ recent_checkpoints: [],
579
+ deltas: [],
580
+ process_posts: [],
581
+ activity_items: [],
582
+ similarity: { target_run_id: runId, neighbors: [] },
583
+ };
584
+ runs.push(runDetail);
585
+ byId.set(runId, runDetail);
586
+ }
587
+ for (const post of posts) {
588
+ const branchId = explicitBranchId(runDetail.run.run_id, post);
589
+ const laneId = explicitLaneId(runDetail.run.run_id, post);
590
+ const branch = ensureBranch(runDetail, branchId);
591
+ if (!branch.lane_ids.includes(laneId)) branch.lane_ids.push(laneId);
592
+ ensureLane(runDetail, {
593
+ lane_id: laneId,
594
+ agent_id: post.agent_id,
595
+ status: statusFromProcessPostKind(post.kind),
596
+ updated_at: post.timestamp ?? isoNow(),
597
+ });
598
+ runDetail.process_posts.push(post);
599
+ const checkpoint = checkpointFromSummary({
600
+ checkpointId: `${runDetail.run.run_id}:post:${runDetail.process_posts.length}`,
601
+ runId: runDetail.run.run_id,
602
+ branchId,
603
+ laneId,
604
+ timestamp: post.timestamp ?? isoNow(),
605
+ summary: `${post.kind}\n${post.summary}\nagent:${post.agent_id}`,
606
+ taskDelta: post.summary,
607
+ evidenceRefs: [...asArray(post.evidence_refs), ...asArray(post.tool_refs)],
608
+ checkpointMeta: checkpointTriggerFromProcessPost(post),
609
+ });
610
+ runDetail.recent_checkpoints.push(checkpoint);
611
+ runDetail.run.updated_at = checkpoint.timestamp;
612
+ runDetail.run.title = runDetail.run.title || post.summary;
613
+ runDetail.run.status = inferRunStatus([runDetail.run.status, statusFromProcessPostKind(post.kind)]);
614
+ if (!runDetail.run.branch_ids.includes(branchId)) runDetail.run.branch_ids.push(branchId);
615
+ if (!runDetail.run.lane_ids.includes(laneId)) runDetail.run.lane_ids.push(laneId);
616
+ runDetail.run.checkpoint_ids.push(checkpoint.checkpoint_id);
617
+ }
618
+ }
619
+ }
620
+
621
+ function attachActivityItems(runs, workspaceState) {
622
+ const byId = new Map();
623
+ for (const run of runs) {
624
+ byId.set(run.run.run_id, run);
625
+ if (run.run.run_id.startsWith("handoff:")) {
626
+ byId.set(run.run.run_id.slice("handoff:".length), run);
627
+ }
628
+ }
629
+ const workspaceRun = byId.get("workspace:current");
630
+
631
+ const pushActivity = (runDetail, item) => {
632
+ if (!runDetail) return;
633
+ if (!Array.isArray(runDetail.activity_items)) runDetail.activity_items = [];
634
+ runDetail.activity_items.push(item);
635
+ };
636
+
637
+ for (const post of sortByTimestamp(workspaceState.processPosts, (item) => item.timestamp ?? "")) {
638
+ const runDetail = byId.get(post.run_id);
639
+ const item = activityItemFromProcessPost(post);
640
+ pushActivity(runDetail, item);
641
+ if (workspaceRun && workspaceRun !== runDetail) {
642
+ pushActivity(workspaceRun, {
643
+ ...item,
644
+ activity_id: `${item.activity_id}:workspace`,
645
+ run_id: workspaceRun.run.run_id,
646
+ });
647
+ }
648
+ }
649
+
650
+ for (const event of sortByTimestamp(workspaceState.statusEvents, (item) => item.timestamp ?? "")) {
651
+ const runId = runIdFromStatusEvent(event) ?? "workspace:current";
652
+ const runDetail = byId.get(runId);
653
+ const item = activityItemFromStatusEvent(runId, event);
654
+ pushActivity(runDetail, item);
655
+ if (workspaceRun && workspaceRun !== runDetail) {
656
+ pushActivity(workspaceRun, {
657
+ ...item,
658
+ activity_id: `${item.activity_id}:workspace`,
659
+ run_id: workspaceRun.run.run_id,
660
+ });
661
+ }
662
+ }
663
+
664
+ for (const entry of sortByTimestamp(workspaceState.ledgerEntries, (item) => item.timestamp_utc ?? "")) {
665
+ const runId = runIdFromLedgerEntry(entry) ?? "workspace:current";
666
+ const runDetail = byId.get(runId);
667
+ const item = activityItemFromLedgerEntry(runId, entry);
668
+ pushActivity(runDetail, item);
669
+ if (workspaceRun && workspaceRun !== runDetail) {
670
+ pushActivity(workspaceRun, {
671
+ ...item,
672
+ activity_id: `${item.activity_id}:workspace`,
673
+ run_id: workspaceRun.run.run_id,
674
+ });
675
+ }
676
+ }
677
+ }
678
+
679
+ function attachLaneHeartbeats(runs) {
680
+ for (const runDetail of runs) {
681
+ const sourceItems = (runDetail.activity_items ?? []).filter((item) => item.source_kind !== "lane_heartbeat");
682
+ for (const lane of runDetail.lanes ?? []) {
683
+ const latestActivity = sortByTimestamp(
684
+ sourceItems.filter((item) => item.lane_id === lane.lane_id || (!item.lane_id && item.actor_id === lane.agent_id)),
685
+ (item) => item.timestamp ?? ""
686
+ ).at(-1);
687
+ runDetail.activity_items.push(activityItemFromLaneHeartbeat(runDetail, lane, latestActivity));
688
+ }
689
+ }
690
+ }
691
+
692
+ function attachLedgerEntries(runs, workspaceState) {
693
+ const byId = new Map(runs.map((run) => [run.run.run_id, run]));
694
+ for (const entry of sortByTimestamp(workspaceState.ledgerEntries, (item) => item.timestamp_utc ?? "")) {
695
+ const runId = runIdFromLedgerEntry(entry);
696
+ if (!runId) continue;
697
+ const runDetail = byId.get(runId);
698
+ if (!runDetail) continue;
699
+ const branchId = `${runDetail.run.run_id}:main`;
700
+ const laneId = `${runDetail.run.run_id}:lane:${slugify(entry.tool ?? "ledger")}`;
701
+ ensureBranch(runDetail, branchId);
702
+ ensureLane(runDetail, {
703
+ lane_id: laneId,
704
+ agent_id: entry.tool ?? "ledger",
705
+ status: statusFromLedgerCategory(entry.category),
706
+ updated_at: entry.timestamp_utc ?? isoNow(),
707
+ });
708
+ const checkpoint = checkpointFromSummary({
709
+ checkpointId: `${runDetail.run.run_id}:ledger:${entry.id ?? runDetail.recent_checkpoints.length + 1}`,
710
+ runId: runDetail.run.run_id,
711
+ branchId,
712
+ laneId,
713
+ timestamp: entry.timestamp_utc ?? isoNow(),
714
+ summary: `${entry.tool}\n${entry.category}\n${entry.message}`,
715
+ taskDelta: entry.message,
716
+ evidenceRefs: asArray(entry.artifacts),
717
+ gitCommitSha: firstDefined(entry.git_commit_sha, entry.metadata?.git_commit_sha),
718
+ checkpointMeta: checkpointTriggerFromLedgerEntry(entry),
719
+ });
720
+ runDetail.recent_checkpoints.push(checkpoint);
721
+ runDetail.run.updated_at = checkpoint.timestamp;
722
+ runDetail.run.status = inferRunStatus([runDetail.run.status, statusFromLedgerCategory(entry.category)]);
723
+ if (!runDetail.run.lane_ids.includes(laneId)) runDetail.run.lane_ids.push(laneId);
724
+ if (!runDetail.run.checkpoint_ids.includes(checkpoint.checkpoint_id)) {
725
+ runDetail.run.checkpoint_ids.push(checkpoint.checkpoint_id);
726
+ }
727
+ }
728
+ }
729
+
730
+ function finalizeRunDetails(runs) {
731
+ for (const run of runs) {
732
+ run.process_posts = sortByTimestamp(run.process_posts ?? [], (post) => post.timestamp ?? "");
733
+ run.activity_items = sortByTimestamp(run.activity_items ?? [], (item) => item.timestamp ?? "");
734
+ run.recent_checkpoints = sortByTimestamp(run.recent_checkpoints ?? [], (checkpoint) => checkpoint.timestamp ?? "");
735
+ run.deltas = run.recent_checkpoints.length > 1
736
+ ? run.recent_checkpoints.slice(1).map((checkpoint, index) => deltaBetween(run.recent_checkpoints[index], checkpoint, `${run.run.run_id}:delta:${index + 1}`))
737
+ : [];
738
+ run.run.branch_ids = unique(run.branches.map((branch) => branch.branch_id));
739
+ run.run.lane_ids = unique(run.lanes.map((lane) => lane.lane_id));
740
+ run.run.checkpoint_ids = unique(run.recent_checkpoints.map((checkpoint) => checkpoint.checkpoint_id));
741
+ run.run.updated_at = firstDefined(run.recent_checkpoints.at(-1)?.timestamp, run.run.updated_at, isoNow());
742
+ run.run.status = inferRunStatus([
743
+ run.run.status,
744
+ ...run.branches.map((branch) => branch.status),
745
+ ...run.lanes.map((lane) => lane.status),
746
+ ]);
747
+ }
748
+ }
749
+
750
+ function attachSimilarity(runs) {
751
+ for (const run of runs) {
752
+ const latest = run.recent_checkpoints[run.recent_checkpoints.length - 1];
753
+ if (!latest) continue;
754
+ const neighbors = runs
755
+ .filter((candidate) => candidate.run.run_id !== run.run.run_id)
756
+ .map((candidate) => {
757
+ const other = candidate.recent_checkpoints[candidate.recent_checkpoints.length - 1];
758
+ if (!other) return null;
759
+ return {
760
+ run_id: candidate.run.run_id,
761
+ score: similarityFromText(latest.process_summary, other.process_summary),
762
+ outcome: candidate.run.status,
763
+ };
764
+ })
765
+ .filter(Boolean)
766
+ .sort((left, right) => right.score - left.score)
767
+ .slice(0, 3);
768
+ run.similarity = {
769
+ target_run_id: run.run.run_id,
770
+ neighbors,
771
+ };
772
+ run.run_summary = summarizeRun(
773
+ run.run,
774
+ run.branches,
775
+ run.lanes,
776
+ run.nodes,
777
+ run.handoff_timeline.items,
778
+ run.recent_checkpoints,
779
+ neighbors
780
+ );
781
+ }
782
+ }
783
+
784
+ export function projectWorkspaceState(workspaceState) {
785
+ const workspace = workspaceRef(workspaceState.workspaceRoot);
786
+ const runs = [
787
+ ...workspaceState.handoffs.map((handoff) => buildHandoffRun(handoff, workspace)),
788
+ ...buildObjectiveRuns(workspaceState, workspace),
789
+ ];
790
+ const workspaceRun = buildWorkspaceRun(workspaceState, workspace);
791
+ if (workspaceRun) runs.push(workspaceRun);
792
+ attachProcessPosts(runs, workspaceState, workspace);
793
+ attachActivityItems(runs, workspaceState);
794
+ attachLaneHeartbeats(runs);
795
+ attachLedgerEntries(runs, workspaceState);
796
+ finalizeRunDetails(runs);
797
+ attachSimilarity(runs);
798
+ const sorted = sortByUpdatedDescending(runs.map((run) => ({
799
+ ...run,
800
+ updated_at: run.run.updated_at,
801
+ }))).map(({ updated_at, ...rest }) => rest);
802
+ return {
803
+ generated_at: isoNow(),
804
+ workspace,
805
+ adapter_profiles: workspaceState.adapterProfiles ?? [],
806
+ run_summaries: sorted.map((run) => run.run_summary),
807
+ runs: sorted,
808
+ };
809
+ }