@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.920

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 (716) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  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/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5819 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +382 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +194 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +495 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2364 -578
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +451 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +876 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9199 -0
  148. package/dist/heart/daemon/cli-help.js +735 -0
  149. package/dist/heart/daemon/cli-parse.js +3211 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2350
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2084 -105
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +5 -2
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +733 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1516 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +237 -0
  244. package/dist/heart/frontend-socket-client.js +164 -0
  245. package/dist/heart/frontend-socket.js +400 -0
  246. package/dist/heart/habits/habit-cancel.js +810 -0
  247. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  248. package/dist/heart/habits/habit-migration.js +194 -0
  249. package/dist/heart/habits/habit-parser.js +278 -0
  250. package/dist/heart/habits/habit-runtime-state.js +93 -0
  251. package/dist/heart/habits/habit-scheduler.js +653 -0
  252. package/dist/heart/habits/habit-session-summary.js +318 -0
  253. package/dist/heart/habits/habit-session.js +636 -0
  254. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  255. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  256. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  257. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  258. package/dist/heart/identity.js +230 -59
  259. package/dist/heart/kept-notes.js +289 -0
  260. package/dist/heart/kicks.js +1 -1
  261. package/dist/heart/machine-identity.js +175 -0
  262. package/dist/heart/mail-import-discovery.js +356 -0
  263. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  264. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  265. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  266. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  267. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  268. package/dist/heart/mailbox/mailbox-http.js +99 -0
  269. package/dist/heart/mailbox/mailbox-read.js +39 -0
  270. package/dist/heart/mailbox/mailbox-types.js +27 -0
  271. package/dist/heart/mailbox/mailbox-view.js +197 -0
  272. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  273. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  274. package/dist/heart/mailbox/readers/mail.js +375 -0
  275. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  276. package/dist/heart/mailbox/readers/sessions.js +231 -0
  277. package/dist/heart/mailbox/readers/shared.js +111 -0
  278. package/dist/heart/mcp/mcp-server.js +696 -0
  279. package/dist/heart/migrate-config.js +100 -0
  280. package/dist/heart/model-capabilities.js +83 -16
  281. package/dist/heart/orientation-frame.js +345 -0
  282. package/dist/heart/platform.js +81 -0
  283. package/dist/heart/primitives.js +1 -1
  284. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  285. package/dist/heart/private-runtime/index.js +18 -0
  286. package/dist/heart/private-runtime/ledger.js +221 -0
  287. package/dist/heart/private-runtime/policy.js +260 -0
  288. package/dist/heart/private-runtime/types.js +2 -0
  289. package/dist/heart/progress-story.js +1 -1
  290. package/dist/heart/provider-attempt.js +137 -0
  291. package/dist/heart/provider-binding-resolver.js +273 -0
  292. package/dist/heart/provider-credentials.js +449 -0
  293. package/dist/heart/provider-failover.js +311 -0
  294. package/dist/heart/provider-models.js +96 -0
  295. package/dist/heart/provider-ping.js +265 -0
  296. package/dist/heart/provider-readiness-cache.js +119 -0
  297. package/dist/heart/provider-visibility.js +188 -0
  298. package/dist/heart/providers/anthropic-token.js +131 -0
  299. package/dist/heart/providers/anthropic.js +173 -60
  300. package/dist/heart/providers/azure.js +23 -11
  301. package/dist/heart/providers/error-classification.js +127 -0
  302. package/dist/heart/providers/github-copilot.js +38 -39
  303. package/dist/heart/providers/minimax-vlm.js +189 -0
  304. package/dist/heart/providers/minimax.js +26 -8
  305. package/dist/heart/providers/openai-codex-token.js +349 -0
  306. package/dist/heart/providers/openai-codex.js +55 -40
  307. package/dist/heart/providers/openai-compatible.js +177 -0
  308. package/dist/heart/reply-style.js +52 -0
  309. package/dist/heart/run-ledger.js +247 -0
  310. package/dist/heart/runtime-capability-check.js +170 -0
  311. package/dist/heart/runtime-credentials.js +607 -0
  312. package/dist/heart/runtime-cwd.js +87 -0
  313. package/dist/heart/sense-truth.js +24 -4
  314. package/dist/heart/session-activity.js +92 -24
  315. package/dist/heart/session-events.js +1504 -0
  316. package/dist/heart/session-playback-cli-main.js +5 -0
  317. package/dist/heart/session-playback-cli.js +36 -0
  318. package/dist/heart/session-playback.js +231 -0
  319. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  320. package/dist/heart/session-redaction-repair.js +552 -0
  321. package/dist/heart/session-stats-cli-main.js +5 -0
  322. package/dist/heart/session-stats.js +183 -0
  323. package/dist/heart/session-transcript.js +133 -0
  324. package/dist/heart/shelf-claims.js +78 -0
  325. package/dist/heart/shepherd-config.js +113 -0
  326. package/dist/heart/source-grounding.js +297 -0
  327. package/dist/heart/start-of-turn-packet.js +372 -0
  328. package/dist/heart/steward-policy.js +656 -0
  329. package/dist/heart/streaming.js +609 -207
  330. package/dist/heart/structured-output.js +196 -0
  331. package/dist/heart/sync-classification.js +176 -0
  332. package/dist/heart/sync-health.js +152 -0
  333. package/dist/heart/sync.js +726 -0
  334. package/dist/heart/target-resolution.js +11 -7
  335. package/dist/heart/tempo.js +93 -0
  336. package/dist/heart/temporal-view.js +41 -0
  337. package/dist/heart/timeouts.js +101 -0
  338. package/dist/heart/tool-activity-callbacks.js +59 -0
  339. package/dist/heart/tool-approval.js +382 -0
  340. package/dist/heart/tool-description.js +155 -0
  341. package/dist/heart/tool-friction.js +55 -0
  342. package/dist/heart/tool-loop.js +206 -0
  343. package/dist/heart/turn-context.js +496 -0
  344. package/dist/heart/turn-execution-lease.js +30 -0
  345. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  346. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  347. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  348. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  349. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  350. package/dist/heart/versioning/release-sources.js +173 -0
  351. package/dist/heart/versioning/self-update-defaults.js +294 -0
  352. package/dist/heart/versioning/self-update.js +196 -0
  353. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  354. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/update-state.js +126 -0
  357. package/dist/heart/versioning/updater-launchd.js +150 -0
  358. package/dist/heart/versioning/version-intent.js +114 -0
  359. package/dist/heart/work-card.js +380 -0
  360. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  361. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  362. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  363. package/dist/mailbox-ui/index.html +16 -0
  364. package/dist/mailroom/attention.js +167 -0
  365. package/dist/mailroom/autonomy.js +209 -0
  366. package/dist/mailroom/blob-store.js +889 -0
  367. package/dist/mailroom/body-cache.js +61 -0
  368. package/dist/mailroom/cache-sync-cli.js +58 -0
  369. package/dist/mailroom/core.js +803 -0
  370. package/dist/mailroom/entry.js +160 -0
  371. package/dist/mailroom/file-store.js +568 -0
  372. package/dist/mailroom/hosted-cache-sync.js +384 -0
  373. package/dist/mailroom/mbox-import.js +393 -0
  374. package/dist/mailroom/migration.js +164 -0
  375. package/dist/mailroom/outbound.js +380 -0
  376. package/dist/mailroom/policy.js +263 -0
  377. package/dist/mailroom/reader.js +292 -0
  378. package/dist/mailroom/search-cache.js +513 -0
  379. package/dist/mailroom/search-relevance.js +319 -0
  380. package/dist/mailroom/smtp-ingress.js +176 -0
  381. package/dist/mailroom/source-state.js +176 -0
  382. package/dist/mailroom/thread.js +109 -0
  383. package/dist/mailroom/travel-extract.js +89 -0
  384. package/dist/mind/bundle-manifest.js +24 -2
  385. package/dist/mind/context.js +307 -139
  386. package/dist/mind/desk-section.js +362 -0
  387. package/dist/mind/diary-integrity.js +60 -0
  388. package/dist/mind/{memory.js → diary.js} +68 -77
  389. package/dist/mind/embedding-provider.js +60 -0
  390. package/dist/mind/file-state.js +179 -0
  391. package/dist/mind/friend-link-codes.js +209 -0
  392. package/dist/mind/friend-merge.js +330 -0
  393. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  394. package/dist/mind/obligation-steering.js +199 -3
  395. package/dist/mind/pending.js +36 -10
  396. package/dist/mind/prompt-budget.js +479 -0
  397. package/dist/mind/prompt-refresh.js +3 -2
  398. package/dist/mind/prompt.js +1085 -198
  399. package/dist/mind/provenance-trust.js +26 -0
  400. package/dist/mind/record-paths.js +312 -0
  401. package/dist/mind/scrutiny.js +173 -0
  402. package/dist/mind/session-transaction.js +564 -0
  403. package/dist/nerves/cli-logging.js +7 -1
  404. package/dist/nerves/coverage/audit-rules.js +15 -6
  405. package/dist/nerves/coverage/audit.js +28 -2
  406. package/dist/nerves/coverage/cli.js +1 -1
  407. package/dist/nerves/coverage/contract.js +5 -5
  408. package/dist/nerves/coverage/file-completeness.js +139 -5
  409. package/dist/nerves/coverage/run-artifacts.js +55 -35
  410. package/dist/nerves/coverage/source-scanner.js +4 -4
  411. package/dist/nerves/event-buffer.js +111 -0
  412. package/dist/nerves/index.js +293 -9
  413. package/dist/nerves/observation.js +20 -0
  414. package/dist/nerves/redact.js +79 -0
  415. package/dist/nerves/review/cli-main.js +5 -0
  416. package/dist/nerves/review/cli.js +156 -0
  417. package/dist/nerves/review/core.js +159 -0
  418. package/dist/nerves/runtime.js +17 -1
  419. package/dist/repertoire/ado-client.js +15 -56
  420. package/dist/repertoire/ado-semantic.js +16 -10
  421. package/dist/repertoire/api-client.js +97 -0
  422. package/dist/repertoire/bitwarden-store.js +1201 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +231 -0
  425. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  426. package/dist/repertoire/coding/context-pack.js +331 -0
  427. package/dist/repertoire/coding/feedback.js +174 -32
  428. package/dist/repertoire/coding/index.js +15 -3
  429. package/dist/repertoire/coding/manager.js +159 -10
  430. package/dist/repertoire/coding/spawner.js +40 -11
  431. package/dist/repertoire/coding/tools.js +182 -18
  432. package/dist/repertoire/coding/workbench-client.js +272 -0
  433. package/dist/repertoire/coding/workbench-manager.js +346 -0
  434. package/dist/repertoire/commerce-errors.js +109 -0
  435. package/dist/repertoire/commerce-self-test.js +156 -0
  436. package/dist/repertoire/credential-access.js +183 -0
  437. package/dist/repertoire/desk/classifier.js +362 -0
  438. package/dist/repertoire/duffel-client.js +185 -0
  439. package/dist/repertoire/github-client.js +14 -55
  440. package/dist/repertoire/graph-client.js +11 -52
  441. package/dist/repertoire/guardrails.js +968 -20
  442. package/dist/repertoire/house-sweep.js +469 -0
  443. package/dist/repertoire/mcp-client.js +58 -5
  444. package/dist/repertoire/mcp-manager.js +427 -139
  445. package/dist/repertoire/mcp-tools.js +132 -0
  446. package/dist/repertoire/mcp-write-guard.js +46 -0
  447. package/dist/repertoire/plugin-mcp.js +175 -0
  448. package/dist/repertoire/plugins.js +253 -0
  449. package/dist/repertoire/relationship-authorization.js +322 -0
  450. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  451. package/dist/repertoire/shell-sessions.js +134 -0
  452. package/dist/repertoire/skills.js +48 -4
  453. package/dist/repertoire/stripe-client.js +131 -0
  454. package/dist/repertoire/tool-arguments.js +182 -0
  455. package/dist/repertoire/tool-results.js +29 -0
  456. package/dist/repertoire/tools-a2a.js +699 -0
  457. package/dist/repertoire/tools-attachments.js +322 -0
  458. package/dist/repertoire/tools-awaiting.js +872 -0
  459. package/dist/repertoire/tools-base.js +83 -1168
  460. package/dist/repertoire/tools-bluebubbles.js +2 -0
  461. package/dist/repertoire/tools-bridge.js +144 -0
  462. package/dist/repertoire/tools-bundle.js +995 -0
  463. package/dist/repertoire/tools-commerce.js +253 -0
  464. package/dist/repertoire/tools-config.js +186 -0
  465. package/dist/repertoire/tools-continuity.js +575 -0
  466. package/dist/repertoire/tools-credential.js +383 -0
  467. package/dist/repertoire/tools-escalation.js +84 -0
  468. package/dist/repertoire/tools-evolution.js +527 -0
  469. package/dist/repertoire/tools-files.js +344 -0
  470. package/dist/repertoire/tools-flight.js +290 -0
  471. package/dist/repertoire/tools-flow.js +119 -0
  472. package/dist/repertoire/tools-friend-link.js +57 -0
  473. package/dist/repertoire/tools-github.js +3 -8
  474. package/dist/repertoire/tools-habits.js +103 -0
  475. package/dist/repertoire/tools-house-care.js +174 -0
  476. package/dist/repertoire/tools-mail.js +1828 -0
  477. package/dist/repertoire/tools-notes.js +496 -0
  478. package/dist/repertoire/tools-obligations.js +182 -0
  479. package/dist/repertoire/tools-orientation.js +31 -0
  480. package/dist/repertoire/tools-record.js +482 -0
  481. package/dist/repertoire/tools-rsvp.js +139 -0
  482. package/dist/repertoire/tools-runtime.js +238 -0
  483. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  484. package/dist/repertoire/tools-session.js +1133 -0
  485. package/dist/repertoire/tools-shell.js +149 -0
  486. package/dist/repertoire/tools-shepherd.js +262 -0
  487. package/dist/repertoire/tools-steward-policy.js +147 -0
  488. package/dist/repertoire/tools-stripe.js +224 -0
  489. package/dist/repertoire/tools-surface.js +369 -0
  490. package/dist/repertoire/tools-teams.js +12 -39
  491. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  492. package/dist/repertoire/tools-travel.js +125 -0
  493. package/dist/repertoire/tools-trip.js +982 -0
  494. package/dist/repertoire/tools-unraid.js +556 -0
  495. package/dist/repertoire/tools-user-profile.js +146 -0
  496. package/dist/repertoire/tools-vault.js +40 -0
  497. package/dist/repertoire/tools-voice-local.js +198 -0
  498. package/dist/repertoire/tools-voice.js +145 -0
  499. package/dist/repertoire/tools.js +514 -156
  500. package/dist/repertoire/travel-api-client.js +360 -0
  501. package/dist/repertoire/unraid-client.js +155 -0
  502. package/dist/repertoire/unraid-restart.js +339 -0
  503. package/dist/repertoire/user-profile.js +131 -0
  504. package/dist/repertoire/vault-setup.js +246 -0
  505. package/dist/repertoire/vault-unlock.js +686 -0
  506. package/dist/rsvp/aisleplanner-client.js +354 -0
  507. package/dist/rsvp/cli.js +936 -0
  508. package/dist/rsvp/config.js +327 -0
  509. package/dist/rsvp/cutover.js +433 -0
  510. package/dist/rsvp/diagnostics.js +232 -0
  511. package/dist/rsvp/diff-renderer.js +176 -0
  512. package/dist/rsvp/habit-policy.js +110 -0
  513. package/dist/rsvp/habit-stage.js +123 -0
  514. package/dist/rsvp/incident-bundle.js +97 -0
  515. package/dist/rsvp/migration.js +204 -0
  516. package/dist/rsvp/native-habit-runner.js +630 -0
  517. package/dist/rsvp/outbound-state.js +628 -0
  518. package/dist/rsvp/query.js +118 -0
  519. package/dist/rsvp/replay.js +233 -0
  520. package/dist/rsvp/snapshot.js +232 -0
  521. package/dist/rsvp/spend-ledger.js +175 -0
  522. package/dist/scripts/claude-code-hook.js +41 -0
  523. package/dist/scripts/claude-code-stop-hook.js +47 -0
  524. package/dist/senses/a2a-entry.js +132 -0
  525. package/dist/senses/acp-server.js +386 -0
  526. package/dist/senses/attention-queue.js +186 -0
  527. package/dist/senses/await-turn-message.js +65 -0
  528. package/dist/senses/bluebubbles/active-turns.js +216 -0
  529. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  530. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  531. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
  532. package/dist/senses/bluebubbles/context-packet.js +207 -0
  533. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  534. package/dist/senses/bluebubbles/entry.js +90 -0
  535. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  536. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  537. package/dist/senses/bluebubbles/index.js +3878 -0
  538. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  539. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  540. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  541. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  542. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  543. package/dist/senses/bluebubbles/processed-log.js +133 -0
  544. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  545. package/dist/senses/bluebubbles/replay.js +284 -0
  546. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  547. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  548. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  549. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  550. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  551. package/dist/senses/cli/bracketed-paste.js +82 -0
  552. package/dist/senses/cli/image-paste.js +287 -0
  553. package/dist/senses/cli/image-ref-navigation.js +75 -0
  554. package/dist/senses/cli/ink-app.js +156 -0
  555. package/dist/senses/cli/inline-diff.js +64 -0
  556. package/dist/senses/cli/input-keys.js +174 -0
  557. package/dist/senses/cli/kill-ring.js +86 -0
  558. package/dist/senses/cli/message-list.js +51 -0
  559. package/dist/senses/cli/ouro-tui.js +607 -0
  560. package/dist/senses/cli/spinner-imperative.js +135 -0
  561. package/dist/senses/cli/spinner.js +101 -0
  562. package/dist/senses/cli/status-line.js +60 -0
  563. package/dist/senses/cli/streaming-markdown.js +526 -0
  564. package/dist/senses/cli/tool-display.js +85 -0
  565. package/dist/senses/cli/tool-render.js +85 -0
  566. package/dist/senses/cli/tui-store.js +241 -0
  567. package/dist/senses/cli/virtual-list.js +35 -0
  568. package/dist/senses/cli-entry.js +60 -8
  569. package/dist/senses/cli.js +601 -304
  570. package/dist/senses/commands.js +66 -3
  571. package/dist/senses/context-packet-ledger.js +371 -0
  572. package/dist/senses/context-packets.js +154 -0
  573. package/dist/senses/habit-lifecycle-guard.js +24 -0
  574. package/dist/senses/habit-turn-message.js +160 -0
  575. package/dist/senses/ingress-evidence.js +2 -0
  576. package/dist/senses/mail-entry.js +66 -0
  577. package/dist/senses/mail.js +524 -0
  578. package/dist/senses/pipeline.js +1158 -204
  579. package/dist/senses/private-runtime-worker.js +859 -0
  580. package/dist/senses/private-runtime.js +1627 -0
  581. package/dist/senses/proactive-content-guard.js +51 -0
  582. package/dist/senses/root-host-approval-port.js +345 -0
  583. package/dist/senses/root-host-approval-runtime.js +393 -0
  584. package/dist/senses/sanctuary-authority-resident.js +102 -0
  585. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  586. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  587. package/dist/senses/sanctuary-grounding.js +118 -0
  588. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  590. package/dist/senses/sanctuary-health-runner.js +104 -0
  591. package/dist/senses/sanctuary-health.js +422 -0
  592. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  593. package/dist/senses/sanctuary-interactive-control.js +410 -0
  594. package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
  595. package/dist/senses/sanctuary-media-optimization.js +514 -0
  596. package/dist/senses/sanctuary-runtime.js +369 -0
  597. package/dist/senses/sanctuary-sab.js +85 -0
  598. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  599. package/dist/senses/shared-turn.js +793 -0
  600. package/dist/senses/shepherd/client.js +196 -0
  601. package/dist/senses/shepherd/cmux.js +344 -0
  602. package/dist/senses/shepherd/herdr.js +315 -0
  603. package/dist/senses/shepherd/host.js +14 -0
  604. package/dist/senses/shepherd/judge.js +137 -0
  605. package/dist/senses/shepherd/owner-notice.js +245 -0
  606. package/dist/senses/shepherd/redact.js +66 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +309 -0
  609. package/dist/senses/shepherd-entry.js +78 -0
  610. package/dist/senses/surface-tool.js +109 -0
  611. package/dist/senses/teams-entry.js +68 -8
  612. package/dist/senses/teams.js +598 -233
  613. package/dist/senses/telegram-admission.js +718 -0
  614. package/dist/senses/telegram-approval-runtime.js +793 -0
  615. package/dist/senses/telegram-attachments.js +186 -0
  616. package/dist/senses/telegram-audit-ledger.js +220 -0
  617. package/dist/senses/telegram-authority-transport.js +231 -0
  618. package/dist/senses/telegram-client.js +1749 -0
  619. package/dist/senses/telegram-effect-adapter.js +900 -0
  620. package/dist/senses/telegram-entry.js +83 -0
  621. package/dist/senses/telegram-handoff.js +80 -0
  622. package/dist/senses/telegram.js +2405 -0
  623. package/dist/senses/trust-gate.js +104 -9
  624. package/dist/senses/voice/audio-playback.js +237 -0
  625. package/dist/senses/voice/audio-routing.js +119 -0
  626. package/dist/senses/voice/call-auth.js +250 -0
  627. package/dist/senses/voice/elevenlabs.js +202 -0
  628. package/dist/senses/voice/floor-control.js +431 -0
  629. package/dist/senses/voice/floor-controller.js +115 -0
  630. package/dist/senses/voice/golden-path.js +116 -0
  631. package/dist/senses/voice/index.js +29 -0
  632. package/dist/senses/voice/local-audio-control.js +344 -0
  633. package/dist/senses/voice/local-audio-devices.js +516 -0
  634. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  635. package/dist/senses/voice/local-audio-identity.js +103 -0
  636. package/dist/senses/voice/local-audio-join.js +325 -0
  637. package/dist/senses/voice/local-audio-mute.js +199 -0
  638. package/dist/senses/voice/local-audio-notify.js +121 -0
  639. package/dist/senses/voice/local-audio-prompts.js +116 -0
  640. package/dist/senses/voice/local-audio-transport.js +427 -0
  641. package/dist/senses/voice/local-audio.js +281 -0
  642. package/dist/senses/voice/local-media-stream.js +145 -0
  643. package/dist/senses/voice/meeting.js +113 -0
  644. package/dist/senses/voice/outbound.js +190 -0
  645. package/dist/senses/voice/phone.js +33 -0
  646. package/dist/senses/voice/playback.js +139 -0
  647. package/dist/senses/voice/process-guards.js +51 -0
  648. package/dist/senses/voice/realtime-eval.js +496 -0
  649. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  650. package/dist/senses/voice/realtime-trace.js +531 -0
  651. package/dist/senses/voice/transcript.js +70 -0
  652. package/dist/senses/voice/turn.js +191 -0
  653. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  654. package/dist/senses/voice/twilio-phone.js +5454 -0
  655. package/dist/senses/voice/types.js +2 -0
  656. package/dist/senses/voice/whisper.js +161 -0
  657. package/dist/senses/voice-entry.js +83 -0
  658. package/dist/senses/voice-realtime-eval-command.js +99 -0
  659. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  660. package/dist/senses/voice-twilio-entry.js +87 -0
  661. package/dist/trips/core.js +138 -0
  662. package/dist/trips/store.js +265 -0
  663. package/dist/util/frontmatter.js +69 -0
  664. package/npm-shrinkwrap.json +8100 -0
  665. package/package.json +74 -13
  666. package/skills/agent-commerce.md +113 -0
  667. package/skills/browser-navigation.md +117 -0
  668. package/skills/commerce-setup-guide.md +116 -0
  669. package/skills/commerce-setup.md +84 -0
  670. package/skills/configure-dev-tools.md +99 -0
  671. package/skills/travel-planning.md +138 -0
  672. package/dist/heart/daemon/auth-flow.js +0 -430
  673. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  674. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  675. package/dist/heart/daemon/update-hooks.js +0 -138
  676. package/dist/heart/obligations.js +0 -191
  677. package/dist/heart/safe-workspace.js +0 -362
  678. package/dist/heart/session-recall.js +0 -116
  679. package/dist/mind/friends/channel.js +0 -84
  680. package/dist/mind/friends/group-context.js +0 -144
  681. package/dist/mind/friends/resolver.js +0 -84
  682. package/dist/mind/friends/store-file.js +0 -190
  683. package/dist/mind/friends/store.js +0 -4
  684. package/dist/mind/friends/tokens.js +0 -26
  685. package/dist/mind/friends/trust-explanation.js +0 -74
  686. package/dist/mind/friends/types.js +0 -29
  687. package/dist/repertoire/tasks/board.js +0 -134
  688. package/dist/repertoire/tasks/index.js +0 -224
  689. package/dist/repertoire/tasks/lifecycle.js +0 -80
  690. package/dist/repertoire/tasks/middleware.js +0 -65
  691. package/dist/repertoire/tasks/parser.js +0 -173
  692. package/dist/repertoire/tasks/scanner.js +0 -132
  693. package/dist/repertoire/tasks/transitions.js +0 -144
  694. package/dist/senses/bluebubbles-entry.js +0 -13
  695. package/dist/senses/bluebubbles.js +0 -1181
  696. package/dist/senses/debug-activity.js +0 -154
  697. package/dist/senses/inner-dialog-worker.js +0 -90
  698. package/dist/senses/inner-dialog.js +0 -525
  699. package/subagents/README.md +0 -7
  700. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  706. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  712. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  713. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  714. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  715. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sanctuaryInstallStateRequiredToolCalls = sanctuaryInstallStateRequiredToolCalls;
4
+ exports.sanctuaryVersionQuestionRequiredToolCalls = sanctuaryVersionQuestionRequiredToolCalls;
5
+ const runtime_1 = require("../nerves/runtime");
6
+ const TOOL_NAME = "sanctuary_get_install_state";
7
+ const REQUEST = /\b(?:use|run|call)\s+sanctuary_get_install_state\b/iu;
8
+ const NEGATED_REQUEST = /\b(?:do not|don't|dont|never|must not|should not|cannot|can't)\s+(?:(?:under|any|all|circumstances|whatsoever|ever|please|really|actually|immediately)\s+)*(?:use|run|call)\s+sanctuary_get_install_state\b|\bnot\s+to\s+(?:use|run|call)\s+sanctuary_get_install_state\b|\b(?:do not|don't|dont)\s+(?:(?:want|need|ask)\b(?:(?![.!?;,:]).){0,64}|(?:(?:under|any|all|circumstances|whatsoever|ever|please|really|actually|immediately)\s+)*(?:attempt|try|plan|intend)\s+(?:to\s+)?)(?:use|run|call)\s+sanctuary_get_install_state\b/giu;
9
+ const HISTORICAL_QUESTION = /\b(?:did|have|has)\s+(?:you\s+)?(?:use|run|call)\s+sanctuary_get_install_state\b[^.!?;:]*/giu;
10
+ const MISMATCH_CODES = new Set([
11
+ "managed_file_missing",
12
+ "managed_file_content",
13
+ "managed_file_mode",
14
+ "bundle_meta_missing",
15
+ "bundle_meta_field",
16
+ "bundle_meta_mode",
17
+ ]);
18
+ const REPAIR_ACTIONS = new Set([
19
+ "restart_from_verified_release",
20
+ "run_verified_update_recovery",
21
+ "roll_back_or_install_verified_release",
22
+ ]);
23
+ function parseInstallState(result) {
24
+ try {
25
+ const parsed = JSON.parse(result);
26
+ const data = parsed.ok === true && parsed.data && typeof parsed.data === "object" && !Array.isArray(parsed.data)
27
+ ? parsed.data
28
+ : undefined;
29
+ const repair = data?.repair && typeof data.repair === "object" && !Array.isArray(data.repair)
30
+ ? data.repair
31
+ : undefined;
32
+ if (!data
33
+ || typeof data.runtimePackageVersion !== "string" || data.runtimePackageVersion.length === 0
34
+ || typeof data.packagedBundleVersion !== "string" || data.packagedBundleVersion.length === 0
35
+ || !(typeof data.liveBundleVersion === "string" && data.liveBundleVersion.length > 0 || data.liveBundleVersion === null)
36
+ || !["exact", "mismatch"].includes(String(data.parity))
37
+ || !Array.isArray(data.mismatchCodes)
38
+ || !data.mismatchCodes.every((code) => typeof code === "string" && MISMATCH_CODES.has(code))
39
+ || !["absent", "rollback", "committing"].includes(String(data.journalState))
40
+ || typeof data.ready !== "boolean"
41
+ || !(repair?.actor === "none" && repair.action === "none"
42
+ || repair?.actor === "human-required" && typeof repair.action === "string" && REPAIR_ACTIONS.has(repair.action)))
43
+ return undefined;
44
+ return {
45
+ runtimePackageVersion: data.runtimePackageVersion,
46
+ packagedBundleVersion: data.packagedBundleVersion,
47
+ liveBundleVersion: data.liveBundleVersion,
48
+ parity: data.parity,
49
+ journalState: data.journalState,
50
+ ready: data.ready,
51
+ repairAction: repair.action,
52
+ };
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }
58
+ function exactAnswerPattern(current) {
59
+ const value = (raw) => raw.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
60
+ const assignment = String.raw `\s*(?:(?:is)\s+|[:=]\s*)?`;
61
+ const separator = String.raw `\s*[,;]\s*`;
62
+ return new RegExp(String.raw `runtime(?: package)?(?: version)?${assignment}${value(current.runtimePackageVersion)}${separator}`
63
+ + String.raw `packaged(?: bundle)?(?: version)?${assignment}${value(current.packagedBundleVersion)}${separator}`
64
+ + String.raw `live(?: bundle)?(?: version)?${assignment}${value(current.liveBundleVersion ?? "null")}${separator}`
65
+ + String.raw `parity${assignment}${value(current.parity)}${separator}`
66
+ + String.raw `journal(?: state)?${assignment}${value(current.journalState)}${separator}`
67
+ + String.raw `ready(?: state)?${assignment}${value(String(current.ready))}${separator}`
68
+ + String.raw `repair(?: action)?${assignment}${value(current.repairAction)}(?=$|[\s,;.!?])`, "iu");
69
+ }
70
+ const RESIDUAL_INSTALL_STATE_CLAIM = /(?:^|[.!?;,]\s*)(?:(?:and|but|however|yet)\s+)*(?:(?:the\s+)?(?:runtime(?: package)?(?: version)?|packaged(?: bundle)?(?: version)?|live(?: bundle)?(?: version)?)\s*(?:(?:is)\s+|[:=]\s*)?(?=v?\d|unknown\b|null\b|missing\b|corrupt\b)|(?:the\s+)?installed package(?: version)?\b|(?:the\s+)?parity\s*(?:(?:is)\s+|[:=]\s*)?(?=(?:not\s+)?(?:exact|mismatch)\b)|(?:the\s+)?journal(?: state)?\s*(?:(?:is)\s+|[:=]\s*)?(?=(?:not\s+)?(?:absent|rollback|committing)\b)|(?:the\s+)?ready(?: state)?\s*(?:(?:is)\s+|[:=]\s*)?(?=(?:not\s+)?(?:true|false|ready)\b)|(?:the\s+)?repair(?: action)?\s*(?:(?:is)\s+|[:=]\s*)?(?=none\b|restart_from_verified_release\b|run_verified_update_recovery\b|roll_back_or_install_verified_release\b|required\b|needed\b)|(?:the\s+)?(?:install(?:ation)?|sanctuary|bundle|service|system|it)\s+(?:is(?:\s+not)?|isn't)\s+ready\b)/iu;
71
+ function sanctuaryInstallStateRequiredToolCalls(request, advertisedToolNames) {
72
+ const normalizedRequest = request.normalize("NFKC").replace(/[‘’]/gu, "'");
73
+ const negationRequest = normalizedRequest.replace(/,/gu, " ");
74
+ const affirmativeRequest = negationRequest
75
+ .replace(NEGATED_REQUEST, " ")
76
+ .replace(HISTORICAL_QUESTION, " ");
77
+ if (!advertisedToolNames.includes(TOOL_NAME)
78
+ || !REQUEST.test(affirmativeRequest))
79
+ return undefined;
80
+ let current;
81
+ const retryMessage = "Call sanctuary_get_install_state with empty arguments, then answer only from that fresh result.";
82
+ (0, runtime_1.emitNervesEvent)({
83
+ component: "senses",
84
+ event: "senses.sanctuary_install_state_required",
85
+ message: "explicit Sanctuary install-state request requires a fresh verified read",
86
+ meta: { requiredToolName: TOOL_NAME },
87
+ });
88
+ return {
89
+ names: [TOOL_NAME],
90
+ retryMessage,
91
+ requireSuccessfulResults: true,
92
+ validateRequiredToolResult: (name, result, args) => {
93
+ if (name !== TOOL_NAME || Object.keys(args).length !== 0)
94
+ return false;
95
+ current = parseInstallState(result);
96
+ return current !== undefined;
97
+ },
98
+ validateTerminalAnswer: (answer) => {
99
+ if (!current) {
100
+ return "Answer from the fresh install-state result and include its runtime package version, packaged bundle version, live bundle version, parity, journal state, ready state, and repair action.";
101
+ }
102
+ const normalizedAnswer = answer.normalize("NFKC").replace(/[‘’]/gu, "'").replace(/\*\*|`/gu, "");
103
+ const exactMatches = [...normalizedAnswer.matchAll(new RegExp(exactAnswerPattern(current).source, "giu"))];
104
+ if (exactMatches.length === 0) {
105
+ const currentValues = [
106
+ current.runtimePackageVersion,
107
+ current.packagedBundleVersion,
108
+ current.liveBundleVersion ?? "null",
109
+ current.parity,
110
+ current.journalState,
111
+ String(current.ready),
112
+ current.repairAction,
113
+ ];
114
+ return currentValues.every((value) => normalizedAnswer.includes(value))
115
+ ? "State each fresh install-state value exactly once in one compact answer."
116
+ : "Answer from the fresh install-state result and include its runtime package version, packaged bundle version, live bundle version, parity, journal state, ready state, and repair action.";
117
+ }
118
+ if (exactMatches.length !== 1)
119
+ return "State each fresh install-state value exactly once in one compact answer.";
120
+ const match = exactMatches[0];
121
+ const residual = normalizedAnswer.replace(match[0], " ").trim();
122
+ if (RESIDUAL_INSTALL_STATE_CLAIM.test(residual))
123
+ return "State each fresh install-state value exactly once in one compact answer.";
124
+ return undefined;
125
+ },
126
+ };
127
+ }
128
+ const VERSION_QUESTION = /\b(?:what|which)(?:'s|\s+is)?\s+(?:your\s+|the\s+)?(?:current\s+|live\s+|installed\s+|running\s+)?version\b|\bversion\s+(?:are|r)\s+(?:you|u)\b|\bwhat\s+(?:are\s+you|you're)\s+(?:on|running)\b|\bare\s+you\s+(?:on|running)\s+(?:the\s+)?(?:latest|newest|new|current)\b/iu;
129
+ const VERSION_CLAIM = /\bv?\d+\.\d+\.\d+(?:-[0-9A-Za-z]+(?:\.[0-9A-Za-z]+)*)?\b/gu;
130
+ /**
131
+ * A natural question about the Butler's own version must be answered from a fresh
132
+ * install-state read. After an upgrade the Butler once answered "Just checked the live
133
+ * state: 0.1.0-alpha.841" from earlier conversation while it was running 845, with no
134
+ * tool call at all. Unlike the explicit install-state contract, the wording stays free:
135
+ * only the version it states is checked against the read.
136
+ */
137
+ function sanctuaryVersionQuestionRequiredToolCalls(request, advertisedToolNames) {
138
+ const normalizedRequest = request.normalize("NFKC").replace(/[‘’]/gu, "'");
139
+ if (!advertisedToolNames.includes(TOOL_NAME) || REQUEST.test(normalizedRequest) || !VERSION_QUESTION.test(normalizedRequest))
140
+ return undefined;
141
+ let current;
142
+ (0, runtime_1.emitNervesEvent)({
143
+ component: "senses",
144
+ event: "senses.sanctuary_version_question_required",
145
+ message: "a question about the running version requires a fresh install-state read",
146
+ meta: { requiredToolName: TOOL_NAME },
147
+ });
148
+ return {
149
+ names: [TOOL_NAME],
150
+ retryMessage: "Call sanctuary_get_install_state with empty arguments now, then state the version from that fresh result, not from earlier conversation.",
151
+ requireSuccessfulResults: true,
152
+ validateRequiredToolResult: (name, result, args) => {
153
+ if (name !== TOOL_NAME || Object.keys(args).length !== 0)
154
+ return false;
155
+ current = parseInstallState(result);
156
+ return current !== undefined;
157
+ },
158
+ validateTerminalAnswer: (answer) => {
159
+ if (!current)
160
+ return "Call sanctuary_get_install_state and state the version from that fresh result.";
161
+ const known = new Set([current.runtimePackageVersion, current.packagedBundleVersion, ...(current.liveBundleVersion ? [current.liveBundleVersion] : [])].map((version) => version.replace(/^v/u, "")));
162
+ const claimed = [...answer.normalize("NFKC").matchAll(VERSION_CLAIM)].map((match) => match[0].replace(/^v/u, ""));
163
+ if (claimed.length === 0)
164
+ return `State the running version from the fresh result: ${current.runtimePackageVersion}.`;
165
+ const stale = claimed.filter((version) => !known.has(version));
166
+ return stale.length === 0 ? undefined : `The fresh install-state result says ${current.runtimePackageVersion}; do not state ${stale.join(", ")} as the current version.`;
167
+ },
168
+ };
169
+ }
@@ -0,0 +1,410 @@
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.proveSanctuaryAttemptedRecoveryWithoutRetry = proveSanctuaryAttemptedRecoveryWithoutRetry;
37
+ exports.executeSanctuaryInteractiveEngine = executeSanctuaryInteractiveEngine;
38
+ exports.createSanctuaryInteractiveControl = createSanctuaryInteractiveControl;
39
+ exports.sanctuaryInteractiveControlReady = sanctuaryInteractiveControlReady;
40
+ const node_crypto_1 = require("node:crypto");
41
+ const node_fs_1 = require("node:fs");
42
+ const node_net_1 = require("node:net");
43
+ const path = __importStar(require("node:path"));
44
+ const approval_store_1 = require("../heart/approval-store");
45
+ const tool_approval_1 = require("../heart/tool-approval");
46
+ const runtime_1 = require("../nerves/runtime");
47
+ const telegram_client_1 = require("./telegram-client");
48
+ const SHA256 = /^[0-9a-f]{64}$/u;
49
+ const MAX_CONTROL_REQUEST = 16 * 1024;
50
+ function object(value, label) {
51
+ if (!value || typeof value !== "object" || Array.isArray(value))
52
+ throw new Error(`${label} must be an object`);
53
+ return value;
54
+ }
55
+ function exactKeys(value, keys, label) {
56
+ if (JSON.stringify(Object.keys(value).sort()) !== JSON.stringify([...keys].sort()))
57
+ throw new Error(`${label} shape is invalid`);
58
+ }
59
+ function sha256(value) {
60
+ return (0, node_crypto_1.createHash)("sha256").update(value, "utf8").digest("hex");
61
+ }
62
+ function exactApproval(projections) {
63
+ const matches = projections.filter(({ approval }) => approval.toolName === "unraid_restart_container" && approval.arguments.container === "calibre-web");
64
+ if (matches.length !== 1)
65
+ throw new Error("interactive production approval is absent or ambiguous");
66
+ return matches[0];
67
+ }
68
+ function exactPending(records, approvalId) {
69
+ const validCallback = (value) => typeof value === "string" && Buffer.byteLength(value) >= 1 && Buffer.byteLength(value) <= 64;
70
+ const matches = records.filter((record) => record.approvalId === approvalId && record.deliveryState === "bound" && record.messageId !== null
71
+ && validCallback(record.approveCallbackData) && validCallback(record.denyCallbackData));
72
+ if (matches.length !== 1)
73
+ throw new Error("interactive production pending approval is absent or ambiguous");
74
+ return matches[0];
75
+ }
76
+ function exactTerminalTombstone(records, approvalId) {
77
+ const validCallback = (value) => typeof value === "string" && Buffer.byteLength(value) >= 1 && Buffer.byteLength(value) <= 64;
78
+ const matches = records.filter((record) => record.approvalId === approvalId && record.deliveryState === "terminal_tombstone" && record.messageId !== null
79
+ && validCallback(record.approveCallbackData) && validCallback(record.denyCallbackData)
80
+ && record.expiryObservation?.schemaVersion === "telegram-approval-expiry-observation-v1"
81
+ && record.expiryObservation.deadlineAt === record.expiresAt && Number.isSafeInteger(record.expiryObservation.observedAt)
82
+ && record.expiryObservation.observedAt >= record.expiresAt && typeof record.expiryObservation.evidenceMac === "string" && SHA256.test(record.expiryObservation.evidenceMac)
83
+ && Number.isSafeInteger(record.terminalizedAt) && Number(record.terminalizedAt) >= record.expiryObservation.observedAt);
84
+ if (matches.length !== 1)
85
+ throw new Error("interactive production terminal tombstone is absent or ambiguous");
86
+ return matches[0];
87
+ }
88
+ function pendingDigest(record) {
89
+ return sha256(JSON.stringify({ approvalId: record.approvalId, messageId: record.messageId, deliveryState: record.deliveryState, approveCallbackData: record.approveCallbackData, denyCallbackData: record.denyCallbackData, expiresAt: record.expiresAt }));
90
+ }
91
+ function proveSanctuaryAttemptedRecoveryWithoutRetry(agentRoot, scenarioHandleDigest, approval) {
92
+ if (!SHA256.test(scenarioHandleDigest))
93
+ throw new Error("attempted recovery scenario is invalid");
94
+ const databaseRoot = path.join(agentRoot, "state", "acceptance", "attempted-recovery-probes");
95
+ (0, node_fs_1.mkdirSync)(databaseRoot, { recursive: true, mode: 0o700 });
96
+ const databasePath = path.join(databaseRoot, `${scenarioHandleDigest}.sqlite`);
97
+ if ((0, node_fs_1.existsSync)(databasePath))
98
+ throw new Error("attempted recovery proof requires inspect-before-retry");
99
+ const instant = new Date("2026-08-21T00:00:00.000Z");
100
+ const first = (0, approval_store_1.openApprovalStore)({ databasePath, now: () => instant });
101
+ const ownerId = "acceptance-attempted-recovery";
102
+ const toolCallId = `acceptance-${approval.toolCallId}`;
103
+ const frozenAssistantMessage = structuredClone(approval.frozenAssistantMessage);
104
+ const toolCalls = frozenAssistantMessage.tool_calls;
105
+ if (!Array.isArray(toolCalls) || toolCalls.length !== 1 || !toolCalls[0] || typeof toolCalls[0] !== "object" || Array.isArray(toolCalls[0])) {
106
+ first.close();
107
+ throw new Error("attempted recovery frozen tool call is invalid");
108
+ }
109
+ toolCalls[0].id = toolCallId;
110
+ const prepared = first.prepare({
111
+ toolCallId, toolName: approval.toolName, arguments: approval.arguments,
112
+ schemaDigest: approval.schemaDigest, toolDigest: approval.toolDigest, policyDigest: approval.policyDigest, policyId: approval.policyId,
113
+ sessionKey: "acceptance:attempted-recovery", sessionPath: path.join(databaseRoot, `${scenarioHandleDigest}.session.json`),
114
+ baseSessionRevision: approval.baseSessionRevision, checkpointDigest: approval.checkpointDigest,
115
+ requesterId: "acceptance-probe", transport: "telegram", transportUserId: "acceptance-probe", transportChatId: "acceptance-probe",
116
+ expiresAt: "2099-01-01T00:00:00.000Z", frozenAssistantMessage,
117
+ });
118
+ first.activate({ approvalId: prepared.record.approvalId, checkpointDigest: prepared.record.checkpointDigest, suspendedSessionRevision: approval.suspendedSessionRevision });
119
+ first.bindPrompt({ approvalId: prepared.record.approvalId, transport: "telegram", transportChatId: "acceptance-probe", transportMessageId: "acceptance-message" });
120
+ const claimed = first.decide({
121
+ approvalId: prepared.record.approvalId, decisionToken: prepared.decisionToken, decision: "approve", requesterId: "acceptance-probe",
122
+ transport: "telegram", transportUserId: "acceptance-probe", transportChatId: "acceptance-probe", transportMessageId: "acceptance-message",
123
+ sessionKey: "acceptance:attempted-recovery", ownerId,
124
+ });
125
+ const attempted = first.markAttempted({ approvalId: claimed.approvalId, ownerId, epoch: claimed.epoch });
126
+ first.close();
127
+ const attemptedRecordDigest = sha256(JSON.stringify(attempted));
128
+ const reopened = (0, approval_store_1.openApprovalStore)({ databasePath, now: () => instant });
129
+ const durableAttempted = reopened.read(attempted.approvalId);
130
+ if (!durableAttempted || durableAttempted.state !== "attempted") {
131
+ reopened.close();
132
+ throw new Error("attempted recovery record was not durable across reopen");
133
+ }
134
+ const recovered = (0, tool_approval_1.recoverAttemptedApproval)({ approvalStore: reopened, approvalId: durableAttempted.approvalId });
135
+ let retryCount = 0;
136
+ try {
137
+ (0, tool_approval_1.recoverAttemptedApproval)({ approvalStore: reopened, approvalId: durableAttempted.approvalId });
138
+ retryCount += 1;
139
+ }
140
+ catch { /* expected */ }
141
+ reopened.close();
142
+ return { observed: recovered.state === "attempted_indeterminate", retryCount, reopened: true, attemptedRecordDigest, recoveredRecordDigest: sha256(JSON.stringify(recovered)) };
143
+ }
144
+ async function executeSanctuaryInteractiveEngine(raw, deps) {
145
+ const payload = object(raw, "interactive runtime payload");
146
+ exactKeys(payload, ["operation", "label", "scenarioHandleDigest"], "interactive runtime payload");
147
+ const operation = payload.operation;
148
+ const label = payload.label;
149
+ const scenarioHandleDigest = payload.scenarioHandleDigest;
150
+ if (typeof scenarioHandleDigest !== "string" || !SHA256.test(scenarioHandleDigest)
151
+ || !["unit-16k-timeout-stale", "unit-16l-duplicate-callback", "unit-16m-restart-continuation"].includes(label)
152
+ || !["drive_timeout_stale", "drive_duplicate_callbacks", "prepare_restart_continuation", "reconcile_restart_continuation"].includes(String(operation))
153
+ || (operation === "drive_timeout_stale") !== (label === "unit-16k-timeout-stale")
154
+ || (operation === "drive_duplicate_callbacks") !== (label === "unit-16l-duplicate-callback"))
155
+ throw new Error("interactive runtime operation binding is invalid");
156
+ const before = exactApproval(deps.readApprovals(scenarioHandleDigest));
157
+ if (!before.approval.suspendedSessionRevision)
158
+ throw new Error("interactive production approval checkpoint is unavailable");
159
+ if (operation === "drive_timeout_stale") {
160
+ if (before.approval.state === "proposed") {
161
+ exactPending(deps.readPending(), before.approval.approvalId);
162
+ return { state: "waiting" };
163
+ }
164
+ if (before.approval.state !== "expired" || before.approval.epoch !== 0)
165
+ throw new Error("timeout stale approval is not expired without a claim");
166
+ const captured = exactTerminalTombstone(deps.readPending(), before.approval.approvalId);
167
+ const session = await deps.createSession();
168
+ try {
169
+ const queryId = (0, node_crypto_1.randomBytes)(18).toString("base64url");
170
+ const result = await session.handle({ callbackData: captured.approveCallbackData, queryId, messageId: captured.messageId });
171
+ const after = exactApproval(deps.readApprovals(scenarioHandleDigest));
172
+ const promptTerminal = !session.pendingApprovalIds().includes(before.approval.approvalId);
173
+ if (!result.handled || result.accepted || result.reason !== "stale_callback" || after.approval.state !== "expired" || after.approval.epoch !== 0 || !promptTerminal) {
174
+ throw new Error("timeout stale callback proof failed");
175
+ }
176
+ return {
177
+ schemaVersion: "sanctuary-timeout-stale-driver-receipt-v1", phase: "complete", label, scenarioHandleDigest,
178
+ approvalIdDigest: sha256(before.approval.approvalId), checkpointDigest: before.approval.checkpointDigest,
179
+ suspendedSessionRevisionDigest: sha256(before.approval.suspendedSessionRevision), approvalEpochBefore: before.approval.epoch,
180
+ callbackAttempts: 1, distinctQueryCount: 1, callbackDataDigest: sha256(captured.approveCallbackData),
181
+ settledCount: 1, claimCount: 0, mutationCount: 0, staleAcknowledged: true, promptTerminal,
182
+ };
183
+ }
184
+ finally {
185
+ session.close();
186
+ }
187
+ }
188
+ if (before.approval.state !== "proposed")
189
+ throw new Error("interactive production approval is not currently proposed");
190
+ const pending = exactPending(deps.readPending(), before.approval.approvalId);
191
+ const common = { approvalIdDigest: sha256(before.approval.approvalId), checkpointDigest: before.approval.checkpointDigest, suspendedSessionRevisionDigest: sha256(before.approval.suspendedSessionRevision), approvalEpochBefore: before.approval.epoch };
192
+ if (operation === "prepare_restart_continuation") {
193
+ const recovery = deps.proveIndeterminateRecovery(before.approval, scenarioHandleDigest);
194
+ if (!recovery.observed || recovery.retryCount !== 0 || !recovery.reopened
195
+ || !SHA256.test(recovery.attemptedRecordDigest) || !SHA256.test(recovery.recoveredRecordDigest)
196
+ || recovery.attemptedRecordDigest === recovery.recoveredRecordDigest)
197
+ throw new Error("isolated attempted recovery proof failed");
198
+ return {
199
+ schemaVersion: "sanctuary-interactive-driver-receipt-v2", phase: "prepared", label, scenarioHandleDigest, ...common,
200
+ pendingDigestBefore: pendingDigest(pending), indeterminateRecoveryObserved: true,
201
+ attemptedRecoveryReopened: true, attemptedRecordDigest: recovery.attemptedRecordDigest, recoveredRecordDigest: recovery.recoveredRecordDigest,
202
+ };
203
+ }
204
+ const session = await deps.createSession();
205
+ try {
206
+ if (operation === "drive_duplicate_callbacks") {
207
+ const queryIds = [(0, node_crypto_1.randomBytes)(18).toString("base64url"), (0, node_crypto_1.randomBytes)(18).toString("base64url")];
208
+ let arrivals = 0;
209
+ let release;
210
+ const barrier = new Promise((resolve) => { release = resolve; });
211
+ const invoke = async (queryId) => { arrivals += 1; if (arrivals === 2)
212
+ release(); await barrier; return session.handle({ callbackData: pending.approveCallbackData, queryId, messageId: pending.messageId }); };
213
+ const results = await Promise.all(queryIds.map(invoke));
214
+ const after = exactApproval(deps.readApprovals(scenarioHandleDigest));
215
+ const stale = await session.handle({ callbackData: pending.approveCallbackData, queryId: (0, node_crypto_1.randomBytes)(18).toString("base64url"), messageId: pending.messageId });
216
+ return { schemaVersion: "sanctuary-interactive-driver-receipt-v2", phase: "complete", label, scenarioHandleDigest, ...common, callbackAttempts: 2, distinctQueryCount: new Set(queryIds).size, callbackDataDigest: sha256(pending.approveCallbackData), barrierObserved: arrivals === 2, settledCount: results.filter(({ handled }) => handled).length, claimCount: after.approval.epoch === before.approval.epoch + 1 ? 1 : 0, mutationCount: after.approval.state === "succeeded" ? 1 : 0, staleReplayAttempts: 1, staleReplaySettled: stale.handled, staleReplayMutationCount: 0, promptTerminal: !session.pendingApprovalIds().includes(before.approval.approvalId), writeCredentialObserved: deps.writeCredentialObserved() };
217
+ }
218
+ const result = await session.handle({ callbackData: pending.approveCallbackData, queryId: (0, node_crypto_1.randomBytes)(18).toString("base64url"), messageId: pending.messageId });
219
+ const after = exactApproval(deps.readApprovals(scenarioHandleDigest));
220
+ if (!after.continuation || after.approval.state !== "succeeded")
221
+ throw new Error("restart continuation did not complete");
222
+ return { approvalEpochAfterRestart: before.approval.epoch, continuationEpochAfter: after.continuation.continuationEpoch, pendingDigestAfter: pendingDigest(pending), pendingRestored: true, callbackAttempts: 1, mutationCount: result.accepted ? 1 : 0, indeterminateRetryCount: 0 };
223
+ }
224
+ finally {
225
+ session.close();
226
+ }
227
+ }
228
+ function createSanctuaryInteractiveControl(options) {
229
+ const socketPath = path.join(options.agentRoot, "state", "acceptance", "telegram-control.sock");
230
+ const runRequest = options.runRequest ?? (async (operation) => operation());
231
+ let server;
232
+ let endpoint;
233
+ let startPromise;
234
+ let stopPromise;
235
+ let updateId = 2_100_000_000;
236
+ const readEndpoint = () => (0, node_fs_1.lstatSync)(socketPath, { bigint: true, throwIfNoEntry: false });
237
+ // Socket mtime, unlike ctime, survives permission-only changes.
238
+ const matches = (observed, current) => current !== undefined && current.isSocket() && current.dev === observed.dev && current.ino === observed.ino
239
+ && current.birthtimeNs === observed.birthtimeNs && current.mtimeNs === observed.mtimeNs;
240
+ const stopListener = async () => {
241
+ const active = server;
242
+ if (!active)
243
+ return;
244
+ if (active.listening) {
245
+ const current = readEndpoint();
246
+ // Native Server.close() also unlinks its pathname, so ownership must precede it.
247
+ if (current && (!endpoint || !matches(endpoint, current)))
248
+ throw new Error("Sanctuary interactive control socket ownership was replaced");
249
+ await new Promise((resolve, reject) => active.close((error) => error ? reject(error) : resolve()));
250
+ }
251
+ server = undefined;
252
+ endpoint = undefined;
253
+ };
254
+ return {
255
+ socketPath,
256
+ start() {
257
+ if (startPromise)
258
+ return startPromise;
259
+ const previousStop = stopPromise;
260
+ stopPromise = undefined;
261
+ const starting = (async () => {
262
+ if (previousStop)
263
+ await previousStop;
264
+ if (server) {
265
+ if (endpoint && matches(endpoint, readEndpoint()))
266
+ return;
267
+ await stopListener();
268
+ }
269
+ (0, node_fs_1.mkdirSync)(path.dirname(socketPath), { recursive: true, mode: 0o700 });
270
+ const previous = readEndpoint();
271
+ if (previous) {
272
+ if (!previous.isSocket())
273
+ throw new Error("Sanctuary interactive control endpoint is not a socket");
274
+ await new Promise((resolve, reject) => {
275
+ const socket = (0, node_net_1.createConnection)(socketPath);
276
+ const finish = (error) => { socket.destroy(); if (error)
277
+ reject(error);
278
+ else
279
+ resolve(); };
280
+ socket.setTimeout(1_000, () => finish(new Error("Sanctuary interactive control ownership probe timed out")));
281
+ socket.once("connect", () => finish(new Error("Sanctuary interactive control endpoint has another live listener")));
282
+ socket.once("error", (error) => finish(error.code === "ECONNREFUSED" ? undefined : error));
283
+ });
284
+ const current = readEndpoint();
285
+ if (!matches(previous, current) || current.ctimeNs !== previous.ctimeNs)
286
+ throw new Error("Sanctuary interactive control endpoint was replaced during the ownership probe");
287
+ (0, node_fs_1.unlinkSync)(socketPath);
288
+ }
289
+ server = (0, node_net_1.createServer)({ allowHalfOpen: true }, (connection) => {
290
+ let raw = "";
291
+ connection.setEncoding("utf8");
292
+ connection.on("error", () => undefined);
293
+ connection.on("data", (chunk) => { raw += chunk; if (Buffer.byteLength(raw) > MAX_CONTROL_REQUEST)
294
+ connection.destroy(); });
295
+ connection.on("end", () => {
296
+ void runRequest(async () => {
297
+ try {
298
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.sanctuary_interactive_control_request", message: "Sanctuary interactive control request received", meta: { bytes: Buffer.byteLength(raw) } });
299
+ const parsed = object(JSON.parse(raw), "interactive control request");
300
+ if (parsed.operation === "interactive_runtime_ready") {
301
+ exactKeys(parsed, ["operation", "label", "scenarioHandleDigest"], "interactive readiness request");
302
+ if (parsed.label !== "unit-16m-restart-continuation" || typeof parsed.scenarioHandleDigest !== "string" || !SHA256.test(parsed.scenarioHandleDigest))
303
+ throw new Error("interactive readiness binding is invalid");
304
+ connection.end(`${JSON.stringify({ ok: true, result: { ready: true } })}\n`);
305
+ return;
306
+ }
307
+ const result = await executeSanctuaryInteractiveEngine(parsed, {
308
+ agentRoot: options.agentRoot,
309
+ readApprovals: (digest) => (0, approval_store_1.readApprovalsByScenarioHandleDigest)(path.join(options.agentRoot, "state", "approvals", "approvals.sqlite"), digest),
310
+ readPending: () => new telegram_client_1.FileTelegramPendingApprovalStore(path.join(options.agentRoot, "state", "approvals", "telegram-pending.json")).load(),
311
+ createSession: async () => ({
312
+ handle: ({ callbackData, queryId, messageId }) => runRequest(() => options.transport.handleUpdate({
313
+ update_id: updateId++,
314
+ callback_query: {
315
+ id: queryId,
316
+ from: { id: Number(options.authorizedUserId) },
317
+ data: callbackData,
318
+ message: {
319
+ message_id: Number(messageId),
320
+ chat: { id: Number(options.authorizedChatId) },
321
+ },
322
+ },
323
+ })),
324
+ pendingApprovalIds: () => options.transport.listPendingDeliveries().map(({ approvalId }) => approvalId),
325
+ close: () => undefined,
326
+ }),
327
+ proveIndeterminateRecovery: (approval, digest) => proveSanctuaryAttemptedRecoveryWithoutRetry(options.agentRoot, digest, approval),
328
+ writeCredentialObserved: () => /credential|api[_-]?key|token|secret/iu.test(raw),
329
+ });
330
+ connection.end(`${JSON.stringify({ ok: true, result })}\n`);
331
+ }
332
+ catch {
333
+ connection.end(`${JSON.stringify({ ok: false, error: "interactive runtime operation failed" })}\n`);
334
+ }
335
+ }).catch(() => { if (!connection.destroyed)
336
+ connection.end(`${JSON.stringify({ ok: false, error: "interactive runtime operation failed" })}\n`); });
337
+ });
338
+ });
339
+ const active = server;
340
+ try {
341
+ await new Promise((resolve, reject) => {
342
+ const onError = (error) => { active.off("listening", onListening); reject(error); };
343
+ const onListening = () => {
344
+ active.off("error", onError);
345
+ try {
346
+ if (!endpoint || !matches(endpoint, readEndpoint()))
347
+ throw new Error("Sanctuary interactive control socket ownership was replaced during startup");
348
+ resolve();
349
+ }
350
+ catch (error) {
351
+ reject(error);
352
+ }
353
+ };
354
+ active.once("error", onError);
355
+ active.once("listening", onListening);
356
+ try {
357
+ active.listen(socketPath);
358
+ if (active.listening) {
359
+ endpoint = readEndpoint();
360
+ if (!endpoint?.isSocket())
361
+ throw new Error("Sanctuary interactive control startup ownership is unproven");
362
+ (0, node_fs_1.chmodSync)(socketPath, 0o600);
363
+ endpoint = readEndpoint();
364
+ }
365
+ }
366
+ catch (error) {
367
+ active.off("error", onError);
368
+ onError(error);
369
+ }
370
+ });
371
+ }
372
+ catch (error) {
373
+ try {
374
+ await stopListener();
375
+ }
376
+ catch (cleanupError) {
377
+ throw new AggregateError([error, cleanupError], "Sanctuary interactive control startup and ownership cleanup failed");
378
+ }
379
+ throw error;
380
+ }
381
+ })().finally(() => { if (startPromise === starting)
382
+ startPromise = undefined; });
383
+ startPromise = starting;
384
+ return starting;
385
+ },
386
+ stop() {
387
+ if (stopPromise)
388
+ return stopPromise;
389
+ const starting = startPromise;
390
+ startPromise = undefined;
391
+ const stopping = (async () => {
392
+ if (starting)
393
+ await starting;
394
+ await stopListener();
395
+ })().finally(() => { if (stopPromise === stopping)
396
+ stopPromise = undefined; });
397
+ stopPromise = stopping;
398
+ return stopping;
399
+ },
400
+ };
401
+ }
402
+ async function sanctuaryInteractiveControlReady(socketPath, timeoutMs = 1_000) {
403
+ return new Promise((resolve) => {
404
+ const socket = (0, node_net_1.createConnection)(socketPath);
405
+ const finish = (ready) => { socket.destroy(); resolve(ready); };
406
+ socket.setTimeout(timeoutMs, () => finish(false));
407
+ socket.once("connect", () => finish(true));
408
+ socket.once("error", () => finish(false));
409
+ });
410
+ }