@apnex/network-adapter 0.1.1 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/build-info.json +6 -0
  2. package/dist/file-logger.d.ts +42 -0
  3. package/dist/file-logger.js +122 -0
  4. package/dist/file-logger.js.map +1 -0
  5. package/dist/index.d.ts +37 -13
  6. package/dist/index.js +42 -15
  7. package/dist/index.js.map +1 -1
  8. package/dist/kernel/adapter-config.d.ts +47 -0
  9. package/dist/kernel/adapter-config.js +90 -0
  10. package/dist/kernel/adapter-config.js.map +1 -0
  11. package/dist/kernel/agent-client.d.ts +25 -20
  12. package/dist/kernel/build-identity.d.ts +24 -0
  13. package/dist/kernel/build-identity.js +45 -0
  14. package/dist/kernel/build-identity.js.map +1 -0
  15. package/dist/kernel/event-router.d.ts +22 -1
  16. package/dist/kernel/event-router.js +45 -7
  17. package/dist/kernel/event-router.js.map +1 -1
  18. package/dist/kernel/handshake.d.ts +40 -4
  19. package/dist/kernel/handshake.js +46 -7
  20. package/dist/kernel/handshake.js.map +1 -1
  21. package/dist/kernel/harness-manifest.d.ts +51 -0
  22. package/dist/kernel/harness-manifest.js +96 -0
  23. package/dist/kernel/harness-manifest.js.map +1 -0
  24. package/dist/kernel/liveness-signal.d.ts +35 -0
  25. package/dist/kernel/liveness-signal.js +61 -0
  26. package/dist/kernel/liveness-signal.js.map +1 -0
  27. package/dist/kernel/liveness-watchdog.d.ts +78 -0
  28. package/dist/kernel/liveness-watchdog.js +115 -0
  29. package/dist/kernel/liveness-watchdog.js.map +1 -0
  30. package/dist/kernel/mcp-agent-client.d.ts +2 -2
  31. package/dist/kernel/mcp-agent-client.js +49 -3
  32. package/dist/kernel/mcp-agent-client.js.map +1 -1
  33. package/dist/kernel/poll-backstop.d.ts +93 -4
  34. package/dist/kernel/poll-backstop.js +193 -25
  35. package/dist/kernel/poll-backstop.js.map +1 -1
  36. package/dist/kernel/state-sync.d.ts +2 -13
  37. package/dist/kernel/state-sync.js.map +1 -1
  38. package/dist/notification-log.d.ts +8 -0
  39. package/dist/notification-log.js +10 -0
  40. package/dist/notification-log.js.map +1 -1
  41. package/dist/observability.d.ts +24 -0
  42. package/dist/observability.js +52 -0
  43. package/dist/observability.js.map +1 -0
  44. package/dist/prompt-format.js +82 -9
  45. package/dist/prompt-format.js.map +1 -1
  46. package/dist/tool-manager/catalog/health-revision.d.ts +43 -0
  47. package/dist/tool-manager/catalog/health-revision.js +61 -0
  48. package/dist/tool-manager/catalog/health-revision.js.map +1 -0
  49. package/dist/tool-manager/{tool-catalog-cache.d.ts → catalog/tool-catalog-cache.d.ts} +39 -19
  50. package/dist/tool-manager/{tool-catalog-cache.js → catalog/tool-catalog-cache.js} +53 -26
  51. package/dist/tool-manager/catalog/tool-catalog-cache.js.map +1 -0
  52. package/dist/tool-manager/catalog/tool-surface-reconciler.d.ts +93 -0
  53. package/dist/tool-manager/catalog/tool-surface-reconciler.js +101 -0
  54. package/dist/tool-manager/catalog/tool-surface-reconciler.js.map +1 -0
  55. package/dist/tool-manager/contracts.d.ts +91 -0
  56. package/dist/tool-manager/contracts.js +20 -0
  57. package/dist/tool-manager/contracts.js.map +1 -0
  58. package/dist/tool-manager/dispatch/dispatch.d.ts +77 -0
  59. package/dist/tool-manager/dispatch/dispatch.js +170 -0
  60. package/dist/tool-manager/dispatch/dispatch.js.map +1 -0
  61. package/dist/tool-manager/dispatch/tool-call-policy.d.ts +32 -0
  62. package/dist/tool-manager/dispatch/tool-call-policy.js +56 -0
  63. package/dist/tool-manager/dispatch/tool-call-policy.js.map +1 -0
  64. package/dist/tool-manager/{dispatcher.d.ts → orchestrator/dispatcher.d.ts} +110 -31
  65. package/dist/tool-manager/orchestrator/dispatcher.js +559 -0
  66. package/dist/tool-manager/orchestrator/dispatcher.js.map +1 -0
  67. package/dist/tool-manager/work-protocol/claimable-digest-tracker.d.ts +60 -0
  68. package/dist/tool-manager/work-protocol/claimable-digest-tracker.js +66 -0
  69. package/dist/tool-manager/work-protocol/claimable-digest-tracker.js.map +1 -0
  70. package/dist/tool-manager/work-protocol/work-lease-tracker.d.ts +59 -0
  71. package/dist/tool-manager/work-protocol/work-lease-tracker.js +134 -0
  72. package/dist/tool-manager/work-protocol/work-lease-tracker.js.map +1 -0
  73. package/dist/wire/mcp-transport.d.ts +1 -1
  74. package/dist/wire/mcp-transport.js +31 -7
  75. package/dist/wire/mcp-transport.js.map +1 -1
  76. package/dist/wire/slot-gate.d.ts +40 -0
  77. package/dist/wire/slot-gate.js +61 -0
  78. package/dist/wire/slot-gate.js.map +1 -0
  79. package/dist/wire/transport.d.ts +18 -0
  80. package/package.json +6 -3
  81. package/dist/kernel/instance.d.ts +0 -40
  82. package/dist/kernel/instance.js +0 -79
  83. package/dist/kernel/instance.js.map +0 -1
  84. package/dist/tool-manager/dispatcher.js +0 -379
  85. package/dist/tool-manager/dispatcher.js.map +0 -1
  86. package/dist/tool-manager/tool-catalog-cache.js.map +0 -1
@@ -32,6 +32,25 @@ import { dirname, join } from "node:path";
32
32
  import { homedir } from "node:os";
33
33
  const DEFAULT_CADENCE_SECONDS = 300; // 5 minutes
34
34
  const MIN_CADENCE_SECONDS = 60; // 1 minute floor — anti-pattern guard
35
+ /**
36
+ * mission-75 (M-TTL-Liveliness-Design) v1.0 §3.3 — second 30s heartbeat
37
+ * timer alongside the existing 300s message-poll timer. Calls the new
38
+ * `transport_heartbeat` MCP tool periodically so the Hub's
39
+ * `lastHeartbeatAt` doesn't age monotonically for idle agents (no
40
+ * pending actions queued; drain is queue-driven NOT periodic per
41
+ * round-2 N1 fold).
42
+ *
43
+ * Defaults match Hub-side env-ified constants:
44
+ * TRANSPORT_HEARTBEAT_INTERVAL_MS = 30_000 (min 10_000)
45
+ * TRANSPORT_HEARTBEAT_ENABLED = true
46
+ *
47
+ * Hub remains source-of-truth for these defaults; adapter reads its
48
+ * own env vars at construction time. Per-agent override (livenessConfig
49
+ * sub-object) is Hub-side only — adapter uses env defaults.
50
+ */
51
+ const DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000;
52
+ const MIN_HEARTBEAT_INTERVAL_MS = 10_000;
53
+ const HEARTBEAT_RETRY_BACKOFF_MS = 5_000;
35
54
  /**
36
55
  * Resolve the cursor file path. Defaults to
37
56
  * `~/.ois/poll-cursor-<role>-<agentId>.json`. The agentId is
@@ -41,6 +60,18 @@ const MIN_CADENCE_SECONDS = 60; // 1 minute floor — anti-pattern guard
41
60
  export function defaultCursorFile(role, agentId) {
42
61
  return join(homedir(), ".ois", `poll-cursor-${role}-${agentId}.json`);
43
62
  }
63
+ /**
64
+ * Resolve a {@link PollBackstopOptions.role} to its current string value.
65
+ * A plain string is returned as-is; a `() => string` thunk is invoked at
66
+ * call-time (bug-173 — lets a dispatcher constructed at MODULE-INIT track
67
+ * the host's configured role once `config.role` has loaded, instead of
68
+ * freezing whatever the env default was at construction). Used by both the
69
+ * PollBackstop tick (target.role filter) and the dispatcher's idea-353
70
+ * wake/stall reconcile so the two read the SAME resolved role.
71
+ */
72
+ export function resolveRole(role) {
73
+ return typeof role === "function" ? role() : role;
74
+ }
44
75
  /**
45
76
  * Read the persisted cursor (or undefined if no cursor file exists).
46
77
  * Corruption-tolerant: returns undefined on parse failure (cold-start
@@ -92,16 +123,27 @@ export function writeCursor(path, lastSeenId, log = () => { }) {
92
123
  log(`[poll-backstop] writeFileSync(${path}) failed: ${err}`);
93
124
  }
94
125
  }
126
+ /**
127
+ * Coerce an `agent.call("list_messages")` return into a ListMessagesBody.
128
+ *
129
+ * bug-103: `IAgentClient.call` → `McpTransport.request` ALREADY unwraps the
130
+ * MCP tool-result envelope — it reads `result.content[0].text` and
131
+ * `JSON.parse`s it (see `mcp-transport.ts` request()). So `raw` here is the
132
+ * `list_messages` body — `{ messages, count }` — directly, NOT the
133
+ * `{ content: [{ text }] }` envelope. The prior implementation re-expected
134
+ * the envelope; since the first-timer was disabled from bug-53 until the
135
+ * bug-103 slice, this path never ran against the real transport, so the
136
+ * contract drift went uncaught (the harness-verify is the dispositive
137
+ * real-transport guard). Returns null on any other shape — defensive
138
+ * against a non-JSON error string, null, or a cognitive-layer summarized
139
+ * result that drops the `messages[]` array.
140
+ */
95
141
  function parseListMessagesResult(raw) {
96
- const env = raw;
97
- if (!env || !env.content || !env.content[0] || env.isError)
142
+ if (!raw || typeof raw !== "object")
98
143
  return null;
99
- try {
100
- return JSON.parse(env.content[0].text);
101
- }
102
- catch {
144
+ if (!Array.isArray(raw.messages))
103
145
  return null;
104
- }
146
+ return raw;
105
147
  }
106
148
  /**
107
149
  * The PollBackstop runs the periodic `list_messages` tick loop and
@@ -114,39 +156,89 @@ function parseListMessagesResult(raw) {
114
156
  export class PollBackstop {
115
157
  opts;
116
158
  timer = null;
159
+ heartbeatTimer = null;
117
160
  resolvedCursorFile = null;
118
161
  inFlight = false;
162
+ heartbeatInFlight = false;
163
+ /**
164
+ * bug-173 — the role resolved at USE-time (`this.opts.role` may be a
165
+ * `() => string` thunk for hosts that construct the dispatcher before
166
+ * config loads). Every role read (poll filter, cursor file, log) goes
167
+ * through here so a configured role propagates without re-construction.
168
+ */
169
+ get currentRole() {
170
+ return resolveRole(this.opts.role);
171
+ }
119
172
  constructor(opts) {
120
173
  const fromEnv = parseInt(process.env.OIS_ADAPTER_POLL_BACKSTOP_S ?? "", 10);
121
174
  const cadence = Math.max(MIN_CADENCE_SECONDS, opts.cadenceSeconds ??
122
175
  (Number.isFinite(fromEnv) ? fromEnv : DEFAULT_CADENCE_SECONDS));
176
+ // mission-75 v1.0 §3.3 — heartbeat timer config (separate from
177
+ // message-poll cadence). Reads TRANSPORT_HEARTBEAT_INTERVAL_MS +
178
+ // TRANSPORT_HEARTBEAT_ENABLED env vars; explicit options override.
179
+ const hbFromEnv = Number(process.env.TRANSPORT_HEARTBEAT_INTERVAL_MS);
180
+ const heartbeatIntervalMs = Math.max(MIN_HEARTBEAT_INTERVAL_MS, opts.heartbeatIntervalMs ??
181
+ (Number.isFinite(hbFromEnv) ? hbFromEnv : DEFAULT_HEARTBEAT_INTERVAL_MS));
182
+ const heartbeatEnabled = opts.heartbeatEnabled ??
183
+ (process.env.TRANSPORT_HEARTBEAT_ENABLED === "false" ? false : true);
184
+ // bug-53: firstTimerEnabled defaults true for backwards-compat with
185
+ // existing mission-56 W3.3 Pull-mode callers; heartbeat-only hosts pass
186
+ // false to skip the first-timer scheduling.
187
+ const firstTimerEnabled = opts.firstTimerEnabled ?? true;
123
188
  this.opts = {
124
189
  role: opts.role,
125
190
  cadenceSeconds: cadence,
126
191
  cursorFile: opts.cursorFile,
127
192
  log: opts.log ?? (() => { }),
128
- onPolledMessage: opts.onPolledMessage,
193
+ onPolledMessage: opts.onPolledMessage ?? (() => { }),
194
+ onHeartbeatTick: opts.onHeartbeatTick ?? (() => { }),
195
+ heartbeatIntervalMs,
196
+ heartbeatEnabled,
197
+ firstTimerEnabled,
129
198
  };
130
199
  }
131
- /** Start the periodic poll. Idempotent. */
200
+ /** Start the periodic poll + heartbeat (if enabled). Idempotent. */
132
201
  start(getAgent) {
133
- if (this.timer)
202
+ // Idempotency guard: if EITHER timer is already set, treat as started.
203
+ // bug-53: previously checked only `this.timer`; under heartbeat-only
204
+ // mode (firstTimerEnabled=false) timer is null but heartbeatTimer may
205
+ // be set — guard against duplicate-start re-scheduling the heartbeat.
206
+ if (this.timer || this.heartbeatTimer)
134
207
  return;
135
208
  const cadenceMs = this.opts.cadenceSeconds * 1000;
136
- this.opts.log(`[poll-backstop] starting (role=${this.opts.role}, cadenceS=${this.opts.cadenceSeconds})`);
137
- this.timer = setInterval(() => {
138
- // Fire-and-forget; tick() handles its own errors.
139
- void this.tick(getAgent);
140
- }, cadenceMs);
141
- if (this.timer.unref)
142
- this.timer.unref();
209
+ this.opts.log(`[poll-backstop] starting (role=${this.currentRole}, cadenceS=${this.opts.firstTimerEnabled ? this.opts.cadenceSeconds : "disabled"}, heartbeatMs=${this.opts.heartbeatEnabled ? this.opts.heartbeatIntervalMs : "disabled"})`);
210
+ // bug-53: skip first-timer scheduling when firstTimerEnabled === false
211
+ // (heartbeat-only hosts; current shim/opencode adapters use SSE for
212
+ // inline message delivery; first-timer Pull-mode wiring deferred).
213
+ if (this.opts.firstTimerEnabled) {
214
+ this.timer = setInterval(() => {
215
+ // Fire-and-forget; tick() handles its own errors.
216
+ void this.tick(getAgent);
217
+ }, cadenceMs);
218
+ if (this.timer.unref)
219
+ this.timer.unref();
220
+ }
221
+ // mission-75 v1.0 §3.3 — second timer for transport_heartbeat. Only
222
+ // started when heartbeatEnabled === true (TRANSPORT_HEARTBEAT_ENABLED
223
+ // env-disable path; tests opt-out).
224
+ if (this.opts.heartbeatEnabled) {
225
+ this.heartbeatTimer = setInterval(() => {
226
+ void this.tickHeartbeat(getAgent);
227
+ }, this.opts.heartbeatIntervalMs);
228
+ if (this.heartbeatTimer.unref)
229
+ this.heartbeatTimer.unref();
230
+ }
143
231
  }
144
- /** Stop the periodic poll. Idempotent. */
232
+ /** Stop the periodic poll + heartbeat. Idempotent. */
145
233
  stop() {
146
- if (!this.timer)
147
- return;
148
- clearInterval(this.timer);
149
- this.timer = null;
234
+ if (this.timer) {
235
+ clearInterval(this.timer);
236
+ this.timer = null;
237
+ }
238
+ if (this.heartbeatTimer) {
239
+ clearInterval(this.heartbeatTimer);
240
+ this.heartbeatTimer = null;
241
+ }
150
242
  this.opts.log("[poll-backstop] stopped");
151
243
  }
152
244
  /**
@@ -175,20 +267,23 @@ export class PollBackstop {
175
267
  // session id which cycles on reconnect.
176
268
  const metrics = agent.getMetrics?.();
177
269
  const id = metrics?.agentId ?? agentId;
178
- this.resolvedCursorFile = defaultCursorFile(this.opts.role, id);
270
+ this.resolvedCursorFile = defaultCursorFile(this.currentRole, id);
179
271
  }
180
272
  }
181
273
  const cursorFile = this.resolvedCursorFile;
182
274
  const since = readCursor(cursorFile);
183
275
  const args = {
184
- targetRole: this.opts.role,
276
+ targetRole: this.currentRole,
185
277
  status: "new",
186
278
  };
187
279
  if (since !== undefined)
188
280
  args.since = since;
189
281
  let raw;
190
282
  try {
191
- raw = await agent.call("list_messages", args);
283
+ // bug-106: `internal` — this catch-up poll is machinery, not an LLM
284
+ // tool-call; the result must NOT be cognitive-layer-summarized
285
+ // (a summarized/truncated messages[] silently drops recovery).
286
+ raw = await agent.call("list_messages", args, { internal: true });
192
287
  }
193
288
  catch (err) {
194
289
  this.opts.log(`[poll-backstop] list_messages failed (non-fatal): ${err?.message ?? String(err)}`);
@@ -239,5 +334,78 @@ export class PollBackstop {
239
334
  this.inFlight = false;
240
335
  }
241
336
  }
337
+ /**
338
+ * mission-75 v1.0 §3.3 — single transport_heartbeat tick. Lightweight
339
+ * no-payload; the call itself is the heartbeat. Failure handling per
340
+ * Design §3.3:
341
+ * - retry once with 5s backoff;
342
+ * - skip cycle on second failure (next cycle attempts);
343
+ * - poll-backstop existing retry semantics for transient blips.
344
+ *
345
+ * Reentrant-safe via heartbeatInFlight guard. Exposed for tests
346
+ * (force-tick on demand).
347
+ */
348
+ async tickHeartbeat(getAgent) {
349
+ if (this.heartbeatInFlight)
350
+ return;
351
+ this.heartbeatInFlight = true;
352
+ try {
353
+ // idea-355 §4.3 (review fix — LIVENESS DECOUPLING): the host tick hook now
354
+ // carries the idea-355 wake/stall reconcile (a Hub round-trip) on top of the
355
+ // bug-180 /health live-refresh. Start it, but do NOT let it gate the liveness
356
+ // heartbeat — transport_heartbeat must never wait on the reconcile's Hub
357
+ // latency, or a slow read erodes the mission-75 TTL margin and can trip a
358
+ // FALSE-unresponsive (the exact bug-186 class). The hook runs CONCURRENTLY
359
+ // with the heartbeat; it has its own error handling + (for the reconcile)
360
+ // its own in-flight latch + read-timeout. bug-180's /health is still fired
361
+ // before/independent of the streaming gate, so an in-life redeploy is caught
362
+ // within one interval regardless of agent state. Best-effort.
363
+ const hookSettled = Promise.resolve()
364
+ .then(() => this.opts.onHeartbeatTick())
365
+ .catch((err) => {
366
+ this.opts.log(`[poll-backstop] onHeartbeatTick threw (non-fatal): ${err?.message ?? String(err)}`);
367
+ });
368
+ // Liveness heartbeat — independent of the hook.
369
+ await this.sendHeartbeat(getAgent);
370
+ // Settle the hook before releasing heartbeatInFlight (bounded by the
371
+ // reconcile's read-timeout) so a slow reconcile can't overlap the next tick.
372
+ await hookSettled;
373
+ }
374
+ finally {
375
+ this.heartbeatInFlight = false;
376
+ }
377
+ }
378
+ /**
379
+ * Send `transport_heartbeat` with one backoff retry. Gated on a streaming
380
+ * agent (the heartbeat needs the agent transport); a non-streaming agent is a
381
+ * no-op. Split out of `tickHeartbeat` so its early returns stay local — the
382
+ * caller must still settle the concurrent tick hook before releasing the
383
+ * heartbeatInFlight guard.
384
+ */
385
+ async sendHeartbeat(getAgent) {
386
+ const agent = getAgent();
387
+ if (!agent || agent.state !== "streaming")
388
+ return;
389
+ try {
390
+ await agent.call("transport_heartbeat", {}, { internal: true });
391
+ return;
392
+ }
393
+ catch (firstErr) {
394
+ this.opts.log(`[poll-backstop] transport_heartbeat failed (1st; retrying in ${HEARTBEAT_RETRY_BACKOFF_MS}ms): ${firstErr?.message ?? String(firstErr)}`);
395
+ }
396
+ // Single retry with backoff. If this fails too, skip the cycle —
397
+ // next cycle (heartbeatIntervalMs from now) will try again.
398
+ await new Promise((resolve) => setTimeout(resolve, HEARTBEAT_RETRY_BACKOFF_MS));
399
+ try {
400
+ // Re-check agent state after the backoff (could have torn down).
401
+ const agent2 = getAgent();
402
+ if (!agent2 || agent2.state !== "streaming")
403
+ return;
404
+ await agent2.call("transport_heartbeat", {}, { internal: true });
405
+ }
406
+ catch (secondErr) {
407
+ this.opts.log(`[poll-backstop] transport_heartbeat failed (2nd; skipping cycle): ${secondErr?.message ?? String(secondErr)}`);
408
+ }
409
+ }
242
410
  }
243
411
  //# sourceMappingURL=poll-backstop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"poll-backstop.js","sourceRoot":"","sources":["../../src/kernel/poll-backstop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"poll-backstop.js","sourceRoot":"","sources":["../../src/kernel/poll-backstop.ts"],"names":[],"mappings":"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"}
@@ -9,19 +9,8 @@
9
9
  * engineer has its canonical agentId by the time it queries pending state.
10
10
  */
11
11
  import type { ILogger, LegacyStringLogger } from "../logger.js";
12
- /**
13
- * A PendingActionItem as returned by `drain_pending_actions` (ADR-017).
14
- * Adapter-facing shape — subset of the Hub's canonical type that's
15
- * relevant for consumption. `id` is the queue item's surrogate ID which
16
- * MUST be passed back as `sourceQueueItemId` on the settling tool call
17
- * (e.g., create_thread_reply) for completion-ACK.
18
- */
19
- export interface DrainedPendingAction {
20
- id: string;
21
- dispatchType: string;
22
- entityRef: string;
23
- payload: Record<string, unknown>;
24
- }
12
+ import type { DrainedPendingAction } from "@apnex/message-router";
13
+ export type { DrainedPendingAction };
25
14
  export interface StateSyncContext {
26
15
  executeTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
27
16
  completeSync: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"state-sync.js","sourceRoot":"","sources":["../../src/kernel/state-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state-sync.js","sourceRoot":"","sources":["../../src/kernel/state-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AA6BlD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAqB;IAC1D,MAAM,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAS,EAAE,oCAAoC,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,oEAAoE;QACpE,oEAAoE;QACpE,mEAAmE;QACnE,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChE,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACrD,GAAG,CAAC,GAAG,CACL,4BAA4B,EAC5B,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EACtB,yBAAyB,GAAG,EAAE,CAC/B,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;YACF,GAAG,CAAC,WAAW,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBAChE,GAAG,CAAC,GAAG,CACL,uCAAuC,EACvC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EACtB,oCAAoC,GAAG,EAAE,CAC1C,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;YACF,GAAG,CAAC,WAAW,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBAClE,GAAG,CAAC,GAAG,CACL,yCAAyC,EACzC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EACtB,sCAAsC,GAAG,EAAE,CAC5C,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,SAAoC,CAAC;YAC/C,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAA+B,CAAC;gBAC/C,GAAG,CAAC,GAAG,CACL,yBAAyB,EACzB,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,EAC5C,6BAA6B,IAAI,CAAC,MAAM,IAAI,SAAS,EAAE,CACxD,CAAC;gBACF,IAAI,GAAG,CAAC,aAAa;oBAAE,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAED,IAAI,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;YACzD,MAAM,EAAE,GAAG,cAAyC,CAAC;YACrD,GAAG,CAAC,GAAG,CACL,4BAA4B,EAC5B,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,EAC9C,gCAAgC,EAAE,CAAC,YAAY,IAAI,CAAC,EAAE,CACvD,CAAC;QACJ,CAAC;QAED,kEAAkE;QAClE,mEAAmE;QACnE,kEAAkE;QAClE,kEAAkE;QAClE,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,UAAqC,CAAC;YAChD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,GAAG,CAAC,GAAG,CACL,0BAA0B,EAC1B,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,EACvB,uBAAuB,KAAK,CAAC,MAAM,yBAAyB,CAC7D,CAAC;YACJ,CAAC;YACD,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;gBAC5B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;oBACxB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;wBAAE,SAAS;oBAC9C,MAAM,IAAI,GAAG,GAA8B,CAAC;oBAC5C,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;wBAAE,SAAS;oBAC1C,GAAG,CAAC,mBAAmB,CAAC;wBACtB,EAAE,EAAE,IAAI,CAAC,EAAE;wBACX,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;wBAC7C,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;wBACvC,OAAO,EAAG,IAAI,CAAC,OAAmC,IAAI,EAAE;qBACzD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,GAAG,CAAC,YAAY,EAAE,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,SAAS,EAAE,2CAA2C,CAAC,CAAC;IACzF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,GAAG,CACL,mBAAmB,EACnB,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EACtB,uBAAuB,GAAG,EAAE,CAC7B,CAAC;QACF,IAAI,CAAC;YACH,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,GAAG,CACL,4BAA4B,EAC5B,SAAS,EACT,wCAAwC,CACzC,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -27,3 +27,11 @@ export interface NotificationLogOptions {
27
27
  * break the runtime).
28
28
  */
29
29
  export declare function appendNotification(entry: NotificationLogEntry, opts: NotificationLogOptions): void;
30
+ /**
31
+ * idea-355 SLICE-1 dedup: the both-shim-identical pending-task notification
32
+ * payload (was duplicated verbatim in the claude + opencode onPendingTask
33
+ * callbacks). Each shim feeds the returned entry to its own
34
+ * appendNotification(..., { logPath, mirror? }) — the host-specific log sink
35
+ * stays in the shim (the last mile).
36
+ */
37
+ export declare function buildPendingTaskNotification(task: Record<string, unknown>): NotificationLogEntry;
@@ -63,4 +63,14 @@ export function appendNotification(entry, opts) {
63
63
  }
64
64
  }
65
65
  }
66
+ /**
67
+ * idea-355 SLICE-1 dedup: the both-shim-identical pending-task notification
68
+ * payload (was duplicated verbatim in the claude + opencode onPendingTask
69
+ * callbacks). Each shim feeds the returned entry to its own
70
+ * appendNotification(..., { logPath, mirror? }) — the host-specific log sink
71
+ * stays in the shim (the last mile).
72
+ */
73
+ export function buildPendingTaskNotification(task) {
74
+ return { event: "task_issued", data: task, action: "Pick up with get_task" };
75
+ }
66
76
  //# sourceMappingURL=notification-log.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"notification-log.js","sourceRoot":"","sources":["../src/notification-log.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notification-log.js","sourceRoot":"","sources":["../src/notification-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * observability.ts — pure helpers for shim observability formalization.
3
+ *
4
+ * Mission-66 W1+W2 commit 4 (per Design §2.2 + ADR-031 §3, §5; spec
5
+ * `docs/specs/shim-observability-events.md` §3 + §5). idea-355 SLICE-1
6
+ * single-home: hoisted from the claude shim so any host's file-logger can
7
+ * redact + level-filter through one implementation (it can't drift).
8
+ *
9
+ * Pure functions: tests import them without triggering a shim's module-init
10
+ * `loadConfig()` side effect.
11
+ */
12
+ import type { LogFields } from "./logger.js";
13
+ export declare const REDACT_KEYS: Set<string>;
14
+ export declare function redactFields(fields: LogFields): LogFields;
15
+ export declare const LOG_LEVELS: readonly ["DEBUG", "INFO", "WARN", "ERROR"];
16
+ export type LogLevel = typeof LOG_LEVELS[number];
17
+ export declare function parseLogLevel(raw: string | undefined): LogLevel;
18
+ /**
19
+ * Decides whether an event with optional `level` field should be emitted
20
+ * given the configured threshold. Pure function for unit-test tractability;
21
+ * the shim runtime binds threshold via the `OIS_SHIM_LOG_LEVEL` env var read
22
+ * at module init.
23
+ */
24
+ export declare function shouldEmitLevel(eventLevel: string | undefined, threshold: LogLevel): boolean;
@@ -0,0 +1,52 @@
1
+ // ── Redaction discipline (ADR-031 §5) ────────────────────────────────
2
+ //
3
+ // Sensitive field names that MUST be redacted before persisting to the
4
+ // events file. Defensive — current callers don't pass these, but a future
5
+ // field rename could accidentally leak. Whole-key match (case-insensitive);
6
+ // any field whose name matches is replaced with `<redacted>`.
7
+ export const REDACT_KEYS = new Set([
8
+ "hubtoken",
9
+ "token",
10
+ "authorization",
11
+ "bearer",
12
+ "apikey",
13
+ "api_key",
14
+ "secret",
15
+ "password",
16
+ ]);
17
+ export function redactFields(fields) {
18
+ const out = {};
19
+ for (const k of Object.keys(fields)) {
20
+ out[k] = REDACT_KEYS.has(k.toLowerCase()) ? "<redacted>" : fields[k];
21
+ }
22
+ return out;
23
+ }
24
+ // ── Log-level filter (ADR-031 §3; OIS_SHIM_LOG_LEVEL env var) ────────
25
+ //
26
+ // Levels: DEBUG < INFO < WARN < ERROR. Default INFO. Filter applied at
27
+ // FileBackedLogger emit boundary; events tagged with `fields.level` below
28
+ // threshold are suppressed (no-op). Events without `level` always emit
29
+ // (default INFO behavior — preserves Phase 1 emit semantics).
30
+ export const LOG_LEVELS = ["DEBUG", "INFO", "WARN", "ERROR"];
31
+ export function parseLogLevel(raw) {
32
+ const normalized = (raw ?? "").toUpperCase();
33
+ return LOG_LEVELS.includes(normalized)
34
+ ? normalized
35
+ : "INFO";
36
+ }
37
+ /**
38
+ * Decides whether an event with optional `level` field should be emitted
39
+ * given the configured threshold. Pure function for unit-test tractability;
40
+ * the shim runtime binds threshold via the `OIS_SHIM_LOG_LEVEL` env var read
41
+ * at module init.
42
+ */
43
+ export function shouldEmitLevel(eventLevel, threshold) {
44
+ if (!eventLevel)
45
+ return true; // unlevelled events always emit (default INFO)
46
+ const idx = LOG_LEVELS.indexOf(eventLevel.toUpperCase());
47
+ if (idx < 0)
48
+ return true; // unknown level treated as unlevelled
49
+ const thresholdIdx = LOG_LEVELS.indexOf(threshold);
50
+ return idx >= thresholdIdx;
51
+ }
52
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAaA,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,4EAA4E;AAC5E,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IACjC,UAAU;IACV,OAAO;IACP,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,GAAG,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,GAAgB,CAAC;AAC1B,CAAC;AAED,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,uEAAuE;AACvE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGtE,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,OAAQ,UAAgC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3D,CAAC,CAAE,UAAuB;QAC1B,CAAC,CAAC,MAAM,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,UAA8B,EAC9B,SAAmB;IAEnB,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC,CAAC,+CAA+C;IAC7E,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAc,CAAC,CAAC;IACrE,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,sCAAsC;IAChE,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnD,OAAO,GAAG,IAAI,YAAY,CAAC;AAC7B,CAAC"}
@@ -41,6 +41,10 @@ export function getActionText(event, data) {
41
41
  return `Read with get_review(taskId="${data.taskId}")`;
42
42
  case "proposal_decided":
43
43
  return "Review decision and act if needed";
44
+ case "work_claimable_digest":
45
+ return "Claimable work available — list_ready_work then claim_work";
46
+ case "work_lease_stall":
47
+ return `Held work ${data.workId ?? ""} nearing lease expiry — renew_lease / block_work / abandon_work`;
44
48
  default:
45
49
  return "Review and act as needed";
46
50
  }
@@ -49,16 +53,39 @@ export function getActionText(event, data) {
49
53
  function renderThreadMessage(data, cfg) {
50
54
  // calibration #20 retire (mission-63 W3): surface the body inline so the
51
55
  // LLM has the actual message content, not just the envelope-shell. The
52
- // Hub-side dispatch payload pre-truncates to 200 chars (thread-policy.ts);
53
- // adapter renders that preview verbatim. Full body still requires get_thread.
56
+ // Hub-side dispatch payload pre-truncates to THREAD_MESSAGE_PREVIEW_CHARS
57
+ // chars (thread-policy.ts; mission-66 commit 6 ratified at 200 chars);
58
+ // adapter renders that preview + truncation marker (mission-66 #26).
59
+ // Full body still requires get_thread.
60
+ //
61
+ // mission-66 commit 6 (#26 marker-protocol; closes calibration #26):
62
+ // Hub-side envelope-builder surfaces `truncated: true` + `fullBytes: <n>`
63
+ // on dispatchPayload when body exceeds preview threshold. Adapter
64
+ // render-template appends marker per Design §2.1.2 architect-lean (b):
65
+ // `[…<N> bytes truncated; query thread for full content]`.
66
+ //
67
+ // M-SSE-Peek-Line-Cleanup Phase 1 (Design v1.1 §0.5.3): when Hub has
68
+ // rendered the canonical peek-line via `payload.body` (auto-derived
69
+ // from event-name + data at emit-time per `deriveRenderContext`),
70
+ // prefer it as the summary line. Falls back to the legacy author-label
71
+ // composition when payload.body is absent (cutover window).
54
72
  const p = cfg.toolPrefix;
55
- const authorLabel = data.author === "architect" ? "Architect"
56
- : data.author === "engineer" ? "Engineer peer"
57
- : "Peer";
73
+ const hubBody = typeof data.body === "string" && data.body.length > 0 ? data.body : null;
58
74
  const title = data.title || data.threadId || "(unknown)";
59
75
  const body = data.message || "";
60
- const bodyLine = body ? `\n\nMessage preview: ${body}` : "";
61
- return (`[${authorLabel}] Replied to thread "${title}".${bodyLine} ` +
76
+ const truncated = data.truncated === true;
77
+ const fullBytes = typeof data.fullBytes === "number" ? data.fullBytes : undefined;
78
+ const truncationMarker = truncated && fullBytes !== undefined
79
+ ? ` […${fullBytes} bytes truncated; query thread for full content]`
80
+ : "";
81
+ const bodyLine = body ? `\n\nMessage preview: ${body}${truncationMarker}` : "";
82
+ const summaryLine = hubBody ?? (() => {
83
+ const authorLabel = data.author === "architect" ? "Architect"
84
+ : data.author === "engineer" ? "Engineer peer"
85
+ : "Peer";
86
+ return `[${authorLabel}] Replied to thread "${title}".`;
87
+ })();
88
+ return (`${summaryLine}${bodyLine} ` +
62
89
  `\n\nIt is your turn. Call ${p}get_thread with threadId="${data.threadId}" ` +
63
90
  `to read the full thread, then reply using ${p}create_thread_reply. ` +
64
91
  `Threads 2.0 discipline: when you signal converged=true you MUST also populate ` +
@@ -147,9 +174,19 @@ function renderMessageArrived(data, cfg) {
147
174
  const pMissionId = payload.missionId || "?";
148
175
  const pMessage = payload.message || "(empty pulse message)";
149
176
  const pResponseShape = payload.responseShape || "short_status";
177
+ // mission-66 W1+W2 commit 5b-final (architect-portion; canonical shape per
178
+ // hub/src/policy/note-schema.ts ratified at thread-428 round 3; landed in
179
+ // commit 5 at 8193061). Canonical kind=note payload shape: { body: string
180
+ // (REQUIRED, non-empty), ...optional metadata }. Hub-side reject-mode at
181
+ // canonical repository write-path (messageRepository.createMessage) throws
182
+ // NoteSchemaValidationError on invalid payload; LLM-callers see error nack
183
+ // via MCP entry-point — caller-side feedback restores bilateral-blind class
184
+ // closure (#41 STRUCTURAL ANCHOR). Per anti-goal #8 coordinated-upgrade
185
+ // discipline + Calibration #48 (Director ratification 2026-04-29).
150
186
  return (`[Hub] Pulse fired (${payload.pulseKind}) for mission ${pMissionId}. ${pMessage} ` +
151
187
  `Respond with shape "${pResponseShape}" via the appropriate channel ` +
152
- `(typically ${p}create_message kind=note OR a short status reply on the active coord-thread). ` +
188
+ `(typically ${p}create_message kind=note with payload {body: "<your status text>"}, ` +
189
+ `OR a short status reply on the active coord-thread). ` +
153
190
  `Message ID: ${msgId}.`);
154
191
  }
155
192
  if (payload.event && typeof payload.event === "string") {
@@ -164,12 +201,42 @@ function renderMessageArrived(data, cfg) {
164
201
  "(empty note body)";
165
202
  const sender = msg.authorAgentId || "unknown";
166
203
  const senderRole = msg.authorRole || "agent";
204
+ // mission-66 W1+W2 commit 5b-final (architect-portion; canonical shape per
205
+ // hub/src/policy/note-schema.ts; see pulse-template comment above for context).
167
206
  return (`[${senderRole}/${sender}] Note: ${body} ` +
168
- `(Message ID: ${msgId}; respond via ${p}create_message kind=note targeting the sender.)`);
207
+ `(Message ID: ${msgId}; respond via ${p}create_message kind=note ` +
208
+ `with payload {body: "<your reply text>"} targeting the sender.)`);
169
209
  }
170
210
  return (`[Hub] Message ${msgId} (kind=${kind}) arrived. ` +
171
211
  `Use ${p}list_messages or ${p}claim_message to fetch full content + ack.`);
172
212
  }
213
+ function renderWorkClaimableDigest(data, cfg) {
214
+ // idea-353 W1 — inbound idle-wake digest. Surfaced ONLY on an upward edge
215
+ // (0→N or a new claimable item) WHILE the agent is idle; the level-trigger
216
+ // de-dup means a steady N>0 / re-tick / Hub-restart does not re-fire.
217
+ const p = cfg.toolPrefix;
218
+ const role = data.role || "your";
219
+ const count = typeof data.count === "number" ? data.count : 0;
220
+ const newCount = typeof data.newCount === "number" ? data.newCount : count;
221
+ const noun = count === 1 ? "item" : "items";
222
+ const newClause = newCount > 0 && newCount < count ? ` (${newCount} new)` : "";
223
+ return (`[Hub] ${count} ${noun} now claimable for the ${role} role${newClause}. ` +
224
+ `Call ${p}list_ready_work to view, then ${p}claim_work to pick one up. ` +
225
+ `(Idle-wake digest: surfaced because you are idle and newly-claimable work appeared.)`);
226
+ }
227
+ function renderWorkLeaseStall(data, cfg) {
228
+ // idea-353 W2 — outbound stall-prompt: the gentle first rung below the
229
+ // lease-TTL → sweeper → poison → thrash ladder. Fires once per lease window
230
+ // when a held lease crosses ~60% of its life without a renew; renewing
231
+ // reopens the window + clears this prompt.
232
+ const p = cfg.toolPrefix;
233
+ const workId = data.workId || "(unknown)";
234
+ const msUntilExpiry = typeof data.msUntilExpiry === "number" ? data.msUntilExpiry : 0;
235
+ const mins = Math.max(0, Math.round(msUntilExpiry / 60000));
236
+ return (`[Hub] Your held work ${workId} is approaching lease expiry (~${mins}m left) without a recent renew. ` +
237
+ `Before the sweeper reaps it: ${p}renew_lease (still working), ${p}block_work (blocked on something), ` +
238
+ `or ${p}abandon_work (giving it up). Renewing clears this prompt.`);
239
+ }
173
240
  // ── Registry ────────────────────────────────────────────────────────────
174
241
  const RENDER_REGISTRY = new Map([
175
242
  ["thread_message", renderThreadMessage],
@@ -181,6 +248,8 @@ const RENDER_REGISTRY = new Map([
181
248
  ["review_completed", renderReviewCompleted],
182
249
  ["revision_required", renderRevisionRequired],
183
250
  ["proposal_decided", renderProposalDecided],
251
+ ["work_claimable_digest", renderWorkClaimableDigest],
252
+ ["work_lease_stall", renderWorkLeaseStall],
184
253
  ]);
185
254
  function defaultTemplate(event, _data, _cfg) {
186
255
  return `[Hub] Notification: ${event}.`;
@@ -213,6 +282,10 @@ export function buildToastMessage(event, data) {
213
282
  const cause = data.cause || "unknown";
214
283
  return `Agent ${id} state-changed (${cause})`;
215
284
  }
285
+ case "work_claimable_digest":
286
+ return `${data.count ?? 0} work item(s) claimable for ${data.role ?? "your role"}`;
287
+ case "work_lease_stall":
288
+ return `Lease expiring: ${data.workId ?? "held work"}`;
216
289
  default:
217
290
  return `Hub: ${event}`;
218
291
  }