@mycadet/assistant 0.12.9 → 0.12.10

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 (651) hide show
  1. package/Dockerfile +0 -8
  2. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +1 -1
  3. package/openapi.yaml +62 -910
  4. package/package.json +3 -7
  5. package/scripts/build-test-fixtures.ts +1 -1
  6. package/scripts/generate-openapi.ts +22 -6
  7. package/scripts/postinstall.ts +4 -10
  8. package/scripts/run-tests.ts +0 -21
  9. package/src/__tests__/adaptive-thinking-repair.test.ts +19 -57
  10. package/src/__tests__/agent-loop.test.ts +0 -76
  11. package/src/__tests__/anthropic-provider.test.ts +6 -6
  12. package/src/__tests__/assert-not-live-db.ts +1 -1
  13. package/src/__tests__/assistant-id-boundary-guard.test.ts +3 -3
  14. package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
  15. package/src/__tests__/attachments-store.test.ts +1 -1
  16. package/src/__tests__/audit-log-rotation.test.ts +1 -1
  17. package/src/__tests__/btw-routes.test.ts +1 -1
  18. package/src/__tests__/byok-default-profile-ensure.test.ts +21 -27
  19. package/src/__tests__/call-conversation-messages.test.ts +0 -5
  20. package/src/__tests__/call-recovery.test.ts +2 -7
  21. package/src/__tests__/call-routes-http.test.ts +0 -12
  22. package/src/__tests__/call-store.test.ts +2 -7
  23. package/src/__tests__/catalog-files.test.ts +7 -5
  24. package/src/__tests__/checker.test.ts +1 -1
  25. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +4 -4
  26. package/src/__tests__/cloud-client-verify-credential.test.ts +0 -4
  27. package/src/__tests__/cloud-credential-catalog-cli.test.ts +14 -14
  28. package/src/__tests__/cloud-profile-guard.test.ts +48 -401
  29. package/src/__tests__/compaction-events.test.ts +2 -2
  30. package/src/__tests__/config-loader-backfill.test.ts +74 -163
  31. package/src/__tests__/config-loader-cloud-defaults.test.ts +11 -11
  32. package/src/__tests__/config-loader-corrupt.test.ts +10 -10
  33. package/src/__tests__/config-loader-quarantine-notice.test.ts +7 -7
  34. package/src/__tests__/config-loader-validation-reset-notice.test.ts +11 -11
  35. package/src/__tests__/config-schema.test.ts +26 -27
  36. package/src/__tests__/config-set-route.test.ts +2 -6
  37. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +28 -300
  38. package/src/__tests__/conversation-agent-loop-overflow.test.ts +39 -246
  39. package/src/__tests__/conversation-agent-loop.test.ts +2 -58
  40. package/src/__tests__/conversation-clear-safety.test.ts +0 -30
  41. package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
  42. package/src/__tests__/conversation-queue.test.ts +1 -1
  43. package/src/__tests__/conversation-runtime-assembly.test.ts +1 -1
  44. package/src/__tests__/conversation-skill-tools.test.ts +4 -444
  45. package/src/__tests__/conversation-slash-commands.test.ts +1 -1
  46. package/src/__tests__/conversation-store.test.ts +1 -84
  47. package/src/__tests__/conversation-surface-state.test.ts +0 -16
  48. package/src/__tests__/credential-health-service.test.ts +14 -1
  49. package/src/__tests__/credential-record-retire.test.ts +1 -1
  50. package/src/__tests__/credential-record-write-through.test.ts +1 -1
  51. package/src/__tests__/credential-security-invariants.test.ts +0 -145
  52. package/src/__tests__/custom-profile-ensure.test.ts +1 -1
  53. package/src/__tests__/default-profile-catalog-fallback.test.ts +5 -15
  54. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -2
  55. package/src/__tests__/dictation-profile-store.test.ts +6 -6
  56. package/src/__tests__/disk-usage.test.ts +28 -164
  57. package/src/__tests__/docker-signing-key-bootstrap.test.ts +1 -1
  58. package/src/__tests__/embedding-cloud-proxy-selection.test.ts +1 -1
  59. package/src/__tests__/emit-event-signal.test.ts +1 -1
  60. package/src/__tests__/gateway-client-cloud-outbound.test.ts +3 -3
  61. package/src/__tests__/gateway-only-enforcement.test.ts +1 -1
  62. package/src/__tests__/guardian-dispatch.test.ts +0 -13
  63. package/src/__tests__/helpers/seed-app.ts +1 -1
  64. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -1
  65. package/src/__tests__/host-shell-tool.test.ts +1 -1
  66. package/src/__tests__/identity-routes.test.ts +1 -1
  67. package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
  68. package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
  69. package/src/__tests__/injector-chain.test.ts +1 -1
  70. package/src/__tests__/injector-config-quarantine-notice.test.ts +1 -1
  71. package/src/__tests__/injector-config-validation-reset-notice.test.ts +1 -1
  72. package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
  73. package/src/__tests__/{platform.test.ts → layout.test.ts} +1 -1
  74. package/src/__tests__/list-all-apps.test.ts +1 -1
  75. package/src/__tests__/live-workspace-guard.test.ts +2 -2
  76. package/src/__tests__/llm-resolver-override-or-default.test.ts +5 -6
  77. package/src/__tests__/llm-resolver.test.ts +7 -7
  78. package/src/__tests__/llm-schema-fallback-profile.test.ts +9 -10
  79. package/src/__tests__/llm-usage-store.test.ts +0 -495
  80. package/src/__tests__/log-export-routes.test.ts +1 -1
  81. package/src/__tests__/mcp-config-secret-boundary.test.ts +12 -53
  82. package/src/__tests__/mcp-list-plugin-servers.test.ts +1 -1
  83. package/src/__tests__/memory-config-file-parity.test.ts +1 -1
  84. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  85. package/src/__tests__/messages-read-boundary-guard.test.ts +0 -2
  86. package/src/__tests__/notification-guardian-path.test.ts +0 -7
  87. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  88. package/src/__tests__/openai-provider.test.ts +8 -8
  89. package/src/__tests__/path-policy.test.ts +1 -1
  90. package/src/__tests__/persona-resolver.test.ts +1 -1
  91. package/src/__tests__/plugin-app-serve-routes.test.ts +1 -1
  92. package/src/__tests__/plugin-effective-enabled-set.test.ts +1 -1
  93. package/src/__tests__/plugin-import-boundary-guard.test.ts +4 -6
  94. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -3
  95. package/src/__tests__/provider-cloud-proxy-integration.test.ts +1 -5
  96. package/src/__tests__/provider-connections-backfill.test.ts +10 -10
  97. package/src/__tests__/prune-old-conversations-job.test.ts +6 -31
  98. package/src/__tests__/resolve-app.test.ts +1 -1
  99. package/src/__tests__/run-due-schedules.test.ts +1 -1
  100. package/src/__tests__/scaffold-managed-skill-tool.test.ts +0 -53
  101. package/src/__tests__/schedule-routes.test.ts +1 -1
  102. package/src/__tests__/schedule-store.test.ts +1 -1
  103. package/src/__tests__/secret-routes-cloud-proxy.test.ts +1 -1
  104. package/src/__tests__/skill-load-plugin-scope.test.ts +1 -1
  105. package/src/__tests__/surface-completion-compaction-boundary.test.ts +1 -1
  106. package/src/__tests__/tool-approval-handler.test.ts +1 -1
  107. package/src/__tests__/tool-audit.test.ts +5 -235
  108. package/src/__tests__/tool-executor-lifecycle-events.test.ts +54 -114
  109. package/src/__tests__/tools-get-route.test.ts +1 -1
  110. package/src/__tests__/turn-outcome-read.test.ts +1 -1
  111. package/src/__tests__/twilio-routes.test.ts +0 -1
  112. package/src/__tests__/usage-attribution.test.ts +0 -31
  113. package/src/__tests__/verification-control-plane-policy.test.ts +3 -10
  114. package/src/__tests__/visible-app-context.test.ts +1 -1
  115. package/src/__tests__/voice-ingress-preflight.test.ts +1 -1
  116. package/src/__tests__/workspace-git-service.test.ts +1 -1
  117. package/src/__tests__/workspace-greetings.test.ts +1 -1
  118. package/src/acp/__tests__/helpers/acp-config-stub.ts +1 -1
  119. package/src/activation/progress-store.ts +1 -1
  120. package/src/activation/turn-hooks.ts +1 -1
  121. package/src/agent/loop.ts +0 -51
  122. package/src/apps/app-store.ts +1 -1
  123. package/src/avatar/__tests__/avatar-store.test.ts +2 -172
  124. package/src/avatar/accent-backfill.ts +1 -1
  125. package/src/avatar/avatar-manifest.ts +1 -1
  126. package/src/avatar/avatar-store.ts +10 -69
  127. package/src/avatar/ensure-raster.ts +1 -1
  128. package/src/avatar/identity-avatar.ts +1 -1
  129. package/src/avatar/sync-avatar.ts +1 -1
  130. package/src/avatar/traits-png-sync.ts +1 -1
  131. package/src/bundler/compiler-tools.ts +1 -1
  132. package/src/bundler/package-resolver.ts +1 -1
  133. package/src/calls/__tests__/call-controller.test.ts +25 -27
  134. package/src/calls/active-call-lease.ts +1 -1
  135. package/src/calls/call-controller.ts +3 -3
  136. package/src/calls/call-domain.ts +4 -8
  137. package/src/calls/call-store.ts +2 -76
  138. package/src/calls/resolve-call-tts-provider.ts +3 -3
  139. package/src/calls/twilio-config.ts +3 -3
  140. package/src/calls/twilio-rest.ts +2 -2
  141. package/src/calls/voice-ingress-preflight.ts +2 -2
  142. package/src/cli/bundled-modules.ts +0 -2
  143. package/src/cli/commands/__tests__/apps.test.ts +1 -1
  144. package/src/cli/commands/__tests__/plugins.test.ts +9 -66
  145. package/src/cli/commands/__tests__/ps.test.ts +67 -0
  146. package/src/cli/commands/auth.help.ts +2 -2
  147. package/src/cli/commands/avatar.ts +1 -1
  148. package/src/cli/commands/changelog.ts +1 -1
  149. package/src/cli/commands/cloud/__tests__/subscription.test.ts +2 -2
  150. package/src/cli/commands/cloud/index.help.ts +1 -1
  151. package/src/cli/commands/cloud/index.ts +2 -2
  152. package/src/cli/commands/db/refresh.ts +1 -1
  153. package/src/cli/commands/db/repair-step-conversation-backfill.ts +1 -1
  154. package/src/cli/commands/db/repair.ts +1 -1
  155. package/src/cli/commands/db/status.ts +1 -1
  156. package/src/cli/commands/inference-profiles.ts +1 -12
  157. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +1 -116
  158. package/src/cli/commands/memory/index.help.ts +1 -43
  159. package/src/cli/commands/memory/memory-v3.ts +0 -64
  160. package/src/cli/commands/plugins.ts +54 -205
  161. package/src/cli/commands/ps.ts +5 -2
  162. package/src/cli/commands/status.ts +1 -1
  163. package/src/cli/index.help.ts +0 -2
  164. package/src/cli/lib/__tests__/inspect-plugin.test.ts +36 -66
  165. package/src/cli/lib/__tests__/install-from-cloud.test.ts +1 -1
  166. package/src/cli/lib/__tests__/install-from-github.test.ts +41 -117
  167. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +2 -185
  168. package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +36 -66
  169. package/src/cli/lib/__tests__/plugin-catalog-visibility.test.ts +4 -6
  170. package/src/cli/lib/__tests__/plugin-details.test.ts +113 -96
  171. package/src/cli/lib/__tests__/search-plugins.test.ts +9 -16
  172. package/src/cli/lib/__tests__/uninstall-plugin.test.ts +1 -1
  173. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +38 -15
  174. package/src/cli/lib/diff-plugin.ts +1 -1
  175. package/src/cli/lib/inspect-plugin.ts +13 -97
  176. package/src/cli/lib/install-from-cloud.ts +1 -1
  177. package/src/cli/lib/install-from-github.ts +75 -154
  178. package/src/cli/lib/install-plugin-dependencies.ts +1 -1
  179. package/src/cli/lib/list-installed-plugins.ts +1 -1
  180. package/src/cli/lib/open-browser.ts +1 -1
  181. package/src/cli/lib/plugin-catalog-cache.ts +8 -51
  182. package/src/cli/lib/plugin-catalog-resolve.ts +3 -22
  183. package/src/cli/lib/plugin-details.ts +5 -27
  184. package/src/cli/lib/plugin-marketplace.ts +18 -266
  185. package/src/cli/lib/search-plugins.ts +23 -43
  186. package/src/cli/lib/toggle-plugin.ts +1 -1
  187. package/src/cli/lib/uninstall-plugin.ts +1 -1
  188. package/src/cli/lib/upgrade-plugin.ts +3 -49
  189. package/src/cli/program.ts +1 -3
  190. package/src/cli.ts +1 -1
  191. package/src/cloud/client.ts +0 -6
  192. package/src/cloud/consent-cache.test.ts +22 -201
  193. package/src/cloud/consent-cache.ts +16 -111
  194. package/src/cloud/sync-identity.ts +1 -1
  195. package/src/config/__tests__/chat-settings.test.ts +1 -1
  196. package/src/config/__tests__/cloud-identity.test.ts +15 -2
  197. package/src/config/__tests__/default-plugin-skill-discovery.test.ts +1 -1
  198. package/src/config/__tests__/default-profile-catalog.test.ts +12 -51
  199. package/src/config/__tests__/deployment-context-defaults.test.ts +13 -13
  200. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +4 -4
  201. package/src/config/__tests__/loader-last-known-good.test.ts +9 -9
  202. package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +7 -7
  203. package/src/config/__tests__/plugin-resident-skill-discovery.test.ts +1 -1
  204. package/src/config/__tests__/profile-materialization.test.ts +2 -4
  205. package/src/config/__tests__/sync-gated-profiles.test.ts +1 -106
  206. package/src/config/acp-agent-write.ts +1 -1
  207. package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +1 -1
  208. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
  209. package/src/config/call-site-defaults.ts +0 -6
  210. package/src/config/cloud-identity.ts +12 -5
  211. package/src/config/composer-preferences.ts +1 -1
  212. package/src/config/default-profile-catalog.ts +8 -75
  213. package/src/config/default-profile-names.ts +2 -25
  214. package/src/config/env-registry.ts +1 -14
  215. package/src/config/env.ts +8 -6
  216. package/src/config/llm-resolver.ts +1 -2
  217. package/src/config/loader.ts +13 -17
  218. package/src/config/profile-materialization.ts +1 -1
  219. package/src/config/schema.ts +1 -7
  220. package/src/config/schemas/call-site-catalog.ts +0 -7
  221. package/src/config/schemas/llm.ts +22 -27
  222. package/src/config/seed-inference-profiles.ts +16 -17
  223. package/src/config/skills.ts +2 -2
  224. package/src/config/sync-gated-profiles.ts +6 -24
  225. package/src/credential-health/credential-health-service.ts +10 -3
  226. package/src/daemon/approval-generators.ts +3 -3
  227. package/src/daemon/config-watcher.ts +2 -2
  228. package/src/daemon/conversation-agent-loop-handlers.ts +0 -18
  229. package/src/daemon/conversation-agent-loop.ts +6 -97
  230. package/src/daemon/conversation-process.ts +1 -1
  231. package/src/daemon/conversation-skill-tools.ts +4 -72
  232. package/src/daemon/conversation-store.ts +1 -1
  233. package/src/daemon/conversation-surface-state.ts +0 -33
  234. package/src/daemon/conversation-surfaces.ts +1 -86
  235. package/src/daemon/conversation-tool-setup.test.ts +1 -1
  236. package/src/daemon/conversation-tool-setup.ts +0 -23
  237. package/src/daemon/conversation.ts +3 -5
  238. package/src/daemon/daemon-control.ts +3 -3
  239. package/src/daemon/dictation-profile-store.ts +3 -3
  240. package/src/daemon/event-loop-watchdog.test.ts +2 -198
  241. package/src/daemon/event-loop-watchdog.ts +0 -185
  242. package/src/daemon/external-plugins-bootstrap.ts +1 -1
  243. package/src/daemon/first-greeting.ts +1 -1
  244. package/src/daemon/handlers/skills.ts +1 -1
  245. package/src/daemon/host-app-control-proxy.ts +1 -1
  246. package/src/daemon/host-cu-proxy.ts +2 -2
  247. package/src/daemon/identity-helpers.ts +1 -1
  248. package/src/daemon/lifecycle.ts +11 -15
  249. package/src/daemon/main.ts +1 -1
  250. package/src/daemon/now-scratchpad.ts +1 -1
  251. package/src/daemon/process-message.ts +4 -4
  252. package/src/daemon/profiler-run-store.ts +2 -2
  253. package/src/daemon/providers-setup.ts +2 -2
  254. package/src/daemon/shutdown-handlers.ts +0 -10
  255. package/src/daemon/sqlite-corruption-watchdog.test.ts +2 -142
  256. package/src/daemon/sqlite-corruption-watchdog.ts +17 -81
  257. package/src/daemon/tool-side-effects.ts +1 -1
  258. package/src/desktop/desktop-session-manager.ts +1 -1
  259. package/src/desktop/desktop-wallpaper-renderer.ts +1 -1
  260. package/src/heartbeat/heartbeat-service.ts +1 -1
  261. package/src/home/feed-writer.ts +1 -1
  262. package/src/home/home-greeting-cache.ts +1 -1
  263. package/src/home/relationship-state-writer.ts +2 -2
  264. package/src/hooks/__tests__/hook-live-reload.test.ts +1 -1
  265. package/src/hooks/hook-loader.ts +2 -2
  266. package/src/inbound/__tests__/oauth-callback-url.test.ts +2 -2
  267. package/src/inbound/oauth-callback-url.ts +3 -3
  268. package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
  269. package/src/ipc/socket-path.ts +1 -1
  270. package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
  271. package/src/live-voice/__tests__/live-voice-vad.test.ts +1 -1
  272. package/src/live-voice/live-voice-session.ts +3 -66
  273. package/src/mcp/__tests__/effective-config.test.ts +1 -1
  274. package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +2 -2
  275. package/src/mcp/__tests__/mcp-oauth-provider.test.ts +2 -3
  276. package/src/mcp/__tests__/reload-signal-emission.test.ts +1 -1
  277. package/src/mcp/__tests__/reload-signal.test.ts +1 -1
  278. package/src/mcp/__tests__/workspace-mcp-config.test.ts +19 -21
  279. package/src/mcp/reload-signal.ts +1 -1
  280. package/src/mcp/workspace-mcp-config.ts +1 -23
  281. package/src/messaging/draft-store.ts +1 -1
  282. package/src/monitoring/__tests__/active-conversations.test.ts +1 -1
  283. package/src/monitoring/__tests__/page-cache.test.ts +1 -1
  284. package/src/monitoring/__tests__/stall-capture.test.ts +1 -1
  285. package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +1 -1
  286. package/src/monitoring/active-conversations.ts +1 -1
  287. package/src/monitoring/control.ts +1 -1
  288. package/src/monitoring/daemon-boot-time.ts +1 -1
  289. package/src/monitoring/daemon-heartbeat.ts +1 -1
  290. package/src/monitoring/page-cache.ts +1 -1
  291. package/src/monitoring/plugin-auto-update.ts +1 -7
  292. package/src/monitoring/plugin-source-watch.ts +1 -1
  293. package/src/monitoring/recovery/db.ts +1 -1
  294. package/src/monitoring/recovery/inflight-content.ts +1 -1
  295. package/src/monitoring/resource-sampler.ts +3 -14
  296. package/src/monitoring/stall-capture.ts +1 -1
  297. package/src/monitoring/worker.ts +9 -76
  298. package/src/monitoring/workspace-git-heartbeat.ts +1 -1
  299. package/src/oauth/connect-orchestrator.ts +4 -4
  300. package/src/permissions/checker.ts +1 -1
  301. package/src/permissions/workspace-policy.ts +1 -1
  302. package/src/persistence/__tests__/main-db-readonly-probe.ts +27 -52
  303. package/src/persistence/__tests__/message-content-file.test.ts +1 -1
  304. package/src/persistence/__tests__/slow-sync-log.test.ts +0 -2
  305. package/src/persistence/attachments-store.ts +1 -1
  306. package/src/persistence/conversation-crud.ts +1 -38
  307. package/src/persistence/conversation-directories.ts +1 -1
  308. package/src/persistence/conversation-types.ts +0 -8
  309. package/src/persistence/db-async-query.ts +1 -1
  310. package/src/persistence/db-connection.ts +11 -1
  311. package/src/persistence/db-init.ts +1 -1
  312. package/src/persistence/db-maintenance.ts +1 -1
  313. package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +1 -1
  314. package/src/persistence/embeddings/embedding-local.ts +4 -4
  315. package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -1
  316. package/src/persistence/embeddings/qdrant-client.ts +1 -1
  317. package/src/persistence/embeddings/qdrant-manager.ts +1 -1
  318. package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +1 -1
  319. package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +1 -1
  320. package/src/persistence/job-handlers/cleanup.ts +8 -17
  321. package/src/persistence/llm-usage-store.ts +2 -229
  322. package/src/persistence/message-content-file.ts +1 -1
  323. package/src/persistence/migrations/209-strip-thinking-from-consolidated.ts +1 -1
  324. package/src/persistence/migrations/222-strip-placeholder-sentinels-from-messages.ts +1 -1
  325. package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +1 -1
  326. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +1 -1
  327. package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.test.ts +13 -0
  328. package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.test.ts +13 -0
  329. package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.test.ts +13 -0
  330. package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.test.ts +13 -0
  331. package/src/persistence/migrations/333-create-telemetry-events-table.test.ts +7 -4
  332. package/src/persistence/migrations/334-backfill-telemetry-events-outbox.test.ts +13 -0
  333. package/src/persistence/migrations/387-drop-telemetry-tables.ts +51 -0
  334. package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +9 -1
  335. package/src/persistence/migrations/__tests__/387-drop-telemetry-tables.test.ts +79 -0
  336. package/src/persistence/migrations/helpers/relocation.ts +1 -1
  337. package/src/persistence/migrations/run-migrations.ts +1 -1
  338. package/src/persistence/migrations/validate-migration-state.ts +1 -1
  339. package/src/persistence/raw-query.ts +1 -29
  340. package/src/persistence/slow-sync-log.ts +0 -23
  341. package/src/persistence/steps.ts +2 -0
  342. package/src/{telemetry → persistence}/tool-audit.ts +6 -121
  343. package/src/plugin-api/index.ts +1 -1
  344. package/src/plugin-api/plugin-name-env.ts +1 -1
  345. package/src/plugins/__tests__/installed-plugin-dirs.test.ts +1 -1
  346. package/src/plugins/collect-source-versions.ts +1 -1
  347. package/src/plugins/defaults/channel/package.json +1 -1
  348. package/src/plugins/defaults/cloud-hosted/package.json +1 -1
  349. package/src/plugins/defaults/compaction/package.json +1 -1
  350. package/src/plugins/defaults/documents/package.json +1 -1
  351. package/src/plugins/defaults/empty-response/package.json +1 -1
  352. package/src/plugins/defaults/exploration-drift/package.json +1 -1
  353. package/src/plugins/defaults/image-fallback/package.json +1 -1
  354. package/src/plugins/defaults/image-recovery/package.json +1 -1
  355. package/src/plugins/defaults/max-tokens-continue/package.json +1 -1
  356. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +1 -1
  357. package/src/plugins/defaults/memory/__tests__/db-maintenance.test.ts +1 -1
  358. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +0 -82
  359. package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +0 -41
  360. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -2
  361. package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -52
  362. package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +0 -18
  363. package/src/plugins/defaults/memory/package.json +1 -1
  364. package/src/plugins/defaults/memory/paths.ts +4 -4
  365. package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +1 -1
  366. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +5 -5
  367. package/src/plugins/defaults/memory/src/memory-v3-routes.ts +0 -207
  368. package/src/plugins/defaults/memory/src/memory-worker-routes.ts +1 -1
  369. package/src/plugins/defaults/memory/startup.ts +1 -22
  370. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +2 -253
  371. package/src/plugins/defaults/memory/v3/orchestrate.ts +5 -129
  372. package/src/plugins/defaults/memory/worker-control.ts +1 -1
  373. package/src/plugins/defaults/memory/worker.ts +2 -2
  374. package/src/plugins/defaults/session/package.json +1 -1
  375. package/src/plugins/defaults/surface-completion-nudge/package.json +1 -1
  376. package/src/plugins/defaults/task-progress/package.json +1 -1
  377. package/src/plugins/defaults/task-progress-nudge/package.json +1 -1
  378. package/src/plugins/defaults/title-generate/package.json +1 -1
  379. package/src/plugins/defaults/tool-error/package.json +1 -1
  380. package/src/plugins/defaults/tool-result-truncate/package.json +1 -1
  381. package/src/plugins/defaults/turn-context/package.json +1 -1
  382. package/src/plugins/defaults/workspace/injectors.ts +1 -1
  383. package/src/plugins/defaults/workspace/package.json +1 -1
  384. package/src/plugins/disabled-state.ts +1 -1
  385. package/src/plugins/ensure-plugin-api-shim.ts +1 -1
  386. package/src/plugins/ensure-shared-dep-links.ts +1 -1
  387. package/src/plugins/installed-plugin-dirs.ts +1 -1
  388. package/src/plugins/mcp-servers.ts +7 -9
  389. package/src/plugins/mtime-cache.ts +2 -2
  390. package/src/plugins/source-versions.ts +1 -1
  391. package/src/prompts/bootstrap-cleanup.ts +1 -1
  392. package/src/prompts/persona-resolver.ts +1 -1
  393. package/src/prompts/sections.ts +2 -2
  394. package/src/prompts/system-prompt.ts +10 -42
  395. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +0 -37
  396. package/src/providers/__tests__/cadet-connection-routing.test.ts +2 -2
  397. package/src/providers/cadet/client.ts +1 -1
  398. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -1
  399. package/src/providers/inference/adapter-factory.ts +1 -1
  400. package/src/providers/inference/backfill.ts +3 -10
  401. package/src/providers/inference/profile-probe.ts +1 -1
  402. package/src/providers/retry.ts +0 -2
  403. package/src/providers/types.ts +0 -7
  404. package/src/providers/usage-tracking.ts +1 -1
  405. package/src/routes/__tests__/route-host.test.ts +1 -1
  406. package/src/routes/control.ts +1 -1
  407. package/src/routes/route-host-client.ts +1 -1
  408. package/src/routes/worker.ts +2 -2
  409. package/src/runtime/agent-wake.ts +1 -1
  410. package/src/runtime/assistant-stream-state.ts +1 -1
  411. package/src/runtime/auth/token-service.ts +1 -1
  412. package/src/runtime/background-job-runner.ts +1 -1
  413. package/src/runtime/middleware/twilio-validation.ts +2 -2
  414. package/src/runtime/routes/__tests__/app-pin-routes.test.ts +1 -1
  415. package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +1 -1
  416. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +3 -33
  417. package/src/runtime/routes/__tests__/cloud-credits-routes.test.ts +5 -4
  418. package/src/runtime/routes/__tests__/cloud-invoice-routes.test.ts +4 -3
  419. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +59 -287
  420. package/src/runtime/routes/__tests__/default-plugin-routes.test.ts +1 -1
  421. package/src/runtime/routes/__tests__/deprecated-route-context.test.ts +15 -62
  422. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +105 -12
  423. package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +1 -1
  424. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -1
  425. package/src/runtime/routes/__tests__/plugins-routes.test.ts +47 -211
  426. package/src/runtime/routes/__tests__/route-host-worker-routes.test.ts +1 -1
  427. package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +1 -1
  428. package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +1 -1
  429. package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +1 -1
  430. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +1 -1
  431. package/src/runtime/routes/__tests__/user-routes-cli.test.ts +1 -1
  432. package/src/runtime/routes/__tests__/user-routes-notices.test.ts +1 -1
  433. package/src/runtime/routes/__tests__/user-routes-request.test.ts +1 -1
  434. package/src/runtime/routes/app-management-routes.ts +1 -1
  435. package/src/runtime/routes/attachment-routes.ts +1 -1
  436. package/src/runtime/routes/audit-routes.ts +1 -1
  437. package/src/runtime/routes/avatar-routes.ts +3 -10
  438. package/src/runtime/routes/cloud-routes.ts +3 -3
  439. package/src/runtime/routes/content-source-routes.ts +1 -1
  440. package/src/runtime/routes/conversation-query-routes.ts +60 -621
  441. package/src/runtime/routes/conversation-routes.ts +1 -38
  442. package/src/runtime/routes/debug-routes.ts +1 -1
  443. package/src/runtime/routes/deprecated-route-context.ts +5 -61
  444. package/src/runtime/routes/heartbeat-routes.ts +1 -1
  445. package/src/runtime/routes/identity-routes.ts +1 -1
  446. package/src/runtime/routes/index.ts +0 -6
  447. package/src/runtime/routes/inference-profile-session-handler.ts +3 -3
  448. package/src/runtime/routes/inference-profiles-routes.ts +48 -21
  449. package/src/runtime/routes/inference-provider-connection-routes.ts +0 -1
  450. package/src/runtime/routes/llm-call-sites-routes.ts +3 -3
  451. package/src/runtime/routes/log-export/__tests__/installed-inventory.test.ts +1 -1
  452. package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +1 -1
  453. package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +1 -1
  454. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  455. package/src/runtime/routes/log-export-routes.ts +17 -15
  456. package/src/runtime/routes/migration-rollback-routes.ts +1 -1
  457. package/src/runtime/routes/migration-routes.ts +2 -3
  458. package/src/runtime/routes/monitoring-routes.ts +2 -2
  459. package/src/runtime/routes/oauth-providers.ts +5 -5
  460. package/src/runtime/routes/plugins-routes.ts +38 -163
  461. package/src/runtime/routes/profiler-routes.ts +1 -1
  462. package/src/runtime/routes/route-host-worker-routes.ts +1 -1
  463. package/src/runtime/routes/sanity-routes.ts +1 -1
  464. package/src/runtime/routes/schedule-routes.ts +1 -1
  465. package/src/runtime/routes/schedule-worker-routes.ts +1 -1
  466. package/src/runtime/routes/settings-routes.ts +1 -1
  467. package/src/runtime/routes/sounds-config-routes.ts +1 -1
  468. package/src/runtime/routes/surface-conversation-resolver.ts +1 -7
  469. package/src/runtime/routes/user-route-dispatcher.ts +1 -3
  470. package/src/runtime/routes/user-route-import.ts +1 -1
  471. package/src/runtime/routes/user-route-resolution.ts +1 -1
  472. package/src/runtime/routes/user-routes-cli.ts +1 -1
  473. package/src/runtime/routes/workspace-commit-routes.ts +1 -1
  474. package/src/runtime/routes/workspace-greetings.ts +1 -1
  475. package/src/runtime/routes/workspace-routes.ts +1 -1
  476. package/src/runtime/routes/workspace-utils.ts +1 -1
  477. package/src/runtime/sync/resource-sync-events.ts +1 -1
  478. package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +1 -1
  479. package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1 -1
  480. package/src/schedule/plugin-schedule-availability.ts +1 -1
  481. package/src/schedule/plugin-schedule-declarations.ts +1 -1
  482. package/src/schedule/run-script.ts +1 -1
  483. package/src/schedule/scheduler.ts +1 -11
  484. package/src/schedule/worker-control.ts +1 -1
  485. package/src/schedule/worker.ts +3 -3
  486. package/src/security/oauth2.ts +2 -2
  487. package/src/security/secret-allowlist.ts +1 -1
  488. package/src/signals/cancel.ts +1 -1
  489. package/src/signals/conversation-undo.ts +1 -1
  490. package/src/signals/emit-event.ts +1 -1
  491. package/src/signals/event-stream.ts +1 -1
  492. package/src/signals/user-message.ts +1 -1
  493. package/src/skills/catalog-install.ts +2 -1
  494. package/src/skills/clawhub.ts +1 -1
  495. package/src/skills/cloud-store.ts +1 -1
  496. package/src/skills/path-classifier.ts +1 -1
  497. package/src/skills/skill-history.ts +1 -1
  498. package/src/skills/skillssh-registry.ts +1 -1
  499. package/src/skills/uninstall.ts +1 -1
  500. package/src/skills/workspace-skill-md-signature.ts +1 -1
  501. package/src/subagent/manager.ts +1 -1
  502. package/src/theme/workspace-theme.ts +1 -1
  503. package/src/tools/browser/auth-cache.ts +1 -1
  504. package/src/tools/browser/browser-manager.ts +1 -1
  505. package/src/tools/browser/runtime-check.ts +1 -1
  506. package/src/tools/executor.ts +4 -4
  507. package/src/tools/filesystem/write.ts +1 -1
  508. package/src/tools/permission-checker.ts +2 -51
  509. package/src/tools/run-standalone.ts +1 -1
  510. package/src/tools/skills/format-input-schema.ts +1 -1
  511. package/src/tools/skills/load.ts +1 -1
  512. package/src/tools/skills/scaffold-cloud.ts +0 -32
  513. package/src/tools/terminal/safe-env.ts +1 -2
  514. package/src/tools/terminal/sanitized-bash.ts +1 -1
  515. package/src/tools/terminal/shell.ts +1 -1
  516. package/src/tools/tool-approval-handler.ts +4 -1
  517. package/src/tools/workflows/manage-workflows.ts +2 -2
  518. package/src/tools/workflows/run-workflow.test.ts +1 -1
  519. package/src/tools/workspace-tools/loader.ts +1 -1
  520. package/src/tts/synthesis-stream.ts +2 -2
  521. package/src/usage/attribution.ts +1 -11
  522. package/src/util/browser.ts +1 -1
  523. package/src/util/bun-runtime.ts +2 -1
  524. package/src/util/device-id.ts +1 -1
  525. package/src/util/disk-usage.ts +4 -139
  526. package/src/util/layout.ts +3 -3
  527. package/src/util/logger.ts +1 -1
  528. package/src/util/logs-db-path.ts +1 -1
  529. package/src/util/memory-db-path.ts +1 -1
  530. package/src/util/{platform.ts → os.ts} +5 -30
  531. package/src/util/process-tree.ts +19 -0
  532. package/src/util/sqlite3-runtime.ts +1 -1
  533. package/src/util/telemetry-db-path.ts +1 -1
  534. package/src/watcher/__tests__/engine.test.ts +0 -23
  535. package/src/watcher/engine.ts +0 -7
  536. package/src/windows-compiled-cli.ts +0 -4
  537. package/src/windows-compiled-worker-entry.ts +0 -6
  538. package/src/workflows/leaf-runner.test.ts +1 -1
  539. package/src/workflows/leaf-runner.ts +1 -1
  540. package/src/workflows/library.ts +1 -1
  541. package/src/workspace/adaptive-thinking-repair.ts +5 -24
  542. package/src/workspace/byok-default-profile-ensure.ts +24 -26
  543. package/src/workspace/custom-profile-ensure.ts +2 -2
  544. package/src/workspace/git-service.ts +1 -1
  545. package/src/workspace/hatched-date.ts +1 -1
  546. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +2 -2
  547. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +1 -1
  548. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +1 -1
  549. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +1 -1
  550. package/src/workspace/migrations/registry.ts +0 -4
  551. package/src/workspace/turn-commit.ts +1 -1
  552. package/docs/activation-funnel-telemetry.md +0 -324
  553. package/scripts/bundled-plugin-packages.ts +0 -154
  554. package/scripts/generate-bundled-plugin-packages.ts +0 -29
  555. package/src/__tests__/activation-early-marking.test.ts +0 -114
  556. package/src/__tests__/auth-fallback-events-store.test.ts +0 -99
  557. package/src/__tests__/config-get-vision-flag.test.ts +0 -139
  558. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +0 -400
  559. package/src/__tests__/internal-telemetry-routes.test.ts +0 -213
  560. package/src/__tests__/telemetry-routes.test.ts +0 -182
  561. package/src/__tests__/turn-events-store.test.ts +0 -376
  562. package/src/__tests__/ui-channel-variants.test.ts +0 -53
  563. package/src/avatar/__tests__/avatar-changed-telemetry.test.ts +0 -217
  564. package/src/avatar/avatar-changed-telemetry.ts +0 -128
  565. package/src/calls/__tests__/call-funnel-telemetry.test.ts +0 -204
  566. package/src/cli/commands/telemetry.help.ts +0 -27
  567. package/src/cli/commands/telemetry.ts +0 -83
  568. package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +0 -251
  569. package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +0 -113
  570. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +0 -384
  571. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +0 -164
  572. package/src/cli/lib/__tests__/plugins-install-offline.test.ts +0 -228
  573. package/src/cli/lib/bundled-marketplace.json +0 -1575
  574. package/src/cli/lib/bundled-plugin-packages.json +0 -827
  575. package/src/cli/lib/bundled-plugin-packages.ts +0 -87
  576. package/src/cli/lib/plugin-catalog-local.ts +0 -94
  577. package/src/cli/lib/plugin-pin-history.ts +0 -276
  578. package/src/cloud/feature-gate.ts +0 -8
  579. package/src/config/__tests__/cloud-rehydration.test.ts +0 -180
  580. package/src/config/cloud-rehydration.ts +0 -35
  581. package/src/daemon/__tests__/auto-profile-router.test.ts +0 -380
  582. package/src/daemon/auto-profile-router.ts +0 -428
  583. package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +0 -391
  584. package/src/monitoring/__tests__/db-integrity-sample.test.ts +0 -113
  585. package/src/monitoring/__tests__/oom-kill-reporter.test.ts +0 -374
  586. package/src/monitoring/db-integrity-check.ts +0 -163
  587. package/src/monitoring/db-integrity-sample.ts +0 -176
  588. package/src/monitoring/oom-kill-reporter.ts +0 -469
  589. package/src/onboarding/__tests__/onboarding-events-store.test.ts +0 -158
  590. package/src/onboarding/onboarding-events-store.ts +0 -296
  591. package/src/persistence/__tests__/raw-query-telemetry.test.ts +0 -76
  592. package/src/persistence/lifecycle-events-store.test.ts +0 -134
  593. package/src/persistence/lifecycle-events-store.ts +0 -110
  594. package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +0 -76
  595. package/src/plugins/defaults/memory/activation-session-store.ts +0 -50
  596. package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +0 -281
  597. package/src/runtime/routes/auto-profile-routes.ts +0 -83
  598. package/src/runtime/routes/internal-telemetry-routes.ts +0 -142
  599. package/src/runtime/routes/telemetry-routes.ts +0 -274
  600. package/src/security/auth-fallback-events-store.ts +0 -57
  601. package/src/telemetry/__tests__/activation-funnel.test.ts +0 -95
  602. package/src/telemetry/__tests__/config-setting-events-store.test.ts +0 -63
  603. package/src/telemetry/__tests__/config-setting-snapshot.test.ts +0 -143
  604. package/src/telemetry/__tests__/flush-checkpoints.test.ts +0 -56
  605. package/src/telemetry/__tests__/live-voice-funnel.test.ts +0 -174
  606. package/src/telemetry/__tests__/outbox-test-harness.ts +0 -85
  607. package/src/telemetry/__tests__/phone-call-funnel.test.ts +0 -72
  608. package/src/telemetry/__tests__/telemetry-event-fixtures.ts +0 -282
  609. package/src/telemetry/__tests__/watchdog-events-store.test.ts +0 -71
  610. package/src/telemetry/activation-funnel.ts +0 -172
  611. package/src/telemetry/config-setting-events-store.ts +0 -40
  612. package/src/telemetry/config-setting-snapshot.ts +0 -170
  613. package/src/telemetry/flush-checkpoints.ts +0 -70
  614. package/src/telemetry/live-voice-funnel.ts +0 -185
  615. package/src/telemetry/memory-corpus-size.test.ts +0 -120
  616. package/src/telemetry/memory-corpus-size.ts +0 -184
  617. package/src/telemetry/memory-tier-reporter.test.ts +0 -195
  618. package/src/telemetry/memory-tier-reporter.ts +0 -130
  619. package/src/telemetry/phone-call-funnel.ts +0 -144
  620. package/src/telemetry/skill-loaded-events-store.test.ts +0 -93
  621. package/src/telemetry/skill-loaded-events-store.ts +0 -39
  622. package/src/telemetry/telemetry-event-sources.test.ts +0 -223
  623. package/src/telemetry/telemetry-event-sources.ts +0 -597
  624. package/src/telemetry/telemetry-events-outbox.test.ts +0 -375
  625. package/src/telemetry/telemetry-events-outbox.ts +0 -237
  626. package/src/telemetry/telemetry-main-db.ts +0 -48
  627. package/src/telemetry/telemetry-wire-source.json +0 -4
  628. package/src/telemetry/telemetry-wire-validation.test.ts +0 -157
  629. package/src/telemetry/telemetry-wire-validation.ts +0 -162
  630. package/src/telemetry/telemetry-wire.generated.ts +0 -483
  631. package/src/telemetry/tool-executed-events-store.test.ts +0 -210
  632. package/src/telemetry/tool-executed-events-store.ts +0 -102
  633. package/src/telemetry/trace-collection-policy.test.ts +0 -28
  634. package/src/telemetry/trace-collection-policy.ts +0 -30
  635. package/src/telemetry/turn-events-store.ts +0 -216
  636. package/src/telemetry/turn-trace-store.test.ts +0 -884
  637. package/src/telemetry/turn-trace-store.ts +0 -399
  638. package/src/telemetry/types.test.ts +0 -38
  639. package/src/telemetry/types.ts +0 -780
  640. package/src/telemetry/usage-telemetry-reporter.test.ts +0 -3445
  641. package/src/telemetry/usage-telemetry-reporter.ts +0 -566
  642. package/src/telemetry/watchdog-direct-emit.test.ts +0 -112
  643. package/src/telemetry/watchdog-direct-emit.ts +0 -104
  644. package/src/telemetry/watchdog-events-store.ts +0 -31
  645. package/src/tools/ui-surface/channel-variants.ts +0 -52
  646. package/src/watcher/__tests__/telemetry.test.ts +0 -178
  647. package/src/watcher/telemetry.ts +0 -93
  648. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +0 -165
  649. package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +0 -151
  650. /package/src/{telemetry → persistence}/tool-usage-store.ts +0 -0
  651. /package/src/{telemetry → persistence}/turn-outcome.ts +0 -0
@@ -1,184 +0,0 @@
1
- import { readdirSync, readFileSync, statSync } from "node:fs";
2
- import { join } from "node:path";
3
-
4
- import { getWorkspaceDir } from "../util/platform.js";
5
-
6
- /**
7
- * Coarse on-disk size of the assistant's memory corpus, in the snake_case
8
- * shape the `memory_tier` watchdog `detail` bag carries to the cloud.
9
- *
10
- * Both corpora are measured on every tier rather than branching on the tier
11
- * itself: an assistant part-way through a v1 -> v2 -> v3 migration has content
12
- * in both trees, and a `memory.enabled: false` assistant still has whatever it
13
- * accumulated before being switched off. Reporting both unconditionally keeps
14
- * the numbers legible across a migration instead of blinking to zero the
15
- * moment a tier flips.
16
- *
17
- * KNOWN GAP: this measures on-disk Markdown only. It does NOT count
18
- * `memory_graph_nodes`, which is a real part of a v1 assistant's learned state
19
- * — `v2/migration.ts` gathers graph nodes alongside PKB Markdown when it
20
- * migrates v1 — so a v1 assistant rich in graph nodes but holding only the
21
- * seeded PKB files reads as near-empty here. Counting them means opening the
22
- * memory SQLite DB from the resource-monitor process, which this probe
23
- * deliberately does not do. Treat `pkb_files` as a lower bound on v1 corpus
24
- * size and confirm v1 assistants directly before sizing a migration off it.
25
- */
26
- export interface MemoryCorpusSize {
27
- /** `.md` files under `memory/concepts/` — the v2/v3 concept-page count. */
28
- concept_pages: number;
29
- /** Total bytes of those concept pages. */
30
- concept_bytes: number;
31
- /** `.md` files under `pkb/` — the v1 personal-knowledge-base corpus. */
32
- pkb_files: number;
33
- /** Total bytes of those PKB files. */
34
- pkb_bytes: number;
35
- /**
36
- * Non-empty lines in `memory/buffer.md` — remembered facts still waiting on
37
- * consolidation. Matches `countBufferLines` in the substrate's
38
- * consolidation job: for a well-formed buffer, one non-empty line is one
39
- * entry.
40
- */
41
- buffer_lines: number;
42
- }
43
-
44
- /**
45
- * Ceiling on directory entries examined per tree. The largest corpus observed
46
- * in the fleet is in the low hundreds of pages, so this never binds in
47
- * practice; it exists so a pathological workspace cannot turn a telemetry
48
- * probe into a long walk.
49
- *
50
- * It counts every dirent seen — directories and non-Markdown files included —
51
- * not just the Markdown matches. A cap on matches alone would not bound the
52
- * walk at all: a tree of a million empty directories contains zero Markdown
53
- * files and would still be traversed in full by this synchronous probe.
54
- *
55
- * A tree that hits the cap returns what it counted so far, making the result
56
- * a floor rather than an error.
57
- */
58
- const MAX_ENTRIES_PER_TREE = 20_000;
59
-
60
- interface TreeSize {
61
- files: number;
62
- bytes: number;
63
- }
64
-
65
- const EMPTY_TREE: TreeSize = { files: 0, bytes: 0 };
66
-
67
- /**
68
- * Recursively total the `.md` files under `dir`.
69
- *
70
- * Deliberately synchronous, and deliberately not routed through the memory
71
- * plugin's `listPages` / `getPageIndex`. This runs in the resource-monitor
72
- * process, where the plugin's page-index cache is cold — going through it
73
- * would read and parse every concept page on each six-hour cycle, and would
74
- * add an import out of `telemetry/` into the plugin tree that the plugin
75
- * import-boundary guard exists to prevent. A bare readdir + stat is the whole
76
- * job here.
77
- *
78
- * `withFileTypes` dirents carry lstat semantics, so a symlinked directory
79
- * reports as a symlink rather than a directory and is skipped — the walk
80
- * cannot follow a link into a cycle, and needs no visited-inode bookkeeping.
81
- *
82
- * `maxEntries` is a parameter only so the ceiling is testable without
83
- * materializing twenty thousand files; production callers take the default.
84
- */
85
- export function measureMarkdownTree(
86
- dir: string,
87
- maxEntries: number = MAX_ENTRIES_PER_TREE,
88
- ): TreeSize {
89
- let files = 0;
90
- let bytes = 0;
91
- let visited = 0;
92
- const pending: string[] = [dir];
93
-
94
- while (pending.length > 0) {
95
- const current = pending.pop();
96
- if (current === undefined) {
97
- break;
98
- }
99
-
100
- let entries;
101
- try {
102
- entries = readdirSync(current, { withFileTypes: true });
103
- } catch {
104
- // A missing or unreadable subtree contributes nothing. The common case
105
- // is ENOENT: the tier that owns this tree was never active here.
106
- continue;
107
- }
108
-
109
- for (const entry of entries) {
110
- visited += 1;
111
- if (visited > maxEntries) {
112
- return { files, bytes };
113
- }
114
- if (entry.isDirectory()) {
115
- pending.push(join(current, entry.name));
116
- continue;
117
- }
118
- if (!entry.isFile() || !entry.name.endsWith(".md")) {
119
- continue;
120
- }
121
- files += 1;
122
- try {
123
- bytes += statSync(join(current, entry.name)).size;
124
- } catch {
125
- // Counted in `files` but contributes no bytes — a file that vanished
126
- // between the readdir and the stat is a race, not a failure.
127
- }
128
- }
129
- }
130
-
131
- return { files, bytes };
132
- }
133
-
134
- /** Non-empty-line count of the file at `path`; 0 when it is absent or empty. */
135
- function countNonEmptyLines(path: string): number {
136
- let content: string;
137
- try {
138
- content = readFileSync(path, "utf8");
139
- } catch {
140
- return 0;
141
- }
142
- if (content.length === 0) {
143
- return 0;
144
- }
145
- return content.split("\n").filter((line) => line.trim().length > 0).length;
146
- }
147
-
148
- /**
149
- * Measure the on-disk memory corpus for this assistant.
150
- *
151
- * Never throws: every probe degrades to zero independently, so a corpus that
152
- * is partly unreadable still reports the part that is.
153
- */
154
- export function measureMemoryCorpusSize(): MemoryCorpusSize {
155
- const workspaceDir = getWorkspaceDir();
156
-
157
- let concepts: TreeSize = EMPTY_TREE;
158
- let pkb: TreeSize = EMPTY_TREE;
159
- let bufferLines = 0;
160
-
161
- try {
162
- concepts = measureMarkdownTree(join(workspaceDir, "memory", "concepts"));
163
- } catch {
164
- concepts = EMPTY_TREE;
165
- }
166
- try {
167
- pkb = measureMarkdownTree(join(workspaceDir, "pkb"));
168
- } catch {
169
- pkb = EMPTY_TREE;
170
- }
171
- try {
172
- bufferLines = countNonEmptyLines(join(workspaceDir, "memory", "buffer.md"));
173
- } catch {
174
- bufferLines = 0;
175
- }
176
-
177
- return {
178
- concept_pages: concepts.files,
179
- concept_bytes: concepts.bytes,
180
- pkb_files: pkb.files,
181
- pkb_bytes: pkb.bytes,
182
- buffer_lines: bufferLines,
183
- };
184
- }
@@ -1,195 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
-
3
- import type { ConsentState } from "../cloud/consent-cache.js";
4
- import { memoryTier } from "../config/memory-tier.js";
5
- import type { AssistantConfig } from "../config/schema.js";
6
- import type { MemoryCorpusSize } from "./memory-corpus-size.js";
7
- import type { WatchdogEventRecord } from "./watchdog-events-store.js";
8
-
9
- // Mutable stubs flipped per test. bun's `mock.module` patches retroactively
10
- // (live bindings), so the reporter's imports resolve to these regardless of
11
- // import order (mirrors `outbox-test-harness.ts`). Kept off the outbox/DB path
12
- // on purpose: mocking `recordWatchdogEvent` lets these assert emission without
13
- // standing up the telemetry DB.
14
- let consent: ConsentState = true;
15
- let currentConfig: AssistantConfig = {} as AssistantConfig;
16
- let recorded: WatchdogEventRecord[] = [];
17
-
18
- // Stubbed so the assertions below stay exact-match: the real probe walks the
19
- // live workspace, whose contents differ per machine. `measureMemoryCorpusSize`
20
- // has its own tests against a temp tree.
21
- const ZERO_CORPUS: MemoryCorpusSize = {
22
- concept_pages: 0,
23
- concept_bytes: 0,
24
- pkb_files: 0,
25
- pkb_bytes: 0,
26
- buffer_lines: 0,
27
- };
28
- let corpus: MemoryCorpusSize = ZERO_CORPUS;
29
- let corpusError: Error | null = null;
30
-
31
- mock.module("./memory-corpus-size.js", () => ({
32
- measureMemoryCorpusSize: () => {
33
- if (corpusError) {
34
- throw corpusError;
35
- }
36
- return corpus;
37
- },
38
- }));
39
- mock.module("../cloud/consent-cache.js", () => ({
40
- getRawShareAnalytics: () => consent,
41
- }));
42
- mock.module("../config/loader.js", () => ({
43
- getConfigReadOnly: () => currentConfig,
44
- }));
45
- mock.module("./watchdog-events-store.js", () => ({
46
- recordWatchdogEvent: (record: WatchdogEventRecord) => {
47
- recorded.push(record);
48
- },
49
- }));
50
-
51
- import {
52
- recordMemoryTierOnce,
53
- startMemoryTierReporter,
54
- stopMemoryTierReporter,
55
- } from "./memory-tier-reporter.js";
56
-
57
- function makeConfig(
58
- enabled: boolean,
59
- v2Enabled: boolean,
60
- v3Live = false,
61
- ): AssistantConfig {
62
- return {
63
- memory: {
64
- enabled,
65
- v2: { enabled: v2Enabled },
66
- v3: { live: v3Live },
67
- },
68
- } as AssistantConfig;
69
- }
70
-
71
- describe("memory-tier-reporter", () => {
72
- beforeEach(() => {
73
- consent = true;
74
- currentConfig = {} as AssistantConfig;
75
- recorded = [];
76
- corpus = ZERO_CORPUS;
77
- corpusError = null;
78
- // Clear any interval/boot-retry timer a prior test's start left behind.
79
- stopMemoryTierReporter();
80
- });
81
-
82
- afterEach(() => {
83
- stopMemoryTierReporter();
84
- delete process.env.CADET_DEV;
85
- });
86
-
87
- test("emits a memory_tier watchdog carrying the current tier", () => {
88
- const config = makeConfig(true, true); // memory on, v2 enabled → "v2"
89
- currentConfig = config;
90
-
91
- recordMemoryTierOnce();
92
-
93
- expect(recorded).toHaveLength(1);
94
- expect(recorded[0]).toEqual({
95
- checkName: "memory_tier",
96
- detail: { tier: memoryTier(config), ...ZERO_CORPUS },
97
- });
98
- expect(recorded[0]?.detail?.tier).toBe("v2");
99
- });
100
-
101
- test("reflects a different tier for a different config (v3 live)", () => {
102
- currentConfig = makeConfig(true, true, true); // v3 live wins over v2
103
- recordMemoryTierOnce();
104
-
105
- expect(recorded[0]?.detail).toEqual({ tier: "v3", ...ZERO_CORPUS });
106
- });
107
-
108
- test("carries the measured corpus size alongside the tier", () => {
109
- currentConfig = makeConfig(true, true, true);
110
- corpus = {
111
- concept_pages: 42,
112
- concept_bytes: 133_700,
113
- pkb_files: 3,
114
- pkb_bytes: 900,
115
- buffer_lines: 7,
116
- };
117
-
118
- recordMemoryTierOnce();
119
-
120
- expect(recorded[0]?.detail).toEqual({ tier: "v3", ...corpus });
121
- });
122
-
123
- test("a failed corpus probe still emits the tier heartbeat", () => {
124
- // The fleet-mix dashboards read `detail.tier`; a sizing failure must
125
- // degrade the payload, never drop the event and gap the series.
126
- currentConfig = makeConfig(true, true, true);
127
- corpusError = new Error("workspace unreadable");
128
-
129
- recordMemoryTierOnce();
130
-
131
- expect(recorded).toHaveLength(1);
132
- expect(recorded[0]?.detail).toEqual({ tier: "v3" });
133
- });
134
-
135
- test("emits every invocation — no memo", () => {
136
- currentConfig = makeConfig(true, false); // "v1"
137
- recordMemoryTierOnce();
138
- recordMemoryTierOnce();
139
- recordMemoryTierOnce();
140
-
141
- expect(recorded).toHaveLength(3);
142
- for (const event of recorded) {
143
- expect(event).toEqual({
144
- checkName: "memory_tier",
145
- detail: { tier: "v1", ...ZERO_CORPUS },
146
- });
147
- }
148
- });
149
-
150
- test("unknown consent emits nothing", () => {
151
- consent = "unknown";
152
- currentConfig = makeConfig(true, true);
153
-
154
- recordMemoryTierOnce();
155
-
156
- expect(recorded).toHaveLength(0);
157
- });
158
-
159
- test("a confirmed opt-out still calls through (recordWatchdogEvent no-ops)", () => {
160
- // The reporter only skips the UNKNOWN state; the `false` opt-out is
161
- // honored one layer down in `recordWatchdogEvent`. Here that layer is the
162
- // stub, so the call is observed — the drop is the real store's concern.
163
- consent = false;
164
- currentConfig = makeConfig(true, true);
165
-
166
- recordMemoryTierOnce();
167
-
168
- expect(recorded).toHaveLength(1);
169
- });
170
-
171
- test("a confirmed opt-out skips the corpus probe entirely", () => {
172
- // The event is dropped one layer down, so walking the workspace for it
173
- // would be pure cost on an assistant that asked us not to collect. The
174
- // throwing stub asserts the probe is never reached.
175
- consent = false;
176
- currentConfig = makeConfig(true, true);
177
- corpusError = new Error("probe must not run");
178
-
179
- recordMemoryTierOnce();
180
-
181
- expect(recorded).toHaveLength(1);
182
- expect(recorded[0]?.detail).toEqual({ tier: "v2" });
183
- });
184
-
185
- test("startMemoryTierReporter is a no-op under CADET_DEV=1", () => {
186
- process.env.CADET_DEV = "1";
187
- consent = true; // consent known → a non-dev start would emit immediately
188
- currentConfig = makeConfig(true, true);
189
-
190
- startMemoryTierReporter();
191
-
192
- // No boot emit and no interval scheduled.
193
- expect(recorded).toHaveLength(0);
194
- });
195
- });
@@ -1,130 +0,0 @@
1
- import { getRawShareAnalytics } from "../cloud/consent-cache.js";
2
- import { getConfigReadOnly } from "../config/loader.js";
3
- import { memoryTier } from "../config/memory-tier.js";
4
- import { getLogger } from "../util/logger.js";
5
- import { measureMemoryCorpusSize } from "./memory-corpus-size.js";
6
- import { recordWatchdogEvent } from "./watchdog-events-store.js";
7
-
8
- const log = getLogger("memory-tier-reporter");
9
-
10
- /**
11
- * How often each assistant re-asserts its coarse memory tier as a
12
- * `memory_tier` watchdog event. Unlike the config-setting snapshot this emits
13
- * UNCONDITIONALLY every cycle (no memo): the cloud-side query wants a
14
- * periodic per-assistant heartbeat of the current tier, so a gap in the series
15
- * is meaningful (assistant offline) rather than "value unchanged". Six-hourly
16
- * keeps the volume trivial while giving a same-day read on the fleet's tier
17
- * mix, and every boot re-asserts the tier regardless.
18
- */
19
- const MEMORY_TIER_INTERVAL_MS = 6 * 60 * 60 * 1000;
20
-
21
- /**
22
- * Watchdog `check_name` carrying the coarse memory tier in `detail.tier`,
23
- * alongside the on-disk corpus size (see {@link measureMemoryCorpusSize}).
24
- *
25
- * The check name and the `detail.tier` bucket strings are frozen — platform
26
- * dashboards group on them. The rest of `detail` is an open bag, so the
27
- * corpus-size keys are additive and need no wire, serializer, or dbt change.
28
- */
29
- const MEMORY_TIER_CHECK_NAME = "memory_tier";
30
-
31
- // The boot-time emit races the first consent refresh (fire-and-forget in the
32
- // monitor's startup), so consent is usually still "unknown" on the first call
33
- // and the emit is skipped. Retry on a short timer until consent resolves
34
- // rather than waiting a full six-hour interval for the per-boot assertion.
35
- const BOOT_RETRY_INTERVAL_MS = 60_000;
36
-
37
- /**
38
- * Emit one `memory_tier` watchdog event for this assistant's current tier.
39
- *
40
- * Consent-gated like the config-setting snapshot but with NO memo: every
41
- * invocation emits, so the cloud sees a periodic heartbeat of the current
42
- * tier rather than only edges. An UNKNOWN consent state skips entirely
43
- * (consent resolves asynchronously after boot; the boot-retry loop re-invokes
44
- * once it lands) — deferring loses nothing since the tier is re-derivable
45
- * state. A confirmed opt-out is honored inside `recordWatchdogEvent`, which
46
- * no-ops on a `false` share_analytics, so the call still goes through and the
47
- * record layer drops it. Never throws: a storage failure is logged and
48
- * retried on the next cycle.
49
- *
50
- * The event also carries the on-disk corpus size. That probe is best-effort
51
- * and isolated: if it fails the event still goes out with the tier alone,
52
- * because the tier heartbeat is what the fleet-mix dashboards depend on and a
53
- * sizing failure must not create a gap in that series. It is also skipped
54
- * outright on a confirmed opt-out — the event is dropped one layer down, so
55
- * walking the workspace for it would be pure cost on the assistants that
56
- * asked us not to collect.
57
- */
58
- export function recordMemoryTierOnce(): void {
59
- const consent = getRawShareAnalytics();
60
- if (consent === "unknown") {
61
- return;
62
- }
63
- try {
64
- // `getConfigReadOnly()` re-reads config.json on change (capturing live
65
- // edits) and never writes to disk — safe for the monitor process.
66
- const tier = memoryTier(getConfigReadOnly());
67
-
68
- let corpus: Record<string, number> = {};
69
- if (consent !== false) {
70
- try {
71
- corpus = { ...measureMemoryCorpusSize() };
72
- } catch (err) {
73
- log.warn({ err }, "memory corpus sizing failed (emitting tier only)");
74
- }
75
- }
76
-
77
- recordWatchdogEvent({
78
- checkName: MEMORY_TIER_CHECK_NAME,
79
- detail: { tier, ...corpus },
80
- });
81
- } catch (err) {
82
- log.warn({ err }, "memory_tier watchdog emit failed (non-fatal)");
83
- }
84
- }
85
-
86
- let tierTimer: ReturnType<typeof setInterval> | null = null;
87
- let bootRetryTimer: ReturnType<typeof setTimeout> | null = null;
88
-
89
- function recordBootTierOnceConsentKnown(): void {
90
- if (getRawShareAnalytics() === "unknown") {
91
- bootRetryTimer = setTimeout(
92
- recordBootTierOnceConsentKnown,
93
- BOOT_RETRY_INTERVAL_MS,
94
- );
95
- bootRetryTimer.unref?.();
96
- return;
97
- }
98
- bootRetryTimer = null;
99
- recordMemoryTierOnce();
100
- }
101
-
102
- /**
103
- * Start the memory-tier reporter in the resource monitor process: emit the
104
- * current tier once at boot (once consent resolves), then every six hours,
105
- * UNCONDITIONALLY. No-op in dev mode (CADET_DEV=1) and idempotent if already
106
- * started. Runs alongside {@link import("./config-setting-snapshot.js").startConfigSnapshotReporter}
107
- * in the monitor worker.
108
- */
109
- export function startMemoryTierReporter(): void {
110
- if (process.env.CADET_DEV === "1") {
111
- return;
112
- }
113
- if (tierTimer) {
114
- return;
115
- }
116
- recordBootTierOnceConsentKnown();
117
- tierTimer = setInterval(recordMemoryTierOnce, MEMORY_TIER_INTERVAL_MS);
118
- }
119
-
120
- /** Stop the memory-tier reporter loop. Idempotent. */
121
- export function stopMemoryTierReporter(): void {
122
- if (tierTimer) {
123
- clearInterval(tierTimer);
124
- tierTimer = null;
125
- }
126
- if (bootRetryTimer) {
127
- clearTimeout(bootRetryTimer);
128
- bootRetryTimer = null;
129
- }
130
- }
@@ -1,144 +0,0 @@
1
- /**
2
- * Phone-call telemetry vocabulary: the single source of truth for the step
3
- * names, funnel version, and dimension values the call store's emitter uses.
4
- *
5
- * The phone half of the live-voice funnel, and deliberately its mirror image:
6
- * same onboarding substrate (`type: "onboarding"`), same open-string
7
- * `step_name` / `funnel_version`, same reason for both. See
8
- * `live-voice-funnel.ts` for the full argument; the short version is that the
9
- * backend stores those two as open strings, so a new funnel needs no platform
10
- * serializer and no wire-contract change.
11
- *
12
- * **Duration is not a field**, for the same reason it is not one on live
13
- * voice: the onboarding event shape has no numeric slot. The two events below
14
- * are keyed by the call session id in `session_id` and the warehouse subtracts
15
- * their `recorded_at` stamps.
16
- *
17
- * **Turn count is not a field either.** Phone turns already carry the call
18
- * session id in their `client` bag (`voiceTelemetry` at the bridge call site),
19
- * so a turn count is a count of those rows.
20
- *
21
- * A call that starts and never ends is **censored, not infinite**: a daemon
22
- * crash between the two writes emits no end event, so duration math must drop
23
- * unmatched `started` rows rather than treat the call as still running.
24
- */
25
-
26
- import type { CallMode, CallStatus } from "../calls/types.js";
27
-
28
- /** Funnel version stamped on every phone-call event. */
29
- export const PHONE_CALL_FUNNEL_VERSION = "phone_call_v1_2026_09";
30
-
31
- /**
32
- * Phone-call funnel steps. `stepName` is the wire value; `stepIndex` is the
33
- * ordinal position.
34
- *
35
- * `callStarted` fires when the call session row is created, before the
36
- * provider has dialled: a call that never connects is exactly the one worth
37
- * counting, so the start event precedes no-answer, busy, provider failure and
38
- * the inbound credential preflight (an inbound session exists before that
39
- * preflight runs and records against it).
40
- *
41
- * It does **not** cover an outbound attempt rejected before a session exists:
42
- * `startCall`, `startVerificationCall` and `startInviteCall` all return on a
43
- * failed `preflightVoiceIngress()` without creating a row, and this funnel is
44
- * keyed by the session id it would have had. Counting those needs a key that
45
- * does not depend on a session row, which is its own piece of work.
46
- */
47
- export const PHONE_CALL_STEPS = {
48
- callStarted: { stepName: "phone_call_started", stepIndex: 0 },
49
- callEnded: { stepName: "phone_call_ended", stepIndex: 1 },
50
- } as const;
51
-
52
- export type PhoneCallStepName =
53
- (typeof PHONE_CALL_STEPS)[keyof typeof PHONE_CALL_STEPS]["stepName"];
54
-
55
- /**
56
- * Which way the call was placed. Inbound is someone dialling the assistant's
57
- * number; outbound is the assistant dialling out on a task.
58
- */
59
- export type PhoneCallDirection = "inbound" | "outbound";
60
-
61
- /**
62
- * How a call ended, stamped as `outcome`.
63
- *
64
- * `failed` means the call died on an error: no answer, a provider or
65
- * credential failure, a dropped media stream. A call the caller or the
66
- * assistant hung up, including one cancelled before it connected, is
67
- * `completed`: it ran its course and the close reason on `screen` says how.
68
- */
69
- export type PhoneCallOutcome = "completed" | "failed";
70
-
71
- /**
72
- * How far a call that produced NO caller turn actually got.
73
- *
74
- * The phone analogue of the live-voice silence taxonomy, and the closest thing
75
- * call telemetry has to a "the phone path didn't work" rate. A bare
76
- * started/ended pair cannot separate a call that never connected from one that
77
- * connected to silence, and those have completely different fixes.
78
- *
79
- * - `no_connect` the call never reached `in_progress`: it failed, was
80
- * cancelled, or was never answered, so nobody could have
81
- * spoken.
82
- * - `no_turn` the call connected and then no caller utterance was ever
83
- * transcribed: a silent line, a failed STT leg, or a caller who
84
- * hung up on the disclosure.
85
- */
86
- export type PhoneCallSilenceReason = "no_connect" | "no_turn";
87
-
88
- /**
89
- * Classify a call that produced no caller turn. Call only when the call really
90
- * produced none: the second branch asserts silence, so a call that did take a
91
- * turn would be mislabelled by it.
92
- */
93
- export function phoneCallSilenceReason(signals: {
94
- connected: boolean;
95
- }): PhoneCallSilenceReason {
96
- return signals.connected ? "no_turn" : "no_connect";
97
- }
98
-
99
- /**
100
- * The mode an ordinary call carries. Only the verification and invite flows
101
- * write a mode on the session row, so a null there is not a missing dimension
102
- * but the ordinary conversation every other path creates.
103
- */
104
- const PHONE_CALL_DEFAULT_MODE: CallMode = "normal";
105
-
106
- /**
107
- * The `screen` dimension for a started call: which way it was placed and what
108
- * kind of call it is, as `started_<direction>:<mode>`.
109
- *
110
- * The mode separates the three things a phone call can be (a normal
111
- * conversation, a callee verification, an invite redemption) because they have
112
- * completely different shapes and success criteria, and a funnel that mixed
113
- * them would report the verification flow's brevity as a conversation problem.
114
- */
115
- export function phoneCallStartScreen(
116
- direction: PhoneCallDirection,
117
- mode?: CallMode | null,
118
- ): string {
119
- return `started_${direction}:${mode ?? PHONE_CALL_DEFAULT_MODE}`;
120
- }
121
-
122
- /**
123
- * The `screen` dimension for an ended call: the terminal status it reached,
124
- * plus a detail half carrying the silence classification when the call took no
125
- * caller turn at all.
126
- *
127
- * The status is the daemon's own `CallStatus` verbatim rather than a mapping,
128
- * so a rename surfaces here as a compile error instead of a silently-empty
129
- * dashboard facet.
130
- *
131
- * The silence value carries a `silent_` prefix to match the live-voice stamp,
132
- * which shares its detail slot with failure codes and renders in an admin
133
- * column labelled "failure code". Reading the two funnels side by side is
134
- * worth more than a shorter string here.
135
- */
136
- export function phoneCallEndScreen(
137
- status: CallStatus,
138
- silenceReason?: PhoneCallSilenceReason | null,
139
- ): string {
140
- if (silenceReason) {
141
- return `ended_${status}:silent_${silenceReason}`;
142
- }
143
- return `ended_${status}`;
144
- }