@ouro.bot/cli 0.1.0-alpha.8 → 0.1.0-alpha.800

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 (624) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -176
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/SerpentGuide.ouro/agent.json +83 -0
  11. package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
  13. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  14. package/assets/bluebubbles-host +264 -0
  15. package/assets/ouroboros.png +0 -0
  16. package/changelog.json +5563 -0
  17. package/deploy/unraid/Dockerfile +48 -0
  18. package/deploy/unraid/README.txt +3012 -0
  19. package/deploy/unraid/audit-container-spec.sh +4 -0
  20. package/deploy/unraid/container-runtime.json +1 -0
  21. package/deploy/unraid/docker-man-template-transaction.mjs +526 -0
  22. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  23. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  24. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  25. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  26. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  27. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  28. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  29. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  30. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  31. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  32. package/deploy/unraid/sanctuary-deployment-target.mjs +709 -0
  33. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  34. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2030 -0
  35. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  36. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  37. package/deploy/unraid/sanctuary.ouro/agent.json +24 -0
  38. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  39. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  40. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  41. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  42. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  43. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +11 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +11 -0
  47. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  48. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +23 -0
  49. package/deploy/unraid/sanctuary.xml +27 -0
  50. package/dist/a2a/card.js +57 -0
  51. package/dist/a2a/client.js +180 -0
  52. package/dist/a2a/config.js +50 -0
  53. package/dist/a2a/delegation-stores.js +56 -0
  54. package/dist/a2a/did-resolution.js +93 -0
  55. package/dist/a2a/identity.js +170 -0
  56. package/dist/a2a/inbound-share.js +107 -0
  57. package/dist/a2a/mission-result-wire.js +196 -0
  58. package/dist/a2a/onboarding.js +115 -0
  59. package/dist/a2a/pin-store.js +132 -0
  60. package/dist/a2a/seen-ledger.js +120 -0
  61. package/dist/a2a/server.js +604 -0
  62. package/dist/a2a/task-store.js +69 -0
  63. package/dist/a2a/transport.js +45 -0
  64. package/dist/a2a/types.js +3 -0
  65. package/dist/arc/attention-types.js +8 -0
  66. package/dist/arc/cares.js +360 -0
  67. package/dist/arc/episodes.js +118 -0
  68. package/dist/arc/evolution.js +490 -0
  69. package/dist/arc/flight-recorder.js +1034 -0
  70. package/dist/arc/intentions.js +134 -0
  71. package/dist/arc/json-store.js +117 -0
  72. package/dist/arc/obligations.js +386 -0
  73. package/dist/arc/packets.js +336 -0
  74. package/dist/arc/presence.js +185 -0
  75. package/dist/arc/task-lifecycle.js +57 -0
  76. package/dist/commerce/store.js +755 -0
  77. package/dist/commerce/types.js +3 -0
  78. package/dist/heart/active-work.js +1009 -0
  79. package/dist/heart/agent-entry.js +252 -3
  80. package/dist/heart/approval-files.js +113 -0
  81. package/dist/heart/approval-store.js +950 -0
  82. package/dist/heart/attachments/image-normalize.js +194 -0
  83. package/dist/heart/attachments/materialize.js +97 -0
  84. package/dist/heart/attachments/originals.js +88 -0
  85. package/dist/heart/attachments/render.js +29 -0
  86. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  87. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  88. package/dist/heart/attachments/sources/index.js +18 -0
  89. package/dist/heart/attachments/sources/telegram.js +71 -0
  90. package/dist/heart/attachments/store.js +132 -0
  91. package/dist/heart/attachments/types.js +93 -0
  92. package/dist/heart/auth/auth-flow.js +495 -0
  93. package/dist/heart/autonomy-budget.js +478 -0
  94. package/dist/heart/awaiting/await-alert.js +148 -0
  95. package/dist/heart/awaiting/await-expiry.js +143 -0
  96. package/dist/heart/awaiting/await-loader.js +91 -0
  97. package/dist/heart/awaiting/await-parser.js +149 -0
  98. package/dist/heart/awaiting/await-runtime-state.js +100 -0
  99. package/dist/heart/awaiting/await-scheduler.js +382 -0
  100. package/dist/heart/background-operations.js +281 -0
  101. package/dist/heart/bridges/manager.js +478 -0
  102. package/dist/heart/bridges/state-machine.js +135 -0
  103. package/dist/heart/bridges/store.js +135 -0
  104. package/dist/heart/bundle-state.js +168 -0
  105. package/dist/heart/commitments.js +135 -0
  106. package/dist/heart/config-registry.js +331 -0
  107. package/dist/heart/config.js +195 -137
  108. package/dist/heart/context-loss-gauntlet.js +387 -0
  109. package/dist/heart/context-loss-sentinel.js +1157 -0
  110. package/dist/heart/core.js +2257 -338
  111. package/dist/heart/cross-chat-delivery.js +133 -0
  112. package/dist/heart/daemon/agent-config-check.js +451 -0
  113. package/dist/heart/daemon/agent-discovery.js +263 -0
  114. package/dist/heart/daemon/agent-service.js +542 -0
  115. package/dist/heart/daemon/agentic-repair.js +547 -0
  116. package/dist/heart/daemon/await-private-wake.js +59 -0
  117. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  118. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  119. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  120. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  121. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  122. package/dist/heart/daemon/cadence.js +180 -0
  123. package/dist/heart/daemon/cli-defaults.js +836 -0
  124. package/dist/heart/daemon/cli-desk.js +322 -0
  125. package/dist/heart/daemon/cli-exec.js +8730 -0
  126. package/dist/heart/daemon/cli-help.js +710 -0
  127. package/dist/heart/daemon/cli-parse.js +2719 -0
  128. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  129. package/dist/heart/daemon/cli-render.js +777 -0
  130. package/dist/heart/daemon/cli-types.js +8 -0
  131. package/dist/heart/daemon/connect-bay.js +323 -0
  132. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  133. package/dist/heart/daemon/container-healthcheck.js +112 -0
  134. package/dist/heart/daemon/container-runtime.js +97 -0
  135. package/dist/heart/daemon/container-spec-auditor-main.js +170 -0
  136. package/dist/heart/daemon/container-spec-auditor.js +236 -0
  137. package/dist/heart/daemon/daemon-bootstrap-startup.js +107 -0
  138. package/dist/heart/daemon/daemon-cli.js +30 -786
  139. package/dist/heart/daemon/daemon-entry.js +971 -13
  140. package/dist/heart/daemon/daemon-health.js +186 -0
  141. package/dist/heart/daemon/daemon-rollup.js +57 -0
  142. package/dist/heart/daemon/daemon-runtime-sync.js +287 -0
  143. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  144. package/dist/heart/daemon/daemon.js +2156 -28
  145. package/dist/heart/daemon/dns-workflow.js +394 -0
  146. package/dist/heart/daemon/doctor-types.js +8 -0
  147. package/dist/heart/daemon/doctor.js +1755 -0
  148. package/dist/heart/daemon/freshness.js +345 -0
  149. package/dist/heart/daemon/habit-private-wake.js +61 -0
  150. package/dist/heart/daemon/health-monitor.js +142 -11
  151. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  152. package/dist/heart/daemon/hooks/bundle-meta.js +226 -0
  153. package/dist/heart/daemon/http-health-probe.js +80 -0
  154. package/dist/heart/daemon/human-command-screens.js +234 -0
  155. package/dist/heart/daemon/human-readiness.js +114 -0
  156. package/dist/heart/daemon/inner-status.js +78 -0
  157. package/dist/heart/daemon/interactive-repair.js +394 -0
  158. package/dist/heart/daemon/launchd.js +188 -0
  159. package/dist/heart/daemon/log-tailer.js +82 -12
  160. package/dist/heart/daemon/logs-prune.js +132 -0
  161. package/dist/heart/daemon/mcp-canary.js +524 -0
  162. package/dist/heart/daemon/message-router.js +80 -11
  163. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  164. package/dist/heart/daemon/os-cron-deps.js +135 -0
  165. package/dist/heart/daemon/os-cron.js +22 -14
  166. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  167. package/dist/heart/daemon/ouro-entry.js +3 -1
  168. package/dist/heart/daemon/plugin-cli.js +432 -0
  169. package/dist/heart/daemon/process-manager.js +739 -54
  170. package/dist/heart/daemon/provider-discovery.js +137 -0
  171. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  172. package/dist/heart/daemon/prunable-bundle.js +144 -0
  173. package/dist/heart/daemon/pulse.js +511 -0
  174. package/dist/heart/daemon/readiness-repair.js +365 -0
  175. package/dist/heart/daemon/run-hooks.js +39 -0
  176. package/dist/heart/daemon/runtime-logging.js +92 -16
  177. package/dist/heart/daemon/runtime-metadata.js +191 -0
  178. package/dist/{repertoire/tasks/lifecycle.js → heart/daemon/runtime-mode.js} +37 -39
  179. package/dist/heart/daemon/safe-mode.js +161 -0
  180. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2609 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1866 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +976 -0
  184. package/dist/heart/daemon/sanctuary-bundle-migration.js +728 -0
  185. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  186. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  187. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  188. package/dist/heart/daemon/sense-manager.js +948 -0
  189. package/dist/heart/daemon/session-id-resolver.js +131 -0
  190. package/dist/heart/daemon/skill-management-installer.js +94 -0
  191. package/dist/heart/daemon/socket-client.js +370 -0
  192. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  193. package/dist/heart/daemon/startup-tui.js +339 -0
  194. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  195. package/dist/heart/daemon/task-scheduler.js +117 -39
  196. package/dist/heart/daemon/terminal-ui.js +499 -0
  197. package/dist/heart/daemon/thoughts.js +591 -0
  198. package/dist/heart/daemon/up-progress.js +366 -0
  199. package/dist/heart/daemon/vault-items.js +56 -0
  200. package/dist/heart/delegation.js +59 -0
  201. package/dist/heart/external-events/router.js +1414 -0
  202. package/dist/heart/habits/habit-cancel.js +810 -0
  203. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  204. package/dist/heart/habits/habit-migration.js +194 -0
  205. package/dist/heart/habits/habit-parser.js +278 -0
  206. package/dist/heart/habits/habit-runtime-state.js +93 -0
  207. package/dist/heart/habits/habit-scheduler.js +653 -0
  208. package/dist/heart/habits/habit-session-summary.js +318 -0
  209. package/dist/heart/habits/habit-session.js +636 -0
  210. package/dist/heart/{daemon → hatch}/hatch-animation.js +10 -3
  211. package/dist/heart/{daemon → hatch}/hatch-flow.js +57 -139
  212. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  213. package/dist/heart/hatch/specialist-orchestrator.js +129 -0
  214. package/dist/heart/hatch/specialist-prompt.js +102 -0
  215. package/dist/heart/hatch/specialist-tools.js +318 -0
  216. package/dist/heart/identity.js +297 -67
  217. package/dist/heart/kept-notes.js +289 -0
  218. package/dist/heart/kicks.js +2 -20
  219. package/dist/heart/machine-identity.js +161 -0
  220. package/dist/heart/mail-import-discovery.js +353 -0
  221. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  222. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  223. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  224. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  225. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  226. package/dist/heart/mailbox/mailbox-http.js +99 -0
  227. package/dist/heart/mailbox/mailbox-read.js +39 -0
  228. package/dist/heart/mailbox/mailbox-types.js +27 -0
  229. package/dist/heart/mailbox/mailbox-view.js +197 -0
  230. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  231. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  232. package/dist/heart/mailbox/readers/mail.js +375 -0
  233. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  234. package/dist/heart/mailbox/readers/sessions.js +232 -0
  235. package/dist/heart/mailbox/readers/shared.js +111 -0
  236. package/dist/heart/mcp/mcp-server.js +696 -0
  237. package/dist/heart/migrate-config.js +100 -0
  238. package/dist/heart/model-capabilities.js +59 -0
  239. package/dist/heart/orientation-frame.js +345 -0
  240. package/dist/heart/platform.js +81 -0
  241. package/dist/heart/primitives.js +1 -1
  242. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  243. package/dist/heart/private-runtime/index.js +18 -0
  244. package/dist/heart/private-runtime/ledger.js +221 -0
  245. package/dist/heart/private-runtime/policy.js +252 -0
  246. package/dist/heart/private-runtime/types.js +2 -0
  247. package/dist/heart/progress-story.js +42 -0
  248. package/dist/heart/provider-attempt.js +137 -0
  249. package/dist/heart/provider-binding-resolver.js +273 -0
  250. package/dist/heart/provider-credentials.js +449 -0
  251. package/dist/heart/provider-failover.js +311 -0
  252. package/dist/heart/provider-models.js +96 -0
  253. package/dist/heart/provider-ping.js +265 -0
  254. package/dist/heart/provider-readiness-cache.js +119 -0
  255. package/dist/heart/provider-visibility.js +188 -0
  256. package/dist/heart/providers/anthropic-token.js +131 -0
  257. package/dist/heart/providers/anthropic.js +236 -58
  258. package/dist/heart/providers/azure.js +104 -13
  259. package/dist/heart/providers/error-classification.js +127 -0
  260. package/dist/heart/providers/github-copilot.js +145 -0
  261. package/dist/heart/providers/minimax-vlm.js +189 -0
  262. package/dist/heart/providers/minimax.js +29 -7
  263. package/dist/heart/providers/openai-codex-token.js +349 -0
  264. package/dist/heart/providers/openai-codex.js +63 -39
  265. package/dist/heart/providers/openai-compatible.js +177 -0
  266. package/dist/heart/run-ledger.js +247 -0
  267. package/dist/heart/runtime-capability-check.js +170 -0
  268. package/dist/heart/runtime-credentials.js +607 -0
  269. package/dist/heart/runtime-cwd.js +87 -0
  270. package/dist/heart/sense-truth.js +79 -0
  271. package/dist/heart/session-activity.js +235 -0
  272. package/dist/heart/session-events.js +1318 -0
  273. package/dist/heart/session-playback-cli-main.js +5 -0
  274. package/dist/heart/session-playback-cli.js +36 -0
  275. package/dist/heart/session-playback.js +231 -0
  276. package/dist/heart/session-stats-cli-main.js +5 -0
  277. package/dist/heart/session-stats.js +182 -0
  278. package/dist/heart/session-transcript.js +133 -0
  279. package/dist/heart/start-of-turn-packet.js +372 -0
  280. package/dist/heart/steward-policy.js +302 -0
  281. package/dist/heart/streaming.js +682 -207
  282. package/dist/heart/structured-output.js +196 -0
  283. package/dist/heart/sync-classification.js +176 -0
  284. package/dist/heart/sync.js +449 -0
  285. package/dist/heart/target-resolution.js +127 -0
  286. package/dist/heart/tempo.js +93 -0
  287. package/dist/heart/temporal-view.js +41 -0
  288. package/dist/heart/timeouts.js +101 -0
  289. package/dist/heart/tool-activity-callbacks.js +59 -0
  290. package/dist/heart/tool-approval.js +342 -0
  291. package/dist/heart/tool-description.js +155 -0
  292. package/dist/heart/tool-friction.js +55 -0
  293. package/dist/heart/tool-loop.js +200 -0
  294. package/dist/heart/turn-context.js +481 -0
  295. package/dist/heart/turn-coordinator.js +28 -0
  296. package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
  297. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  298. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  299. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  300. package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
  301. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  302. package/dist/heart/versioning/staged-restart.js +146 -0
  303. package/dist/heart/versioning/update-checker.js +116 -0
  304. package/dist/heart/versioning/update-hooks.js +154 -0
  305. package/dist/heart/versioning/version-intent.js +114 -0
  306. package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
  307. package/dist/heart/work-card.js +380 -0
  308. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  309. package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
  310. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  311. package/dist/mailbox-ui/index.html +16 -0
  312. package/dist/mailroom/attention.js +167 -0
  313. package/dist/mailroom/autonomy.js +209 -0
  314. package/dist/mailroom/blob-store.js +889 -0
  315. package/dist/mailroom/body-cache.js +61 -0
  316. package/dist/mailroom/cache-sync-cli.js +58 -0
  317. package/dist/mailroom/core.js +803 -0
  318. package/dist/mailroom/entry.js +160 -0
  319. package/dist/mailroom/file-store.js +568 -0
  320. package/dist/mailroom/hosted-cache-sync.js +384 -0
  321. package/dist/mailroom/mbox-import.js +393 -0
  322. package/dist/mailroom/migration.js +164 -0
  323. package/dist/mailroom/outbound.js +380 -0
  324. package/dist/mailroom/policy.js +263 -0
  325. package/dist/mailroom/reader.js +292 -0
  326. package/dist/mailroom/search-cache.js +513 -0
  327. package/dist/mailroom/search-relevance.js +319 -0
  328. package/dist/mailroom/smtp-ingress.js +176 -0
  329. package/dist/mailroom/source-state.js +176 -0
  330. package/dist/mailroom/thread.js +109 -0
  331. package/dist/mailroom/travel-extract.js +89 -0
  332. package/dist/mind/bundle-manifest.js +93 -1
  333. package/dist/mind/context.js +287 -104
  334. package/dist/mind/desk-section.js +362 -0
  335. package/dist/mind/diary-integrity.js +60 -0
  336. package/dist/mind/{memory.js → diary.js} +90 -98
  337. package/dist/mind/embedding-provider.js +60 -0
  338. package/dist/mind/file-state.js +179 -0
  339. package/dist/mind/first-impressions.js +16 -2
  340. package/dist/mind/{associative-recall.js → note-search.js} +61 -60
  341. package/dist/mind/obligation-steering.js +227 -0
  342. package/dist/mind/pending.js +102 -9
  343. package/dist/mind/phrases.js +1 -0
  344. package/dist/mind/prompt-budget.js +479 -0
  345. package/dist/mind/prompt-refresh.js +3 -2
  346. package/dist/mind/prompt.js +1377 -140
  347. package/dist/mind/provenance-trust.js +26 -0
  348. package/dist/mind/record-paths.js +312 -0
  349. package/dist/mind/scrutiny.js +173 -0
  350. package/dist/mind/session-transaction.js +415 -0
  351. package/dist/mind/token-estimate.js +8 -12
  352. package/dist/nerves/cli-logging.js +22 -3
  353. package/dist/nerves/coverage/audit-rules.js +15 -6
  354. package/dist/nerves/coverage/audit.js +28 -2
  355. package/dist/nerves/coverage/cli.js +1 -1
  356. package/dist/nerves/coverage/contract.js +5 -5
  357. package/dist/nerves/coverage/file-completeness.js +139 -5
  358. package/dist/nerves/coverage/run-artifacts.js +56 -36
  359. package/dist/nerves/coverage/source-scanner.js +4 -4
  360. package/dist/nerves/event-buffer.js +111 -0
  361. package/dist/nerves/index.js +305 -9
  362. package/dist/nerves/observation.js +20 -0
  363. package/dist/nerves/redact.js +79 -0
  364. package/dist/nerves/review/cli-main.js +5 -0
  365. package/dist/nerves/review/cli.js +156 -0
  366. package/dist/nerves/review/core.js +159 -0
  367. package/dist/nerves/runtime.js +17 -1
  368. package/dist/repertoire/ado-client.js +17 -56
  369. package/dist/repertoire/ado-semantic.js +16 -10
  370. package/dist/repertoire/api-client.js +97 -0
  371. package/dist/repertoire/bitwarden-store.js +1045 -0
  372. package/dist/repertoire/bundle-templates.js +71 -0
  373. package/dist/repertoire/bw-installer.js +180 -0
  374. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  375. package/dist/repertoire/coding/context-pack.js +331 -0
  376. package/dist/repertoire/coding/feedback.js +322 -0
  377. package/dist/repertoire/coding/index.js +18 -3
  378. package/dist/repertoire/coding/manager.js +228 -14
  379. package/dist/repertoire/coding/spawner.js +61 -14
  380. package/dist/repertoire/coding/tools.js +279 -12
  381. package/dist/repertoire/coding/workbench-client.js +272 -0
  382. package/dist/repertoire/coding/workbench-manager.js +346 -0
  383. package/dist/repertoire/commerce-errors.js +109 -0
  384. package/dist/repertoire/commerce-self-test.js +156 -0
  385. package/dist/repertoire/credential-access.js +178 -0
  386. package/dist/repertoire/data/ado-endpoints.json +188 -0
  387. package/dist/repertoire/desk/classifier.js +362 -0
  388. package/dist/repertoire/duffel-client.js +185 -0
  389. package/dist/repertoire/github-client.js +14 -55
  390. package/dist/repertoire/graph-client.js +11 -52
  391. package/dist/repertoire/guardrails.js +1083 -0
  392. package/dist/repertoire/mcp-client.js +295 -0
  393. package/dist/repertoire/mcp-manager.js +434 -0
  394. package/dist/repertoire/mcp-tools.js +83 -0
  395. package/dist/repertoire/plugin-mcp.js +175 -0
  396. package/dist/repertoire/plugins.js +253 -0
  397. package/dist/repertoire/relationship-authorization.js +194 -0
  398. package/dist/repertoire/shell-sessions.js +133 -0
  399. package/dist/repertoire/skills.js +45 -24
  400. package/dist/repertoire/stripe-client.js +131 -0
  401. package/dist/repertoire/tool-arguments.js +148 -0
  402. package/dist/repertoire/tool-results.js +29 -0
  403. package/dist/repertoire/tools-a2a.js +699 -0
  404. package/dist/repertoire/tools-attachments.js +322 -0
  405. package/dist/repertoire/tools-awaiting.js +575 -0
  406. package/dist/repertoire/tools-base.js +85 -707
  407. package/dist/repertoire/tools-bluebubbles.js +95 -0
  408. package/dist/repertoire/tools-bridge.js +144 -0
  409. package/dist/repertoire/tools-bundle.js +993 -0
  410. package/dist/repertoire/tools-commerce.js +253 -0
  411. package/dist/repertoire/tools-config.js +186 -0
  412. package/dist/repertoire/tools-continuity.js +575 -0
  413. package/dist/repertoire/tools-credential.js +383 -0
  414. package/dist/repertoire/tools-evolution.js +527 -0
  415. package/dist/repertoire/tools-files.js +344 -0
  416. package/dist/repertoire/tools-flight.js +290 -0
  417. package/dist/repertoire/tools-flow.js +119 -0
  418. package/dist/repertoire/tools-github.js +3 -8
  419. package/dist/repertoire/tools-habits.js +103 -0
  420. package/dist/repertoire/tools-mail.js +1828 -0
  421. package/dist/repertoire/tools-notes.js +485 -0
  422. package/dist/repertoire/tools-obligations.js +182 -0
  423. package/dist/repertoire/tools-orientation.js +31 -0
  424. package/dist/repertoire/tools-record.js +482 -0
  425. package/dist/repertoire/tools-rsvp.js +139 -0
  426. package/dist/repertoire/tools-runtime.js +150 -0
  427. package/dist/repertoire/tools-session.js +1108 -0
  428. package/dist/repertoire/tools-shell.js +133 -0
  429. package/dist/repertoire/tools-steward-policy.js +95 -0
  430. package/dist/repertoire/tools-stripe.js +224 -0
  431. package/dist/repertoire/tools-surface.js +369 -0
  432. package/dist/repertoire/tools-teams.js +67 -61
  433. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  434. package/dist/repertoire/tools-travel.js +125 -0
  435. package/dist/repertoire/tools-trip.js +982 -0
  436. package/dist/repertoire/tools-unraid.js +484 -0
  437. package/dist/repertoire/tools-user-profile.js +146 -0
  438. package/dist/repertoire/tools-vault.js +40 -0
  439. package/dist/repertoire/tools-voice.js +145 -0
  440. package/dist/repertoire/tools.js +441 -102
  441. package/dist/repertoire/travel-api-client.js +360 -0
  442. package/dist/repertoire/unraid-client.js +155 -0
  443. package/dist/repertoire/unraid-restart.js +212 -0
  444. package/dist/repertoire/user-profile.js +131 -0
  445. package/dist/repertoire/vault-setup.js +246 -0
  446. package/dist/repertoire/vault-unlock.js +628 -0
  447. package/dist/rsvp/aisleplanner-client.js +354 -0
  448. package/dist/rsvp/cli.js +926 -0
  449. package/dist/rsvp/config.js +327 -0
  450. package/dist/rsvp/cutover.js +433 -0
  451. package/dist/rsvp/diagnostics.js +232 -0
  452. package/dist/rsvp/diff-renderer.js +176 -0
  453. package/dist/rsvp/habit-policy.js +110 -0
  454. package/dist/rsvp/habit-stage.js +123 -0
  455. package/dist/rsvp/incident-bundle.js +97 -0
  456. package/dist/rsvp/migration.js +204 -0
  457. package/dist/rsvp/native-habit-runner.js +630 -0
  458. package/dist/rsvp/outbound-state.js +628 -0
  459. package/dist/rsvp/query.js +118 -0
  460. package/dist/rsvp/replay.js +233 -0
  461. package/dist/rsvp/snapshot.js +232 -0
  462. package/dist/rsvp/spend-ledger.js +175 -0
  463. package/dist/scripts/claude-code-hook.js +41 -0
  464. package/dist/scripts/claude-code-stop-hook.js +47 -0
  465. package/dist/senses/a2a-entry.js +115 -0
  466. package/dist/senses/attention-queue.js +186 -0
  467. package/dist/senses/await-turn-message.js +58 -0
  468. package/dist/senses/bluebubbles/active-turns.js +216 -0
  469. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  470. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  471. package/dist/senses/bluebubbles/client.js +799 -0
  472. package/dist/senses/bluebubbles/context-packet.js +207 -0
  473. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  474. package/dist/senses/bluebubbles/entry.js +90 -0
  475. package/dist/senses/bluebubbles/inbound-log.js +127 -0
  476. package/dist/senses/bluebubbles/index.js +3839 -0
  477. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  478. package/dist/senses/bluebubbles/media.js +389 -0
  479. package/dist/senses/bluebubbles/model.js +392 -0
  480. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +57 -6
  481. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  482. package/dist/senses/bluebubbles/processed-log.js +133 -0
  483. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  484. package/dist/senses/bluebubbles/replay.js +284 -0
  485. package/dist/senses/bluebubbles/runtime-state.js +137 -0
  486. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  487. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  488. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  489. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  490. package/dist/senses/cli/bracketed-paste.js +82 -0
  491. package/dist/senses/cli/image-paste.js +287 -0
  492. package/dist/senses/cli/image-ref-navigation.js +75 -0
  493. package/dist/senses/cli/ink-app.js +156 -0
  494. package/dist/senses/cli/inline-diff.js +64 -0
  495. package/dist/senses/cli/input-keys.js +174 -0
  496. package/dist/senses/cli/kill-ring.js +86 -0
  497. package/dist/senses/cli/message-list.js +51 -0
  498. package/dist/senses/cli/ouro-tui.js +607 -0
  499. package/dist/senses/cli/spinner-imperative.js +135 -0
  500. package/dist/senses/cli/spinner.js +101 -0
  501. package/dist/senses/cli/status-line.js +60 -0
  502. package/dist/senses/cli/streaming-markdown.js +526 -0
  503. package/dist/senses/cli/tool-display.js +85 -0
  504. package/dist/senses/cli/tool-render.js +85 -0
  505. package/dist/senses/cli/tui-store.js +241 -0
  506. package/dist/senses/cli/virtual-list.js +35 -0
  507. package/dist/senses/cli-entry.js +60 -8
  508. package/dist/senses/cli-layout.js +187 -0
  509. package/dist/senses/cli.js +813 -281
  510. package/dist/senses/commands.js +66 -3
  511. package/dist/senses/context-packet-ledger.js +371 -0
  512. package/dist/senses/context-packets.js +154 -0
  513. package/dist/senses/continuity.js +94 -0
  514. package/dist/senses/habit-lifecycle-guard.js +24 -0
  515. package/dist/senses/habit-turn-message.js +160 -0
  516. package/dist/senses/ingress-evidence.js +2 -0
  517. package/dist/senses/mail-entry.js +66 -0
  518. package/dist/senses/mail.js +524 -0
  519. package/dist/senses/pipeline.js +1213 -0
  520. package/dist/senses/private-runtime-worker.js +859 -0
  521. package/dist/senses/private-runtime.js +1496 -0
  522. package/dist/senses/proactive-content-guard.js +51 -0
  523. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  524. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  525. package/dist/senses/sanctuary-grounding.js +118 -0
  526. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  527. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  528. package/dist/senses/sanctuary-health-runner.js +101 -0
  529. package/dist/senses/sanctuary-health.js +408 -0
  530. package/dist/senses/sanctuary-interactive-control.js +306 -0
  531. package/dist/senses/sanctuary-media-catalog-contract.js +235 -0
  532. package/dist/senses/sanctuary-media-optimization.js +514 -0
  533. package/dist/senses/sanctuary-runtime.js +338 -0
  534. package/dist/senses/sanctuary-sab.js +85 -0
  535. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  536. package/dist/senses/shared-turn.js +571 -0
  537. package/dist/senses/surface-tool.js +109 -0
  538. package/dist/senses/teams-entry.js +60 -8
  539. package/dist/senses/teams.js +953 -211
  540. package/dist/senses/telegram-admission.js +711 -0
  541. package/dist/senses/telegram-approval-runtime.js +566 -0
  542. package/dist/senses/telegram-attachments.js +182 -0
  543. package/dist/senses/telegram-audit-ledger.js +220 -0
  544. package/dist/senses/telegram-client.js +1677 -0
  545. package/dist/senses/telegram-effect-adapter.js +859 -0
  546. package/dist/senses/telegram-entry.js +83 -0
  547. package/dist/senses/telegram.js +2026 -0
  548. package/dist/senses/trust-gate.js +207 -2
  549. package/dist/senses/voice/audio-playback.js +237 -0
  550. package/dist/senses/voice/audio-routing.js +119 -0
  551. package/dist/senses/voice/elevenlabs.js +202 -0
  552. package/dist/senses/voice/floor-control.js +431 -0
  553. package/dist/senses/voice/floor-controller.js +115 -0
  554. package/dist/senses/voice/golden-path.js +116 -0
  555. package/dist/senses/voice/index.js +29 -0
  556. package/dist/senses/voice/meeting.js +113 -0
  557. package/dist/senses/voice/outbound.js +190 -0
  558. package/dist/senses/voice/phone.js +33 -0
  559. package/dist/senses/voice/playback.js +139 -0
  560. package/dist/senses/voice/realtime-eval.js +496 -0
  561. package/dist/senses/voice/realtime-trace.js +531 -0
  562. package/dist/senses/voice/transcript.js +70 -0
  563. package/dist/senses/voice/turn.js +191 -0
  564. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  565. package/dist/senses/voice/twilio-phone.js +5081 -0
  566. package/dist/senses/voice/types.js +2 -0
  567. package/dist/senses/voice/whisper.js +161 -0
  568. package/dist/senses/voice-entry.js +81 -0
  569. package/dist/senses/voice-realtime-eval-command.js +99 -0
  570. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  571. package/dist/senses/voice-twilio-entry.js +87 -0
  572. package/dist/trips/core.js +138 -0
  573. package/dist/trips/store.js +265 -0
  574. package/dist/util/frontmatter.js +69 -0
  575. package/npm-shrinkwrap.json +8144 -0
  576. package/package.json +82 -12
  577. package/skills/agent-commerce.md +113 -0
  578. package/skills/browser-navigation.md +117 -0
  579. package/skills/commerce-setup-guide.md +116 -0
  580. package/skills/commerce-setup.md +84 -0
  581. package/skills/configure-dev-tools.md +99 -0
  582. package/skills/travel-planning.md +138 -0
  583. package/AdoptionSpecialist.ouro/agent.json +0 -20
  584. package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
  585. package/dist/heart/daemon/specialist-orchestrator.js +0 -160
  586. package/dist/heart/daemon/specialist-prompt.js +0 -47
  587. package/dist/heart/daemon/specialist-session.js +0 -142
  588. package/dist/heart/daemon/specialist-tools.js +0 -132
  589. package/dist/heart/daemon/subagent-installer.js +0 -125
  590. package/dist/inner-worker-entry.js +0 -4
  591. package/dist/mind/friends/channel.js +0 -49
  592. package/dist/mind/friends/resolver.js +0 -84
  593. package/dist/mind/friends/store-file.js +0 -171
  594. package/dist/mind/friends/store.js +0 -4
  595. package/dist/mind/friends/tokens.js +0 -26
  596. package/dist/mind/friends/types.js +0 -21
  597. package/dist/repertoire/tasks/board.js +0 -122
  598. package/dist/repertoire/tasks/index.js +0 -210
  599. package/dist/repertoire/tasks/middleware.js +0 -65
  600. package/dist/repertoire/tasks/parser.js +0 -173
  601. package/dist/repertoire/tasks/scanner.js +0 -132
  602. package/dist/repertoire/tasks/transitions.js +0 -145
  603. package/dist/senses/bluebubbles-client.js +0 -279
  604. package/dist/senses/bluebubbles-entry.js +0 -11
  605. package/dist/senses/bluebubbles-model.js +0 -253
  606. package/dist/senses/bluebubbles.js +0 -332
  607. package/dist/senses/inner-dialog-worker.js +0 -61
  608. package/dist/senses/inner-dialog.js +0 -231
  609. package/subagents/README.md +0 -73
  610. package/subagents/work-doer.md +0 -233
  611. package/subagents/work-merger.md +0 -624
  612. package/subagents/work-planner.md +0 -373
  613. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  614. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  615. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  616. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  617. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  618. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  619. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  620. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  621. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  622. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  623. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  624. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
@@ -0,0 +1,372 @@
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.buildCapabilitiesSection = buildCapabilitiesSection;
37
+ exports.buildStartOfTurnPacket = buildStartOfTurnPacket;
38
+ exports.renderStartOfTurnPacket = renderStartOfTurnPacket;
39
+ exports.renderCompactStartOfTurnPacket = renderCompactStartOfTurnPacket;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const runtime_1 = require("../nerves/runtime");
43
+ const bundle_state_1 = require("./bundle-state");
44
+ const tempo_1 = require("./tempo");
45
+ const cares_1 = require("../arc/cares");
46
+ const flight_recorder_1 = require("../arc/flight-recorder");
47
+ const context_loss_sentinel_1 = require("./context-loss-sentinel");
48
+ const orientation_frame_1 = require("./orientation-frame");
49
+ function estimateTokens(text) {
50
+ return Math.ceil(text.length / 4);
51
+ }
52
+ // --- Section builders (pure derivation from authored data, no embellishment) ---
53
+ function buildPlotLine(episodes, tempo) {
54
+ if (episodes.length === 0)
55
+ return "";
56
+ const limit = tempo === "crisis" ? 3 : tempo === "brief" ? 2 : 5;
57
+ const selected = episodes.slice(0, limit);
58
+ const lines = selected.map((ep) => {
59
+ const parts = [`- ${ep.summary}`];
60
+ if (ep.whyItMattered && tempo !== "brief") {
61
+ parts[0] += ` (${ep.whyItMattered})`;
62
+ }
63
+ return parts[0];
64
+ });
65
+ return lines.join("\n");
66
+ }
67
+ function buildObligationsSection(obligations) {
68
+ if (obligations.length === 0)
69
+ return "";
70
+ return obligations
71
+ .map((ob) => {
72
+ const parts = [`- ${ob.content}`];
73
+ if (ob.meaning?.resumeHint) {
74
+ parts.push(` [hint: ${ob.meaning.resumeHint}]`);
75
+ }
76
+ if (ob.meaning?.stalenessClass && ob.meaning.stalenessClass !== "fresh") {
77
+ parts.push(` (${ob.meaning.stalenessClass})`);
78
+ }
79
+ if (ob.meaning?.waitingOn) {
80
+ parts.push(` waiting on ${ob.meaning.waitingOn.kind}: ${ob.meaning.waitingOn.target}`);
81
+ }
82
+ return parts.join("");
83
+ })
84
+ .join("\n");
85
+ }
86
+ function buildCaresSection(cares, now) {
87
+ if (cares.length === 0)
88
+ return "";
89
+ return cares
90
+ .map((care) => {
91
+ const c = (0, cares_1.projectCareEvidence)(care, now);
92
+ if ("recheckRequired" in c)
93
+ return `- system care [${c.salience}] evidence stale; recheck required`;
94
+ const parts = [`- ${c.label}`];
95
+ if (c.salience !== "low") {
96
+ parts.push(` [${c.salience}]`);
97
+ }
98
+ if (c.currentRisk) {
99
+ parts.push(` risk: ${c.currentRisk}`);
100
+ }
101
+ return parts.join("");
102
+ })
103
+ .join("\n");
104
+ }
105
+ function buildPresenceSection(peers) {
106
+ if (peers.length === 0)
107
+ return "";
108
+ return peers
109
+ .map((p) => `- ${p.agentName}: ${p.availability}/${p.lane}`)
110
+ .join("\n");
111
+ }
112
+ function buildResumeHint(view, obligations) {
113
+ // Compose from authored obligation resumeHints and top intentions
114
+ const hints = [];
115
+ const effectiveObligations = obligations ?? view.activeObligations;
116
+ for (const ob of effectiveObligations) {
117
+ if (ob.meaning?.resumeHint) {
118
+ hints.push(ob.meaning.resumeHint);
119
+ }
120
+ }
121
+ for (const intent of view.openIntentions.slice(0, 3)) {
122
+ hints.push(intent.content);
123
+ }
124
+ if (hints.length === 0) {
125
+ // Fall back to top obligation content
126
+ if (effectiveObligations.length > 0) {
127
+ hints.push(effectiveObligations[0].content);
128
+ }
129
+ }
130
+ if (hints.length === 0)
131
+ return "";
132
+ return hints.join("; ");
133
+ }
134
+ /**
135
+ * Build a compact summary of capability changes between runtime versions.
136
+ * Reads bundle-meta.json for version info and changelog.json for change descriptions.
137
+ * Returns undefined if no version change detected or files are missing/malformed.
138
+ */
139
+ function buildCapabilitiesSection(bundleRoot) {
140
+ let meta;
141
+ try {
142
+ const raw = fs.readFileSync(path.join(bundleRoot, "bundle-meta.json"), "utf-8");
143
+ meta = JSON.parse(raw);
144
+ }
145
+ catch {
146
+ (0, runtime_1.emitNervesEvent)({
147
+ component: "heart",
148
+ event: "heart.capabilities_check",
149
+ message: "bundle-meta.json missing or malformed",
150
+ meta: { bundleRoot },
151
+ });
152
+ return undefined;
153
+ }
154
+ const currentVersion = meta.runtimeVersion;
155
+ const previousVersion = meta.previousRuntimeVersion;
156
+ if (typeof currentVersion !== "string" || typeof previousVersion !== "string") {
157
+ return undefined;
158
+ }
159
+ if (currentVersion === previousVersion) {
160
+ return undefined;
161
+ }
162
+ (0, runtime_1.emitNervesEvent)({
163
+ component: "heart",
164
+ event: "heart.capabilities_version_change",
165
+ message: `runtime version changed from ${previousVersion} to ${currentVersion}`,
166
+ meta: { previousVersion, currentVersion },
167
+ });
168
+ let changelog;
169
+ try {
170
+ const raw = fs.readFileSync(path.join(bundleRoot, "changelog.json"), "utf-8");
171
+ changelog = JSON.parse(raw);
172
+ }
173
+ catch {
174
+ // changelog missing -- still report the version change
175
+ }
176
+ const parts = [`Updated from ${previousVersion} to ${currentVersion}`];
177
+ if (changelog && Array.isArray(changelog)) {
178
+ const relevantChanges = [];
179
+ for (const entry of changelog) {
180
+ if (entry.version === previousVersion)
181
+ break;
182
+ if (Array.isArray(entry.changes)) {
183
+ relevantChanges.push(...entry.changes);
184
+ }
185
+ }
186
+ if (relevantChanges.length > 0) {
187
+ parts.push(`: ${relevantChanges.join("; ")}`);
188
+ }
189
+ }
190
+ return parts.join("");
191
+ }
192
+ function buildStartOfTurnPacket(view, opts) {
193
+ const tempo = view.tempo;
194
+ const tokenBudget = tempo_1.TEMPO_BUDGETS[tempo];
195
+ const effectiveObligations = opts?.canonicalObligations ? opts.canonicalObligations.all : view.activeObligations;
196
+ const packet = {
197
+ plotLine: buildPlotLine(view.recentEpisodes, tempo),
198
+ obligations: buildObligationsSection(effectiveObligations),
199
+ cares: buildCaresSection(view.activeCares, opts?.careEvidenceNow ?? Date.now()),
200
+ presence: buildPresenceSection(view.peerPresence),
201
+ arcResume: opts?.flightRecorderResume ? (0, flight_recorder_1.formatFlightRecorderResume)(opts.flightRecorderResume) : undefined,
202
+ recoverySentinel: opts?.recoverySentinel,
203
+ resumeHint: buildResumeHint(view, opts?.canonicalObligations ? effectiveObligations : undefined),
204
+ currentSessionTiming: opts?.currentSessionTiming,
205
+ friendContactTiming: opts?.friendContactTiming,
206
+ tempo,
207
+ tokenBudget,
208
+ assembledAt: new Date().toISOString(),
209
+ };
210
+ (0, runtime_1.emitNervesEvent)({
211
+ component: "heart",
212
+ event: "heart.start_of_turn_packet_built",
213
+ message: `start-of-turn packet built: tempo=${tempo}`,
214
+ meta: {
215
+ tempo,
216
+ plotLineTokens: estimateTokens(packet.plotLine),
217
+ obligationsTokens: estimateTokens(packet.obligations),
218
+ caresTokens: estimateTokens(packet.cares),
219
+ presenceTokens: estimateTokens(packet.presence),
220
+ resumeHintTokens: estimateTokens(packet.resumeHint),
221
+ },
222
+ });
223
+ return packet;
224
+ }
225
+ /**
226
+ * Renders a start-of-turn packet to prompt text, respecting token budget.
227
+ * Truncation priority (last truncated first):
228
+ * resumeHint (PROTECTED) > obligations > cares > plotLine > presence
229
+ * So presence is truncated first, then plotLine, then cares, then obligations.
230
+ * resumeHint is never truncated.
231
+ */
232
+ function renderStartOfTurnPacket(packet, options = {}) {
233
+ const budget = packet.tokenBudget;
234
+ const resumePriorWork = options.resumePriorWork === true;
235
+ // Assemble sections in priority order (highest priority first for budget allocation)
236
+ // Each section is { label, content, priority } where lower priority number = truncated first
237
+ const sections = [
238
+ // bundleState and syncFailure share the top remediation tier — both
239
+ // are actionable "fix your git" signals. bundleState is preferred
240
+ // because it's structured (array of enum values) while syncFailure is
241
+ // a legacy free-form string; both render when populated.
242
+ { label: "provider", content: packet.providerSelection ?? "", priority: 8 },
243
+ { label: "bundleState", content: (0, bundle_state_1.renderBundleStateHint)(packet.bundleState ?? []), priority: 7 },
244
+ { label: "syncFailure", content: packet.syncFailure ?? "", priority: 7 },
245
+ { label: "arc", content: packet.arcResume ?? "", priority: 7 },
246
+ { label: "recoverySentinel", content: packet.recoverySentinel ? (0, context_loss_sentinel_1.formatContextLossSentinelText)(packet.recoverySentinel) : "", priority: 7 },
247
+ { label: "resume", content: packet.resumeHint, priority: 6 },
248
+ { label: "friendContact", content: packet.friendContactTiming ?? "", priority: 6 },
249
+ { label: "sessionTiming", content: packet.currentSessionTiming ?? "", priority: 5 },
250
+ { label: "obligations", content: packet.obligations, priority: 5 },
251
+ { label: "cares", content: packet.cares, priority: 4 },
252
+ { label: "plot", content: packet.plotLine, priority: 3 },
253
+ { label: "capabilities", content: packet.capabilities ?? "", priority: 2 },
254
+ { label: "presence", content: packet.presence, priority: 1 },
255
+ ].filter((s) => s.content.length > 0);
256
+ if (sections.length === 0) {
257
+ (0, runtime_1.emitNervesEvent)({
258
+ component: "heart",
259
+ event: "heart.start_of_turn_packet_rendered",
260
+ message: "start-of-turn packet rendered: empty",
261
+ meta: { tokens: 0, tempo: packet.tempo },
262
+ });
263
+ return "";
264
+ }
265
+ // Build the rendered output, truncating lower-priority sections first
266
+ let rendered = formatSections(sections, resumePriorWork);
267
+ let tokens = estimateTokens(rendered);
268
+ // Truncate sections from lowest priority until we fit budget
269
+ const sortedByPriority = [...sections].sort((a, b) => a.priority - b.priority);
270
+ for (const section of sortedByPriority) {
271
+ if (tokens <= budget.max)
272
+ break;
273
+ // Skip continuity sections — they are protected.
274
+ if (section.label === "resume" || section.label === "arc" || section.label === "recoverySentinel" || section.label === "friendContact" || section.label === "sessionTiming")
275
+ continue;
276
+ // Remove this section entirely
277
+ const idx = sections.findIndex((s) => s.label === section.label);
278
+ sections.splice(idx, 1);
279
+ rendered = formatSections(sections, resumePriorWork);
280
+ tokens = estimateTokens(rendered);
281
+ }
282
+ // If still over budget after removing all non-protected sections, trim what's left
283
+ if (tokens > budget.max) {
284
+ const maxChars = budget.max * 4;
285
+ rendered = rendered.slice(0, maxChars);
286
+ }
287
+ (0, runtime_1.emitNervesEvent)({
288
+ component: "heart",
289
+ event: "heart.start_of_turn_packet_rendered",
290
+ message: `start-of-turn packet rendered: ${tokens} tokens`,
291
+ meta: { tokens, tempo: packet.tempo, sectionCount: sections.length },
292
+ });
293
+ return rendered;
294
+ }
295
+ function formatSections(sections, resumePriorWork) {
296
+ const parts = [];
297
+ for (const section of sections) {
298
+ switch (section.label) {
299
+ case "resume":
300
+ parts.push((0, orientation_frame_1.labelPriorWorkSurface)(`**Next:**\n${section.content}`, resumePriorWork));
301
+ break;
302
+ case "arc":
303
+ parts.push((0, orientation_frame_1.labelPriorWorkSurface)(`**Arc:**\n${section.content}`, resumePriorWork));
304
+ break;
305
+ case "recoverySentinel":
306
+ parts.push((0, orientation_frame_1.labelPriorWorkSurface)(`**Recovery Sentinel:**\n${section.content}`, resumePriorWork));
307
+ break;
308
+ case "sessionTiming":
309
+ parts.push(`**Thread timing:** ${section.content}`);
310
+ break;
311
+ case "friendContact":
312
+ parts.push(`**Recent contact:** ${section.content}`);
313
+ break;
314
+ case "obligations":
315
+ parts.push((0, orientation_frame_1.labelPriorWorkSurface)(`**Owed:**\n${section.content}`, resumePriorWork));
316
+ break;
317
+ case "cares":
318
+ parts.push(`**Cares:**\n${section.content}`);
319
+ break;
320
+ case "plot":
321
+ parts.push(`**Recent:**\n${section.content}`);
322
+ break;
323
+ case "presence":
324
+ parts.push(`**Peers:**\n${section.content}`);
325
+ break;
326
+ case "capabilities":
327
+ parts.push(`**Capabilities:** ${section.content}`);
328
+ break;
329
+ case "syncFailure":
330
+ parts.push(`**Sync warning:** ${section.content}`);
331
+ break;
332
+ case "bundleState":
333
+ parts.push(`**Bundle:** ${section.content}`);
334
+ break;
335
+ case "provider":
336
+ parts.push(`**Provider:**\n${section.content}`);
337
+ break;
338
+ }
339
+ }
340
+ return parts.join("\n\n");
341
+ }
342
+ /**
343
+ * Ultra-compact version for coding context (max 200 tokens).
344
+ * Just resumeHint + top obligation + top care, single-line bullets.
345
+ */
346
+ function renderCompactStartOfTurnPacket(packet, options = {}) {
347
+ const parts = [];
348
+ const instruction = (0, orientation_frame_1.priorWorkInstruction)(options.resumePriorWork === true);
349
+ if (packet.resumeHint) {
350
+ parts.push(`next:\n${instruction}\n${packet.resumeHint}`);
351
+ }
352
+ if (packet.obligations) {
353
+ // Just first line of obligations
354
+ const firstOb = packet.obligations.split("\n")[0];
355
+ parts.push(`owed:\n${instruction}\n${firstOb.replace(/^- /, "")}`);
356
+ }
357
+ if (packet.cares) {
358
+ const firstCare = packet.cares.split("\n")[0];
359
+ parts.push(`care: ${firstCare.replace(/^- /, "")}`);
360
+ }
361
+ const compact = parts.join(" | ");
362
+ // Hard cap at 200 tokens (800 chars)
363
+ const maxChars = 200 * 4;
364
+ const result = compact.length > maxChars ? compact.slice(0, maxChars) : compact;
365
+ (0, runtime_1.emitNervesEvent)({
366
+ component: "heart",
367
+ event: "heart.start_of_turn_packet_compact_rendered",
368
+ message: `compact start-of-turn packet: ${estimateTokens(result)} tokens`,
369
+ meta: { tokens: estimateTokens(result) },
370
+ });
371
+ return result;
372
+ }
@@ -0,0 +1,302 @@
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.readStewardPolicy = readStewardPolicy;
37
+ exports.updateStewardPolicy = updateStewardPolicy;
38
+ exports.readRoutineActionReceipts = readRoutineActionReceipts;
39
+ exports.inspectRoutineActionGrant = inspectRoutineActionGrant;
40
+ exports.consumeRoutineActionGrant = consumeRoutineActionGrant;
41
+ exports.transitionRoutineActionReceipt = transitionRoutineActionReceipt;
42
+ exports.recoverRoutineActionReceipts = recoverRoutineActionReceipts;
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const node_crypto_1 = require("node:crypto");
46
+ const runtime_1 = require("../nerves/runtime");
47
+ const session_transaction_1 = require("../mind/session-transaction");
48
+ const EMPTY_POLICY = { schemaVersion: 1, version: 0, desiredStates: {}, routineActionGrants: {}, updatedAt: null };
49
+ function policyDir(agentRoot) {
50
+ return path.join(agentRoot, "state", "policy");
51
+ }
52
+ function policyPath(agentRoot) {
53
+ return path.join(policyDir(agentRoot), "steward.json");
54
+ }
55
+ function receiptsPath(agentRoot) {
56
+ return path.join(policyDir(agentRoot), "action-receipts.ndjson");
57
+ }
58
+ function auditPath(agentRoot) {
59
+ return path.join(policyDir(agentRoot), "policy-audit.ndjson");
60
+ }
61
+ function ensureDirectory(agentRoot) {
62
+ fs.mkdirSync(policyDir(agentRoot), { recursive: true, mode: 0o700 });
63
+ fs.chmodSync(policyDir(agentRoot), 0o700);
64
+ }
65
+ function appendReceipt(filePath, value) {
66
+ const creating = !fs.existsSync(filePath);
67
+ const fd = fs.openSync(filePath, "a", 0o600);
68
+ try {
69
+ fs.writeFileSync(fd, `${JSON.stringify(value)}\n`, "utf8");
70
+ fs.fsyncSync(fd);
71
+ }
72
+ finally {
73
+ fs.closeSync(fd);
74
+ }
75
+ fs.chmodSync(filePath, 0o600);
76
+ if (creating) {
77
+ const directory = fs.openSync(path.dirname(filePath), fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
78
+ try {
79
+ fs.fsyncSync(directory);
80
+ }
81
+ finally {
82
+ fs.closeSync(directory);
83
+ }
84
+ }
85
+ }
86
+ function requireText(value, label) {
87
+ const result = value.trim();
88
+ if (!result)
89
+ throw new Error(`${label} must be nonempty`);
90
+ return result;
91
+ }
92
+ function optionalExpiry(value, now) {
93
+ if (!value)
94
+ return undefined;
95
+ const epoch = Date.parse(value);
96
+ if (!Number.isFinite(epoch) || new Date(epoch).toISOString() !== value || epoch <= Date.parse(now))
97
+ throw new Error("policy expiry must be a future canonical timestamp");
98
+ return value;
99
+ }
100
+ function validateStewardPolicy(value) {
101
+ if (!value || typeof value !== "object" || Array.isArray(value))
102
+ throw new Error("steward policy is invalid");
103
+ const candidate = value;
104
+ if (candidate.schemaVersion !== 1 || !Number.isInteger(candidate.version) || candidate.version < 0 || typeof candidate.desiredStates !== "object" || !candidate.desiredStates || typeof candidate.routineActionGrants !== "object" || !candidate.routineActionGrants) {
105
+ throw new Error("steward policy is invalid");
106
+ }
107
+ return candidate;
108
+ }
109
+ function readStewardPolicy(agentRoot) {
110
+ const filePath = policyPath(agentRoot);
111
+ if (!fs.existsSync(filePath))
112
+ return structuredClone(EMPTY_POLICY);
113
+ return validateStewardPolicy(JSON.parse(fs.readFileSync(filePath, "utf8")));
114
+ }
115
+ function updateStewardPolicy(agentRoot, input) {
116
+ if (input.actor.trustLevel !== "family")
117
+ throw new Error("steward policy mutation requires family authority");
118
+ const authorizingSessionEvent = requireText(input.actor.sessionEventId, "authorizing session event");
119
+ const issuer = requireText(input.actor.friendId, "issuer");
120
+ return (0, session_transaction_1.withImmediateSessionTurnLease)(policyPath(agentRoot), (lease) => {
121
+ const snapshot = (0, session_transaction_1.readSessionTransaction)(policyPath(agentRoot), lease);
122
+ const current = snapshot.value === null ? structuredClone(EMPTY_POLICY) : validateStewardPolicy(snapshot.value);
123
+ if (current.version !== input.expectedVersion)
124
+ throw new Error(`steward policy version changed: expected ${input.expectedVersion}, got ${current.version}`);
125
+ const now = input.now ?? new Date().toISOString();
126
+ const expiresAt = optionalExpiry(input.mutation.expiresAt, now);
127
+ const version = current.version + 1;
128
+ const next = { ...current, version, desiredStates: { ...current.desiredStates }, routineActionGrants: { ...current.routineActionGrants }, updatedAt: now };
129
+ if (input.mutation.kind === "set_desired_state") {
130
+ next.desiredStates[requireText(input.mutation.key, "desired state key")] = {
131
+ value: requireText(input.mutation.value, "desired state value"),
132
+ provenance: input.mutation.provenance,
133
+ version,
134
+ source: requireText(input.mutation.source, "desired state source"),
135
+ ...(expiresAt ? { expiresAt } : {}),
136
+ };
137
+ }
138
+ else {
139
+ if (input.mutation.provenance !== "stated" && input.mutation.provenance !== "installed_explicit_policy")
140
+ throw new Error("routine action grants require explicit authority");
141
+ if (!Number.isInteger(input.mutation.maxCount) || input.mutation.maxCount < 1 || !Number.isFinite(input.mutation.windowMs) || input.mutation.windowMs <= 0)
142
+ throw new Error("routine action grant bounds are invalid");
143
+ if (!input.mutation.verificationRequired)
144
+ throw new Error("routine action grants require post-action verification");
145
+ const targets = [...new Set(input.mutation.targets.map((value) => requireText(value, "routine action target")))];
146
+ if (targets.length === 0)
147
+ throw new Error("routine action grant requires a target");
148
+ next.routineActionGrants[requireText(input.mutation.key, "routine action key")] = {
149
+ action: requireText(input.mutation.action, "routine action"), targets, maxCount: input.mutation.maxCount, windowMs: input.mutation.windowMs,
150
+ verificationRequired: input.mutation.verificationRequired, exclusions: [...new Set(input.mutation.exclusions)], provenance: input.mutation.provenance,
151
+ issuer, authorizedAt: now, authorizingSessionEvent, version, ...(expiresAt ? { expiresAt } : {}),
152
+ };
153
+ }
154
+ ensureDirectory(agentRoot);
155
+ (0, session_transaction_1.writeSessionTransaction)(policyPath(agentRoot), next, { lease, expectedRevision: snapshot.revision });
156
+ appendReceipt(auditPath(agentRoot), { schemaVersion: 1, policyVersion: version, issuer, authorizingSessionEvent, mutationKind: input.mutation.kind, at: now });
157
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.steward_policy_updated", message: "updated steward policy", meta: { version, mutationKind: input.mutation.kind, issuer } });
158
+ return next;
159
+ });
160
+ }
161
+ function readActionReceiptHistory(agentRoot) {
162
+ const filePath = receiptsPath(agentRoot);
163
+ if (!fs.existsSync(filePath))
164
+ return [];
165
+ return fs.readFileSync(filePath, "utf8").split("\n").filter(Boolean).map((line) => JSON.parse(line));
166
+ }
167
+ function readRoutineActionReceipts(agentRoot) {
168
+ const latest = new Map();
169
+ for (const receipt of readActionReceiptHistory(agentRoot))
170
+ latest.set(receipt.id, receipt);
171
+ return [...latest.values()];
172
+ }
173
+ function expectedOff(policy, target, now) {
174
+ const desired = policy.desiredStates[`container:${target}`];
175
+ if (!desired || (desired.expiresAt && Date.parse(desired.expiresAt) <= Date.parse(now)))
176
+ return false;
177
+ return /^(?:off|disabled|paused|intentionally_off|intentionally_paused)$/u.test(desired.value.trim().toLowerCase());
178
+ }
179
+ const UNRESOLVED_ACTION_STATES = new Set(["reserved", "attempting", "effect_acknowledged", "recovery_pending", "indeterminate"]);
180
+ function inspectRoutineActionGrantSnapshot(policy, receipts, input) {
181
+ if (input.expectedPolicyVersion !== undefined && policy.version !== input.expectedPolicyVersion)
182
+ return { allowed: false, reason: "routine action policy version changed" };
183
+ const grant = policy.routineActionGrants[input.key];
184
+ if (!grant)
185
+ return { allowed: false, reason: "routine action grant is missing" };
186
+ if (grant.action !== input.action)
187
+ return { allowed: false, reason: "routine action does not match the grant" };
188
+ if (!grant.targets.includes(input.target) || grant.exclusions.includes(input.target))
189
+ return { allowed: false, reason: "routine action target is not authorized" };
190
+ const now = input.now ?? new Date().toISOString();
191
+ if (grant.expiresAt && Date.parse(grant.expiresAt) <= Date.parse(now))
192
+ return { allowed: false, reason: "routine action grant expired" };
193
+ if (expectedOff(policy, input.target, now))
194
+ return { allowed: false, reason: "container is expected off" };
195
+ if (receipts.some((receipt) => receipt.action === input.action && receipt.target === input.target && UNRESOLVED_ACTION_STATES.has(receipt.state))) {
196
+ return { allowed: false, reason: "routine action has an unresolved receipt for this target" };
197
+ }
198
+ return { allowed: true, policyVersion: policy.version, grantVersion: grant.version, key: input.key, action: grant.action, target: input.target };
199
+ }
200
+ function inspectRoutineActionGrant(agentRoot, input) {
201
+ try {
202
+ const policy = readStewardPolicy(agentRoot);
203
+ return inspectRoutineActionGrantSnapshot(policy, readRoutineActionReceipts(agentRoot), input);
204
+ }
205
+ catch (error) {
206
+ return { allowed: false, reason: error instanceof Error ? error.message : "routine action policy is unavailable" };
207
+ }
208
+ }
209
+ function consumeRoutineActionGrant(agentRoot, input) {
210
+ return (0, session_transaction_1.withImmediateSessionTurnLease)(policyPath(agentRoot), (lease) => {
211
+ const snapshot = (0, session_transaction_1.readSessionTransaction)(policyPath(agentRoot), lease);
212
+ const policy = snapshot.value === null ? structuredClone(EMPTY_POLICY) : validateStewardPolicy(snapshot.value);
213
+ const grant = policy.routineActionGrants[input.key];
214
+ const now = input.now ?? new Date().toISOString();
215
+ const action = input.action ?? grant?.action ?? "";
216
+ const receipts = readRoutineActionReceipts(agentRoot);
217
+ const decision = inspectRoutineActionGrantSnapshot(policy, receipts, { key: input.key, action, target: input.target, expectedPolicyVersion: input.expectedPolicyVersion, now });
218
+ if (!decision.allowed)
219
+ throw new Error(decision.reason);
220
+ ensureDirectory(agentRoot);
221
+ const windowStart = Date.parse(now) - grant.windowMs;
222
+ const used = receipts.filter((receipt) => receipt.key === input.key && Date.parse(receipt.reservedAt) > windowStart).length;
223
+ if (used >= grant.maxCount)
224
+ throw new Error("routine action rate limit reached");
225
+ const id = `action-${(0, node_crypto_1.randomUUID)()}`;
226
+ const receipt = {
227
+ schemaVersion: 2,
228
+ id,
229
+ state: "reserved",
230
+ key: input.key,
231
+ action,
232
+ target: input.target,
233
+ policyVersion: policy.version,
234
+ grantVersion: grant.version,
235
+ reservedAt: now,
236
+ updatedAt: now,
237
+ authorizationReceiptId: input.authorizationReceiptId ?? `policy-${grant.issuer}-${grant.authorizingSessionEvent}`,
238
+ authorizationVersion: input.authorizationVersion ?? grant.version,
239
+ attemptId: input.attemptId ?? `attempt-${(0, node_crypto_1.randomUUID)()}`,
240
+ attempt: 1,
241
+ expectedBeforeState: input.expectedBeforeState ?? null,
242
+ resolvedTarget: input.resolvedTarget ?? { id: "unresolved", name: input.target },
243
+ effect: input.effect ?? { operation: action, targetId: input.resolvedTarget?.id ?? "unresolved" },
244
+ effectReceipt: null,
245
+ verifiedAfterState: null,
246
+ recoveryState: { state: "not_needed", compensation: "none" },
247
+ };
248
+ appendReceipt(receiptsPath(agentRoot), receipt);
249
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.routine_action_reserved", message: "reserved routine action grant", meta: { key: input.key, target: input.target, policyVersion: policy.version } });
250
+ return receipt;
251
+ });
252
+ }
253
+ function transitionRoutineActionReceipt(agentRoot, input) {
254
+ return (0, session_transaction_1.withImmediateSessionTurnLease)(policyPath(agentRoot), () => {
255
+ const current = readRoutineActionReceipts(agentRoot).find((receipt) => receipt.id === input.id);
256
+ if (!current)
257
+ throw new Error("routine action receipt is missing");
258
+ if (current.state !== input.expectedState)
259
+ throw new Error(`routine action receipt state changed: expected ${input.expectedState}, got ${current.state}`);
260
+ const now = input.at ?? new Date().toISOString();
261
+ const recoveryState = input.recoveryState ?? current.recoveryState;
262
+ const next = {
263
+ ...current,
264
+ state: input.state,
265
+ updatedAt: now,
266
+ ...(input.effectReceipt !== undefined ? { effectReceipt: input.effectReceipt } : {}),
267
+ ...(input.verifiedAfterState !== undefined ? { verifiedAfterState: input.verifiedAfterState } : {}),
268
+ recoveryState,
269
+ };
270
+ appendReceipt(receiptsPath(agentRoot), next);
271
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.routine_action_transitioned", message: "transitioned routine action receipt", meta: { id: next.id, state: next.state, target: next.target } });
272
+ return next;
273
+ });
274
+ }
275
+ async function recoverRoutineActionReceipts(agentRoot, options) {
276
+ const recovered = [];
277
+ for (const receipt of readRoutineActionReceipts(agentRoot)) {
278
+ if (receipt.state === "reserved") {
279
+ recovered.push(transitionRoutineActionReceipt(agentRoot, { id: receipt.id, expectedState: "reserved", state: "recovered_no_effect", recoveryState: { state: "completed", compensation: "none" } }));
280
+ continue;
281
+ }
282
+ if (receipt.state === "attempting") {
283
+ recovered.push(transitionRoutineActionReceipt(agentRoot, { id: receipt.id, expectedState: "attempting", state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } }));
284
+ continue;
285
+ }
286
+ if (receipt.state !== "effect_acknowledged" && receipt.state !== "recovery_pending")
287
+ continue;
288
+ const pending = receipt.state === "effect_acknowledged"
289
+ ? transitionRoutineActionReceipt(agentRoot, { id: receipt.id, expectedState: "effect_acknowledged", state: "recovery_pending", recoveryState: { state: "pending", compensation: "none" } })
290
+ : receipt;
291
+ options.afterRecoveryClaim?.(pending);
292
+ const observed = await options.observeTarget(pending.resolvedTarget);
293
+ if (observed.id === pending.resolvedTarget.id && observed.name === pending.resolvedTarget.name && observed.state === "running") {
294
+ recovered.push(transitionRoutineActionReceipt(agentRoot, { id: pending.id, expectedState: "recovery_pending", state: "verified", verifiedAfterState: observed.state, recoveryState: { state: "completed", compensation: "none" } }));
295
+ }
296
+ else {
297
+ recovered.push(transitionRoutineActionReceipt(agentRoot, { id: pending.id, expectedState: "recovery_pending", state: "indeterminate", recoveryState: { state: "manual_inspection_required", compensation: "none" } }));
298
+ }
299
+ }
300
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.routine_action_recovery", message: "reconciled interrupted routine action receipts", meta: { recoveredCount: recovered.length } });
301
+ return recovered;
302
+ }