vericify 1.0.2 → 1.2.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.
@@ -7,6 +7,7 @@ import {
7
7
  checkpointTriggerFromStatusEvent,
8
8
  checkpointTriggerFromWorkspaceSummary,
9
9
  } from "../checkpoints/policy.js";
10
+ import { collapseAndScoreActivityItems, compareRunsByAttention, deriveRunLiveSignal } from "./live-signal.js";
10
11
 
11
12
  function sortByUpdatedDescending(items) {
12
13
  return [...items].sort((left, right) => String(right.updated_at).localeCompare(String(left.updated_at)));
@@ -61,6 +62,85 @@ function statusFromProcessPostKind(kind) {
61
62
  return "running";
62
63
  }
63
64
 
65
+ const OBSERVER_STATUS_EVENT_TYPES = new Set([
66
+ "HUB_RUN_FOCUSED",
67
+ "HUB_VIEW_CHANGED",
68
+ "HUB_REFRESHED",
69
+ "HUB_COMMAND_WRITTEN",
70
+ "HUB_SESSION_STARTED",
71
+ "HUB_SESSION_STOPPED",
72
+ "HUB_SESSION_RESUMED",
73
+ ]);
74
+
75
+ const OBSERVER_LEDGER_CATEGORIES = new Set([
76
+ "operator_focus",
77
+ "operator_view",
78
+ "operator_refresh",
79
+ "operator_write",
80
+ ]);
81
+
82
+ const PRIMARY_PROCESS_POST_KINDS = new Set([
83
+ "blocker",
84
+ "completion",
85
+ "handoff_note",
86
+ "operator_note",
87
+ "intervention",
88
+ "stale_ack",
89
+ ]);
90
+
91
+ function isObserverStatusEvent(event) {
92
+ return event?.payload?.observer_telemetry === true ||
93
+ (event?.source_module === "vericify-hub" && OBSERVER_STATUS_EVENT_TYPES.has(event?.event_type));
94
+ }
95
+
96
+ function isObserverLedgerEntry(entry) {
97
+ return entry?.metadata?.observer_telemetry === true ||
98
+ (entry?.tool === "vericify-hub" && OBSERVER_LEDGER_CATEGORIES.has(entry?.category));
99
+ }
100
+
101
+ function recordSourceMetadata(record) {
102
+ return {
103
+ record_source: record.record_source,
104
+ record_source_kind: record.record_source_kind,
105
+ record_source_path: record.record_source_path,
106
+ record_sources: Array.isArray(record.record_sources) ? record.record_sources : [],
107
+ };
108
+ }
109
+
110
+ function signalPolicyForProcessPost(post) {
111
+ return {
112
+ signal_class: PRIMARY_PROCESS_POST_KINDS.has(post.kind) ? "primary" : "secondary",
113
+ visible_by_default: true,
114
+ };
115
+ }
116
+
117
+ function signalPolicyForStatusEvent(event) {
118
+ if (isObserverStatusEvent(event)) {
119
+ return {
120
+ signal_class: "background",
121
+ visible_by_default: false,
122
+ };
123
+ }
124
+ const normalizedStatus = statusFromEventStatus(event.status);
125
+ return {
126
+ signal_class: normalizedStatus === "blocked" || normalizedStatus === "completed" ? "primary" : "secondary",
127
+ visible_by_default: true,
128
+ };
129
+ }
130
+
131
+ function signalPolicyForLedgerEntry(entry) {
132
+ if (isObserverLedgerEntry(entry)) {
133
+ return {
134
+ signal_class: "background",
135
+ visible_by_default: false,
136
+ };
137
+ }
138
+ return {
139
+ signal_class: entry.category === "regression" ? "primary" : "secondary",
140
+ visible_by_default: true,
141
+ };
142
+ }
143
+
64
144
  function humanizeToken(value) {
65
145
  return String(value ?? "")
66
146
  .replace(/[-_]+/g, " ")
@@ -80,6 +160,8 @@ function activityItemFromProcessPost(post) {
80
160
  status: statusFromProcessPostKind(post.kind),
81
161
  summary: post.summary,
82
162
  refs: unique([...asArray(post.evidence_refs), ...asArray(post.tool_refs)]),
163
+ ...recordSourceMetadata(post),
164
+ ...signalPolicyForProcessPost(post),
83
165
  };
84
166
  }
85
167
 
@@ -96,6 +178,8 @@ function activityItemFromStatusEvent(runId, event) {
96
178
  status: statusFromEventStatus(event.status),
97
179
  summary: event.payload?.summary ?? event.event_type,
98
180
  refs: asArray(event.payload?.evidence_ref),
181
+ ...recordSourceMetadata(event),
182
+ ...signalPolicyForStatusEvent(event),
99
183
  };
100
184
  }
101
185
 
@@ -112,6 +196,8 @@ function activityItemFromLedgerEntry(runId, entry) {
112
196
  status: statusFromLedgerCategory(entry.category),
113
197
  summary: entry.message,
114
198
  refs: asArray(entry.artifacts),
199
+ ...recordSourceMetadata(entry),
200
+ ...signalPolicyForLedgerEntry(entry),
115
201
  };
116
202
  }
117
203
 
@@ -140,6 +226,12 @@ function activityItemFromLaneHeartbeat(runDetail, lane, latestActivity) {
140
226
  status: lane.status,
141
227
  summary: summarizeLaneHeartbeat(lane, latestActivity),
142
228
  refs: latestActivity?.refs ?? [],
229
+ record_source: "derived",
230
+ record_source_kind: "lane_heartbeat",
231
+ record_source_path: undefined,
232
+ record_sources: [],
233
+ signal_class: "continuity",
234
+ visible_by_default: false,
143
235
  };
144
236
  }
145
237
 
@@ -227,7 +319,7 @@ function deltaBetween(left, right, id) {
227
319
  };
228
320
  }
229
321
 
230
- function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighbors) {
322
+ function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighbors, liveSignal) {
231
323
  const latestCheckpoint = checkpoints[checkpoints.length - 1];
232
324
  return {
233
325
  run_id: run.run_id,
@@ -241,6 +333,19 @@ function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighb
241
333
  updated_at: run.updated_at,
242
334
  similar_runs: neighbors,
243
335
  latest_checkpoint: latestCheckpoint,
336
+ attention_class: liveSignal?.attention_class,
337
+ attention_reason: liveSignal?.attention_reason,
338
+ attention_score: liveSignal?.attention_score,
339
+ attention_rank: liveSignal?.attention_rank,
340
+ freshness_class: liveSignal?.freshness_class,
341
+ expected_next_event: liveSignal?.expected_next_event,
342
+ overdue_at: liveSignal?.overdue_at,
343
+ current_actor_id: liveSignal?.current_actor_id,
344
+ waiting_on_actor_id: liveSignal?.waiting_on_actor_id,
345
+ needs_narrative: liveSignal?.needs_narrative,
346
+ recommended_post_kind: liveSignal?.recommended_post_kind,
347
+ signal_confidence: liveSignal?.signal_confidence,
348
+ partner_dependency_class: liveSignal?.partner_dependency_class,
244
349
  };
245
350
  }
246
351
 
@@ -326,16 +431,18 @@ function buildHandoffRun(handoff, workspace) {
326
431
  }
327
432
 
328
433
  function buildWorkspaceRun(workspaceState, workspace) {
434
+ const meaningfulEvents = workspaceState.statusEvents.filter((event) => !isObserverStatusEvent(event));
435
+ const meaningfulLedger = workspaceState.ledgerEntries.filter((entry) => !isObserverLedgerEntry(entry));
329
436
  if (
330
437
  workspaceState.todoNodes.length === 0 &&
331
- workspaceState.statusEvents.length === 0 &&
332
- workspaceState.ledgerEntries.length === 0 &&
438
+ meaningfulEvents.length === 0 &&
439
+ meaningfulLedger.length === 0 &&
333
440
  workspaceState.processPosts.length === 0
334
441
  ) return null;
335
442
  const runId = "workspace:current";
336
443
  const branchId = `${runId}:main`;
337
- const activeEvents = workspaceState.statusEvents.slice(-25);
338
- const activeLedger = workspaceState.ledgerEntries.slice(-12);
444
+ const activeEvents = meaningfulEvents.slice(-25);
445
+ const activeLedger = meaningfulLedger.slice(-12);
339
446
  const activePosts = workspaceState.processPosts.slice(-12);
340
447
  const laneMap = new Map();
341
448
  for (const event of activeEvents) {
@@ -402,11 +509,16 @@ function buildWorkspaceRun(workspaceState, workspace) {
402
509
  title: "Workspace Current",
403
510
  objective: "Current workspace execution state",
404
511
  status: branch.status,
405
- created_at: workspaceState.statusEvents[0]?.timestamp ?? isoNow(),
512
+ created_at: firstDefined(
513
+ meaningfulEvents[0]?.timestamp,
514
+ activePosts[0]?.timestamp,
515
+ meaningfulLedger[0]?.timestamp_utc,
516
+ isoNow()
517
+ ),
406
518
  updated_at: firstDefined(
407
519
  workspaceState.processPosts[workspaceState.processPosts.length - 1]?.timestamp,
408
- workspaceState.statusEvents[workspaceState.statusEvents.length - 1]?.timestamp,
409
- workspaceState.ledgerEntries[workspaceState.ledgerEntries.length - 1]?.timestamp_utc,
520
+ meaningfulEvents[meaningfulEvents.length - 1]?.timestamp,
521
+ meaningfulLedger[meaningfulLedger.length - 1]?.timestamp_utc,
410
522
  isoNow()
411
523
  ),
412
524
  branch_ids: [branchId],
@@ -441,18 +553,22 @@ function buildObjectiveRuns(workspaceState, workspace) {
441
553
  grouped.get(key).push(event);
442
554
  }
443
555
  return [...grouped.entries()].map(([runId, events]) => {
556
+ if (runId === "workspace:current") return null;
444
557
  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)));
558
+ const meaningfulEvents = sortedEvents.filter((event) => !isObserverStatusEvent(event));
559
+ if (!meaningfulEvents.length) return null;
560
+ const latestMeaningfulEvent = meaningfulEvents[meaningfulEvents.length - 1];
561
+ const branchIds = unique(meaningfulEvents.map((event) => explicitBranchId(runId, event)));
562
+ const laneIds = unique(meaningfulEvents.map((event) => explicitLaneId(runId, event)));
447
563
  const branches = branchIds.map((branchId) => ({
448
564
  branch_id: branchId,
449
565
  run_id: runId,
450
566
  name: branchId === `${runId}:main` ? "main" : branchId.split(":").at(-1) ?? "branch",
451
- status: statusFromEventStatus(sortedEvents[sortedEvents.length - 1]?.status),
567
+ status: statusFromEventStatus(latestMeaningfulEvent?.status),
452
568
  lane_ids: laneIds.filter((laneId) => laneId.startsWith(branchId) || branchId === `${runId}:main`),
453
569
  }));
454
570
  const lanes = laneIds.map((laneId) => {
455
- const related = sortedEvents.filter((event) => explicitLaneId(runId, event) === laneId);
571
+ const related = meaningfulEvents.filter((event) => explicitLaneId(runId, event) === laneId);
456
572
  const latest = related[related.length - 1];
457
573
  return {
458
574
  lane_id: laneId,
@@ -463,7 +579,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
463
579
  updated_at: latest.timestamp ?? isoNow(),
464
580
  };
465
581
  });
466
- const checkpoints = sortedEvents.map((event, index) => checkpointFromSummary({
582
+ const checkpoints = meaningfulEvents.map((event, index) => checkpointFromSummary({
467
583
  checkpointId: `${runId}:cp:${index + 1}`,
468
584
  runId,
469
585
  branchId: explicitBranchId(runId, event),
@@ -473,7 +589,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
473
589
  taskDelta: event.payload?.summary ?? event.event_type,
474
590
  evidenceRefs: event.payload?.evidence_ref ? [event.payload.evidence_ref] : [],
475
591
  gitCommitSha: firstDefined(event.git_commit_sha, event.payload?.git_commit_sha, event.metadata?.git_commit_sha),
476
- checkpointMeta: checkpointTriggerFromStatusEvent(event, sortedEvents[index - 1]),
592
+ checkpointMeta: checkpointTriggerFromStatusEvent(event, meaningfulEvents[index - 1]),
477
593
  }));
478
594
  const deltas = checkpoints.length > 1
479
595
  ? checkpoints.slice(1).map((checkpoint, index) => deltaBetween(checkpoints[index], checkpoint, `${runId}:delta:${index + 1}`))
@@ -481,11 +597,11 @@ function buildObjectiveRuns(workspaceState, workspace) {
481
597
  const run = {
482
598
  run_id: runId,
483
599
  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(),
600
+ title: latestMeaningfulEvent?.payload?.summary ?? runId,
601
+ objective: meaningfulEvents[0]?.objective_id ?? meaningfulEvents[0]?.trace_id ?? runId,
602
+ status: statusFromEventStatus(latestMeaningfulEvent?.status),
603
+ created_at: meaningfulEvents[0]?.timestamp ?? isoNow(),
604
+ updated_at: latestMeaningfulEvent?.timestamp ?? isoNow(),
489
605
  branch_ids: branches.map((branch) => branch.branch_id),
490
606
  lane_ids: lanes.map((lane) => lane.lane_id),
491
607
  checkpoint_ids: checkpoints.map((checkpoint) => checkpoint.checkpoint_id),
@@ -502,7 +618,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
502
618
  activity_items: [],
503
619
  similarity: { target_run_id: runId, neighbors: [] },
504
620
  };
505
- });
621
+ }).filter(Boolean);
506
622
  }
507
623
 
508
624
  function ensureBranch(runDetail, branchId) {
@@ -678,7 +794,9 @@ function attachActivityItems(runs, workspaceState) {
678
794
 
679
795
  function attachLaneHeartbeats(runs) {
680
796
  for (const runDetail of runs) {
681
- const sourceItems = (runDetail.activity_items ?? []).filter((item) => item.source_kind !== "lane_heartbeat");
797
+ const sourceItems = (runDetail.activity_items ?? []).filter((item) =>
798
+ item.source_kind !== "lane_heartbeat" && item.visible_by_default !== false
799
+ );
682
800
  for (const lane of runDetail.lanes ?? []) {
683
801
  const latestActivity = sortByTimestamp(
684
802
  sourceItems.filter((item) => item.lane_id === lane.lane_id || (!item.lane_id && item.actor_id === lane.agent_id)),
@@ -689,9 +807,16 @@ function attachLaneHeartbeats(runs) {
689
807
  }
690
808
  }
691
809
 
810
+ function collapseActivityItems(runs, now) {
811
+ for (const runDetail of runs) {
812
+ runDetail.activity_items = collapseAndScoreActivityItems(runDetail.activity_items ?? [], { now });
813
+ }
814
+ }
815
+
692
816
  function attachLedgerEntries(runs, workspaceState) {
693
817
  const byId = new Map(runs.map((run) => [run.run.run_id, run]));
694
818
  for (const entry of sortByTimestamp(workspaceState.ledgerEntries, (item) => item.timestamp_utc ?? "")) {
819
+ if (isObserverLedgerEntry(entry)) continue;
695
820
  const runId = runIdFromLedgerEntry(entry);
696
821
  if (!runId) continue;
697
822
  const runDetail = byId.get(runId);
@@ -769,6 +894,16 @@ function attachSimilarity(runs) {
769
894
  target_run_id: run.run.run_id,
770
895
  neighbors,
771
896
  };
897
+ }
898
+ }
899
+
900
+ function attachLiveSignals(runs, now) {
901
+ for (const run of runs) {
902
+ run.live_signal = deriveRunLiveSignal(run, { now });
903
+ }
904
+ const ranked = [...runs].sort(compareRunsByAttention);
905
+ ranked.forEach((run, index) => {
906
+ run.live_signal.attention_rank = index + 1;
772
907
  run.run_summary = summarizeRun(
773
908
  run.run,
774
909
  run.branches,
@@ -776,12 +911,15 @@ function attachSimilarity(runs) {
776
911
  run.nodes,
777
912
  run.handoff_timeline.items,
778
913
  run.recent_checkpoints,
779
- neighbors
914
+ run.similarity?.neighbors ?? [],
915
+ run.live_signal
780
916
  );
781
- }
917
+ });
918
+ return ranked;
782
919
  }
783
920
 
784
- export function projectWorkspaceState(workspaceState) {
921
+ export function projectWorkspaceState(workspaceState, options = {}) {
922
+ const now = options.now ?? isoNow();
785
923
  const workspace = workspaceRef(workspaceState.workspaceRoot);
786
924
  const runs = [
787
925
  ...workspaceState.handoffs.map((handoff) => buildHandoffRun(handoff, workspace)),
@@ -791,19 +929,36 @@ export function projectWorkspaceState(workspaceState) {
791
929
  if (workspaceRun) runs.push(workspaceRun);
792
930
  attachProcessPosts(runs, workspaceState, workspace);
793
931
  attachActivityItems(runs, workspaceState);
794
- attachLaneHeartbeats(runs);
795
932
  attachLedgerEntries(runs, workspaceState);
933
+ collapseActivityItems(runs, now);
934
+ attachLaneHeartbeats(runs);
796
935
  finalizeRunDetails(runs);
797
936
  attachSimilarity(runs);
798
- const sorted = sortByUpdatedDescending(runs.map((run) => ({
799
- ...run,
800
- updated_at: run.run.updated_at,
801
- }))).map(({ updated_at, ...rest }) => rest);
937
+ const sorted = attachLiveSignals(runs, now);
802
938
  return {
803
- generated_at: isoNow(),
939
+ generated_at: now,
804
940
  workspace,
805
941
  adapter_profiles: workspaceState.adapterProfiles ?? [],
806
942
  run_summaries: sorted.map((run) => run.run_summary),
807
943
  runs: sorted,
944
+ attention_items: sorted.map((run) => ({
945
+ run_id: run.run.run_id,
946
+ title: run.run.title,
947
+ status: run.run.status,
948
+ attention_rank: run.live_signal?.attention_rank,
949
+ attention_class: run.live_signal?.attention_class,
950
+ attention_reason: run.live_signal?.attention_reason,
951
+ attention_score: run.live_signal?.attention_score,
952
+ why_now: run.live_signal?.why_now,
953
+ expected_next_event: run.live_signal?.expected_next_event,
954
+ overdue_at: run.live_signal?.overdue_at,
955
+ recommended_owner_action: run.live_signal?.recommended_owner_action,
956
+ recommended_post_kind: run.live_signal?.recommended_post_kind,
957
+ needs_narrative: run.live_signal?.needs_narrative,
958
+ freshness_class: run.live_signal?.freshness_class,
959
+ signal_confidence: run.live_signal?.signal_confidence,
960
+ current_actor_id: run.live_signal?.current_actor_id,
961
+ waiting_on_actor_id: run.live_signal?.waiting_on_actor_id,
962
+ })),
808
963
  };
809
964
  }
package/src/tui/app.js CHANGED
@@ -280,6 +280,7 @@ export async function runHub({ workspaceRoot, feedFile, loadState, watchedPaths
280
280
  summary,
281
281
  run_id: runId,
282
282
  workspace_root: workspaceRoot,
283
+ observer_telemetry: true,
283
284
  },
284
285
  });
285
286
  };
package/src/tui/panels.js CHANGED
@@ -42,6 +42,10 @@ function activityBadge(sourceKind) {
42
42
  return "pp";
43
43
  }
44
44
 
45
+ function displaySummary(item) {
46
+ return item.collapse_summary ?? item.display_summary ?? item.summary;
47
+ }
48
+
45
49
  export function layoutTierForWidth(width) {
46
50
  if (width < 110) return "narrow";
47
51
  if (width < 170) return "medium";
@@ -63,7 +67,19 @@ function globalActivity(projected) {
63
67
  run_status: run.run.status,
64
68
  }))
65
69
  )
66
- .sort((left, right) => String(right.timestamp).localeCompare(String(left.timestamp)));
70
+ .sort((left, right) => {
71
+ const scoreDelta = (right.score ?? 0) - (left.score ?? 0);
72
+ if (scoreDelta !== 0) return scoreDelta;
73
+ return String(right.timestamp).localeCompare(String(left.timestamp));
74
+ });
75
+ }
76
+
77
+ function visibleActivity(items) {
78
+ return items.filter((item) => item.visible_by_default !== false);
79
+ }
80
+
81
+ function meaningfulActivity(items) {
82
+ return visibleActivity(items).filter((item) => item.signal_class === "primary" || item.signal_class === "secondary");
67
83
  }
68
84
 
69
85
  function latestDelta(run) {
@@ -127,84 +143,59 @@ function buildLaneDetailRows(run, tier) {
127
143
 
128
144
  function buildRunTriageRows(run) {
129
145
  if (!run) return ["No run selected."];
146
+ const signal = run.live_signal ?? {};
130
147
  const rows = [];
131
- const blockedNodes = (run.nodes ?? []).filter((node) => node.status === "blocked");
132
- if (blockedNodes.length) {
133
- rows.push(`P1 blocked nodes ${blockedNodes.length}: ${top(blockedNodes.map((node) => node.title), 2).join(", ")}`);
148
+ rows.push(`P${signal.attention_score >= 140 ? 1 : 2} ${signal.attention_class ?? "observe_only"}: ${signal.attention_reason ?? "No immediate action required."}`);
149
+ rows.push(`Why now: ${signal.why_now ?? "No meaningful movement yet."}`);
150
+ rows.push(`Next: ${signal.expected_next_event ?? "observe_only"} | owner action ${signal.recommended_owner_action ?? "observe_only"}`);
151
+ if (signal.needs_narrative) {
152
+ rows.push(`Narrative required: ${signal.recommended_post_kind} | ${signal.recommended_summary_template}`);
134
153
  }
154
+ const blockedNodes = (run.nodes ?? []).filter((node) => node.status === "blocked");
155
+ if (blockedNodes.length) rows.push(`Blocked nodes ${blockedNodes.length}: ${top(blockedNodes.map((node) => node.title), 2).join(", ")}`);
135
156
  const queuedHandoffs = (run.handoff_timeline?.items ?? []).filter((handoff) => handoff.status === "open" || handoff.status === "blocked");
136
- if (queuedHandoffs.length) {
137
- rows.push(`P1 handoff queue ${queuedHandoffs.length}: ${top(queuedHandoffs.map((handoff) => handoff.handoff_id), 2).join(", ")}`);
138
- }
139
- const staleLanes = (run.lanes ?? [])
140
- .filter((lane) => lane.status !== "completed")
141
- .sort((left, right) => String(left.updated_at).localeCompare(String(right.updated_at)));
142
- if (staleLanes.length) {
143
- const lane = staleLanes[0];
144
- rows.push(`P2 stale lane: ${lane.agent_id} last signaled ${relativeTimeFromNow(lane.updated_at)}`);
145
- }
157
+ if (queuedHandoffs.length) rows.push(`Open handoffs ${queuedHandoffs.length}: ${top(queuedHandoffs.map((handoff) => handoff.handoff_id), 2).join(", ")}`);
146
158
  const blockedNeighbor = (run.similarity?.neighbors ?? []).find((neighbor) => neighbor.outcome === "blocked");
147
159
  if (blockedNeighbor) {
148
- rows.push(`P2 failure echo: compare with ${blockedNeighbor.run_id} at ${(blockedNeighbor.score * 100).toFixed(0)}%`);
160
+ rows.push(`Failure echo: compare with ${blockedNeighbor.run_id} at ${(blockedNeighbor.score * 100).toFixed(0)}%`);
149
161
  }
150
162
  const recoveryNeighbor = (run.similarity?.neighbors ?? []).find((neighbor) => neighbor.outcome === "completed");
151
163
  if (recoveryNeighbor) {
152
- rows.push(`OK recovery path: ${recoveryNeighbor.run_id} reached done from a ${(recoveryNeighbor.score * 100).toFixed(0)}% similar path`);
164
+ rows.push(`Recovery path: ${recoveryNeighbor.run_id} reached done from a ${(recoveryNeighbor.score * 100).toFixed(0)}% similar path`);
153
165
  }
154
166
  return rows.length ? rows : ["No acute risks. Run is flowing."];
155
167
  }
156
168
 
157
169
  function buildGlobalTriageRows(projected, selectedRun) {
158
- const rows = [];
159
- const blockedRuns = (projected.runs ?? []).filter((run) => run.run.status === "blocked");
160
- if (blockedRuns.length) {
161
- rows.push(`P1 blocked runs ${blockedRuns.length}: ${top(blockedRuns.map((run) => run.run.title), 3).join(", ")}`);
162
- }
163
- const openHandoffs = (projected.runs ?? [])
164
- .flatMap((run) => run.handoff_timeline?.items ?? [])
165
- .filter((handoff) => handoff.status === "open" || handoff.status === "blocked");
166
- if (openHandoffs.length) {
167
- rows.push(`P1 handoffs awaiting movement ${openHandoffs.length}: ${top(openHandoffs.map((handoff) => handoff.handoff_id), 3).join(", ")}`);
168
- }
169
- const blockedNodes = (projected.runs ?? []).flatMap((run) => run.nodes ?? []).filter((node) => node.status === "blocked");
170
- if (blockedNodes.length) {
171
- rows.push(`P1 blocked nodes ${blockedNodes.length}: ${top(blockedNodes.map((node) => node.title), 3).join(", ")}`);
172
- }
173
- const staleLanes = (projected.runs ?? [])
174
- .flatMap((run) => (run.lanes ?? []).map((lane) => ({ run, lane })))
175
- .filter(({ lane }) => lane.status !== "completed")
176
- .sort((left, right) => String(left.lane.updated_at).localeCompare(String(right.lane.updated_at)));
177
- if (staleLanes.length) {
178
- const { run, lane } = staleLanes[0];
179
- rows.push(`P2 stale lane ${lane.agent_id} in ${run.run.title}: last signal ${relativeTimeFromNow(lane.updated_at)}`);
180
- }
170
+ const attention = top((projected.attention_items ?? []).filter((item) => item.attention_class !== "observe_only"), 5);
171
+ const rows = attention.map((item) =>
172
+ `P${item.attention_score >= 140 ? 1 : 2} ${compactStatus(item.status)} ${item.title} | ${item.attention_reason} | next ${item.expected_next_event ?? "observe_only"}`
173
+ );
181
174
  const blockedNeighbor = selectedRun?.similarity?.neighbors?.find((neighbor) => neighbor.outcome === "blocked");
182
175
  if (blockedNeighbor) {
183
- rows.push(`P2 compare now: selected run resembles blocked ${blockedNeighbor.run_id} at ${(blockedNeighbor.score * 100).toFixed(0)}%`);
176
+ rows.push(`Compare now: selected run resembles blocked ${blockedNeighbor.run_id} at ${(blockedNeighbor.score * 100).toFixed(0)}%`);
184
177
  }
185
178
  return rows.length ? rows : ["No hot triage. Traffic is flowing."];
186
179
  }
187
180
 
188
181
  function buildSelectedRunRadar(selectedRun) {
189
182
  if (!selectedRun) return ["No selected run."];
183
+ const signal = selectedRun.live_signal ?? {};
190
184
  const checkpoint = latestCheckpoint(selectedRun);
191
185
  const delta = latestDelta(selectedRun);
192
- const nextNode = activeNodeLabels(selectedRun)[0];
193
- const queuedHandoff = (selectedRun.handoff_timeline?.items ?? []).find((handoff) => handoff.status === "open" || handoff.status === "blocked");
194
- const risk = buildRunTriageRows(selectedRun)[0];
195
186
  return [
196
187
  `${compactStatus(selectedRun.run.status)} ${selectedRun.run.title}`,
197
188
  `NOW ${checkpoint ? checkpoint.process_summary.split("\n")[0] : "No checkpoint yet."}`,
198
- `NEXT ${queuedHandoff ? `${queuedHandoff.to_agent} for ${queuedHandoff.node_ref ?? queuedHandoff.handoff_id}` : nextNode ? `advance ${nextNode}` : "await new movement"}`,
199
- `RISK ${risk}`,
189
+ `NEXT ${signal.expected_next_event ?? activeNodeLabels(selectedRun)[0] ?? "await new movement"} | action ${signal.recommended_owner_action ?? "observe_only"}`,
190
+ `PULSE ${signal.why_now ?? "No meaningful movement yet."}`,
200
191
  `PATH ${delta ? delta.layers.join(" / ") : "entry only"} | confidence ${((selectedRun.run_summary?.completion_confidence ?? 0) * 100).toFixed(0)}%`,
201
192
  ];
202
193
  }
203
194
 
204
195
  function buildTrafficRows(projected, tier) {
205
196
  const limit = tier === "narrow" ? 6 : 10;
206
- return top(globalActivity(projected), limit).map((item) =>
207
- `${formatTimestamp(item.timestamp)} [${activityBadge(item.source_kind)}] ${urgencyBadge(item.status)} ${item.run_title} | ${item.actor_id} | ${item.summary}`
197
+ return top(meaningfulActivity(globalActivity(projected)), limit).map((item) =>
198
+ `${formatTimestamp(item.timestamp)} [${activityBadge(item.source_kind)}] ${urgencyBadge(item.status)} ${item.run_title} | ${item.actor_id} | ${displaySummary(item)}`
208
199
  );
209
200
  }
210
201
 
@@ -230,6 +221,37 @@ function historyCueRows(projected, selectedRun) {
230
221
  ];
231
222
  }
232
223
 
224
+ function buildPresenceRows(run) {
225
+ if (!run) return ["No run selected."];
226
+ const signal = run.live_signal ?? {};
227
+ const captureCommand = signal.recommended_post_kind
228
+ ? `/ post --run-id ${run.run.run_id} --agent-id ${signal.current_actor_id ?? "operator"} --kind ${signal.recommended_post_kind} --summary "${signal.recommended_summary_template}"`
229
+ : undefined;
230
+ return [
231
+ `Owner ${signal.current_actor_id ?? "-"} | waiting ${signal.waiting_on_actor_id ?? "-"} | source ${signal.presence_source ?? "-"}`,
232
+ `Freshness ${signal.freshness_class ?? "-"} | last response ${signal.last_response_at ? relativeTimeFromNow(signal.last_response_at) : "-"}`,
233
+ `Next ${signal.expected_next_event ?? "observe_only"} | late ${signal.overdue_at ? relativeTimeFromNow(signal.overdue_at) : "-"} | confidence ${signal.signal_confidence ? `${(signal.signal_confidence * 100).toFixed(0)}%` : "-"}`,
234
+ captureCommand ? `Capture ${captureCommand}` : `Action ${signal.recommended_owner_action ?? "observe_only"}`,
235
+ ];
236
+ }
237
+
238
+ function buildQueueRows(projected) {
239
+ const queue = (projected.runs ?? [])
240
+ .flatMap((run) => (run.handoff_timeline?.items ?? []).map((handoff) => ({ run, handoff })))
241
+ .filter(({ handoff }) => handoff.status === "open" || handoff.status === "accepted" || handoff.status === "blocked")
242
+ .sort((left, right) => String(right.handoff.updated_at ?? right.handoff.created_at).localeCompare(String(left.handoff.updated_at ?? left.handoff.created_at)));
243
+ return top(queue, 6).map(({ run, handoff }) =>
244
+ `${urgencyBadge(handoff.status)} ${handoff.status} ${handoff.from_agent} -> ${handoff.to_agent} | ${run.run.title} | ${handoff.node_ref ?? handoff.handoff_id}`
245
+ );
246
+ }
247
+
248
+ function buildQuietContextRows(projected, selectedRun) {
249
+ return [
250
+ ...compareCueRows(selectedRun),
251
+ ...historyCueRows(projected, selectedRun),
252
+ ];
253
+ }
254
+
233
255
  function buildCompareSummaryRows(report) {
234
256
  if (!report) return ["No comparable run available."];
235
257
  return [
@@ -291,8 +313,8 @@ function buildRecoveryCueRows(report) {
291
313
 
292
314
  function buildHistoryTimelineRows(projected, selectedRun, tier) {
293
315
  const activity = selectedRun
294
- ? top([...(selectedRun.activity_items ?? [])].sort((left, right) => String(right.timestamp).localeCompare(String(left.timestamp))), tier === "narrow" ? 6 : 8)
295
- : top(globalActivity(projected), tier === "narrow" ? 6 : 8);
316
+ ? top(visibleActivity([...(selectedRun.activity_items ?? [])].sort((left, right) => String(right.timestamp).localeCompare(String(left.timestamp)))), tier === "narrow" ? 6 : 8)
317
+ : top(visibleActivity(globalActivity(projected)), tier === "narrow" ? 6 : 8);
296
318
  return activity.map((item) =>
297
319
  `${formatTimestamp(item.timestamp)} [${activityBadge(item.source_kind)}] ${item.actor_id} | ${item.summary}`
298
320
  );
@@ -326,16 +348,18 @@ export function buildHubMetrics(projected, options = {}) {
326
348
  const lanes = runs.flatMap((run) => run.lanes ?? []);
327
349
  const nodes = runs.flatMap((run) => run.nodes ?? []);
328
350
  const handoffs = runs.flatMap((run) => run.handoff_timeline?.items ?? []);
329
- const activityCount = runs.reduce((sum, run) => sum + (run.activity_items?.length ?? 0), 0);
351
+ const activityCount = runs.reduce((sum, run) => sum + meaningfulActivity(run.activity_items ?? []).length, 0);
330
352
  const runningRuns = runs.filter((run) => run.run.status === "running").length;
331
353
  const blockedRuns = runs.filter((run) => run.run.status === "blocked").length;
354
+ const staleRuns = runs.filter((run) => ["stale", "stale_acknowledged", "archival"].includes(run.live_signal?.freshness_class)).length;
355
+ const narrativeGaps = runs.filter((run) => run.live_signal?.needs_narrative).length;
332
356
  const liveLanes = lanes.filter((lane) => lane.status === "running").length;
333
357
  const blockedNodes = nodes.filter((node) => node.status === "blocked").length;
334
358
  const openHandoffs = handoffs.filter((handoff) => handoff.status === "open" || handoff.status === "blocked").length;
335
359
  if (tier === "narrow") {
336
- return `Runs ${runs.length} | Live ${runningRuns} | Blkd ${blockedRuns} | Lanes ${liveLanes}/${lanes.length} | HOs ${openHandoffs} | Nodes ${blockedNodes} | Act ${activityCount}`;
360
+ return `Runs ${runs.length} | Live ${runningRuns} | Blkd ${blockedRuns} | Stale ${staleRuns} | Notes ${narrativeGaps} | HOs ${openHandoffs} | Act ${activityCount}`;
337
361
  }
338
- return `Runs ${runs.length} | Live ${runningRuns} | Blocked ${blockedRuns} | Lanes ${lanes.length}/${liveLanes} live | Handoffs ${openHandoffs} open | Nodes ${blockedNodes} blocked | Activity ${activityCount}`;
362
+ return `Runs ${runs.length} | Live ${runningRuns} | Blocked ${blockedRuns} | Stale ${staleRuns} | Narrative ${narrativeGaps} | Handoffs ${openHandoffs} open | Nodes ${blockedNodes} blocked | Activity ${activityCount}`;
339
363
  }
340
364
 
341
365
  export function buildRunBoardSection(projected, selectedRun, options = {}) {
@@ -343,7 +367,7 @@ export function buildRunBoardSection(projected, selectedRun, options = {}) {
343
367
  const rows = top(projected.run_summaries ?? [], tier === "narrow" ? 6 : 8).map((summary) => {
344
368
  const isSelected = summary.run_id === selectedRun?.run?.run_id ? ">" : " ";
345
369
  const node = summary.current_node_labels?.[0] ?? "steady";
346
- return `${isSelected} ${urgencyBadge(summary.status)} ${compactStatus(summary.status)} ${summary.title} | br ${summary.branch_count} | ln ${summary.lane_count} | node ${node} | ${relativeTimeFromNow(summary.updated_at)}`;
370
+ return `${isSelected} ${urgencyBadge(summary.status)} ${compactStatus(summary.status)} ${summary.title} | ${summary.attention_class ?? "observe_only"} | ${summary.freshness_class ?? "-"} | node ${node} | ${relativeTimeFromNow(summary.updated_at)}`;
347
371
  });
348
372
  return {
349
373
  title: "Run Board",
@@ -428,11 +452,12 @@ export function buildAdaptersSections(projected, options = {}) {
428
452
  export function buildHubSections(projected, selectedRun, options = {}) {
429
453
  const { tier = "wide" } = options;
430
454
  return [
431
- { title: "Triage Shelf", rows: buildGlobalTriageRows(projected, selectedRun), tone: "HOT" },
432
- { title: "Selected Run Radar", rows: buildSelectedRunRadar(selectedRun), tone: selectedRun?.run?.status === "blocked" ? "HOT" : "LIVE" },
433
- { title: "Network Traffic", rows: buildTrafficRows(projected, tier), tone: "FLOW", fullWidth: tier === "wide" },
434
- { title: "Compare Cue", rows: compareCueRows(selectedRun), tone: "DIFF" },
435
- { title: "History Cue", rows: historyCueRows(projected, selectedRun), tone: "TRACE" },
455
+ { title: "Pulse", rows: buildSelectedRunRadar(selectedRun ?? projected.runs?.[0]), tone: selectedRun?.run?.status === "blocked" ? "HOT" : "LIVE" },
456
+ { title: "Attention", rows: buildGlobalTriageRows(projected, selectedRun), tone: "HOT" },
457
+ { title: "Latest Meaningful Change", rows: buildTrafficRows(projected, tier), tone: "FLOW", fullWidth: tier === "wide" },
458
+ { title: "Presence", rows: buildPresenceRows(selectedRun ?? projected.runs?.[0]), tone: "STATUS" },
459
+ { title: "Queue", rows: buildQueueRows(projected), tone: "QUEUE" },
460
+ { title: "Quiet Context", rows: buildQuietContextRows(projected, selectedRun), tone: "TRACE", fullWidth: tier === "wide" },
436
461
  ];
437
462
  }
438
463
 
@@ -451,8 +476,8 @@ export function buildInspectSections(run, options = {}) {
451
476
  const delta = index > 0 ? run.deltas?.find((candidate) => candidate.to_checkpoint_id === checkpoint.checkpoint_id) : undefined;
452
477
  return `${formatTimestamp(checkpoint.timestamp)} | ${checkpoint.process_summary.split("\n")[0]} | ${delta ? delta.layers.join("/") : "entry"}`;
453
478
  });
454
- const activityRows = (run.activity_items ?? []).slice(-12).map((item) =>
455
- `${formatTimestamp(item.timestamp)} [${activityBadge(item.source_kind)}] ${urgencyBadge(item.status)} ${item.actor_id} | ${item.summary}`
479
+ const activityRows = meaningfulActivity(run.activity_items ?? []).slice(-12).map((item) =>
480
+ `${formatTimestamp(item.timestamp)} [${activityBadge(item.source_kind)}] ${urgencyBadge(item.status)} ${item.actor_id} | ${displaySummary(item)}`
456
481
  );
457
482
  const similarityRows = (run.similarity?.neighbors ?? []).slice(0, 4).map((neighbor) => summarizeNeighbor(run, neighbor));
458
483
 
@@ -463,11 +488,13 @@ export function buildInspectSections(run, options = {}) {
463
488
  `${compactStatus(run.run.status)} ${run.run.title}`,
464
489
  `Objective: ${run.run.objective ?? "-"}`,
465
490
  `Updated: ${formatTimestamp(run.run.updated_at)} (${relativeTimeFromNow(run.run.updated_at)})`,
491
+ `Attention: ${run.live_signal?.attention_class ?? "observe_only"} | freshness ${run.live_signal?.freshness_class ?? "-"}`,
466
492
  ],
467
493
  tone: run.run.status === "blocked" ? "HOT" : "LIVE",
468
494
  },
469
- { title: "Lane Skyline", rows: buildLaneSkylineRows(run, tier), tone: "FLOW" },
470
- { title: "Triage Shelf", rows: buildRunTriageRows(run), tone: "HOT" },
495
+ { title: "Pulse", rows: buildSelectedRunRadar(run), tone: "FLOW" },
496
+ { title: "Attention", rows: buildRunTriageRows(run), tone: "HOT" },
497
+ { title: "Presence", rows: buildPresenceRows(run), tone: "STATUS" },
471
498
  { title: "Handoff Queue", rows: handoffRows.length ? handoffRows : ["No queued handoffs."], tone: "QUEUE" },
472
499
  { title: "Branch Divergence", rows: branchRows(run), tone: "FORK" },
473
500
  { title: "Lane Detail", rows: buildLaneDetailRows(run, tier), tone: "FLOW" },
@@ -54,6 +54,7 @@ export function createRuntimeRecorder({
54
54
  view,
55
55
  source,
56
56
  interactive: true,
57
+ observer_telemetry: true,
57
58
  ...payload,
58
59
  },
59
60
  });
@@ -67,6 +68,7 @@ export function createRuntimeRecorder({
67
68
  view,
68
69
  source,
69
70
  interactive: true,
71
+ observer_telemetry: true,
70
72
  ...metadata,
71
73
  },
72
74
  });