@ouro.bot/cli 0.1.0-alpha.72 → 0.1.0-alpha.721

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 (505) hide show
  1. package/README.md +133 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +4569 -14
  13. package/dist/a2a/card.js +57 -0
  14. package/dist/a2a/client.js +180 -0
  15. package/dist/a2a/config.js +50 -0
  16. package/dist/a2a/delegation-stores.js +56 -0
  17. package/dist/a2a/did-resolution.js +93 -0
  18. package/dist/a2a/identity.js +170 -0
  19. package/dist/a2a/inbound-share.js +107 -0
  20. package/dist/a2a/mission-result-wire.js +196 -0
  21. package/dist/a2a/onboarding.js +115 -0
  22. package/dist/a2a/pin-store.js +132 -0
  23. package/dist/a2a/seen-ledger.js +120 -0
  24. package/dist/a2a/server.js +604 -0
  25. package/dist/a2a/task-store.js +69 -0
  26. package/dist/a2a/transport.js +45 -0
  27. package/dist/a2a/types.js +3 -0
  28. package/dist/arc/attention-types.js +8 -0
  29. package/dist/arc/cares.js +144 -0
  30. package/dist/arc/episodes.js +118 -0
  31. package/dist/arc/evolution.js +490 -0
  32. package/dist/arc/flight-recorder.js +1034 -0
  33. package/dist/arc/intentions.js +134 -0
  34. package/dist/arc/json-store.js +117 -0
  35. package/dist/arc/obligations.js +348 -0
  36. package/dist/arc/packets.js +336 -0
  37. package/dist/arc/presence.js +185 -0
  38. package/dist/arc/task-lifecycle.js +57 -0
  39. package/dist/commerce/store.js +755 -0
  40. package/dist/commerce/types.js +3 -0
  41. package/dist/heart/active-work.js +867 -43
  42. package/dist/heart/agent-entry.js +190 -3
  43. package/dist/heart/attachments/image-normalize.js +194 -0
  44. package/dist/heart/attachments/materialize.js +97 -0
  45. package/dist/heart/attachments/originals.js +88 -0
  46. package/dist/heart/attachments/render.js +29 -0
  47. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  48. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  49. package/dist/heart/attachments/sources/index.js +16 -0
  50. package/dist/heart/attachments/store.js +103 -0
  51. package/dist/heart/attachments/types.js +93 -0
  52. package/dist/heart/auth/auth-flow.js +479 -0
  53. package/dist/heart/autonomy-budget.js +434 -0
  54. package/dist/heart/awaiting/await-alert.js +146 -0
  55. package/dist/heart/awaiting/await-expiry.js +108 -0
  56. package/dist/heart/awaiting/await-loader.js +91 -0
  57. package/dist/heart/awaiting/await-parser.js +141 -0
  58. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  59. package/dist/heart/awaiting/await-scheduler.js +378 -0
  60. package/dist/heart/background-operations.js +281 -0
  61. package/dist/heart/bridges/manager.js +137 -17
  62. package/dist/heart/bridges/store.js +14 -2
  63. package/dist/heart/bundle-state.js +168 -0
  64. package/dist/heart/commitments.js +135 -0
  65. package/dist/heart/config-registry.js +331 -0
  66. package/dist/heart/config.js +119 -127
  67. package/dist/heart/context-loss-gauntlet.js +354 -0
  68. package/dist/heart/context-loss-sentinel.js +1155 -0
  69. package/dist/heart/core.js +1306 -278
  70. package/dist/heart/cross-chat-delivery.js +8 -22
  71. package/dist/heart/daemon/agent-config-check.js +451 -0
  72. package/dist/heart/daemon/agent-discovery.js +185 -3
  73. package/dist/heart/daemon/agent-service.js +542 -0
  74. package/dist/heart/daemon/agentic-repair.js +547 -0
  75. package/dist/heart/daemon/await-private-wake.js +59 -0
  76. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  77. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  78. package/dist/heart/daemon/cadence.js +180 -0
  79. package/dist/heart/daemon/cli-defaults.js +825 -0
  80. package/dist/heart/daemon/cli-desk.js +322 -0
  81. package/dist/heart/daemon/cli-exec.js +8264 -0
  82. package/dist/heart/daemon/cli-help.js +678 -0
  83. package/dist/heart/daemon/cli-parse.js +2539 -0
  84. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  85. package/dist/heart/daemon/cli-render.js +770 -0
  86. package/dist/heart/daemon/cli-types.js +8 -0
  87. package/dist/heart/daemon/connect-bay.js +323 -0
  88. package/dist/heart/daemon/daemon-cli.js +29 -2010
  89. package/dist/heart/daemon/daemon-entry.js +842 -10
  90. package/dist/heart/daemon/daemon-health.js +176 -0
  91. package/dist/heart/daemon/daemon-rollup.js +57 -0
  92. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  93. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  94. package/dist/heart/daemon/daemon.js +1289 -84
  95. package/dist/heart/daemon/dns-workflow.js +394 -0
  96. package/dist/heart/daemon/doctor-types.js +8 -0
  97. package/dist/heart/daemon/doctor.js +1126 -0
  98. package/dist/heart/daemon/habit-private-wake.js +56 -0
  99. package/dist/heart/daemon/health-monitor.js +142 -11
  100. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  101. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  102. package/dist/heart/daemon/http-health-probe.js +80 -0
  103. package/dist/heart/daemon/human-command-screens.js +234 -0
  104. package/dist/heart/daemon/human-readiness.js +114 -0
  105. package/dist/heart/daemon/inner-status.js +78 -0
  106. package/dist/heart/daemon/interactive-repair.js +394 -0
  107. package/dist/heart/daemon/launchd.js +37 -8
  108. package/dist/heart/daemon/log-tailer.js +79 -10
  109. package/dist/heart/daemon/logs-prune.js +110 -0
  110. package/dist/heart/daemon/mcp-canary.js +393 -0
  111. package/dist/heart/daemon/message-router.js +45 -5
  112. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  113. package/dist/heart/daemon/os-cron-deps.js +135 -0
  114. package/dist/heart/daemon/os-cron.js +22 -14
  115. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  116. package/dist/heart/daemon/ouro-entry.js +3 -1
  117. package/dist/heart/daemon/plugin-cli.js +432 -0
  118. package/dist/heart/daemon/process-manager.js +519 -40
  119. package/dist/heart/daemon/provider-discovery.js +137 -0
  120. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  121. package/dist/heart/daemon/pulse.js +511 -0
  122. package/dist/heart/daemon/readiness-repair.js +365 -0
  123. package/dist/heart/daemon/run-hooks.js +2 -0
  124. package/dist/heart/daemon/runtime-logging.js +41 -14
  125. package/dist/heart/daemon/runtime-metadata.js +2 -30
  126. package/dist/heart/daemon/safe-mode.js +161 -0
  127. package/dist/heart/daemon/sense-manager.js +670 -48
  128. package/dist/heart/daemon/session-id-resolver.js +131 -0
  129. package/dist/heart/daemon/skill-management-installer.js +1 -1
  130. package/dist/heart/daemon/socket-client.js +171 -12
  131. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  132. package/dist/heart/daemon/startup-tui.js +338 -0
  133. package/dist/heart/daemon/task-scheduler.js +117 -39
  134. package/dist/heart/daemon/terminal-ui.js +499 -0
  135. package/dist/heart/daemon/thoughts.js +255 -43
  136. package/dist/heart/daemon/up-progress.js +366 -0
  137. package/dist/heart/daemon/vault-items.js +56 -0
  138. package/dist/heart/delegation.js +1 -4
  139. package/dist/heart/external-events/router.js +121 -0
  140. package/dist/heart/habits/habit-migration.js +189 -0
  141. package/dist/heart/habits/habit-parser.js +214 -0
  142. package/dist/heart/habits/habit-runtime-state.js +114 -0
  143. package/dist/heart/habits/habit-scheduler.js +431 -0
  144. package/dist/heart/habits/habit-session-summary.js +318 -0
  145. package/dist/heart/habits/habit-session.js +620 -0
  146. package/dist/heart/{daemon → hatch}/hatch-flow.js +51 -60
  147. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  148. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  149. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  150. package/dist/heart/identity.js +174 -59
  151. package/dist/heart/kept-notes.js +289 -0
  152. package/dist/heart/kicks.js +1 -1
  153. package/dist/heart/machine-identity.js +161 -0
  154. package/dist/heart/mail-import-discovery.js +353 -0
  155. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  156. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  157. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  158. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  159. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  160. package/dist/heart/mailbox/mailbox-http.js +99 -0
  161. package/dist/heart/mailbox/mailbox-read.js +39 -0
  162. package/dist/heart/mailbox/mailbox-types.js +27 -0
  163. package/dist/heart/mailbox/mailbox-view.js +197 -0
  164. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  165. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  166. package/dist/heart/mailbox/readers/mail.js +375 -0
  167. package/dist/heart/mailbox/readers/runtime-readers.js +824 -0
  168. package/dist/heart/mailbox/readers/sessions.js +232 -0
  169. package/dist/heart/mailbox/readers/shared.js +111 -0
  170. package/dist/heart/mcp/mcp-server.js +696 -0
  171. package/dist/heart/migrate-config.js +100 -0
  172. package/dist/heart/model-capabilities.js +11 -0
  173. package/dist/heart/orientation-frame.js +217 -0
  174. package/dist/heart/platform.js +81 -0
  175. package/dist/heart/primitives.js +1 -1
  176. package/dist/heart/private-runtime/decision-renderer.js +156 -0
  177. package/dist/heart/private-runtime/index.js +18 -0
  178. package/dist/heart/private-runtime/ledger.js +218 -0
  179. package/dist/heart/private-runtime/policy.js +214 -0
  180. package/dist/heart/private-runtime/types.js +2 -0
  181. package/dist/heart/progress-story.js +1 -1
  182. package/dist/heart/provider-attempt.js +134 -0
  183. package/dist/heart/provider-binding-resolver.js +273 -0
  184. package/dist/heart/provider-credentials.js +441 -0
  185. package/dist/heart/provider-failover.js +311 -0
  186. package/dist/heart/provider-models.js +81 -0
  187. package/dist/heart/provider-ping.js +262 -0
  188. package/dist/heart/provider-readiness-cache.js +119 -0
  189. package/dist/heart/provider-visibility.js +188 -0
  190. package/dist/heart/providers/anthropic-token.js +131 -0
  191. package/dist/heart/providers/anthropic.js +139 -52
  192. package/dist/heart/providers/azure.js +23 -11
  193. package/dist/heart/providers/error-classification.js +127 -0
  194. package/dist/heart/providers/github-copilot.js +34 -38
  195. package/dist/heart/providers/minimax-vlm.js +189 -0
  196. package/dist/heart/providers/minimax.js +26 -8
  197. package/dist/heart/providers/openai-codex-token.js +349 -0
  198. package/dist/heart/providers/openai-codex.js +55 -40
  199. package/dist/heart/run-ledger.js +247 -0
  200. package/dist/heart/runtime-capability-check.js +170 -0
  201. package/dist/heart/runtime-credentials.js +398 -0
  202. package/dist/heart/runtime-cwd.js +87 -0
  203. package/dist/heart/sense-truth.js +20 -4
  204. package/dist/heart/session-activity.js +90 -24
  205. package/dist/heart/session-events.js +1133 -0
  206. package/dist/heart/session-playback-cli-main.js +5 -0
  207. package/dist/heart/session-playback-cli.js +36 -0
  208. package/dist/heart/session-playback.js +231 -0
  209. package/dist/heart/session-stats-cli-main.js +5 -0
  210. package/dist/heart/session-stats.js +182 -0
  211. package/dist/heart/session-transcript.js +133 -0
  212. package/dist/heart/start-of-turn-packet.js +365 -0
  213. package/dist/heart/streaming.js +44 -27
  214. package/dist/heart/structured-output.js +196 -0
  215. package/dist/heart/sync-classification.js +176 -0
  216. package/dist/heart/sync.js +449 -0
  217. package/dist/heart/target-resolution.js +11 -7
  218. package/dist/heart/tempo.js +93 -0
  219. package/dist/heart/temporal-view.js +41 -0
  220. package/dist/heart/timeouts.js +101 -0
  221. package/dist/heart/tool-activity-callbacks.js +59 -0
  222. package/dist/heart/tool-description.js +155 -0
  223. package/dist/heart/tool-friction.js +55 -0
  224. package/dist/heart/tool-loop.js +200 -0
  225. package/dist/heart/turn-context.js +472 -0
  226. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  227. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  228. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  229. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  230. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  231. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  232. package/dist/heart/versioning/update-hooks.js +154 -0
  233. package/dist/heart/work-card.js +380 -0
  234. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  235. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  236. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  237. package/dist/mailbox-ui/index.html +16 -0
  238. package/dist/mailroom/attention.js +167 -0
  239. package/dist/mailroom/autonomy.js +209 -0
  240. package/dist/mailroom/blob-store.js +715 -0
  241. package/dist/mailroom/body-cache.js +61 -0
  242. package/dist/mailroom/core.js +788 -0
  243. package/dist/mailroom/entry.js +160 -0
  244. package/dist/mailroom/file-store.js +568 -0
  245. package/dist/mailroom/mbox-import.js +393 -0
  246. package/dist/mailroom/migration.js +164 -0
  247. package/dist/mailroom/outbound.js +380 -0
  248. package/dist/mailroom/policy.js +263 -0
  249. package/dist/mailroom/reader.js +233 -0
  250. package/dist/mailroom/search-cache.js +334 -0
  251. package/dist/mailroom/search-relevance.js +319 -0
  252. package/dist/mailroom/smtp-ingress.js +176 -0
  253. package/dist/mailroom/source-state.js +176 -0
  254. package/dist/mailroom/thread.js +109 -0
  255. package/dist/mailroom/travel-extract.js +89 -0
  256. package/dist/mind/bundle-manifest.js +24 -2
  257. package/dist/mind/context.js +250 -101
  258. package/dist/mind/desk-section.js +362 -0
  259. package/dist/mind/diary-integrity.js +60 -0
  260. package/dist/mind/{memory.js → diary.js} +68 -77
  261. package/dist/mind/embedding-provider.js +60 -0
  262. package/dist/mind/file-state.js +179 -0
  263. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  264. package/dist/mind/obligation-steering.js +221 -0
  265. package/dist/mind/pending.js +13 -8
  266. package/dist/mind/prompt-budget.js +380 -0
  267. package/dist/mind/prompt-refresh.js +3 -2
  268. package/dist/mind/prompt.js +1027 -170
  269. package/dist/mind/provenance-trust.js +26 -0
  270. package/dist/mind/record-paths.js +312 -0
  271. package/dist/mind/scrutiny.js +173 -0
  272. package/dist/nerves/cli-logging.js +7 -1
  273. package/dist/nerves/coverage/audit-rules.js +15 -6
  274. package/dist/nerves/coverage/audit.js +28 -2
  275. package/dist/nerves/coverage/cli.js +1 -1
  276. package/dist/nerves/coverage/contract.js +5 -5
  277. package/dist/nerves/coverage/file-completeness.js +139 -5
  278. package/dist/nerves/event-buffer.js +111 -0
  279. package/dist/nerves/index.js +234 -4
  280. package/dist/nerves/observation.js +20 -0
  281. package/dist/nerves/redact.js +79 -0
  282. package/dist/nerves/review/cli-main.js +5 -0
  283. package/dist/nerves/review/cli.js +156 -0
  284. package/dist/nerves/review/core.js +152 -0
  285. package/dist/nerves/runtime.js +5 -1
  286. package/dist/repertoire/ado-client.js +15 -56
  287. package/dist/repertoire/ado-semantic.js +16 -10
  288. package/dist/repertoire/api-client.js +97 -0
  289. package/dist/repertoire/bitwarden-store.js +1045 -0
  290. package/dist/repertoire/bundle-templates.js +71 -0
  291. package/dist/repertoire/bw-installer.js +180 -0
  292. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  293. package/dist/repertoire/coding/context-pack.js +331 -0
  294. package/dist/repertoire/coding/feedback.js +218 -30
  295. package/dist/repertoire/coding/index.js +15 -3
  296. package/dist/repertoire/coding/manager.js +166 -10
  297. package/dist/repertoire/coding/spawner.js +58 -11
  298. package/dist/repertoire/coding/tools.js +242 -14
  299. package/dist/repertoire/coding/workbench-client.js +272 -0
  300. package/dist/repertoire/coding/workbench-manager.js +346 -0
  301. package/dist/repertoire/commerce-errors.js +109 -0
  302. package/dist/repertoire/commerce-self-test.js +156 -0
  303. package/dist/repertoire/credential-access.js +178 -0
  304. package/dist/repertoire/desk/classifier.js +362 -0
  305. package/dist/repertoire/duffel-client.js +185 -0
  306. package/dist/repertoire/github-client.js +14 -55
  307. package/dist/repertoire/graph-client.js +11 -52
  308. package/dist/repertoire/guardrails.js +139 -18
  309. package/dist/repertoire/mcp-client.js +44 -3
  310. package/dist/repertoire/mcp-manager.js +259 -20
  311. package/dist/repertoire/mcp-tools.js +83 -0
  312. package/dist/repertoire/plugin-mcp.js +175 -0
  313. package/dist/repertoire/plugins.js +253 -0
  314. package/dist/repertoire/shell-sessions.js +133 -0
  315. package/dist/repertoire/skills.js +48 -4
  316. package/dist/repertoire/stripe-client.js +131 -0
  317. package/dist/repertoire/tool-results.js +29 -0
  318. package/dist/repertoire/tools-a2a.js +699 -0
  319. package/dist/repertoire/tools-attachments.js +317 -0
  320. package/dist/repertoire/tools-awaiting.js +372 -0
  321. package/dist/repertoire/tools-base.js +65 -1095
  322. package/dist/repertoire/tools-bluebubbles.js +2 -0
  323. package/dist/repertoire/tools-bridge.js +144 -0
  324. package/dist/repertoire/tools-bundle.js +993 -0
  325. package/dist/repertoire/tools-commerce.js +253 -0
  326. package/dist/repertoire/tools-config.js +186 -0
  327. package/dist/repertoire/tools-continuity.js +252 -0
  328. package/dist/repertoire/tools-credential.js +383 -0
  329. package/dist/repertoire/tools-evolution.js +527 -0
  330. package/dist/repertoire/tools-files.js +344 -0
  331. package/dist/repertoire/tools-flight.js +290 -0
  332. package/dist/repertoire/tools-flow.js +119 -0
  333. package/dist/repertoire/tools-github.js +3 -8
  334. package/dist/repertoire/tools-mail.js +1975 -0
  335. package/dist/repertoire/tools-notes.js +459 -0
  336. package/dist/repertoire/tools-obligations.js +182 -0
  337. package/dist/repertoire/tools-orientation.js +31 -0
  338. package/dist/repertoire/tools-record.js +482 -0
  339. package/dist/repertoire/tools-rsvp.js +139 -0
  340. package/dist/repertoire/tools-runtime.js +150 -0
  341. package/dist/repertoire/tools-session.js +881 -0
  342. package/dist/repertoire/tools-shell.js +120 -0
  343. package/dist/repertoire/tools-stripe.js +224 -0
  344. package/dist/repertoire/tools-surface.js +355 -0
  345. package/dist/repertoire/tools-teams.js +12 -39
  346. package/dist/repertoire/tools-travel.js +125 -0
  347. package/dist/repertoire/tools-trip.js +982 -0
  348. package/dist/repertoire/tools-user-profile.js +146 -0
  349. package/dist/repertoire/tools-vault.js +40 -0
  350. package/dist/repertoire/tools-voice.js +145 -0
  351. package/dist/repertoire/tools.js +249 -79
  352. package/dist/repertoire/travel-api-client.js +360 -0
  353. package/dist/repertoire/user-profile.js +131 -0
  354. package/dist/repertoire/vault-setup.js +246 -0
  355. package/dist/repertoire/vault-unlock.js +594 -0
  356. package/dist/rsvp/aisleplanner-client.js +354 -0
  357. package/dist/rsvp/cli.js +820 -0
  358. package/dist/rsvp/config.js +327 -0
  359. package/dist/rsvp/cutover.js +433 -0
  360. package/dist/rsvp/diagnostics.js +222 -0
  361. package/dist/rsvp/diff-renderer.js +176 -0
  362. package/dist/rsvp/habit-policy.js +103 -0
  363. package/dist/rsvp/habit-stage.js +108 -0
  364. package/dist/rsvp/incident-bundle.js +97 -0
  365. package/dist/rsvp/migration.js +204 -0
  366. package/dist/rsvp/native-habit-runner.js +490 -0
  367. package/dist/rsvp/outbound-state.js +268 -0
  368. package/dist/rsvp/query.js +118 -0
  369. package/dist/rsvp/replay.js +233 -0
  370. package/dist/rsvp/snapshot.js +232 -0
  371. package/dist/rsvp/spend-ledger.js +175 -0
  372. package/dist/scripts/claude-code-hook.js +41 -0
  373. package/dist/scripts/claude-code-stop-hook.js +47 -0
  374. package/dist/senses/a2a-entry.js +115 -0
  375. package/dist/senses/attention-queue.js +186 -0
  376. package/dist/senses/await-turn-message.js +58 -0
  377. package/dist/senses/bluebubbles/active-turns.js +216 -0
  378. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  379. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  380. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +226 -19
  381. package/dist/senses/bluebubbles/context-packet.js +122 -0
  382. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  383. package/dist/senses/bluebubbles/entry.js +77 -0
  384. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  385. package/dist/senses/bluebubbles/index.js +2907 -0
  386. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  387. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  388. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  389. package/dist/senses/bluebubbles/outbound-state.js +304 -0
  390. package/dist/senses/bluebubbles/processed-log.js +133 -0
  391. package/dist/senses/bluebubbles/replay.js +284 -0
  392. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  393. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  394. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  395. package/dist/senses/cli/bracketed-paste.js +82 -0
  396. package/dist/senses/cli/image-paste.js +287 -0
  397. package/dist/senses/cli/image-ref-navigation.js +75 -0
  398. package/dist/senses/cli/ink-app.js +156 -0
  399. package/dist/senses/cli/inline-diff.js +64 -0
  400. package/dist/senses/cli/input-keys.js +174 -0
  401. package/dist/senses/cli/kill-ring.js +86 -0
  402. package/dist/senses/cli/message-list.js +51 -0
  403. package/dist/senses/cli/ouro-tui.js +607 -0
  404. package/dist/senses/cli/spinner-imperative.js +135 -0
  405. package/dist/senses/cli/spinner.js +101 -0
  406. package/dist/senses/cli/status-line.js +60 -0
  407. package/dist/senses/cli/streaming-markdown.js +526 -0
  408. package/dist/senses/cli/tool-display.js +85 -0
  409. package/dist/senses/cli/tool-render.js +85 -0
  410. package/dist/senses/cli/tui-store.js +240 -0
  411. package/dist/senses/cli/virtual-list.js +35 -0
  412. package/dist/senses/cli-entry.js +60 -8
  413. package/dist/senses/cli-layout.js +100 -0
  414. package/dist/senses/cli.js +521 -214
  415. package/dist/senses/commands.js +66 -3
  416. package/dist/senses/context-packet-ledger.js +371 -0
  417. package/dist/senses/context-packets.js +154 -0
  418. package/dist/senses/habit-turn-message.js +160 -0
  419. package/dist/senses/mail-entry.js +66 -0
  420. package/dist/senses/mail.js +395 -0
  421. package/dist/senses/pipeline.js +988 -178
  422. package/dist/senses/private-runtime-worker.js +739 -0
  423. package/dist/senses/private-runtime.js +1157 -0
  424. package/dist/senses/proactive-content-guard.js +51 -0
  425. package/dist/senses/shared-turn.js +416 -0
  426. package/dist/senses/surface-tool.js +109 -0
  427. package/dist/senses/teams-entry.js +60 -8
  428. package/dist/senses/teams.js +397 -112
  429. package/dist/senses/trust-gate.js +104 -9
  430. package/dist/senses/voice/audio-playback.js +237 -0
  431. package/dist/senses/voice/audio-routing.js +119 -0
  432. package/dist/senses/voice/elevenlabs.js +202 -0
  433. package/dist/senses/voice/floor-control.js +431 -0
  434. package/dist/senses/voice/floor-controller.js +115 -0
  435. package/dist/senses/voice/golden-path.js +116 -0
  436. package/dist/senses/voice/index.js +29 -0
  437. package/dist/senses/voice/meeting.js +113 -0
  438. package/dist/senses/voice/outbound.js +190 -0
  439. package/dist/senses/voice/phone.js +33 -0
  440. package/dist/senses/voice/playback.js +139 -0
  441. package/dist/senses/voice/realtime-eval.js +496 -0
  442. package/dist/senses/voice/realtime-trace.js +531 -0
  443. package/dist/senses/voice/transcript.js +70 -0
  444. package/dist/senses/voice/turn.js +191 -0
  445. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  446. package/dist/senses/voice/twilio-phone.js +5081 -0
  447. package/dist/senses/voice/types.js +2 -0
  448. package/dist/senses/voice/whisper.js +161 -0
  449. package/dist/senses/voice-entry.js +81 -0
  450. package/dist/senses/voice-realtime-eval-command.js +99 -0
  451. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  452. package/dist/senses/voice-twilio-entry.js +87 -0
  453. package/dist/trips/core.js +138 -0
  454. package/dist/trips/store.js +265 -0
  455. package/dist/util/frontmatter.js +69 -0
  456. package/package.json +57 -12
  457. package/skills/agent-commerce.md +113 -0
  458. package/skills/browser-navigation.md +117 -0
  459. package/skills/commerce-setup-guide.md +116 -0
  460. package/skills/commerce-setup.md +84 -0
  461. package/skills/configure-dev-tools.md +99 -0
  462. package/skills/travel-planning.md +138 -0
  463. package/dist/heart/daemon/auth-flow.js +0 -430
  464. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  465. package/dist/heart/daemon/update-hooks.js +0 -138
  466. package/dist/heart/safe-workspace.js +0 -228
  467. package/dist/heart/session-recall.js +0 -116
  468. package/dist/mind/friends/channel.js +0 -84
  469. package/dist/mind/friends/group-context.js +0 -144
  470. package/dist/mind/friends/resolver.js +0 -84
  471. package/dist/mind/friends/store-file.js +0 -190
  472. package/dist/mind/friends/store.js +0 -4
  473. package/dist/mind/friends/tokens.js +0 -26
  474. package/dist/mind/friends/trust-explanation.js +0 -74
  475. package/dist/mind/friends/types.js +0 -29
  476. package/dist/repertoire/tasks/board.js +0 -134
  477. package/dist/repertoire/tasks/index.js +0 -224
  478. package/dist/repertoire/tasks/lifecycle.js +0 -80
  479. package/dist/repertoire/tasks/middleware.js +0 -65
  480. package/dist/repertoire/tasks/parser.js +0 -173
  481. package/dist/repertoire/tasks/scanner.js +0 -132
  482. package/dist/repertoire/tasks/transitions.js +0 -144
  483. package/dist/senses/bluebubbles-entry.js +0 -13
  484. package/dist/senses/bluebubbles.js +0 -1180
  485. package/dist/senses/debug-activity.js +0 -148
  486. package/dist/senses/inner-dialog-worker.js +0 -90
  487. package/dist/senses/inner-dialog.js +0 -480
  488. package/subagents/README.md +0 -7
  489. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  490. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  491. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  492. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  493. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  494. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  495. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  496. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  497. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  498. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  499. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  500. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  501. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  502. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  503. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  504. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  505. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,1034 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isHabitRunTrigger = isHabitRunTrigger;
37
+ exports.flightRecorderLatestPath = flightRecorderLatestPath;
38
+ exports.decisionsFromHabitRunTraceSteps = decisionsFromHabitRunTraceSteps;
39
+ exports.isFlightRecorderResume = isFlightRecorderResume;
40
+ exports.readFlightRecorderResume = readFlightRecorderResume;
41
+ exports.writeFlightRecorderResume = writeFlightRecorderResume;
42
+ exports.recordFlightRecorderEvent = recordFlightRecorderEvent;
43
+ exports.isSafeHabitRunId = isSafeHabitRunId;
44
+ exports.readHabitRunReceipt = readHabitRunReceipt;
45
+ exports.listHabitRunReceipts = listHabitRunReceipts;
46
+ exports.writeHabitRunReceipt = writeHabitRunReceipt;
47
+ exports.formatFlightRecorderResume = formatFlightRecorderResume;
48
+ exports.createHabitRunId = createHabitRunId;
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const crypto_1 = require("crypto");
52
+ const session_events_1 = require("../heart/session-events");
53
+ const runtime_1 = require("../nerves/runtime");
54
+ const obligations_1 = require("./obligations");
55
+ const packets_1 = require("./packets");
56
+ function isHabitRunTrigger(value) {
57
+ return value === "cron"
58
+ || value === "launchd"
59
+ || value === "poke"
60
+ || value === "overdue"
61
+ || value === "manual";
62
+ }
63
+ function flightRecorderDir(agentRoot) {
64
+ return path.join(agentRoot, "arc", "flight-recorder");
65
+ }
66
+ function eventsDir(agentRoot) {
67
+ return path.join(flightRecorderDir(agentRoot), "events");
68
+ }
69
+ function receiptsDir(agentRoot) {
70
+ return path.join(flightRecorderDir(agentRoot), "habit-receipts");
71
+ }
72
+ function habitReceiptPath(agentRoot, runId) {
73
+ return path.join(receiptsDir(agentRoot), `${runId}.json`);
74
+ }
75
+ function flightRecorderLatestPath(agentRoot) {
76
+ return path.join(flightRecorderDir(agentRoot), "latest.json");
77
+ }
78
+ function eventDay(recordedAt) {
79
+ return recordedAt.slice(0, 10) || "unknown";
80
+ }
81
+ function atomicWriteJson(filePath, value) {
82
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
83
+ const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
84
+ fs.writeFileSync(tmpPath, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
85
+ fs.renameSync(tmpPath, filePath);
86
+ }
87
+ function cappedArray(values) {
88
+ return values.map((value) => (0, session_events_1.capStructuredRecordString)(value));
89
+ }
90
+ function decisionsFromHabitRunTraceSteps(traceSteps = []) {
91
+ const decisions = [];
92
+ for (const step of traceSteps) {
93
+ for (const decision of step.decisions ?? []) {
94
+ const trimmed = decision.trim();
95
+ if (trimmed.length > 0)
96
+ decisions.push((0, session_events_1.capStructuredRecordString)(trimmed));
97
+ }
98
+ }
99
+ return uniqueStrings(decisions);
100
+ }
101
+ function normalizeEvent(input) {
102
+ const recordedAt = input.recordedAt ?? new Date().toISOString();
103
+ return {
104
+ schemaVersion: 1,
105
+ id: input.id ?? `fr-${(0, crypto_1.randomUUID)()}`,
106
+ kind: input.kind,
107
+ recordedAt,
108
+ ...(input.turnId ? { turnId: input.turnId } : {}),
109
+ ...(input.sessionRef ? { sessionRef: input.sessionRef } : {}),
110
+ summary: (0, session_events_1.capStructuredRecordString)(input.summary),
111
+ ...(input.currentAsk !== undefined ? { currentAsk: input.currentAsk ? (0, session_events_1.capStructuredRecordString)(input.currentAsk) : null } : {}),
112
+ ...(input.nextSafeAction !== undefined ? { nextSafeAction: input.nextSafeAction ? (0, session_events_1.capStructuredRecordString)(input.nextSafeAction) : null } : {}),
113
+ ...(input.stopBefore ? { stopBefore: cappedArray(input.stopBefore) } : {}),
114
+ ...(input.blockedBecause ? { blockedBecause: cappedArray(input.blockedBecause) } : {}),
115
+ ...(input.activeObligationIds ? { activeObligationIds: cappedArray(input.activeObligationIds) } : {}),
116
+ ...(input.activeReturnObligationIds ? { activeReturnObligationIds: cappedArray(input.activeReturnObligationIds) } : {}),
117
+ ...(input.activePacketIds ? { activePacketIds: cappedArray(input.activePacketIds) } : {}),
118
+ ...(input.openEvolutionCaseIds ? { openEvolutionCaseIds: cappedArray(input.openEvolutionCaseIds) } : {}),
119
+ ...(input.recentClaimIds ? { recentClaimIds: cappedArray(input.recentClaimIds) } : {}),
120
+ ...(input.unverifiedClaimIds ? { unverifiedClaimIds: cappedArray(input.unverifiedClaimIds) } : {}),
121
+ ...(input.producedRefs ? { producedRefs: input.producedRefs.map((ref) => ({ ...ref, locator: (0, session_events_1.capStructuredRecordString)(ref.locator) })) } : {}),
122
+ ...(input.meta ? { meta: (0, session_events_1.capStructuredRecordStringLeaves)(input.meta) } : {}),
123
+ };
124
+ }
125
+ function degradedResume(issues) {
126
+ return {
127
+ schemaVersion: 1,
128
+ hasCompleteState: false,
129
+ canContinue: false,
130
+ missing: ["currentAsk", "nextSafeAction"],
131
+ gaps: [],
132
+ currentAsk: { value: null, confidence: "unknown", sourceEventIds: [] },
133
+ nextSafeAction: { value: null, stopBefore: [], sourceEventIds: [] },
134
+ blockedBecause: [],
135
+ activeObligationIds: [],
136
+ activeReturnObligationIds: [],
137
+ activePacketIds: [],
138
+ openEvolutionCaseIds: [],
139
+ recentClaimIds: [],
140
+ unverifiedClaimIds: [],
141
+ lastSafeCheckpoint: { turnId: null, sessionRef: null, recordedAt: null, sourceEventIds: [] },
142
+ recorderHealth: {
143
+ status: "degraded",
144
+ issues,
145
+ },
146
+ };
147
+ }
148
+ /* v8 ignore start -- defensive schema guard fan-out; tests cover valid load and malformed-shape degradation @preserve */
149
+ function isStringArray(value) {
150
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string");
151
+ }
152
+ function isNullableString(value) {
153
+ return value === null || typeof value === "string";
154
+ }
155
+ function isFlightRecorderResume(value) {
156
+ if (!value || typeof value !== "object" || Array.isArray(value))
157
+ return false;
158
+ const record = value;
159
+ const currentAsk = record.currentAsk;
160
+ const nextSafeAction = record.nextSafeAction;
161
+ const lastSafeCheckpoint = record.lastSafeCheckpoint;
162
+ const recorderHealth = record.recorderHealth;
163
+ return record.schemaVersion === 1
164
+ && typeof record.hasCompleteState === "boolean"
165
+ && typeof record.canContinue === "boolean"
166
+ && isStringArray(record.missing)
167
+ && isStringArray(record.gaps)
168
+ && !!currentAsk
169
+ && typeof currentAsk === "object"
170
+ && !Array.isArray(currentAsk)
171
+ && isNullableString(currentAsk.value)
172
+ && (currentAsk.confidence === "current" || currentAsk.confidence === "stale_risky" || currentAsk.confidence === "unknown")
173
+ && isStringArray(currentAsk.sourceEventIds)
174
+ && !!nextSafeAction
175
+ && typeof nextSafeAction === "object"
176
+ && !Array.isArray(nextSafeAction)
177
+ && isNullableString(nextSafeAction.value)
178
+ && isStringArray(nextSafeAction.stopBefore)
179
+ && isStringArray(nextSafeAction.sourceEventIds)
180
+ && isStringArray(record.blockedBecause)
181
+ && isStringArray(record.activeObligationIds)
182
+ && isStringArray(record.activeReturnObligationIds)
183
+ && isStringArray(record.activePacketIds)
184
+ && isStringArray(record.openEvolutionCaseIds)
185
+ && isStringArray(record.recentClaimIds)
186
+ && isStringArray(record.unverifiedClaimIds)
187
+ && !!lastSafeCheckpoint
188
+ && typeof lastSafeCheckpoint === "object"
189
+ && !Array.isArray(lastSafeCheckpoint)
190
+ && isNullableString(lastSafeCheckpoint.turnId)
191
+ && isNullableString(lastSafeCheckpoint.sessionRef)
192
+ && isNullableString(lastSafeCheckpoint.recordedAt)
193
+ && isStringArray(lastSafeCheckpoint.sourceEventIds)
194
+ && !!recorderHealth
195
+ && typeof recorderHealth === "object"
196
+ && !Array.isArray(recorderHealth)
197
+ && (recorderHealth.status === "ok" || recorderHealth.status === "degraded" || recorderHealth.status === "unavailable")
198
+ && isStringArray(recorderHealth.issues);
199
+ }
200
+ /* v8 ignore stop */
201
+ /* v8 ignore start -- semantic invariant fan-out is defensive; regression tests cover unsafe continuation normalization @preserve */
202
+ function nonEmpty(value) {
203
+ return typeof value === "string" && value.trim().length > 0;
204
+ }
205
+ function uniqueStrings(values) {
206
+ return [...new Set(values)];
207
+ }
208
+ function normalizeResumeInvariants(resume) {
209
+ const hasCurrentAsk = nonEmpty(resume.currentAsk.value);
210
+ const hasNextSafeAction = nonEmpty(resume.nextSafeAction.value);
211
+ const hasCompleteState = hasCurrentAsk && hasNextSafeAction;
212
+ const missing = [
213
+ ...(hasCurrentAsk ? [] : ["currentAsk"]),
214
+ ...(hasNextSafeAction ? [] : ["nextSafeAction"]),
215
+ ];
216
+ const missingChanged = resume.missing.join("\n") !== missing.join("\n");
217
+ const issues = [
218
+ ...(resume.canContinue && !hasCompleteState ? ["canContinue true while hasCompleteState false"] : []),
219
+ ...(resume.canContinue && !hasCurrentAsk ? ["canContinue true without currentAsk"] : []),
220
+ ...(resume.canContinue && !hasNextSafeAction ? ["canContinue true without nextSafeAction"] : []),
221
+ ...(resume.canContinue && resume.blockedBecause.length > 0 ? ["canContinue true while blocked"] : []),
222
+ ...(resume.canContinue && resume.recorderHealth.status !== "ok" ? ["canContinue true while recorder health is not ok"] : []),
223
+ ];
224
+ if (issues.length === 0 && resume.hasCompleteState === hasCompleteState && !missingChanged)
225
+ return resume;
226
+ return {
227
+ ...resume,
228
+ hasCompleteState,
229
+ canContinue: issues.length === 0 ? resume.canContinue : false,
230
+ missing,
231
+ currentAsk: {
232
+ ...resume.currentAsk,
233
+ confidence: hasCurrentAsk ? resume.currentAsk.confidence : "unknown",
234
+ },
235
+ recorderHealth: issues.length > 0
236
+ ? {
237
+ status: resume.recorderHealth.status === "unavailable" ? "unavailable" : "degraded",
238
+ issues: uniqueStrings([...resume.recorderHealth.issues, ...issues]),
239
+ }
240
+ : resume.recorderHealth,
241
+ };
242
+ }
243
+ const FLIGHT_RECORDER_RECONCILE_SOURCE_ID = "reconcile:active-obligations";
244
+ function remainingArcWorkDescriptions(resume) {
245
+ return [
246
+ ...resume.activeReturnObligationIds.map((id) => `return obligation ${id}`),
247
+ ...resume.activePacketIds.map((id) => `packet ${id}`),
248
+ ...resume.openEvolutionCaseIds.map((id) => `evolution case ${id}`),
249
+ ];
250
+ }
251
+ function nextSafeActionAfterObligationReconcile(resume, activeObligations, staleActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, unverifiableActivePacketIds) {
252
+ if (unverifiableActiveObligationIds.length > 0) {
253
+ return (0, session_events_1.capStructuredRecordString)(`inspect unverifiable active obligations before acting: ${unverifiableActiveObligationIds.join(", ")}`);
254
+ }
255
+ if (unverifiableActiveReturnObligationIds.length > 0) {
256
+ return (0, session_events_1.capStructuredRecordString)(`inspect unverifiable active return obligations before acting: ${unverifiableActiveReturnObligationIds.join(", ")}`);
257
+ }
258
+ if (unverifiableActivePacketIds.length > 0) {
259
+ return (0, session_events_1.capStructuredRecordString)(`inspect unverifiable active packets before acting: ${unverifiableActivePacketIds.join(", ")}`);
260
+ }
261
+ const firstActive = activeObligations[0];
262
+ if (firstActive) {
263
+ const detail = firstActive.nextAction?.trim() || firstActive.content;
264
+ return (0, session_events_1.capStructuredRecordString)(`continue open obligation ${firstActive.id}: ${detail}`);
265
+ }
266
+ const remainingWork = remainingArcWorkDescriptions(resume);
267
+ if (remainingWork.length > 0) {
268
+ return (0, session_events_1.capStructuredRecordString)(`continue remaining Arc work: ${remainingWork.slice(0, 5).join(", ")}`);
269
+ }
270
+ if (staleActiveObligationIds.length > 0) {
271
+ return (0, session_events_1.capStructuredRecordString)(`wait for new input; reconciled completed or missing obligations: ${staleActiveObligationIds.join(", ")}`);
272
+ }
273
+ if (staleActiveReturnObligationIds.length > 0) {
274
+ return (0, session_events_1.capStructuredRecordString)(`wait for new input; reconciled completed or missing return obligations: ${staleActiveReturnObligationIds.join(", ")}`);
275
+ }
276
+ return (0, session_events_1.capStructuredRecordString)(`wait for new input; reconciled completed or missing packets: ${staleActivePacketIds.join(", ")}`);
277
+ }
278
+ function reconcileActiveReturnObligationIds(resume, returnObligations, activeReturnObligations) {
279
+ const canonicalIdSet = new Set(returnObligations.map((obligation) => obligation.id));
280
+ const activeIdSet = new Set(activeReturnObligations.map((obligation) => obligation.id));
281
+ const resumeIdSet = new Set(resume.activeReturnObligationIds);
282
+ const staleActiveReturnObligationIds = resume.activeReturnObligationIds.filter((id) => canonicalIdSet.has(id) && !activeIdSet.has(id));
283
+ const unverifiableActiveReturnObligationIds = resume.activeReturnObligationIds.filter((id) => !canonicalIdSet.has(id));
284
+ const missingActiveReturnObligationIds = activeReturnObligations
285
+ .map((obligation) => obligation.id)
286
+ .filter((id) => !resumeIdSet.has(id));
287
+ const activeReturnObligationIds = uniqueStrings([
288
+ ...resume.activeReturnObligationIds.filter((id) => !staleActiveReturnObligationIds.includes(id)),
289
+ ...missingActiveReturnObligationIds,
290
+ ]);
291
+ return {
292
+ activeReturnObligationIds,
293
+ staleActiveReturnObligationIds,
294
+ missingActiveReturnObligationIds,
295
+ unverifiableActiveReturnObligationIds,
296
+ };
297
+ }
298
+ function reconcileActivePacketIds(resume, packets, activePackets) {
299
+ const canonicalIdSet = new Set(packets.map((packet) => packet.id));
300
+ const activeIdSet = new Set(activePackets.map((packet) => packet.id));
301
+ const resumeIdSet = new Set(resume.activePacketIds);
302
+ const staleActivePacketIds = resume.activePacketIds.filter((id) => canonicalIdSet.has(id) && !activeIdSet.has(id));
303
+ const unverifiableActivePacketIds = resume.activePacketIds.filter((id) => !canonicalIdSet.has(id));
304
+ const missingActivePacketIds = activePackets
305
+ .map((packet) => packet.id)
306
+ .filter((id) => !resumeIdSet.has(id));
307
+ const activePacketIds = uniqueStrings([
308
+ ...resume.activePacketIds.filter((id) => !staleActivePacketIds.includes(id)),
309
+ ...missingActivePacketIds,
310
+ ]);
311
+ return { activePacketIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds };
312
+ }
313
+ function reconcileActiveObligations(agentRoot, resume) {
314
+ const obligations = (0, obligations_1.readVerifiedObligations)(agentRoot);
315
+ const activeObligations = (0, obligations_1.readVerifiedPendingObligations)(agentRoot);
316
+ const returnObligations = (0, obligations_1.listReturnObligationsForRoot)(agentRoot);
317
+ const activeReturnObligations = (0, obligations_1.listActiveReturnObligationsForRoot)(agentRoot);
318
+ const packets = (0, packets_1.listPonderPackets)(agentRoot);
319
+ const activePackets = (0, packets_1.listActivePonderPackets)(agentRoot);
320
+ const canonicalIdSet = new Set(obligations.map((obligation) => obligation.id));
321
+ const openIdSet = new Set(activeObligations.map((obligation) => obligation.id));
322
+ const resumeIdSet = new Set(resume.activeObligationIds);
323
+ const staleActiveObligationIds = resume.activeObligationIds.filter((id) => canonicalIdSet.has(id) && !openIdSet.has(id));
324
+ const unverifiableActiveObligationIds = resume.activeObligationIds.filter((id) => !canonicalIdSet.has(id));
325
+ const missingActiveObligationIds = activeObligations
326
+ .map((obligation) => obligation.id)
327
+ .filter((id) => !resumeIdSet.has(id));
328
+ const { activeReturnObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, } = reconcileActiveReturnObligationIds(resume, returnObligations, activeReturnObligations);
329
+ const { activePacketIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds, } = reconcileActivePacketIds(resume, packets, activePackets);
330
+ if (staleActiveObligationIds.length === 0
331
+ && missingActiveObligationIds.length === 0
332
+ && unverifiableActiveObligationIds.length === 0
333
+ && staleActiveReturnObligationIds.length === 0
334
+ && missingActiveReturnObligationIds.length === 0
335
+ && unverifiableActiveReturnObligationIds.length === 0
336
+ && staleActivePacketIds.length === 0
337
+ && missingActivePacketIds.length === 0
338
+ && unverifiableActivePacketIds.length === 0) {
339
+ return {
340
+ resume,
341
+ staleActiveObligationIds,
342
+ missingActiveObligationIds,
343
+ unverifiableActiveObligationIds,
344
+ staleActiveReturnObligationIds,
345
+ missingActiveReturnObligationIds,
346
+ unverifiableActiveReturnObligationIds,
347
+ staleActivePacketIds,
348
+ missingActivePacketIds,
349
+ unverifiableActivePacketIds,
350
+ };
351
+ }
352
+ const activeObligationIds = uniqueStrings([
353
+ ...resume.activeObligationIds.filter((id) => !staleActiveObligationIds.includes(id)),
354
+ ...missingActiveObligationIds,
355
+ ]);
356
+ const hasActiveArcContinuation = activeObligationIds.length > 0
357
+ || activeReturnObligationIds.length > 0
358
+ || activePacketIds.length > 0
359
+ || resume.openEvolutionCaseIds.length > 0;
360
+ const isTerminalWait = (staleActiveObligationIds.length > 0
361
+ || staleActiveReturnObligationIds.length > 0
362
+ || staleActivePacketIds.length > 0) && !hasActiveArcContinuation;
363
+ const mustSynthesizeAction = staleActiveObligationIds.length > 0
364
+ || unverifiableActiveObligationIds.length > 0
365
+ || staleActiveReturnObligationIds.length > 0
366
+ || unverifiableActiveReturnObligationIds.length > 0
367
+ || staleActivePacketIds.length > 0
368
+ || unverifiableActivePacketIds.length > 0
369
+ || !nonEmpty(resume.nextSafeAction.value);
370
+ const nextSafeActionValue = mustSynthesizeAction
371
+ ? nextSafeActionAfterObligationReconcile({ ...resume, activeObligationIds, activeReturnObligationIds, activePacketIds }, activeObligations, staleActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, unverifiableActivePacketIds)
372
+ : resume.nextSafeAction.value;
373
+ const unverifiableIssues = [
374
+ ...(unverifiableActiveObligationIds.length > 0
375
+ ? [`active obligation ids could not be verified in arc/obligations: ${unverifiableActiveObligationIds.join(", ")}`]
376
+ : []),
377
+ ...(unverifiableActiveReturnObligationIds.length > 0
378
+ ? [`active return obligation ids could not be verified in arc/obligations/inner: ${unverifiableActiveReturnObligationIds.join(", ")}`]
379
+ : []),
380
+ ...(unverifiableActivePacketIds.length > 0
381
+ ? [`active packet ids could not be verified in arc/packets: ${unverifiableActivePacketIds.join(", ")}`]
382
+ : []),
383
+ ];
384
+ const recorderHealth = unverifiableIssues.length > 0
385
+ ? {
386
+ status: resume.recorderHealth.status === "unavailable" ? "unavailable" : "degraded",
387
+ issues: uniqueStrings([...resume.recorderHealth.issues, ...unverifiableIssues]),
388
+ }
389
+ : resume.recorderHealth;
390
+ const canContinue = nonEmpty(resume.currentAsk.value)
391
+ && nonEmpty(nextSafeActionValue)
392
+ && resume.blockedBecause.length === 0
393
+ && recorderHealth.status === "ok"
394
+ && hasActiveArcContinuation
395
+ && !isTerminalWait;
396
+ return {
397
+ resume: normalizeResumeInvariants({
398
+ ...resume,
399
+ canContinue,
400
+ recorderHealth,
401
+ activeObligationIds,
402
+ activeReturnObligationIds,
403
+ activePacketIds,
404
+ nextSafeAction: {
405
+ ...resume.nextSafeAction,
406
+ value: nextSafeActionValue,
407
+ sourceEventIds: mustSynthesizeAction
408
+ ? [FLIGHT_RECORDER_RECONCILE_SOURCE_ID]
409
+ : resume.nextSafeAction.sourceEventIds,
410
+ stopBefore: unverifiableActiveObligationIds.length > 0
411
+ || unverifiableActiveReturnObligationIds.length > 0
412
+ || unverifiableActivePacketIds.length > 0
413
+ ? uniqueStrings([
414
+ ...resume.nextSafeAction.stopBefore,
415
+ ...(unverifiableActiveObligationIds.length > 0 ? ["acting on unverifiable obligation state"] : []),
416
+ ...(unverifiableActiveReturnObligationIds.length > 0 ? ["acting on unverifiable return obligation state"] : []),
417
+ ...(unverifiableActivePacketIds.length > 0 ? ["acting on unverifiable packet state"] : []),
418
+ ])
419
+ : resume.nextSafeAction.stopBefore,
420
+ },
421
+ }),
422
+ staleActiveObligationIds,
423
+ missingActiveObligationIds,
424
+ unverifiableActiveObligationIds,
425
+ staleActiveReturnObligationIds,
426
+ missingActiveReturnObligationIds,
427
+ unverifiableActiveReturnObligationIds,
428
+ staleActivePacketIds,
429
+ missingActivePacketIds,
430
+ unverifiableActivePacketIds,
431
+ };
432
+ }
433
+ function normalizeResumeForAgentRoot(agentRoot, resume) {
434
+ return reconcileActiveObligations(agentRoot, normalizeResumeInvariants(resume));
435
+ }
436
+ function emitFlightRecorderReconciled(agentRoot, staleActiveObligationIds, missingActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds) {
437
+ if (staleActiveObligationIds.length === 0
438
+ && missingActiveObligationIds.length === 0
439
+ && unverifiableActiveObligationIds.length === 0
440
+ && staleActiveReturnObligationIds.length === 0
441
+ && missingActiveReturnObligationIds.length === 0
442
+ && unverifiableActiveReturnObligationIds.length === 0
443
+ && staleActivePacketIds.length === 0
444
+ && missingActivePacketIds.length === 0
445
+ && unverifiableActivePacketIds.length === 0)
446
+ return;
447
+ (0, runtime_1.emitNervesEvent)({
448
+ component: "mind",
449
+ event: "mind.flight_recorder_resume_reconciled",
450
+ message: "flight recorder resume reconciled with canonical Arc state",
451
+ meta: {
452
+ agentRoot,
453
+ staleActiveObligationIds,
454
+ missingActiveObligationIds,
455
+ unverifiableActiveObligationIds,
456
+ staleActiveReturnObligationIds,
457
+ missingActiveReturnObligationIds,
458
+ unverifiableActiveReturnObligationIds,
459
+ staleActivePacketIds,
460
+ missingActivePacketIds,
461
+ unverifiableActivePacketIds,
462
+ },
463
+ });
464
+ }
465
+ function latestFromEvent(event, previous) {
466
+ const currentAskValue = event.currentAsk !== undefined ? event.currentAsk : previous.currentAsk.value;
467
+ const nextSafeActionValue = event.nextSafeAction !== undefined ? event.nextSafeAction : previous.nextSafeAction.value;
468
+ const currentAskSourceEventIds = event.currentAsk !== undefined ? [event.id] : previous.currentAsk.sourceEventIds;
469
+ const nextSafeActionSourceEventIds = event.nextSafeAction !== undefined ? [event.id] : previous.nextSafeAction.sourceEventIds;
470
+ const inheritedBlocker = event.blockedBecause === undefined && previous.blockedBecause.length > 0;
471
+ const lastSafeCheckpointEventIds = inheritedBlocker
472
+ ? uniqueStrings([...previous.lastSafeCheckpoint.sourceEventIds, event.id])
473
+ : [event.id];
474
+ const hasCurrentAsk = typeof currentAskValue === "string" && currentAskValue.trim().length > 0;
475
+ const hasNextSafeAction = typeof nextSafeActionValue === "string" && nextSafeActionValue.trim().length > 0;
476
+ return {
477
+ ...previous,
478
+ hasCompleteState: hasCurrentAsk && hasNextSafeAction,
479
+ canContinue: hasCurrentAsk && hasNextSafeAction && (event.blockedBecause?.length ?? previous.blockedBecause.length) === 0,
480
+ missing: [
481
+ ...(hasCurrentAsk ? [] : ["currentAsk"]),
482
+ ...(hasNextSafeAction ? [] : ["nextSafeAction"]),
483
+ ],
484
+ currentAsk: {
485
+ value: currentAskValue,
486
+ confidence: hasCurrentAsk ? "current" : "unknown",
487
+ sourceEventIds: currentAskSourceEventIds,
488
+ },
489
+ nextSafeAction: {
490
+ value: nextSafeActionValue,
491
+ stopBefore: event.stopBefore ?? previous.nextSafeAction.stopBefore,
492
+ sourceEventIds: nextSafeActionSourceEventIds,
493
+ },
494
+ blockedBecause: event.blockedBecause ?? previous.blockedBecause,
495
+ activeObligationIds: event.activeObligationIds ?? previous.activeObligationIds,
496
+ activeReturnObligationIds: event.activeReturnObligationIds ?? previous.activeReturnObligationIds,
497
+ activePacketIds: event.activePacketIds ?? previous.activePacketIds,
498
+ openEvolutionCaseIds: event.openEvolutionCaseIds ?? previous.openEvolutionCaseIds,
499
+ recentClaimIds: event.recentClaimIds ?? previous.recentClaimIds,
500
+ unverifiedClaimIds: event.unverifiedClaimIds ?? previous.unverifiedClaimIds,
501
+ lastSafeCheckpoint: {
502
+ turnId: event.turnId ?? previous.lastSafeCheckpoint.turnId,
503
+ sessionRef: event.sessionRef ?? previous.lastSafeCheckpoint.sessionRef,
504
+ recordedAt: event.recordedAt,
505
+ sourceEventIds: lastSafeCheckpointEventIds,
506
+ },
507
+ recorderHealth: { status: "ok", issues: [] },
508
+ };
509
+ }
510
+ function readFlightRecorderResume(agentRoot) {
511
+ const latestPath = flightRecorderLatestPath(agentRoot);
512
+ try {
513
+ const parsed = JSON.parse(fs.readFileSync(latestPath, "utf-8"));
514
+ if (!isFlightRecorderResume(parsed)) {
515
+ throw new Error("latest.json has invalid flight-recorder resume shape");
516
+ }
517
+ const { resume, staleActiveObligationIds, missingActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds, } = normalizeResumeForAgentRoot(agentRoot, parsed);
518
+ if (staleActiveObligationIds.length > 0
519
+ || missingActiveObligationIds.length > 0
520
+ || unverifiableActiveObligationIds.length > 0
521
+ || staleActiveReturnObligationIds.length > 0
522
+ || missingActiveReturnObligationIds.length > 0
523
+ || unverifiableActiveReturnObligationIds.length > 0
524
+ || staleActivePacketIds.length > 0
525
+ || missingActivePacketIds.length > 0
526
+ || unverifiableActivePacketIds.length > 0) {
527
+ emitFlightRecorderReconciled(agentRoot, staleActiveObligationIds, missingActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds);
528
+ }
529
+ (0, runtime_1.emitNervesEvent)({
530
+ component: "mind",
531
+ event: "mind.flight_recorder_resume_read",
532
+ message: "flight recorder resume read",
533
+ meta: { agentRoot, canContinue: resume.canContinue, hasCompleteState: resume.hasCompleteState },
534
+ });
535
+ return resume;
536
+ }
537
+ catch (error) {
538
+ const issue = fs.existsSync(latestPath)
539
+ ? `latest.json unreadable: ${error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error)}`
540
+ : "latest.json missing";
541
+ (0, runtime_1.emitNervesEvent)({
542
+ component: "mind",
543
+ event: "mind.flight_recorder_resume_read",
544
+ message: "flight recorder resume missing or degraded",
545
+ meta: { agentRoot, issue },
546
+ });
547
+ return degradedResume([issue]);
548
+ }
549
+ }
550
+ function writeFlightRecorderResume(agentRoot, resume) {
551
+ const { resume: safeResume, staleActiveObligationIds, missingActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds, } = normalizeResumeForAgentRoot(agentRoot, resume);
552
+ atomicWriteJson(flightRecorderLatestPath(agentRoot), safeResume);
553
+ emitFlightRecorderReconciled(agentRoot, staleActiveObligationIds, missingActiveObligationIds, unverifiableActiveObligationIds, staleActiveReturnObligationIds, missingActiveReturnObligationIds, unverifiableActiveReturnObligationIds, staleActivePacketIds, missingActivePacketIds, unverifiableActivePacketIds);
554
+ (0, runtime_1.emitNervesEvent)({
555
+ component: "mind",
556
+ event: "mind.flight_recorder_resume_written",
557
+ message: "flight recorder resume written",
558
+ meta: { agentRoot, canContinue: safeResume.canContinue, hasCompleteState: safeResume.hasCompleteState },
559
+ });
560
+ }
561
+ function recordFlightRecorderEvent(agentRoot, input) {
562
+ const event = normalizeEvent(input);
563
+ fs.mkdirSync(eventsDir(agentRoot), { recursive: true });
564
+ fs.appendFileSync(path.join(eventsDir(agentRoot), `${eventDay(event.recordedAt)}.jsonl`), `${JSON.stringify(event)}\n`, "utf-8");
565
+ const latest = latestFromEvent(event, readFlightRecorderResume(agentRoot));
566
+ writeFlightRecorderResume(agentRoot, latest);
567
+ (0, runtime_1.emitNervesEvent)({
568
+ component: "mind",
569
+ event: "mind.flight_recorder_event_recorded",
570
+ message: "flight recorder event recorded",
571
+ meta: { agentRoot, eventId: event.id, kind: event.kind },
572
+ });
573
+ return event;
574
+ }
575
+ function isSafeHabitRunId(value) {
576
+ return typeof value === "string"
577
+ && /^[A-Za-z0-9][A-Za-z0-9_.:-]*$/.test(value)
578
+ && !value.includes("..");
579
+ }
580
+ function isPlainRecord(value) {
581
+ return !!value && typeof value === "object" && !Array.isArray(value);
582
+ }
583
+ function isProducedRefArray(value) {
584
+ return Array.isArray(value)
585
+ && value.every((entry) => isPlainRecord(entry)
586
+ && (entry.kind === "arc"
587
+ || entry.kind === "desk_task"
588
+ || entry.kind === "desk_record"
589
+ || entry.kind === "claim"
590
+ || entry.kind === "surface"
591
+ || entry.kind === "none")
592
+ && typeof entry.locator === "string");
593
+ }
594
+ function isHabitSurfaceAttemptArray(value) {
595
+ return Array.isArray(value)
596
+ && value.every((entry) => isPlainRecord(entry)
597
+ && typeof entry.recipient === "string"
598
+ && typeof entry.channel === "string"
599
+ && (entry.reason === "needed_input"
600
+ || entry.reason === "status"
601
+ || entry.reason === "answer"
602
+ || entry.reason === "blocked"
603
+ || entry.reason === "other")
604
+ && (entry.result === "sent"
605
+ || entry.result === "delivered"
606
+ || entry.result === "delivered_now"
607
+ || entry.result === "queued"
608
+ || entry.result === "deferred"
609
+ || entry.result === "blocked"
610
+ || entry.result === "failed"
611
+ || entry.result === "unavailable")
612
+ && (entry.routeKind === undefined
613
+ || entry.routeKind === "family"
614
+ || entry.routeKind === "originator"
615
+ || entry.routeKind === "extra")
616
+ && (entry.rawStatus === undefined || typeof entry.rawStatus === "string")
617
+ && (entry.error === undefined || typeof entry.error === "string"));
618
+ }
619
+ function isHabitRunTraceStepKind(value) {
620
+ return value === "trigger"
621
+ || value === "habit_definition"
622
+ || value === "fetch"
623
+ || value === "snapshot"
624
+ || value === "render"
625
+ || value === "decision"
626
+ || value === "produced_ref"
627
+ || value === "surface_attempt"
628
+ || value === "send"
629
+ || value === "ledger"
630
+ || value === "error"
631
+ || value === "complete";
632
+ }
633
+ function isHabitRunTraceStepStatus(value) {
634
+ return value === "started"
635
+ || value === "succeeded"
636
+ || value === "skipped"
637
+ || value === "blocked"
638
+ || value === "failed";
639
+ }
640
+ function isHabitRunTraceRefArray(value) {
641
+ return Array.isArray(value)
642
+ && value.every((entry) => isPlainRecord(entry)
643
+ && typeof entry.kind === "string"
644
+ && entry.kind.trim().length > 0
645
+ && typeof entry.locator === "string"
646
+ && entry.locator.trim().length > 0
647
+ && (entry.label === undefined || typeof entry.label === "string"));
648
+ }
649
+ function isHabitRunTraceStepArray(value) {
650
+ return Array.isArray(value)
651
+ && value.every((entry) => isPlainRecord(entry)
652
+ && entry.schemaVersion === 1
653
+ && typeof entry.stepId === "string"
654
+ && entry.stepId.trim().length > 0
655
+ && isHabitRunTraceStepKind(entry.kind)
656
+ && isHabitRunTraceStepStatus(entry.status)
657
+ && typeof entry.at === "string"
658
+ && entry.at.trim().length > 0
659
+ && typeof entry.summary === "string"
660
+ && entry.summary.trim().length > 0
661
+ && (entry.refs === undefined || isHabitRunTraceRefArray(entry.refs))
662
+ && (entry.producedRefs === undefined || isProducedRefArray(entry.producedRefs))
663
+ && (entry.decisions === undefined || isStringArray(entry.decisions))
664
+ && (entry.surfaceAttempt === undefined || isHabitSurfaceAttemptArray([entry.surfaceAttempt]))
665
+ && (entry.error === undefined || typeof entry.error === "string")
666
+ && (entry.meta === undefined || isPlainRecord(entry.meta)));
667
+ }
668
+ function isHabitReturnRouteArray(value) {
669
+ return Array.isArray(value)
670
+ && value.every((entry) => isPlainRecord(entry)
671
+ && (entry.kind === "family" || entry.kind === "originator" || entry.kind === "extra")
672
+ && typeof entry.recipient === "string"
673
+ && (entry.status === "allowed" || entry.status === "unresolved")
674
+ && (entry.friendId === undefined || typeof entry.friendId === "string")
675
+ && (entry.channel === undefined || typeof entry.channel === "string")
676
+ && (entry.key === undefined || typeof entry.key === "string")
677
+ && (entry.reason === undefined || typeof entry.reason === "string"));
678
+ }
679
+ function isHabitPermissionEnvelope(value) {
680
+ if (!isPlainRecord(value))
681
+ return false;
682
+ return value.schemaVersion === 1
683
+ && typeof value.canMessageOutward === "boolean"
684
+ && isHabitReturnRouteArray(value.returnRoutes)
685
+ && isStringArray(value.deniedTools)
686
+ && isStringArray(value.warnings);
687
+ }
688
+ function isHabitToolPolicy(value) {
689
+ if (!isPlainRecord(value))
690
+ return false;
691
+ return (value.requestedTools === null || isStringArray(value.requestedTools))
692
+ && isStringArray(value.grantedTools)
693
+ && isStringArray(value.deniedTools)
694
+ && typeof value.outwardMessagingAllowed === "boolean";
695
+ }
696
+ function defaultHabitRunSummarySnapshot(receipt) {
697
+ const decisions = decisionsFromHabitRunTraceSteps(receipt.traceSteps);
698
+ if (receipt.errors.length > 0) {
699
+ return {
700
+ summary: `Habit ${receipt.habitName} finished with errors: ${receipt.errors.join("; ")}`,
701
+ decisions,
702
+ nextLikelyStep: null,
703
+ };
704
+ }
705
+ const surface = receipt.surfaceAttempts.find((attempt) => attempt.result !== "blocked" && attempt.result !== "failed" && attempt.result !== "unavailable");
706
+ if (surface) {
707
+ return {
708
+ summary: `Habit ${receipt.habitName} surfaced via ${surface.recipient}/${surface.channel}.`,
709
+ decisions,
710
+ nextLikelyStep: null,
711
+ };
712
+ }
713
+ const produced = receipt.producedRefs.find((ref) => ref.kind !== "none");
714
+ if (produced) {
715
+ return {
716
+ summary: `Habit ${receipt.habitName} produced ${produced.kind}: ${produced.locator}.`,
717
+ decisions,
718
+ nextLikelyStep: null,
719
+ };
720
+ }
721
+ return {
722
+ summary: `Habit ${receipt.habitName} finished with ${receipt.outcome}.`,
723
+ decisions,
724
+ nextLikelyStep: null,
725
+ };
726
+ }
727
+ function normalizeHabitRunSummarySnapshot(value, fallback) {
728
+ const snapshot = isPlainRecord(value) ? value : {};
729
+ const summary = typeof snapshot.summary === "string" && snapshot.summary.trim().length > 0
730
+ ? snapshot.summary
731
+ : fallback.summary;
732
+ const nextLikelyStep = snapshot.nextLikelyStep === null
733
+ ? null
734
+ : typeof snapshot.nextLikelyStep === "string" && snapshot.nextLikelyStep.trim().length > 0
735
+ ? snapshot.nextLikelyStep
736
+ : fallback.nextLikelyStep;
737
+ return {
738
+ summary: (0, session_events_1.capStructuredRecordString)(summary),
739
+ decisions: cappedArray(isStringArray(snapshot.decisions) && snapshot.decisions.length > 0 ? snapshot.decisions : fallback.decisions),
740
+ nextLikelyStep: nextLikelyStep === null ? null : (0, session_events_1.capStructuredRecordString)(nextLikelyStep),
741
+ };
742
+ }
743
+ function isHabitRunReceipt(value) {
744
+ if (!isPlainRecord(value))
745
+ return false;
746
+ return value.schemaVersion === 2
747
+ && isSafeHabitRunId(value.runId)
748
+ && typeof value.sessionId === "string"
749
+ && typeof value.habitName === "string"
750
+ && (value.trigger === "cron"
751
+ || value.trigger === "launchd"
752
+ || value.trigger === "poke"
753
+ || value.trigger === "overdue"
754
+ || value.trigger === "manual")
755
+ && typeof value.startedAt === "string"
756
+ && typeof value.endedAt === "string"
757
+ && (value.outcome === "no_change"
758
+ || value.outcome === "wrote_arc"
759
+ || value.outcome === "updated_desk"
760
+ || value.outcome === "wrote_record"
761
+ || value.outcome === "surfaced"
762
+ || value.outcome === "blocked"
763
+ || value.outcome === "error")
764
+ && typeof value.definitionLocator === "string"
765
+ && typeof value.sessionLocator === "string"
766
+ && typeof value.pendingLocator === "string"
767
+ && typeof value.runtimeStateLocator === "string"
768
+ && typeof value.receiptLocator === "string"
769
+ && (value.operationId === undefined || value.operationId === null || typeof value.operationId === "string")
770
+ && (value.nextRunAt === null || typeof value.nextRunAt === "string")
771
+ && isHabitPermissionEnvelope(value.permissionEnvelope)
772
+ && isHabitToolPolicy(value.toolPolicy)
773
+ && (value.summarySnapshot === undefined || isPlainRecord(value.summarySnapshot))
774
+ && isProducedRefArray(value.producedRefs)
775
+ && isHabitSurfaceAttemptArray(value.surfaceAttempts)
776
+ && (value.traceSteps === undefined || isHabitRunTraceStepArray(value.traceSteps))
777
+ && isStringArray(value.errors);
778
+ }
779
+ function isLegacyHabitRunReceipt(value) {
780
+ if (!isPlainRecord(value))
781
+ return false;
782
+ return value.schemaVersion === 1
783
+ && isSafeHabitRunId(value.runId)
784
+ && typeof value.habitName === "string"
785
+ && (value.trigger === "cron"
786
+ || value.trigger === "launchd"
787
+ || value.trigger === "poke"
788
+ || value.trigger === "overdue"
789
+ || value.trigger === "manual")
790
+ && typeof value.startedAt === "string"
791
+ && typeof value.endedAt === "string"
792
+ && (value.outcome === "no_change"
793
+ || value.outcome === "wrote_arc"
794
+ || value.outcome === "updated_desk"
795
+ || value.outcome === "wrote_record"
796
+ || value.outcome === "surfaced"
797
+ || value.outcome === "blocked"
798
+ || value.outcome === "error")
799
+ && isProducedRefArray(value.producedRefs)
800
+ && isHabitSurfaceAttemptArray(value.surfaceAttempts)
801
+ && isStringArray(value.errors);
802
+ }
803
+ function warnMalformedHabitReceipt(agentRoot, runId, reason) {
804
+ (0, runtime_1.emitNervesEvent)({
805
+ level: "warn",
806
+ component: "mind",
807
+ event: "mind.flight_recorder_habit_receipt_malformed",
808
+ message: "flight recorder habit receipt malformed",
809
+ meta: { agentRoot, runId: (0, session_events_1.capStructuredRecordString)(runId), reason },
810
+ });
811
+ }
812
+ function normalizeLegacyHabitRunReceipt(receipt) {
813
+ const sawSurface = receipt.surfaceAttempts.length > 0 || receipt.producedRefs.some((ref) => ref.kind === "surface");
814
+ return {
815
+ schemaVersion: 2,
816
+ runId: receipt.runId,
817
+ sessionId: receipt.runId,
818
+ habitName: receipt.habitName,
819
+ trigger: receipt.trigger,
820
+ startedAt: receipt.startedAt,
821
+ endedAt: receipt.endedAt,
822
+ outcome: receipt.outcome,
823
+ definitionLocator: `habits/${receipt.habitName}.md`,
824
+ sessionLocator: `state/habit-sessions/${receipt.runId}/session.json`,
825
+ pendingLocator: `state/habit-sessions/${receipt.runId}/pending`,
826
+ runtimeStateLocator: `state/habits/${receipt.habitName}.json`,
827
+ receiptLocator: `arc/flight-recorder/habit-receipts/${receipt.runId}.json`,
828
+ operationId: null,
829
+ nextRunAt: null,
830
+ permissionEnvelope: {
831
+ schemaVersion: 1,
832
+ canMessageOutward: sawSurface,
833
+ returnRoutes: [],
834
+ deniedTools: sawSurface ? [] : ["send_message", "surface"],
835
+ warnings: ["legacy receipt normalized without habit permission envelope"],
836
+ },
837
+ toolPolicy: {
838
+ requestedTools: null,
839
+ grantedTools: sawSurface ? ["surface"] : [],
840
+ deniedTools: sawSurface ? [] : ["send_message", "surface"],
841
+ outwardMessagingAllowed: sawSurface,
842
+ },
843
+ summarySnapshot: defaultHabitRunSummarySnapshot(receipt),
844
+ producedRefs: receipt.producedRefs,
845
+ surfaceAttempts: receipt.surfaceAttempts,
846
+ traceSteps: [],
847
+ errors: receipt.errors,
848
+ };
849
+ }
850
+ function capHabitRunTraceRefs(refs) {
851
+ if (!refs || refs.length === 0)
852
+ return undefined;
853
+ return refs.map((ref) => ({
854
+ kind: (0, session_events_1.capStructuredRecordString)(ref.kind),
855
+ locator: (0, session_events_1.capStructuredRecordString)(ref.locator),
856
+ ...(ref.label ? { label: (0, session_events_1.capStructuredRecordString)(ref.label) } : {}),
857
+ }));
858
+ }
859
+ function capHabitRunTraceStep(step) {
860
+ const refs = capHabitRunTraceRefs(step.refs);
861
+ const producedRefs = step.producedRefs?.map((ref) => ({ ...ref, locator: (0, session_events_1.capStructuredRecordString)(ref.locator) }));
862
+ const decisions = step.decisions ? cappedArray(step.decisions) : undefined;
863
+ const surfaceAttempt = step.surfaceAttempt
864
+ ? {
865
+ ...step.surfaceAttempt,
866
+ recipient: (0, session_events_1.capStructuredRecordString)(step.surfaceAttempt.recipient),
867
+ channel: (0, session_events_1.capStructuredRecordString)(step.surfaceAttempt.channel),
868
+ ...(step.surfaceAttempt.rawStatus ? { rawStatus: (0, session_events_1.capStructuredRecordString)(step.surfaceAttempt.rawStatus) } : {}),
869
+ ...(step.surfaceAttempt.error ? { error: (0, session_events_1.capStructuredRecordString)(step.surfaceAttempt.error) } : {}),
870
+ }
871
+ : undefined;
872
+ return {
873
+ schemaVersion: 1,
874
+ stepId: (0, session_events_1.capStructuredRecordString)(step.stepId),
875
+ kind: step.kind,
876
+ status: step.status,
877
+ at: (0, session_events_1.capStructuredRecordString)(step.at),
878
+ summary: (0, session_events_1.capStructuredRecordString)(step.summary),
879
+ ...(refs ? { refs } : {}),
880
+ ...(producedRefs && producedRefs.length > 0 ? { producedRefs } : {}),
881
+ ...(decisions && decisions.length > 0 ? { decisions } : {}),
882
+ ...(surfaceAttempt ? { surfaceAttempt } : {}),
883
+ ...(step.error ? { error: (0, session_events_1.capStructuredRecordString)(step.error) } : {}),
884
+ ...(step.meta ? { meta: (0, session_events_1.capStructuredRecordStringLeaves)(step.meta) } : {}),
885
+ };
886
+ }
887
+ function normalizeHabitRunTraceSteps(traceSteps) {
888
+ return (traceSteps ?? []).map((step) => capHabitRunTraceStep(step));
889
+ }
890
+ function capHabitRunReceipt(receipt) {
891
+ const traceSteps = normalizeHabitRunTraceSteps(receipt.traceSteps);
892
+ const fallbackSnapshot = defaultHabitRunSummarySnapshot({ ...receipt, traceSteps });
893
+ return {
894
+ ...receipt,
895
+ habitName: (0, session_events_1.capStructuredRecordString)(receipt.habitName),
896
+ definitionLocator: (0, session_events_1.capStructuredRecordString)(receipt.definitionLocator),
897
+ sessionLocator: (0, session_events_1.capStructuredRecordString)(receipt.sessionLocator),
898
+ pendingLocator: (0, session_events_1.capStructuredRecordString)(receipt.pendingLocator),
899
+ runtimeStateLocator: (0, session_events_1.capStructuredRecordString)(receipt.runtimeStateLocator),
900
+ receiptLocator: (0, session_events_1.capStructuredRecordString)(receipt.receiptLocator),
901
+ operationId: receipt.operationId ? (0, session_events_1.capStructuredRecordString)(receipt.operationId) : null,
902
+ permissionEnvelope: {
903
+ ...receipt.permissionEnvelope,
904
+ returnRoutes: receipt.permissionEnvelope.returnRoutes.map((route) => ({
905
+ ...route,
906
+ recipient: (0, session_events_1.capStructuredRecordString)(route.recipient),
907
+ ...(route.friendId ? { friendId: (0, session_events_1.capStructuredRecordString)(route.friendId) } : {}),
908
+ ...(route.channel ? { channel: (0, session_events_1.capStructuredRecordString)(route.channel) } : {}),
909
+ ...(route.key ? { key: (0, session_events_1.capStructuredRecordString)(route.key) } : {}),
910
+ ...(route.reason ? { reason: (0, session_events_1.capStructuredRecordString)(route.reason) } : {}),
911
+ })),
912
+ deniedTools: cappedArray(receipt.permissionEnvelope.deniedTools),
913
+ warnings: cappedArray(receipt.permissionEnvelope.warnings),
914
+ },
915
+ toolPolicy: {
916
+ requestedTools: receipt.toolPolicy.requestedTools ? cappedArray(receipt.toolPolicy.requestedTools) : null,
917
+ grantedTools: cappedArray(receipt.toolPolicy.grantedTools),
918
+ deniedTools: cappedArray(receipt.toolPolicy.deniedTools),
919
+ outwardMessagingAllowed: receipt.toolPolicy.outwardMessagingAllowed,
920
+ },
921
+ summarySnapshot: normalizeHabitRunSummarySnapshot(receipt.summarySnapshot, fallbackSnapshot),
922
+ producedRefs: receipt.producedRefs.map((ref) => ({ ...ref, locator: (0, session_events_1.capStructuredRecordString)(ref.locator) })),
923
+ surfaceAttempts: receipt.surfaceAttempts.map((attempt) => ({
924
+ ...attempt,
925
+ recipient: (0, session_events_1.capStructuredRecordString)(attempt.recipient),
926
+ channel: (0, session_events_1.capStructuredRecordString)(attempt.channel),
927
+ ...(attempt.rawStatus ? { rawStatus: (0, session_events_1.capStructuredRecordString)(attempt.rawStatus) } : {}),
928
+ ...(attempt.error ? { error: (0, session_events_1.capStructuredRecordString)(attempt.error) } : {}),
929
+ })),
930
+ traceSteps,
931
+ errors: receipt.errors.map((error) => (0, session_events_1.capStructuredRecordString)(error)),
932
+ };
933
+ }
934
+ function normalizeHabitRunReceiptForWrite(receipt) {
935
+ return capHabitRunReceipt(receipt.schemaVersion === 1 ? normalizeLegacyHabitRunReceipt(receipt) : receipt);
936
+ }
937
+ function readHabitRunReceipt(agentRoot, runId) {
938
+ if (!isSafeHabitRunId(runId)) {
939
+ warnMalformedHabitReceipt(agentRoot, runId, "unsafe run id");
940
+ return null;
941
+ }
942
+ try {
943
+ const parsed = JSON.parse(fs.readFileSync(habitReceiptPath(agentRoot, runId), "utf-8"));
944
+ const receipt = isHabitRunReceipt(parsed)
945
+ ? parsed
946
+ : isLegacyHabitRunReceipt(parsed)
947
+ ? normalizeLegacyHabitRunReceipt(parsed)
948
+ : null;
949
+ if (!receipt) {
950
+ warnMalformedHabitReceipt(agentRoot, runId, "invalid habit receipt shape");
951
+ return null;
952
+ }
953
+ (0, runtime_1.emitNervesEvent)({
954
+ component: "mind",
955
+ event: "mind.flight_recorder_habit_receipt_read",
956
+ message: "flight recorder habit receipt read",
957
+ meta: { agentRoot, runId },
958
+ });
959
+ return capHabitRunReceipt(receipt);
960
+ }
961
+ catch (error) {
962
+ warnMalformedHabitReceipt(agentRoot, runId, error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error));
963
+ return null;
964
+ }
965
+ }
966
+ function listHabitRunReceipts(agentRoot, options = {}) {
967
+ const dir = receiptsDir(agentRoot);
968
+ if (!fs.existsSync(dir))
969
+ return [];
970
+ const receipts = fs.readdirSync(dir)
971
+ .filter((fileName) => fileName.endsWith(".json"))
972
+ .map((fileName) => readHabitRunReceipt(agentRoot, path.basename(fileName, ".json")))
973
+ .filter((receipt) => receipt !== null)
974
+ .sort((left, right) => right.endedAt.localeCompare(left.endedAt) || right.runId.localeCompare(left.runId));
975
+ return typeof options.limit === "number" && options.limit >= 0 ? receipts.slice(0, options.limit) : receipts;
976
+ }
977
+ function writeHabitRunReceipt(agentRoot, receipt) {
978
+ fs.mkdirSync(receiptsDir(agentRoot), { recursive: true });
979
+ const safeReceipt = normalizeHabitRunReceiptForWrite(receipt);
980
+ if (!isSafeHabitRunId(safeReceipt.runId)) {
981
+ warnMalformedHabitReceipt(agentRoot, safeReceipt.runId, "unsafe run id");
982
+ throw new Error(`unsafe habit run id: ${safeReceipt.runId}`);
983
+ }
984
+ atomicWriteJson(habitReceiptPath(agentRoot, safeReceipt.runId), safeReceipt);
985
+ recordFlightRecorderEvent(agentRoot, {
986
+ kind: "habit_run",
987
+ recordedAt: safeReceipt.endedAt,
988
+ summary: `habit ${safeReceipt.habitName} finished with ${safeReceipt.outcome}`,
989
+ producedRefs: safeReceipt.producedRefs,
990
+ meta: {
991
+ receiptPath: path.join("arc", "flight-recorder", "habit-receipts", `${safeReceipt.runId}.json`),
992
+ operationId: safeReceipt.operationId ?? null,
993
+ },
994
+ });
995
+ (0, runtime_1.emitNervesEvent)({
996
+ component: "mind",
997
+ event: "mind.flight_recorder_habit_receipt_written",
998
+ message: "flight recorder habit receipt written",
999
+ meta: { agentRoot, runId: safeReceipt.runId, habitName: safeReceipt.habitName, outcome: safeReceipt.outcome },
1000
+ });
1001
+ }
1002
+ function formatFlightRecorderResume(resume) {
1003
+ const lines = ["## Arc resume"];
1004
+ lines.push(`can continue: ${resume.canContinue ? "yes" : "no"}`);
1005
+ lines.push(`complete state: ${resume.hasCompleteState ? "yes" : "no"}`);
1006
+ if (resume.currentAsk.value)
1007
+ lines.push(`current ask: ${resume.currentAsk.value}`);
1008
+ if (resume.nextSafeAction.value)
1009
+ lines.push(`next safe action: ${resume.nextSafeAction.value}`);
1010
+ if (resume.nextSafeAction.stopBefore.length > 0)
1011
+ lines.push(`stop before: ${resume.nextSafeAction.stopBefore.join(", ")}`);
1012
+ if (resume.blockedBecause.length > 0)
1013
+ lines.push(`blocked: ${resume.blockedBecause.join("; ")}`);
1014
+ if (resume.missing.length > 0)
1015
+ lines.push(`missing: ${resume.missing.join(", ")}`);
1016
+ if (resume.gaps.length > 0)
1017
+ lines.push(`gaps: ${resume.gaps.join("; ")}`);
1018
+ if (resume.activeObligationIds.length > 0)
1019
+ lines.push(`obligations: ${resume.activeObligationIds.join(", ")}`);
1020
+ if (resume.activeReturnObligationIds.length > 0)
1021
+ lines.push(`return obligations: ${resume.activeReturnObligationIds.join(", ")}`);
1022
+ if (resume.activePacketIds.length > 0)
1023
+ lines.push(`packets: ${resume.activePacketIds.join(", ")}`);
1024
+ if (resume.unverifiedClaimIds.length > 0)
1025
+ lines.push(`unverified claims: ${resume.unverifiedClaimIds.join(", ")}`);
1026
+ if (resume.recorderHealth.status !== "ok") {
1027
+ lines.push(`recorder health: ${resume.recorderHealth.status} (${resume.recorderHealth.issues.join("; ")})`);
1028
+ }
1029
+ return lines.join("\n");
1030
+ }
1031
+ function createHabitRunId(habitName, now = new Date()) {
1032
+ const safeName = habitName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "habit";
1033
+ return `${now.toISOString().replace(/[:.]/g, "-")}-${safeName}-${(0, crypto_1.randomUUID)().slice(0, 8)}`;
1034
+ }