@apnex/network-adapter 0.1.2 → 0.1.6

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 +134 -4
  34. package/dist/kernel/poll-backstop.js +254 -24
  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 +70 -0
  71. package/dist/tool-manager/work-protocol/work-lease-tracker.js +146 -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
@@ -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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-format.js","sourceRoot":"","sources":["../src/prompt-format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-format.js","sourceRoot":"","sources":["../src/prompt-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,IAA6B;IAE7B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,uBAAuB,CAAC;QACjC,KAAK,mBAAmB;YACtB,OAAO,wCAAwC,CAAC;QAClD,KAAK,gBAAgB;YACnB,OAAO,kCAAkC,IAAI,CAAC,QAAQ,yCAAyC,CAAC;QAClG,KAAK,8BAA8B;YACjC,OAAO,0DAA0D,CAAC;QACpE,KAAK,wBAAwB;YAC3B,OAAO,uCAAuC,IAAI,CAAC,MAAM,sBAAsB,CAAC;QAClF,KAAK,kBAAkB;YACrB,OAAO,gCAAgC,IAAI,CAAC,MAAM,IAAI,CAAC;QACzD,KAAK,kBAAkB;YACrB,OAAO,mCAAmC,CAAC;QAC7C,KAAK,uBAAuB;YAC1B,OAAO,4DAA4D,CAAC;QACtE,KAAK,kBAAkB;YACrB,OAAO,aAAa,IAAI,CAAC,MAAM,IAAI,EAAE,iEAAiE,CAAC;QACzG;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC;AAmBD,0EAA0E;AAE1E,SAAS,mBAAmB,CAAC,IAA6B,EAAE,GAAuB;IACjF,yEAAyE;IACzE,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,qEAAqE;IACrE,uCAAuC;IACvC,EAAE;IACF,qEAAqE;IACrE,0EAA0E;IAC1E,kEAAkE;IAClE,uEAAuE;IACvE,2DAA2D;IAC3D,EAAE;IACF,qEAAqE;IACrE,oEAAoE;IACpE,kEAAkE;IAClE,uEAAuE;IACvE,4DAA4D;IAC5D,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACzF,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAK,IAAI,CAAC,QAAmB,IAAI,WAAW,CAAC;IACjF,MAAM,IAAI,GAAI,IAAI,CAAC,OAAkB,IAAI,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;IAC1C,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,MAAM,gBAAgB,GAAG,SAAS,IAAI,SAAS,KAAK,SAAS;QAC3D,CAAC,CAAC,MAAM,SAAS,kDAAkD;QACnE,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,wBAAwB,IAAI,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/E,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE;QACnC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW;YAC3D,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe;gBAC9C,CAAC,CAAC,MAAM,CAAC;QACX,OAAO,IAAI,WAAW,wBAAwB,KAAK,IAAI,CAAC;IAC1D,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,CACL,GAAG,WAAW,GAAG,QAAQ,GAAG;QAC5B,6BAA6B,CAAC,6BAA6B,IAAI,CAAC,QAAQ,IAAI;QAC5E,6CAA6C,CAAC,uBAAuB;QACrE,gFAAgF;QAChF,mDAAmD;QACnD,gFAAgF;QAChF,4DAA4D;QAC5D,uHAAuH,CACxH,CAAC;AACJ,CAAC;AAED,SAAS,gCAAgC,CAAC,IAA6B,EAAE,IAAwB;IAC/F,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,2DAA2D;IAC3D,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAK,IAAI,CAAC,QAAmB,IAAI,WAAW,CAAC;IACjF,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,MAAM,CAAC;IACjD,MAAM,OAAO,GAAI,IAAI,CAAC,OAAkB,IAAI,QAAQ,CAAC;IACrD,MAAM,SAAS,GAAI,IAAI,CAAC,oBAA+B,IAAI,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAI,IAAI,CAAC,aAAwB,IAAI,CAAC,CAAC;IACrD,MAAM,MAAM,GAAI,IAAI,CAAC,WAAsB,IAAI,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,OAAO,CACL,iBAAiB,KAAK,4BAA4B,MAAM,IAAI;QAC5D,YAAY,OAAO,IAAI;QACvB,sBAAsB,SAAS,cAAc,QAAQ,YAAY,MAAM,GAAG,OAAO,KAAK;QACtF,kFAAkF,CACnF,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,IAA6B,EAAE,IAAwB;IACtF,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,iEAAiE;IACjE,2BAA2B;IAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;IAChE,MAAM,QAAQ,GAAI,IAAI,CAAC,QAAgD,IAAI,EAAE,CAAC;IAC9E,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,SAAS,CAAC;IAClD,MAAM,EAAE,GAAI,KAAK,EAAE,EAAa,IAAI,SAAS,CAAC;IAC9C,MAAM,IAAI,GAAI,KAAK,EAAE,IAAe,IAAI,EAAE,CAAC;IAC3C,MAAM,IAAI,GAAI,KAAK,EAAE,IAAe,IAAI,OAAO,CAAC;IAChD,MAAM,WAAW,GAAI,KAAK,EAAE,aAAwB,IAAI,SAAS,CAAC;IAClE,MAAM,WAAW,GAAI,KAAK,EAAE,aAAwB,IAAI,SAAS,CAAC;IAClE,MAAM,kBAAkB,GACtB,eAAe,IAAI,QAAQ;QACzB,CAAC,CAAC,iBAAiB,QAAQ,CAAC,aAAuB,MAAM,WAAW,EAAE;QACtE,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,kBAAkB,GACtB,eAAe,IAAI,QAAQ;QACzB,CAAC,CAAC,iBAAiB,QAAQ,CAAC,aAAuB,MAAM,WAAW,EAAE;QACtE,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,WAAW,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACpG,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAC9F,OAAO,CACL,eAAe,IAAI,IAAI,IAAI,KAAK,EAAE,oBAAoB,cAAc,WAAW,KAAK,IAAI,CACzF,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAAC,IAA6B,EAAE,GAAuB;IACzF,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,OAAO,CACL,uDAAuD,IAAI,CAAC,MAAM,IAAI;QACtE,QAAQ,CAAC,kCAAkC,IAAI,CAAC,MAAM,IAAI;QAC1D,0CAA0C,CAC3C,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,IAA6B,EAAE,GAAuB;IAC9E,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,OAAO,CACL,uCAAuC,IAAI,CAAC,MAAM,IAAI,SAAS,KAAK;QACpE,QAAQ,CAAC,wCAAwC,CAClD,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,IAA6B,EAAE,GAAuB;IACnF,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,OAAO,CACL,wBAAwB,IAAI,CAAC,MAAM,IAAI,aAAa,IAAI;QACxD,gBAAgB,CAAC,2BAA2B,IAAI,CAAC,MAAM,IAAI,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,IAA6B,EAAE,GAAuB;IACpF,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,OAAO,CACL,+BAA+B,IAAI,CAAC,MAAM,IAAI,MAAM,iBAAiB;QACrE,aAAa,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,IAAI,qBAAqB,IAAI;QAC1E,oBAAoB,IAAI,CAAC,iBAAiB,IAAI,SAAS,IAAI;QAC3D,YAAY,IAAI,CAAC,aAAa,IAAI,GAAG,sCAAsC,CAAC,gBAAgB,CAC7F,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,IAA6B,EAAE,IAAwB;IACpF,OAAO,wBAAwB,IAAI,CAAC,UAAU,IAAI,EAAE,KAAK,IAAI,CAAC,QAAQ,IAAI,SAAS,GAAG,CAAC;AACzF,CAAC;AAED,SAAS,oBAAoB,CAAC,IAA6B,EAAE,GAAuB;IAClF,qEAAqE;IACrE,oEAAoE;IACpE,8DAA8D;IAC9D,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,MAAM,GAAG,GAAI,IAAI,CAAC,OAAmC,IAAI,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAI,GAAG,CAAC,OAAmC,IAAI,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAI,GAAG,CAAC,EAAa,IAAI,GAAG,CAAC;IACxC,MAAM,IAAI,GAAI,GAAG,CAAC,IAAe,IAAI,SAAS,CAAC;IAE/C,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC/D,MAAM,UAAU,GAAI,OAAO,CAAC,SAAoB,IAAI,GAAG,CAAC;QACxD,MAAM,QAAQ,GAAI,OAAO,CAAC,OAAkB,IAAI,uBAAuB,CAAC;QACxE,MAAM,cAAc,GAAI,OAAO,CAAC,aAAwB,IAAI,cAAc,CAAC;QAC3E,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,mEAAmE;QACnE,OAAO,CACL,sBAAsB,OAAO,CAAC,SAAS,iBAAiB,UAAU,KAAK,QAAQ,GAAG;YAClF,uBAAuB,cAAc,gCAAgC;YACrE,cAAc,CAAC,sEAAsE;YACrF,uDAAuD;YACvD,eAAe,KAAK,GAAG,CACxB,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvD,OAAO,CACL,6BAA6B,OAAO,CAAC,KAAK,IAAI;YAC9C,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,EAAG,OAAO,CAAC,IAAgC,IAAI,EAAE,CAAC,IAAI;YACpF,eAAe,KAAK,GAAG,CACxB,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,GACP,OAAO,CAAC,IAAe;YACvB,OAAO,CAAC,IAAe;YACvB,OAAO,CAAC,OAAkB;YAC3B,mBAAmB,CAAC;QACtB,MAAM,MAAM,GAAI,GAAG,CAAC,aAAwB,IAAI,SAAS,CAAC;QAC1D,MAAM,UAAU,GAAI,GAAG,CAAC,UAAqB,IAAI,OAAO,CAAC;QACzD,2EAA2E;QAC3E,gFAAgF;QAChF,OAAO,CACL,IAAI,UAAU,IAAI,MAAM,WAAW,IAAI,GAAG;YAC1C,gBAAgB,KAAK,iBAAiB,CAAC,2BAA2B;YAClE,iEAAiE,CAClE,CAAC;IACJ,CAAC;IAED,OAAO,CACL,iBAAiB,KAAK,UAAU,IAAI,aAAa;QACjD,OAAO,CAAC,oBAAoB,CAAC,4CAA4C,CAC1E,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,IAA6B,EAAE,GAAuB;IACvF,0EAA0E;IAC1E,2EAA2E;IAC3E,sEAAsE;IACtE,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,MAAM,IAAI,GAAI,IAAI,CAAC,IAAe,IAAI,MAAM,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3E,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5C,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,OAAO,CACL,SAAS,KAAK,IAAI,IAAI,0BAA0B,IAAI,QAAQ,SAAS,IAAI;QACzE,QAAQ,CAAC,iCAAiC,CAAC,6BAA6B;QACxE,sFAAsF,CACvF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,IAA6B,EAAE,GAAuB;IAClF,uEAAuE;IACvE,4EAA4E;IAC5E,uEAAuE;IACvE,2CAA2C;IAC3C,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;IACzB,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,WAAW,CAAC;IACtD,MAAM,aAAa,GAAG,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC;IAC5D,OAAO,CACL,wBAAwB,MAAM,kCAAkC,IAAI,kCAAkC;QACtG,gCAAgC,CAAC,gCAAgC,CAAC,qCAAqC;QACvG,MAAM,CAAC,2DAA2D,CACnE,CAAC;AACJ,CAAC;AAED,2EAA2E;AAE3E,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAC3D,CAAC,gBAAgB,EAAE,mBAAmB,CAAC;IACvC,CAAC,8BAA8B,EAAE,gCAAgC,CAAC;IAClE,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;IAChD,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;IACzC,CAAC,wBAAwB,EAAE,2BAA2B,CAAC;IACvD,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACjC,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;IAC3C,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;IAC7C,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;IAC3C,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;IACpD,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;CAC3C,CAAC,CAAC;AAEH,SAAS,eAAe,CAAC,KAAa,EAAE,KAA8B,EAAE,IAAwB;IAC9F,OAAO,uBAAuB,KAAK,GAAG,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,IAA6B,EAC7B,GAAuB;IAEvB,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzC,OAAO,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,IAA6B;IAE7B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,kBAAkB,IAAI,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACtD,KAAK,kBAAkB;YACrB,OAAO,oBAAoB,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QACrD,KAAK,mBAAmB;YACtB,OAAO,sBAAsB,IAAI,CAAC,MAAM,IAAI,MAAM,oBAAoB,CAAC;QACzE,KAAK,kBAAkB;YACrB,OAAO,YAAY,IAAI,CAAC,UAAU,IAAI,EAAE,KAAK,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC5E,KAAK,wBAAwB;YAC3B,OAAO,2BAA2B,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QAC5D,KAAK,gBAAgB;YACnB,OAAO,kBAAkB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC;QACtE,KAAK,8BAA8B;YACjC,OAAO,sBAAsB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,MAAM,IAAI,WAAW,KAAK,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,IAAI,CAAC,oBAAoB,IAAI,CAAC,YAAY,CAAC;QACrK,KAAK,qBAAqB,CAAC,CAAC,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;YAChE,MAAM,EAAE,GAAI,KAAK,EAAE,EAAa,IAAI,SAAS,CAAC;YAC9C,MAAM,KAAK,GAAI,IAAI,CAAC,KAAgB,IAAI,SAAS,CAAC;YAClD,OAAO,SAAS,EAAE,mBAAmB,KAAK,GAAG,CAAC;QAChD,CAAC;QACD,KAAK,uBAAuB;YAC1B,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,+BAA+B,IAAI,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;QACrF,KAAK,kBAAkB;YACrB,OAAO,mBAAmB,IAAI,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;QACzD;YACE,OAAO,QAAQ,KAAK,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * health-revision.ts — the Hub /health `toolSurfaceRevision` fetcher,
3
+ * hoisted to the kernel (idea-355 SLICE-1T).
4
+ *
5
+ * This is the network mechanism the bug-180 `ToolSurfaceReconciler` injects as
6
+ * its `fetchLiveRevision` dependency: resolve the Hub's live tool-surface
7
+ * revision (an opaque ETag served on /health since bug-114) over plain HTTP,
8
+ * independent of the MCP transport.
9
+ *
10
+ * Previously this lived inline in each shim (the claude shim's
11
+ * `fetchLiveToolSurfaceRevision`). Hoisting it single-homes the network
12
+ * mechanism so both shims share ONE implementation. The factory is PURE — it
13
+ * holds no module state and carries NO cache side-effect: callers that want a
14
+ * cached-revision marker (the claude shim's `cachedToolSurfaceRevision`) wrap
15
+ * the returned function and apply the side-effect on a non-null result.
16
+ *
17
+ * Contract:
18
+ * - derive `healthUrl` by replacing a trailing `/mcp` (optionally with a
19
+ * further path) on `hubUrl` with `/health`;
20
+ * - fetch it (global `fetch` only — opencode bundles via esbuild with no
21
+ * node_modules, so no node-fetch/undici);
22
+ * - return `json.toolSurfaceRevision` when it is a non-empty string;
23
+ * - return null on `!res.ok`, a missing/empty/non-string field, or any throw
24
+ * (never reject — the reconciler treats null as "unknown, trust the cache"
25
+ * and never emits a spurious list_changed).
26
+ */
27
+ export interface FetchLiveToolSurfaceRevisionOptions {
28
+ /** The Hub MCP URL (…/mcp). The /health URL is derived from it. */
29
+ hubUrl: string;
30
+ /**
31
+ * Fetch implementation. Defaults to the global `fetch`. Injectable so the
32
+ * factory is unit-testable without a live Hub.
33
+ */
34
+ fetch?: typeof globalThis.fetch;
35
+ /** Diagnostic logger. No-op default. */
36
+ log?: (msg: string) => void;
37
+ }
38
+ /**
39
+ * Build a pure `fetchLiveRevision` function for the bug-180
40
+ * `ToolSurfaceReconciler`. Resolves the Hub's live /health
41
+ * `toolSurfaceRevision`, or null on any failure (never rejects).
42
+ */
43
+ export declare function makeFetchLiveToolSurfaceRevision(opts: FetchLiveToolSurfaceRevisionOptions): () => Promise<string | null>;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * health-revision.ts — the Hub /health `toolSurfaceRevision` fetcher,
3
+ * hoisted to the kernel (idea-355 SLICE-1T).
4
+ *
5
+ * This is the network mechanism the bug-180 `ToolSurfaceReconciler` injects as
6
+ * its `fetchLiveRevision` dependency: resolve the Hub's live tool-surface
7
+ * revision (an opaque ETag served on /health since bug-114) over plain HTTP,
8
+ * independent of the MCP transport.
9
+ *
10
+ * Previously this lived inline in each shim (the claude shim's
11
+ * `fetchLiveToolSurfaceRevision`). Hoisting it single-homes the network
12
+ * mechanism so both shims share ONE implementation. The factory is PURE — it
13
+ * holds no module state and carries NO cache side-effect: callers that want a
14
+ * cached-revision marker (the claude shim's `cachedToolSurfaceRevision`) wrap
15
+ * the returned function and apply the side-effect on a non-null result.
16
+ *
17
+ * Contract:
18
+ * - derive `healthUrl` by replacing a trailing `/mcp` (optionally with a
19
+ * further path) on `hubUrl` with `/health`;
20
+ * - fetch it (global `fetch` only — opencode bundles via esbuild with no
21
+ * node_modules, so no node-fetch/undici);
22
+ * - return `json.toolSurfaceRevision` when it is a non-empty string;
23
+ * - return null on `!res.ok`, a missing/empty/non-string field, or any throw
24
+ * (never reject — the reconciler treats null as "unknown, trust the cache"
25
+ * and never emits a spurious list_changed).
26
+ */
27
+ /**
28
+ * Build a pure `fetchLiveRevision` function for the bug-180
29
+ * `ToolSurfaceReconciler`. Resolves the Hub's live /health
30
+ * `toolSurfaceRevision`, or null on any failure (never rejects).
31
+ */
32
+ export function makeFetchLiveToolSurfaceRevision(opts) {
33
+ const log = opts.log ?? (() => { });
34
+ const doFetch = opts.fetch ?? globalThis.fetch;
35
+ const healthUrl = opts.hubUrl.replace(/\/mcp(\/.*)?$/, "/health");
36
+ return async () => {
37
+ try {
38
+ const res = await doFetch(healthUrl);
39
+ if (!res.ok) {
40
+ log(`[Cache] /health fetch returned status ${res.status} — cache invalidation will trust existing cache`);
41
+ return null;
42
+ }
43
+ const json = (await res.json());
44
+ if (typeof json.version === "string") {
45
+ log(`[Cache] Hub version: ${json.version}`);
46
+ }
47
+ if (typeof json.toolSurfaceRevision === "string" &&
48
+ json.toolSurfaceRevision !== "") {
49
+ log(`[Cache] Tool-surface revision resolved: ${json.toolSurfaceRevision}`);
50
+ return json.toolSurfaceRevision;
51
+ }
52
+ log(`[Cache] /health returned no toolSurfaceRevision field — cache invalidation will trust existing cache`);
53
+ return null;
54
+ }
55
+ catch (err) {
56
+ log(`[Cache] /health fetch failed (non-fatal): ${err?.message ?? String(err)}`);
57
+ return null;
58
+ }
59
+ };
60
+ }
61
+ //# sourceMappingURL=health-revision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-revision.js","sourceRoot":"","sources":["../../../src/tool-manager/catalog/health-revision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAC9C,IAAyC;IAEzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAElE,OAAO,KAAK,IAA4B,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,GAAG,CACD,yCAAyC,GAAG,CAAC,MAAM,iDAAiD,CACrG,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;YACF,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACrC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,IACE,OAAO,IAAI,CAAC,mBAAmB,KAAK,QAAQ;gBAC5C,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAC/B,CAAC;gBACD,GAAG,CAAC,2CAA2C,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;gBAC3E,OAAO,IAAI,CAAC,mBAAmB,CAAC;YAClC,CAAC;YACD,GAAG,CACD,sGAAsG,CACvG,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,6CAA8C,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3F,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -10,16 +10,20 @@
10
10
  *
11
11
  * Storage: $WORK_DIR/.ois/tool-catalog.json
12
12
  * {
13
- * schemaVersion: 1,
14
- * hubVersion: "1.0.0",
13
+ * schemaVersion: 2,
14
+ * toolSurfaceRevision: "a1b2c3d4e5f6a7b8",
15
15
  * fetchedAt: "2026-04-22T...Z",
16
16
  * catalog: [...]
17
17
  * }
18
18
  *
19
- * Invalidation: Hub-version mismatch only. No TTL — the catalog is
20
- * static between Hub deploys; TTL would add noise without correctness
21
- * value. Schema-version mismatch on read returns null (cache treated
22
- * as invalid; future schema evolution bumps CATALOG_SCHEMA_VERSION).
19
+ * Invalidation: tool-surface-revision mismatch (bug-114). The cache is
20
+ * keyed off a Hub-owned ETag (`/health` `toolSurfaceRevision`) that
21
+ * tracks the actual tool surface added/removed tools, description or
22
+ * schema changes rather than `hubVersion`, which was a hardcoded
23
+ * `"1.0.0"` literal that never changed (so the cache never invalidated).
24
+ * No TTL — the revision detects drift directly. Schema-version mismatch
25
+ * on read returns null (cache treated as invalid; schema evolution bumps
26
+ * CATALOG_SCHEMA_VERSION).
23
27
  *
24
28
  * Atomicity: writeCache uses tmp-file + rename so partial writes on
25
29
  * crash don't corrupt the cache. Parse errors on read also return
@@ -29,7 +33,10 @@
29
33
  * the primary flow):
30
34
  * - missing file: readCache returns null
31
35
  * - parse error: readCache returns null + logs
32
- * - schema-version mismatch: readCache returns null
36
+ * - schema-version mismatch: readCache returns null + logs +
37
+ * unlinks the stale file (bug-114
38
+ * fallback-gap hardening — forces clean
39
+ * rebuild on next bootstrap)
33
40
  * - $WORK_DIR readonly: writeCache logs + no-ops
34
41
  * - disk full: writeCache logs + no-ops
35
42
  */
@@ -37,8 +44,14 @@
37
44
  * Bumping CATALOG_SCHEMA_VERSION forces all existing cache files to
38
45
  * be treated as invalid + re-bootstrapped. Use when changing the
39
46
  * cache file shape.
47
+ *
48
+ * 1 → 2 (bug-114): `hubVersion` field replaced by `toolSurfaceRevision`.
49
+ * The bump is the state-migration step — every on-disk cache written in
50
+ * the v1 (`hubVersion`) shape fails the read-time schema check, returns
51
+ * null, and re-bootstraps. Free retroactive cleanup of the whole fleet's
52
+ * stale caches.
40
53
  */
41
- export declare const CATALOG_SCHEMA_VERSION = 1;
54
+ export declare const CATALOG_SCHEMA_VERSION = 2;
42
55
  /**
43
56
  * MCP tool catalog entry shape. Kept loose (`unknown[]`) since the
44
57
  * cache is opaque storage; the dispatcher hands the catalog back to
@@ -47,7 +60,12 @@ export declare const CATALOG_SCHEMA_VERSION = 1;
47
60
  export type ToolCatalog = unknown[];
48
61
  export interface CachedCatalog {
49
62
  schemaVersion: number;
50
- hubVersion: string;
63
+ /**
64
+ * bug-114 — the Hub-owned tool-surface ETag seen at fetch-time
65
+ * (`/health` `toolSurfaceRevision`). The cache is valid while this
66
+ * matches the live revision; treated as opaque (record-then-compare).
67
+ */
68
+ toolSurfaceRevision: string;
51
69
  fetchedAt: string;
52
70
  catalog: ToolCatalog;
53
71
  }
@@ -66,20 +84,22 @@ export declare function readCache(workDir: string, log?: (msg: string) => void):
66
84
  * intact OR the new cache fully landed. Best-effort: failures log
67
85
  * and return; the caller's primary flow continues.
68
86
  */
69
- export declare function writeCache(workDir: string, catalog: ToolCatalog, hubVersion: string, log?: (msg: string) => void): void;
87
+ export declare function writeCache(workDir: string, catalog: ToolCatalog, toolSurfaceRevision: string, log?: (msg: string) => void): void;
70
88
  /**
71
- * Check cache validity against the current Hub version.
89
+ * Check cache validity against the current Hub tool-surface revision.
72
90
  *
73
91
  * Two semantics:
74
- * - currentHubVersion is a non-empty string: strict equality vs
75
- * cached.hubVersion. Mismatch → invalid → caller re-bootstraps.
76
- * - currentHubVersion is null/undefined/empty: caller doesn't know
77
- * the current Hub version yet (e.g. /health fetch in flight at
78
- * startup). Trust the cache (probe-friendly default) worst
79
- * case is serving a stale catalog ONCE until the next /health
80
- * fetch completes and a real session refreshes the cache.
92
+ * - currentRevision is a non-empty string: strict equality vs
93
+ * cached.toolSurfaceRevision. Mismatch → invalid → caller
94
+ * re-bootstraps.
95
+ * - currentRevision is null/undefined/empty: caller doesn't know the
96
+ * current revision yet (e.g. /health fetch in flight at startup, or
97
+ * an old Hub that doesn't return the field). Trust the cache
98
+ * (probe-friendly default) worst case is serving a stale catalog
99
+ * ONCE until the next /health fetch completes and a real session
100
+ * refreshes the cache.
81
101
  *
82
102
  * Schema-version check is enforced inside readCache, so isCacheValid
83
103
  * never sees a wrong-schema cached object.
84
104
  */
85
- export declare function isCacheValid(cached: CachedCatalog, currentHubVersion: string | null | undefined): boolean;
105
+ export declare function isCacheValid(cached: CachedCatalog, currentRevision: string | null | undefined): boolean;
@@ -10,16 +10,20 @@
10
10
  *
11
11
  * Storage: $WORK_DIR/.ois/tool-catalog.json
12
12
  * {
13
- * schemaVersion: 1,
14
- * hubVersion: "1.0.0",
13
+ * schemaVersion: 2,
14
+ * toolSurfaceRevision: "a1b2c3d4e5f6a7b8",
15
15
  * fetchedAt: "2026-04-22T...Z",
16
16
  * catalog: [...]
17
17
  * }
18
18
  *
19
- * Invalidation: Hub-version mismatch only. No TTL — the catalog is
20
- * static between Hub deploys; TTL would add noise without correctness
21
- * value. Schema-version mismatch on read returns null (cache treated
22
- * as invalid; future schema evolution bumps CATALOG_SCHEMA_VERSION).
19
+ * Invalidation: tool-surface-revision mismatch (bug-114). The cache is
20
+ * keyed off a Hub-owned ETag (`/health` `toolSurfaceRevision`) that
21
+ * tracks the actual tool surface added/removed tools, description or
22
+ * schema changes rather than `hubVersion`, which was a hardcoded
23
+ * `"1.0.0"` literal that never changed (so the cache never invalidated).
24
+ * No TTL — the revision detects drift directly. Schema-version mismatch
25
+ * on read returns null (cache treated as invalid; schema evolution bumps
26
+ * CATALOG_SCHEMA_VERSION).
23
27
  *
24
28
  * Atomicity: writeCache uses tmp-file + rename so partial writes on
25
29
  * crash don't corrupt the cache. Parse errors on read also return
@@ -29,7 +33,10 @@
29
33
  * the primary flow):
30
34
  * - missing file: readCache returns null
31
35
  * - parse error: readCache returns null + logs
32
- * - schema-version mismatch: readCache returns null
36
+ * - schema-version mismatch: readCache returns null + logs +
37
+ * unlinks the stale file (bug-114
38
+ * fallback-gap hardening — forces clean
39
+ * rebuild on next bootstrap)
33
40
  * - $WORK_DIR readonly: writeCache logs + no-ops
34
41
  * - disk full: writeCache logs + no-ops
35
42
  */
@@ -39,8 +46,14 @@ import { join, dirname } from "node:path";
39
46
  * Bumping CATALOG_SCHEMA_VERSION forces all existing cache files to
40
47
  * be treated as invalid + re-bootstrapped. Use when changing the
41
48
  * cache file shape.
49
+ *
50
+ * 1 → 2 (bug-114): `hubVersion` field replaced by `toolSurfaceRevision`.
51
+ * The bump is the state-migration step — every on-disk cache written in
52
+ * the v1 (`hubVersion`) shape fails the read-time schema check, returns
53
+ * null, and re-bootstraps. Free retroactive cleanup of the whole fleet's
54
+ * stale caches.
42
55
  */
43
- export const CATALOG_SCHEMA_VERSION = 1;
56
+ export const CATALOG_SCHEMA_VERSION = 2;
44
57
  /** Compute the canonical cache path for a given WORK_DIR. */
45
58
  export function cachePathFor(workDir) {
46
59
  return join(workDir, ".ois", "tool-catalog.json");
@@ -60,15 +73,27 @@ export function readCache(workDir, log) {
60
73
  const parsed = JSON.parse(raw);
61
74
  if (typeof parsed.schemaVersion !== "number" ||
62
75
  parsed.schemaVersion !== CATALOG_SCHEMA_VERSION ||
63
- typeof parsed.hubVersion !== "string" ||
76
+ typeof parsed.toolSurfaceRevision !== "string" ||
64
77
  typeof parsed.fetchedAt !== "string" ||
65
78
  !Array.isArray(parsed.catalog)) {
66
- log?.(`[tool-catalog-cache] readCache: cache invalid (schema/shape mismatch) at ${path}`);
79
+ log?.(`[tool-catalog-cache] readCache: cache invalid (schema/shape mismatch) at ${path} — unlinking to force clean rebuild`);
80
+ // bug-114 fallback-gap hardening (2026-05-26): unlink the stale
81
+ // file so the next bootstrap doesn't repeatedly read-then-discard
82
+ // it. Without this, every cold-start after a
83
+ // CATALOG_SCHEMA_VERSION bump re-encounters the same stale file
84
+ // until operator intervention. Best-effort; primary flow tolerates
85
+ // unlink failures.
86
+ try {
87
+ unlinkSync(path);
88
+ }
89
+ catch (unlinkErr) {
90
+ log?.(`[tool-catalog-cache] readCache: unlink failed (non-fatal): ${unlinkErr.message ?? unlinkErr}`);
91
+ }
67
92
  return null;
68
93
  }
69
94
  return {
70
95
  schemaVersion: parsed.schemaVersion,
71
- hubVersion: parsed.hubVersion,
96
+ toolSurfaceRevision: parsed.toolSurfaceRevision,
72
97
  fetchedAt: parsed.fetchedAt,
73
98
  catalog: parsed.catalog,
74
99
  };
@@ -84,12 +109,12 @@ export function readCache(workDir, log) {
84
109
  * intact OR the new cache fully landed. Best-effort: failures log
85
110
  * and return; the caller's primary flow continues.
86
111
  */
87
- export function writeCache(workDir, catalog, hubVersion, log) {
112
+ export function writeCache(workDir, catalog, toolSurfaceRevision, log) {
88
113
  const path = cachePathFor(workDir);
89
114
  const tmpPath = `${path}.tmp.${process.pid}`;
90
115
  const body = {
91
116
  schemaVersion: CATALOG_SCHEMA_VERSION,
92
- hubVersion,
117
+ toolSurfaceRevision,
93
118
  fetchedAt: new Date().toISOString(),
94
119
  catalog,
95
120
  };
@@ -112,26 +137,28 @@ export function writeCache(workDir, catalog, hubVersion, log) {
112
137
  }
113
138
  }
114
139
  /**
115
- * Check cache validity against the current Hub version.
140
+ * Check cache validity against the current Hub tool-surface revision.
116
141
  *
117
142
  * Two semantics:
118
- * - currentHubVersion is a non-empty string: strict equality vs
119
- * cached.hubVersion. Mismatch → invalid → caller re-bootstraps.
120
- * - currentHubVersion is null/undefined/empty: caller doesn't know
121
- * the current Hub version yet (e.g. /health fetch in flight at
122
- * startup). Trust the cache (probe-friendly default) worst
123
- * case is serving a stale catalog ONCE until the next /health
124
- * fetch completes and a real session refreshes the cache.
143
+ * - currentRevision is a non-empty string: strict equality vs
144
+ * cached.toolSurfaceRevision. Mismatch → invalid → caller
145
+ * re-bootstraps.
146
+ * - currentRevision is null/undefined/empty: caller doesn't know the
147
+ * current revision yet (e.g. /health fetch in flight at startup, or
148
+ * an old Hub that doesn't return the field). Trust the cache
149
+ * (probe-friendly default) worst case is serving a stale catalog
150
+ * ONCE until the next /health fetch completes and a real session
151
+ * refreshes the cache.
125
152
  *
126
153
  * Schema-version check is enforced inside readCache, so isCacheValid
127
154
  * never sees a wrong-schema cached object.
128
155
  */
129
- export function isCacheValid(cached, currentHubVersion) {
130
- if (currentHubVersion === null ||
131
- currentHubVersion === undefined ||
132
- currentHubVersion === "") {
156
+ export function isCacheValid(cached, currentRevision) {
157
+ if (currentRevision === null ||
158
+ currentRevision === undefined ||
159
+ currentRevision === "") {
133
160
  return true;
134
161
  }
135
- return cached.hubVersion === currentHubVersion;
162
+ return cached.toolSurfaceRevision === currentRevision;
136
163
  }
137
164
  //# sourceMappingURL=tool-catalog-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-catalog-cache.js","sourceRoot":"","sources":["../../../src/tool-manager/catalog/tool-catalog-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * tool-surface-reconciler.ts — declared-vs-applied reconcile for the Hub
3
+ * MCP tool surface (bug-180 / FR-21).
4
+ *
5
+ * Problem this closes: the host (e.g. Claude Code) enumerates `tools/list`
6
+ * ONCE at startup. On the pre-identity probe path the dispatcher serves the
7
+ * persisted on-disk catalog (tool-catalog-cache). When a Hub redeploy changes
8
+ * the tool surface, the in-memory catalog the host holds goes stale and
9
+ * nothing re-enumerates it — neither a client hard-reset nor /reload-plugins,
10
+ * because the long-lived proxy process never re-fetches and the redeploy emits
11
+ * no in-life `notifications/tools/list_changed` to already-connected hosts.
12
+ *
13
+ * The fix treats tool-surface delivery as a reconcile, mirroring the storage
14
+ * substrate's SchemaDef-reconciler:
15
+ * - desired-state = the Hub's tool surface, versioned by `toolSurfaceRevision`
16
+ * (a deterministic hash of the registered tool set, served
17
+ * on /health; Hub-side since bug-114).
18
+ * - applied-state = the revision the host most recently enumerated.
19
+ * - watch/notify = MCP `notifications/tools/list_changed` (the Hub already
20
+ * advertises `tools.listChanged: true`).
21
+ *
22
+ * On drift between applied and desired, emit `list_changed`; the host re-calls
23
+ * `tools/list` and — identity now resolved — the dispatcher serves the live
24
+ * surface (it skips the probe-cache path once identityReady is true).
25
+ *
26
+ * This class owns ONLY the reconcile decision + the applied-revision marker.
27
+ * All I/O is injected so it is unit-testable without a live Hub:
28
+ * - fetchLiveRevision: resolve the Hub's current /health `toolSurfaceRevision`
29
+ * (null on fetch failure / a Hub that doesn't return the field).
30
+ * - readServedRevision: the revision the host's startup enumeration was
31
+ * served from — the on-disk cache's `toolSurfaceRevision` (null when no
32
+ * cache exists, i.e. a fresh install that bootstrapped live).
33
+ * - emitListChanged: emit `notifications/tools/list_changed` to the host.
34
+ *
35
+ * Two trigger points share one `reconcile()`:
36
+ * - L1 (primary): on the shim's `identityReady` event — catches the
37
+ * redeploy-then-reconnect case that caused bug-180.
38
+ * - L2 (backstop): on the existing PollBackstop heartbeat cadence — catches
39
+ * a redeploy WHILE a session stays connected (no reconnect, so no fresh
40
+ * identityReady).
41
+ *
42
+ * The applied-revision baseline is established on the first successful
43
+ * reconcile (whichever trigger fires first), seeded from the on-disk cache so
44
+ * a stale-cache-vs-live delta is detected even if L2 races ahead of L1.
45
+ */
46
+ export interface ToolSurfaceReconcilerDeps {
47
+ /**
48
+ * Resolve the Hub's live tool-surface revision (the /health
49
+ * `toolSurfaceRevision` ETag). Returns null when the fetch fails or the Hub
50
+ * doesn't return the field — the reconcile then no-ops (fail-safe: never
51
+ * emit a spurious `list_changed` on an unknown live state).
52
+ */
53
+ fetchLiveRevision: () => Promise<string | null>;
54
+ /**
55
+ * The revision the host's current tool view was enumerated from — the
56
+ * on-disk cache's `toolSurfaceRevision`. Used to seed the applied-state
57
+ * baseline on the first reconcile (the pre-identity probe served this).
58
+ * null when no cache exists (fresh install bootstrapped live → no drift).
59
+ */
60
+ readServedRevision: () => string | null;
61
+ /** Emit `notifications/tools/list_changed` to the host. */
62
+ emitListChanged: () => void;
63
+ /** Diagnostic logger. No-op default. */
64
+ log?: (msg: string) => void;
65
+ }
66
+ export interface ReconcileOutcome {
67
+ /** True iff a drift was detected and `list_changed` was emitted this pass. */
68
+ emitted: boolean;
69
+ /** The live revision resolved this pass (null on fetch failure). */
70
+ live: string | null;
71
+ }
72
+ export declare class ToolSurfaceReconciler {
73
+ private readonly deps;
74
+ /**
75
+ * The revision the host is believed to currently have applied. null until
76
+ * the first successful reconcile establishes the baseline.
77
+ */
78
+ private appliedRevision;
79
+ private readonly log;
80
+ constructor(deps: ToolSurfaceReconcilerDeps);
81
+ /** Test/diagnostic accessor for the current applied-state marker. */
82
+ getAppliedRevision(): string | null;
83
+ /**
84
+ * One reconcile pass. Idempotent and safe to call from either trigger:
85
+ * 1. Resolve the live revision; no-op on unknown (fetch failed).
86
+ * 2. On first pass, seed the applied baseline from the on-disk cache
87
+ * (what the host's startup probe served) — or from live if no cache.
88
+ * 3. On applied-vs-live drift, emit `list_changed` + advance the baseline.
89
+ *
90
+ * @param reason short label for logs (e.g. "identityReady", "heartbeat").
91
+ */
92
+ reconcile(reason?: string): Promise<ReconcileOutcome>;
93
+ }