@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831

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 (647) 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 +5308 -16
  16. package/deploy/unraid/Dockerfile +54 -0
  17. package/deploy/unraid/README.txt +2983 -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-deployment-target.mjs +710 -0
  34. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  35. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
  36. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  37. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  38. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  39. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  40. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  41. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  42. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
  43. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  44. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  45. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  46. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
  49. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  50. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
  51. package/deploy/unraid/sanctuary.xml +28 -0
  52. package/dist/a2a/card.js +57 -0
  53. package/dist/a2a/client.js +180 -0
  54. package/dist/a2a/config.js +50 -0
  55. package/dist/a2a/delegation-stores.js +56 -0
  56. package/dist/a2a/did-resolution.js +93 -0
  57. package/dist/a2a/identity.js +170 -0
  58. package/dist/a2a/inbound-share.js +107 -0
  59. package/dist/a2a/mission-result-wire.js +196 -0
  60. package/dist/a2a/onboarding.js +115 -0
  61. package/dist/a2a/pin-store.js +132 -0
  62. package/dist/a2a/seen-ledger.js +120 -0
  63. package/dist/a2a/server.js +604 -0
  64. package/dist/a2a/task-store.js +69 -0
  65. package/dist/a2a/transport.js +45 -0
  66. package/dist/a2a/types.js +3 -0
  67. package/dist/arc/attention-types.js +8 -0
  68. package/dist/arc/cares.js +360 -0
  69. package/dist/arc/episodes.js +118 -0
  70. package/dist/arc/evolution.js +490 -0
  71. package/dist/arc/flight-recorder.js +1034 -0
  72. package/dist/arc/intentions.js +134 -0
  73. package/dist/arc/json-store.js +117 -0
  74. package/dist/arc/obligations.js +386 -0
  75. package/dist/arc/packets.js +336 -0
  76. package/dist/arc/presence.js +185 -0
  77. package/dist/arc/task-lifecycle.js +57 -0
  78. package/dist/commerce/store.js +755 -0
  79. package/dist/commerce/types.js +3 -0
  80. package/dist/heart/active-work.js +798 -40
  81. package/dist/heart/agent-entry.js +252 -3
  82. package/dist/heart/approval-files.js +113 -0
  83. package/dist/heart/approval-store.js +960 -0
  84. package/dist/heart/attachments/image-normalize.js +194 -0
  85. package/dist/heart/attachments/materialize.js +97 -0
  86. package/dist/heart/attachments/originals.js +88 -0
  87. package/dist/heart/attachments/render.js +29 -0
  88. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  89. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  90. package/dist/heart/attachments/sources/index.js +18 -0
  91. package/dist/heart/attachments/sources/telegram.js +71 -0
  92. package/dist/heart/attachments/store.js +132 -0
  93. package/dist/heart/attachments/types.js +93 -0
  94. package/dist/heart/auth/auth-flow.js +495 -0
  95. package/dist/heart/autonomy-budget.js +478 -0
  96. package/dist/heart/awaiting/await-alert.js +148 -0
  97. package/dist/heart/awaiting/await-expiry.js +143 -0
  98. package/dist/heart/awaiting/await-loader.js +91 -0
  99. package/dist/heart/awaiting/await-parser.js +149 -0
  100. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  101. package/dist/heart/awaiting/await-scheduler.js +382 -0
  102. package/dist/heart/background-operations.js +281 -0
  103. package/dist/heart/bridges/manager.js +137 -17
  104. package/dist/heart/bridges/store.js +14 -2
  105. package/dist/heart/bundle-state.js +168 -0
  106. package/dist/heart/commitments.js +44 -18
  107. package/dist/heart/config-registry.js +331 -0
  108. package/dist/heart/config.js +174 -131
  109. package/dist/heart/context-loss-gauntlet.js +387 -0
  110. package/dist/heart/context-loss-sentinel.js +1157 -0
  111. package/dist/heart/core.js +2169 -581
  112. package/dist/heart/cross-chat-delivery.js +9 -22
  113. package/dist/heart/daemon/agent-config-check.js +451 -0
  114. package/dist/heart/daemon/agent-discovery.js +185 -3
  115. package/dist/heart/daemon/agent-service.js +542 -0
  116. package/dist/heart/daemon/agentic-repair.js +547 -0
  117. package/dist/heart/daemon/await-private-wake.js +59 -0
  118. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  119. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  120. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  121. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  122. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  123. package/dist/heart/daemon/cadence.js +180 -0
  124. package/dist/heart/daemon/cli-defaults.js +854 -0
  125. package/dist/heart/daemon/cli-desk.js +322 -0
  126. package/dist/heart/daemon/cli-exec.js +8822 -0
  127. package/dist/heart/daemon/cli-help.js +716 -0
  128. package/dist/heart/daemon/cli-parse.js +2771 -0
  129. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  130. package/dist/heart/daemon/cli-render.js +777 -0
  131. package/dist/heart/daemon/cli-types.js +8 -0
  132. package/dist/heart/daemon/connect-bay.js +323 -0
  133. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  134. package/dist/heart/daemon/container-healthcheck.js +112 -0
  135. package/dist/heart/daemon/container-runtime.js +97 -0
  136. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  137. package/dist/heart/daemon/container-spec-auditor.js +229 -0
  138. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  139. package/dist/heart/daemon/daemon-cli.js +29 -2349
  140. package/dist/heart/daemon/daemon-entry.js +930 -11
  141. package/dist/heart/daemon/daemon-health.js +186 -0
  142. package/dist/heart/daemon/daemon-rollup.js +57 -0
  143. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  144. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  145. package/dist/heart/daemon/daemon.js +2084 -105
  146. package/dist/heart/daemon/dns-workflow.js +394 -0
  147. package/dist/heart/daemon/doctor-types.js +8 -0
  148. package/dist/heart/daemon/doctor.js +1755 -0
  149. package/dist/heart/daemon/freshness.js +345 -0
  150. package/dist/heart/daemon/habit-private-wake.js +61 -0
  151. package/dist/heart/daemon/health-monitor.js +142 -11
  152. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  153. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  154. package/dist/heart/daemon/http-health-probe.js +80 -0
  155. package/dist/heart/daemon/human-command-screens.js +234 -0
  156. package/dist/heart/daemon/human-readiness.js +114 -0
  157. package/dist/heart/daemon/inner-status.js +78 -0
  158. package/dist/heart/daemon/interactive-repair.js +394 -0
  159. package/dist/heart/daemon/launchd.js +37 -8
  160. package/dist/heart/daemon/log-tailer.js +79 -10
  161. package/dist/heart/daemon/logs-prune.js +132 -0
  162. package/dist/heart/daemon/mcp-canary.js +524 -0
  163. package/dist/heart/daemon/message-router.js +65 -5
  164. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  165. package/dist/heart/daemon/os-cron-deps.js +135 -0
  166. package/dist/heart/daemon/os-cron.js +22 -14
  167. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  168. package/dist/heart/daemon/ouro-entry.js +3 -1
  169. package/dist/heart/daemon/plugin-cli.js +432 -0
  170. package/dist/heart/daemon/process-manager.js +733 -61
  171. package/dist/heart/daemon/provider-discovery.js +137 -0
  172. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  173. package/dist/heart/daemon/prunable-bundle.js +144 -0
  174. package/dist/heart/daemon/pulse.js +511 -0
  175. package/dist/heart/daemon/readiness-repair.js +365 -0
  176. package/dist/heart/daemon/run-hooks.js +2 -0
  177. package/dist/heart/daemon/runtime-logging.js +47 -14
  178. package/dist/heart/daemon/runtime-metadata.js +2 -30
  179. package/dist/heart/daemon/runtime-mode.js +13 -2
  180. package/dist/heart/daemon/safe-mode.js +161 -0
  181. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  182. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  183. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  184. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  185. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  186. package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
  187. package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
  188. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  189. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
  190. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  191. package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
  192. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  193. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
  194. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  195. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  196. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  197. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  198. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  199. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  200. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  201. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
  202. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  203. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
  204. package/dist/heart/daemon/sense-manager.js +699 -48
  205. package/dist/heart/daemon/session-id-resolver.js +131 -0
  206. package/dist/heart/daemon/skill-management-installer.js +1 -1
  207. package/dist/heart/daemon/socket-client.js +180 -12
  208. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  209. package/dist/heart/daemon/startup-tui.js +339 -0
  210. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  211. package/dist/heart/daemon/task-scheduler.js +117 -39
  212. package/dist/heart/daemon/terminal-ui.js +499 -0
  213. package/dist/heart/daemon/thoughts.js +138 -54
  214. package/dist/heart/daemon/up-progress.js +366 -0
  215. package/dist/heart/daemon/vault-items.js +56 -0
  216. package/dist/heart/delegation.js +1 -4
  217. package/dist/heart/external-events/router.js +1430 -0
  218. package/dist/heart/frontend-approval-runtime.js +506 -0
  219. package/dist/heart/frontend-journal.js +215 -0
  220. package/dist/heart/frontend-session-service.js +237 -0
  221. package/dist/heart/frontend-socket-client.js +164 -0
  222. package/dist/heart/frontend-socket.js +400 -0
  223. package/dist/heart/habits/habit-cancel.js +810 -0
  224. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  225. package/dist/heart/habits/habit-migration.js +194 -0
  226. package/dist/heart/habits/habit-parser.js +278 -0
  227. package/dist/heart/habits/habit-runtime-state.js +93 -0
  228. package/dist/heart/habits/habit-scheduler.js +653 -0
  229. package/dist/heart/habits/habit-session-summary.js +318 -0
  230. package/dist/heart/habits/habit-session.js +636 -0
  231. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  232. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  233. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  234. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  235. package/dist/heart/identity.js +196 -59
  236. package/dist/heart/kept-notes.js +289 -0
  237. package/dist/heart/kicks.js +1 -1
  238. package/dist/heart/machine-identity.js +161 -0
  239. package/dist/heart/mail-import-discovery.js +356 -0
  240. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  241. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  242. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  243. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  244. package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
  245. package/dist/heart/mailbox/mailbox-http.js +99 -0
  246. package/dist/heart/mailbox/mailbox-read.js +39 -0
  247. package/dist/heart/mailbox/mailbox-types.js +27 -0
  248. package/dist/heart/mailbox/mailbox-view.js +197 -0
  249. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  250. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  251. package/dist/heart/mailbox/readers/mail.js +375 -0
  252. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  253. package/dist/heart/mailbox/readers/sessions.js +231 -0
  254. package/dist/heart/mailbox/readers/shared.js +111 -0
  255. package/dist/heart/mcp/mcp-server.js +696 -0
  256. package/dist/heart/migrate-config.js +100 -0
  257. package/dist/heart/model-capabilities.js +11 -0
  258. package/dist/heart/orientation-frame.js +345 -0
  259. package/dist/heart/platform.js +81 -0
  260. package/dist/heart/primitives.js +1 -1
  261. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  262. package/dist/heart/private-runtime/index.js +18 -0
  263. package/dist/heart/private-runtime/ledger.js +221 -0
  264. package/dist/heart/private-runtime/policy.js +252 -0
  265. package/dist/heart/private-runtime/types.js +2 -0
  266. package/dist/heart/progress-story.js +1 -1
  267. package/dist/heart/provider-attempt.js +137 -0
  268. package/dist/heart/provider-binding-resolver.js +273 -0
  269. package/dist/heart/provider-credentials.js +449 -0
  270. package/dist/heart/provider-failover.js +311 -0
  271. package/dist/heart/provider-models.js +96 -0
  272. package/dist/heart/provider-ping.js +265 -0
  273. package/dist/heart/provider-readiness-cache.js +119 -0
  274. package/dist/heart/provider-visibility.js +188 -0
  275. package/dist/heart/providers/anthropic-token.js +131 -0
  276. package/dist/heart/providers/anthropic.js +173 -60
  277. package/dist/heart/providers/azure.js +23 -11
  278. package/dist/heart/providers/error-classification.js +127 -0
  279. package/dist/heart/providers/github-copilot.js +34 -38
  280. package/dist/heart/providers/minimax-vlm.js +189 -0
  281. package/dist/heart/providers/minimax.js +26 -8
  282. package/dist/heart/providers/openai-codex-token.js +349 -0
  283. package/dist/heart/providers/openai-codex.js +55 -40
  284. package/dist/heart/providers/openai-compatible.js +177 -0
  285. package/dist/heart/run-ledger.js +247 -0
  286. package/dist/heart/runtime-capability-check.js +170 -0
  287. package/dist/heart/runtime-credentials.js +607 -0
  288. package/dist/heart/runtime-cwd.js +87 -0
  289. package/dist/heart/sense-truth.js +22 -4
  290. package/dist/heart/session-activity.js +92 -24
  291. package/dist/heart/session-events.js +1504 -0
  292. package/dist/heart/session-playback-cli-main.js +5 -0
  293. package/dist/heart/session-playback-cli.js +36 -0
  294. package/dist/heart/session-playback.js +231 -0
  295. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  296. package/dist/heart/session-redaction-repair.js +552 -0
  297. package/dist/heart/session-stats-cli-main.js +5 -0
  298. package/dist/heart/session-stats.js +183 -0
  299. package/dist/heart/session-transcript.js +133 -0
  300. package/dist/heart/start-of-turn-packet.js +372 -0
  301. package/dist/heart/steward-policy.js +618 -0
  302. package/dist/heart/streaming.js +604 -207
  303. package/dist/heart/structured-output.js +196 -0
  304. package/dist/heart/sync-classification.js +176 -0
  305. package/dist/heart/sync.js +449 -0
  306. package/dist/heart/target-resolution.js +11 -7
  307. package/dist/heart/tempo.js +93 -0
  308. package/dist/heart/temporal-view.js +41 -0
  309. package/dist/heart/timeouts.js +101 -0
  310. package/dist/heart/tool-activity-callbacks.js +59 -0
  311. package/dist/heart/tool-approval.js +382 -0
  312. package/dist/heart/tool-description.js +155 -0
  313. package/dist/heart/tool-friction.js +55 -0
  314. package/dist/heart/tool-loop.js +200 -0
  315. package/dist/heart/turn-context.js +482 -0
  316. package/dist/heart/turn-execution-lease.js +30 -0
  317. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  318. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  319. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  320. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  321. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  322. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  323. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  324. package/dist/heart/versioning/update-hooks.js +154 -0
  325. package/dist/heart/versioning/version-intent.js +114 -0
  326. package/dist/heart/work-card.js +380 -0
  327. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  328. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  329. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  330. package/dist/mailbox-ui/index.html +16 -0
  331. package/dist/mailroom/attention.js +167 -0
  332. package/dist/mailroom/autonomy.js +209 -0
  333. package/dist/mailroom/blob-store.js +889 -0
  334. package/dist/mailroom/body-cache.js +61 -0
  335. package/dist/mailroom/cache-sync-cli.js +58 -0
  336. package/dist/mailroom/core.js +803 -0
  337. package/dist/mailroom/entry.js +160 -0
  338. package/dist/mailroom/file-store.js +568 -0
  339. package/dist/mailroom/hosted-cache-sync.js +384 -0
  340. package/dist/mailroom/mbox-import.js +393 -0
  341. package/dist/mailroom/migration.js +164 -0
  342. package/dist/mailroom/outbound.js +380 -0
  343. package/dist/mailroom/policy.js +263 -0
  344. package/dist/mailroom/reader.js +292 -0
  345. package/dist/mailroom/search-cache.js +513 -0
  346. package/dist/mailroom/search-relevance.js +319 -0
  347. package/dist/mailroom/smtp-ingress.js +176 -0
  348. package/dist/mailroom/source-state.js +176 -0
  349. package/dist/mailroom/thread.js +109 -0
  350. package/dist/mailroom/travel-extract.js +89 -0
  351. package/dist/mind/bundle-manifest.js +24 -2
  352. package/dist/mind/context.js +309 -111
  353. package/dist/mind/desk-section.js +362 -0
  354. package/dist/mind/diary-integrity.js +60 -0
  355. package/dist/mind/{memory.js → diary.js} +68 -77
  356. package/dist/mind/embedding-provider.js +60 -0
  357. package/dist/mind/file-state.js +179 -0
  358. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  359. package/dist/mind/obligation-steering.js +199 -3
  360. package/dist/mind/pending.js +36 -10
  361. package/dist/mind/prompt-budget.js +479 -0
  362. package/dist/mind/prompt-refresh.js +3 -2
  363. package/dist/mind/prompt.js +1050 -189
  364. package/dist/mind/provenance-trust.js +26 -0
  365. package/dist/mind/record-paths.js +312 -0
  366. package/dist/mind/scrutiny.js +173 -0
  367. package/dist/mind/session-transaction.js +564 -0
  368. package/dist/nerves/cli-logging.js +7 -1
  369. package/dist/nerves/coverage/audit-rules.js +15 -6
  370. package/dist/nerves/coverage/audit.js +28 -2
  371. package/dist/nerves/coverage/cli.js +1 -1
  372. package/dist/nerves/coverage/contract.js +5 -5
  373. package/dist/nerves/coverage/file-completeness.js +139 -5
  374. package/dist/nerves/coverage/run-artifacts.js +55 -35
  375. package/dist/nerves/coverage/source-scanner.js +4 -4
  376. package/dist/nerves/event-buffer.js +111 -0
  377. package/dist/nerves/index.js +293 -9
  378. package/dist/nerves/observation.js +20 -0
  379. package/dist/nerves/redact.js +79 -0
  380. package/dist/nerves/review/cli-main.js +5 -0
  381. package/dist/nerves/review/cli.js +156 -0
  382. package/dist/nerves/review/core.js +159 -0
  383. package/dist/nerves/runtime.js +17 -1
  384. package/dist/repertoire/ado-client.js +15 -56
  385. package/dist/repertoire/ado-semantic.js +16 -10
  386. package/dist/repertoire/api-client.js +97 -0
  387. package/dist/repertoire/bitwarden-store.js +1045 -0
  388. package/dist/repertoire/bundle-templates.js +71 -0
  389. package/dist/repertoire/bw-installer.js +180 -0
  390. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  391. package/dist/repertoire/coding/context-pack.js +331 -0
  392. package/dist/repertoire/coding/feedback.js +174 -32
  393. package/dist/repertoire/coding/index.js +15 -3
  394. package/dist/repertoire/coding/manager.js +159 -10
  395. package/dist/repertoire/coding/spawner.js +58 -11
  396. package/dist/repertoire/coding/tools.js +221 -15
  397. package/dist/repertoire/coding/workbench-client.js +272 -0
  398. package/dist/repertoire/coding/workbench-manager.js +346 -0
  399. package/dist/repertoire/commerce-errors.js +109 -0
  400. package/dist/repertoire/commerce-self-test.js +156 -0
  401. package/dist/repertoire/credential-access.js +178 -0
  402. package/dist/repertoire/desk/classifier.js +362 -0
  403. package/dist/repertoire/duffel-client.js +185 -0
  404. package/dist/repertoire/github-client.js +14 -55
  405. package/dist/repertoire/graph-client.js +11 -52
  406. package/dist/repertoire/guardrails.js +811 -18
  407. package/dist/repertoire/mcp-client.js +44 -3
  408. package/dist/repertoire/mcp-manager.js +427 -139
  409. package/dist/repertoire/mcp-tools.js +124 -0
  410. package/dist/repertoire/plugin-mcp.js +175 -0
  411. package/dist/repertoire/plugins.js +253 -0
  412. package/dist/repertoire/relationship-authorization.js +322 -0
  413. package/dist/repertoire/shell-sessions.js +134 -0
  414. package/dist/repertoire/skills.js +48 -4
  415. package/dist/repertoire/stripe-client.js +131 -0
  416. package/dist/repertoire/tool-arguments.js +170 -0
  417. package/dist/repertoire/tool-results.js +29 -0
  418. package/dist/repertoire/tools-a2a.js +699 -0
  419. package/dist/repertoire/tools-attachments.js +322 -0
  420. package/dist/repertoire/tools-awaiting.js +575 -0
  421. package/dist/repertoire/tools-base.js +77 -1138
  422. package/dist/repertoire/tools-bluebubbles.js +2 -0
  423. package/dist/repertoire/tools-bridge.js +144 -0
  424. package/dist/repertoire/tools-bundle.js +993 -0
  425. package/dist/repertoire/tools-commerce.js +253 -0
  426. package/dist/repertoire/tools-config.js +186 -0
  427. package/dist/repertoire/tools-continuity.js +575 -0
  428. package/dist/repertoire/tools-credential.js +383 -0
  429. package/dist/repertoire/tools-evolution.js +527 -0
  430. package/dist/repertoire/tools-files.js +344 -0
  431. package/dist/repertoire/tools-flight.js +290 -0
  432. package/dist/repertoire/tools-flow.js +119 -0
  433. package/dist/repertoire/tools-github.js +3 -8
  434. package/dist/repertoire/tools-habits.js +103 -0
  435. package/dist/repertoire/tools-mail.js +1828 -0
  436. package/dist/repertoire/tools-notes.js +485 -0
  437. package/dist/repertoire/tools-obligations.js +182 -0
  438. package/dist/repertoire/tools-orientation.js +31 -0
  439. package/dist/repertoire/tools-record.js +482 -0
  440. package/dist/repertoire/tools-rsvp.js +139 -0
  441. package/dist/repertoire/tools-runtime.js +150 -0
  442. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  443. package/dist/repertoire/tools-session.js +1133 -0
  444. package/dist/repertoire/tools-shell.js +149 -0
  445. package/dist/repertoire/tools-steward-policy.js +119 -0
  446. package/dist/repertoire/tools-stripe.js +224 -0
  447. package/dist/repertoire/tools-surface.js +369 -0
  448. package/dist/repertoire/tools-teams.js +12 -39
  449. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  450. package/dist/repertoire/tools-travel.js +125 -0
  451. package/dist/repertoire/tools-trip.js +982 -0
  452. package/dist/repertoire/tools-unraid.js +531 -0
  453. package/dist/repertoire/tools-user-profile.js +146 -0
  454. package/dist/repertoire/tools-vault.js +40 -0
  455. package/dist/repertoire/tools-voice.js +145 -0
  456. package/dist/repertoire/tools.js +494 -148
  457. package/dist/repertoire/travel-api-client.js +360 -0
  458. package/dist/repertoire/unraid-client.js +155 -0
  459. package/dist/repertoire/unraid-restart.js +339 -0
  460. package/dist/repertoire/user-profile.js +131 -0
  461. package/dist/repertoire/vault-setup.js +246 -0
  462. package/dist/repertoire/vault-unlock.js +628 -0
  463. package/dist/rsvp/aisleplanner-client.js +354 -0
  464. package/dist/rsvp/cli.js +926 -0
  465. package/dist/rsvp/config.js +327 -0
  466. package/dist/rsvp/cutover.js +433 -0
  467. package/dist/rsvp/diagnostics.js +232 -0
  468. package/dist/rsvp/diff-renderer.js +176 -0
  469. package/dist/rsvp/habit-policy.js +110 -0
  470. package/dist/rsvp/habit-stage.js +123 -0
  471. package/dist/rsvp/incident-bundle.js +97 -0
  472. package/dist/rsvp/migration.js +204 -0
  473. package/dist/rsvp/native-habit-runner.js +630 -0
  474. package/dist/rsvp/outbound-state.js +628 -0
  475. package/dist/rsvp/query.js +118 -0
  476. package/dist/rsvp/replay.js +233 -0
  477. package/dist/rsvp/snapshot.js +232 -0
  478. package/dist/rsvp/spend-ledger.js +175 -0
  479. package/dist/scripts/claude-code-hook.js +41 -0
  480. package/dist/scripts/claude-code-stop-hook.js +47 -0
  481. package/dist/senses/a2a-entry.js +115 -0
  482. package/dist/senses/acp-server.js +386 -0
  483. package/dist/senses/attention-queue.js +186 -0
  484. package/dist/senses/await-turn-message.js +58 -0
  485. package/dist/senses/bluebubbles/active-turns.js +216 -0
  486. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  487. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  488. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  489. package/dist/senses/bluebubbles/context-packet.js +207 -0
  490. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  491. package/dist/senses/bluebubbles/entry.js +90 -0
  492. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  493. package/dist/senses/bluebubbles/index.js +3841 -0
  494. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  495. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  496. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  497. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  498. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  499. package/dist/senses/bluebubbles/processed-log.js +133 -0
  500. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  501. package/dist/senses/bluebubbles/replay.js +284 -0
  502. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  503. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  504. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  505. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  506. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  507. package/dist/senses/cli/bracketed-paste.js +82 -0
  508. package/dist/senses/cli/image-paste.js +287 -0
  509. package/dist/senses/cli/image-ref-navigation.js +75 -0
  510. package/dist/senses/cli/ink-app.js +156 -0
  511. package/dist/senses/cli/inline-diff.js +64 -0
  512. package/dist/senses/cli/input-keys.js +174 -0
  513. package/dist/senses/cli/kill-ring.js +86 -0
  514. package/dist/senses/cli/message-list.js +51 -0
  515. package/dist/senses/cli/ouro-tui.js +607 -0
  516. package/dist/senses/cli/spinner-imperative.js +135 -0
  517. package/dist/senses/cli/spinner.js +101 -0
  518. package/dist/senses/cli/status-line.js +60 -0
  519. package/dist/senses/cli/streaming-markdown.js +526 -0
  520. package/dist/senses/cli/tool-display.js +85 -0
  521. package/dist/senses/cli/tool-render.js +85 -0
  522. package/dist/senses/cli/tui-store.js +241 -0
  523. package/dist/senses/cli/virtual-list.js +35 -0
  524. package/dist/senses/cli-entry.js +60 -8
  525. package/dist/senses/cli.js +604 -320
  526. package/dist/senses/commands.js +66 -3
  527. package/dist/senses/context-packet-ledger.js +371 -0
  528. package/dist/senses/context-packets.js +154 -0
  529. package/dist/senses/habit-lifecycle-guard.js +24 -0
  530. package/dist/senses/habit-turn-message.js +160 -0
  531. package/dist/senses/ingress-evidence.js +2 -0
  532. package/dist/senses/mail-entry.js +66 -0
  533. package/dist/senses/mail.js +524 -0
  534. package/dist/senses/pipeline.js +1115 -204
  535. package/dist/senses/private-runtime-worker.js +859 -0
  536. package/dist/senses/private-runtime.js +1517 -0
  537. package/dist/senses/proactive-content-guard.js +51 -0
  538. package/dist/senses/root-host-approval-port.js +345 -0
  539. package/dist/senses/root-host-approval-runtime.js +393 -0
  540. package/dist/senses/sanctuary-authority-resident.js +102 -0
  541. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  542. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  543. package/dist/senses/sanctuary-grounding.js +118 -0
  544. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  545. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  546. package/dist/senses/sanctuary-health-runner.js +100 -0
  547. package/dist/senses/sanctuary-health.js +408 -0
  548. package/dist/senses/sanctuary-install-state-contract.js +126 -0
  549. package/dist/senses/sanctuary-interactive-control.js +410 -0
  550. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  551. package/dist/senses/sanctuary-media-optimization.js +514 -0
  552. package/dist/senses/sanctuary-runtime.js +340 -0
  553. package/dist/senses/sanctuary-sab.js +85 -0
  554. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  555. package/dist/senses/shared-turn.js +772 -0
  556. package/dist/senses/surface-tool.js +109 -0
  557. package/dist/senses/teams-entry.js +60 -8
  558. package/dist/senses/teams.js +519 -218
  559. package/dist/senses/telegram-admission.js +718 -0
  560. package/dist/senses/telegram-approval-runtime.js +793 -0
  561. package/dist/senses/telegram-attachments.js +186 -0
  562. package/dist/senses/telegram-audit-ledger.js +220 -0
  563. package/dist/senses/telegram-authority-transport.js +231 -0
  564. package/dist/senses/telegram-client.js +1749 -0
  565. package/dist/senses/telegram-effect-adapter.js +896 -0
  566. package/dist/senses/telegram-entry.js +83 -0
  567. package/dist/senses/telegram.js +2324 -0
  568. package/dist/senses/trust-gate.js +104 -9
  569. package/dist/senses/voice/audio-playback.js +237 -0
  570. package/dist/senses/voice/audio-routing.js +119 -0
  571. package/dist/senses/voice/elevenlabs.js +202 -0
  572. package/dist/senses/voice/floor-control.js +431 -0
  573. package/dist/senses/voice/floor-controller.js +115 -0
  574. package/dist/senses/voice/golden-path.js +116 -0
  575. package/dist/senses/voice/index.js +29 -0
  576. package/dist/senses/voice/meeting.js +113 -0
  577. package/dist/senses/voice/outbound.js +190 -0
  578. package/dist/senses/voice/phone.js +33 -0
  579. package/dist/senses/voice/playback.js +139 -0
  580. package/dist/senses/voice/realtime-eval.js +496 -0
  581. package/dist/senses/voice/realtime-trace.js +531 -0
  582. package/dist/senses/voice/transcript.js +70 -0
  583. package/dist/senses/voice/turn.js +191 -0
  584. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  585. package/dist/senses/voice/twilio-phone.js +5031 -0
  586. package/dist/senses/voice/types.js +2 -0
  587. package/dist/senses/voice/whisper.js +161 -0
  588. package/dist/senses/voice-entry.js +81 -0
  589. package/dist/senses/voice-realtime-eval-command.js +99 -0
  590. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  591. package/dist/senses/voice-twilio-entry.js +87 -0
  592. package/dist/trips/core.js +138 -0
  593. package/dist/trips/store.js +265 -0
  594. package/dist/util/frontmatter.js +69 -0
  595. package/npm-shrinkwrap.json +8138 -0
  596. package/package.json +72 -13
  597. package/skills/agent-commerce.md +113 -0
  598. package/skills/browser-navigation.md +117 -0
  599. package/skills/commerce-setup-guide.md +116 -0
  600. package/skills/commerce-setup.md +84 -0
  601. package/skills/configure-dev-tools.md +99 -0
  602. package/skills/travel-planning.md +138 -0
  603. package/dist/heart/daemon/auth-flow.js +0 -430
  604. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  605. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  606. package/dist/heart/daemon/update-hooks.js +0 -138
  607. package/dist/heart/obligations.js +0 -191
  608. package/dist/heart/safe-workspace.js +0 -228
  609. package/dist/heart/session-recall.js +0 -116
  610. package/dist/mind/friends/channel.js +0 -84
  611. package/dist/mind/friends/group-context.js +0 -144
  612. package/dist/mind/friends/resolver.js +0 -84
  613. package/dist/mind/friends/store-file.js +0 -190
  614. package/dist/mind/friends/store.js +0 -4
  615. package/dist/mind/friends/tokens.js +0 -26
  616. package/dist/mind/friends/trust-explanation.js +0 -74
  617. package/dist/mind/friends/types.js +0 -29
  618. package/dist/repertoire/tasks/board.js +0 -134
  619. package/dist/repertoire/tasks/index.js +0 -224
  620. package/dist/repertoire/tasks/lifecycle.js +0 -80
  621. package/dist/repertoire/tasks/middleware.js +0 -65
  622. package/dist/repertoire/tasks/parser.js +0 -173
  623. package/dist/repertoire/tasks/scanner.js +0 -132
  624. package/dist/repertoire/tasks/transitions.js +0 -144
  625. package/dist/senses/bluebubbles-entry.js +0 -13
  626. package/dist/senses/bluebubbles.js +0 -1181
  627. package/dist/senses/debug-activity.js +0 -154
  628. package/dist/senses/inner-dialog-worker.js +0 -90
  629. package/dist/senses/inner-dialog.js +0 -525
  630. package/subagents/README.md +0 -7
  631. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  632. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  633. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  634. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  635. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  636. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  637. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  638. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  639. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  640. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  641. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  642. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  643. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  644. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  645. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  646. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  647. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,729 @@
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.SANCTUARY_BUNDLE_ROLLBACK_FILE = exports.SANCTUARY_PACKAGE_MANAGED_FILES = void 0;
37
+ exports.inspectSanctuaryDirectoryFromBase = inspectSanctuaryDirectoryFromBase;
38
+ exports.sanctuaryDirectoriesShareIdentity = sanctuaryDirectoriesShareIdentity;
39
+ exports.inspectSanctuaryPackageManagedBundle = inspectSanctuaryPackageManagedBundle;
40
+ exports.ensureSanctuaryPackageManagedBundle = ensureSanctuaryPackageManagedBundle;
41
+ exports.inspectSanctuaryPackageManagedBundleRollback = inspectSanctuaryPackageManagedBundleRollback;
42
+ exports.rollbackSanctuaryPackageManagedBundle = rollbackSanctuaryPackageManagedBundle;
43
+ exports.commitSanctuaryPackageManagedBundle = commitSanctuaryPackageManagedBundle;
44
+ exports.migrateSanctuaryPackageManagedBundle = migrateSanctuaryPackageManagedBundle;
45
+ const fs = __importStar(require("node:fs"));
46
+ const path = __importStar(require("node:path"));
47
+ const node_crypto_1 = require("node:crypto");
48
+ const runtime_1 = require("../../nerves/runtime");
49
+ exports.SANCTUARY_PACKAGE_MANAGED_FILES = [
50
+ "provider-readiness.json",
51
+ "tool-profiles.json",
52
+ "mcp/media-mcp.mjs",
53
+ "habits/sanctuary-health.md",
54
+ "psyche/ASPIRATIONS.md",
55
+ "psyche/IDENTITY.md",
56
+ "psyche/LORE.md",
57
+ "psyche/SOUL.md",
58
+ "psyche/TACIT.md",
59
+ ];
60
+ exports.SANCTUARY_BUNDLE_ROLLBACK_FILE = ".sanctuary-package-managed-rollback.json";
61
+ const SANCTUARY_BUNDLE_COMMITTING_FILE = `${exports.SANCTUARY_BUNDLE_ROLLBACK_FILE}.committing`;
62
+ const BUNDLE_META_VERSION_FIELDS = ["runtimeVersion", "bundleSchemaVersion", "lastUpdated"];
63
+ class SanctuaryInspectionFault extends Error {
64
+ code;
65
+ constructor(code) {
66
+ super(code);
67
+ this.code = code;
68
+ }
69
+ }
70
+ const CANONICAL_EMPTY_PACKAGED_POLICY = { schemaVersion: 1, version: 0, desiredStates: {}, routineActionGrants: {}, updatedAt: null };
71
+ function readObject(filePath) {
72
+ const value = JSON.parse(fs.readFileSync(filePath, "utf8"));
73
+ if (!value || typeof value !== "object" || Array.isArray(value))
74
+ throw new Error(`${path.basename(filePath)} must contain an object`);
75
+ return value;
76
+ }
77
+ function isMissing(error) {
78
+ return !!error && typeof error === "object" && "code" in error && error.code === "ENOENT";
79
+ }
80
+ function isFilesystemFailure(error) {
81
+ return !!error && typeof error === "object" && "code" in error && typeof error.code === "string";
82
+ }
83
+ function inspectSanctuaryDirectoryFromBase(baseRoot, segments) {
84
+ if (!path.isAbsolute(baseRoot))
85
+ return null;
86
+ let current = path.resolve(baseRoot);
87
+ let stat = null;
88
+ for (const candidate of [current, ...segments.map((segment) => { current = path.join(current, segment); return current; })]) {
89
+ try {
90
+ stat = fs.lstatSync(candidate);
91
+ }
92
+ catch (error) {
93
+ if (isMissing(error))
94
+ return null;
95
+ throw error;
96
+ }
97
+ if (stat.isSymbolicLink() || !stat.isDirectory())
98
+ return null;
99
+ }
100
+ const realPath = fs.realpathSync(current);
101
+ if (realPath !== path.resolve(current))
102
+ return null;
103
+ return { realPath, device: stat.dev, inode: stat.ino };
104
+ }
105
+ function sanctuaryDirectoriesShareIdentity(left, right) {
106
+ return left.realPath === right.realPath || (left.device === right.device && left.inode === right.inode);
107
+ }
108
+ function inspectStandaloneSanctuaryDirectory(root) {
109
+ if (!path.isAbsolute(root))
110
+ return null;
111
+ const resolved = path.resolve(root);
112
+ return inspectSanctuaryDirectoryFromBase(path.dirname(resolved), [path.basename(resolved)]);
113
+ }
114
+ function isCanonicalEmptyPackagedPolicy(value) {
115
+ return JSON.stringify(Object.keys(value).sort()) === JSON.stringify(Object.keys(CANONICAL_EMPTY_PACKAGED_POLICY).sort())
116
+ && value.schemaVersion === 1
117
+ && value.version === 0
118
+ && value.updatedAt === null
119
+ && !!value.desiredStates
120
+ && typeof value.desiredStates === "object"
121
+ && !Array.isArray(value.desiredStates)
122
+ && Object.keys(value.desiredStates).length === 0
123
+ && !!value.routineActionGrants
124
+ && typeof value.routineActionGrants === "object"
125
+ && !Array.isArray(value.routineActionGrants)
126
+ && Object.keys(value.routineActionGrants).length === 0;
127
+ }
128
+ function validatePackagedPolicy(packageRoot) {
129
+ const relative = "state/policy/steward.json";
130
+ validateDestination(packageRoot, relative);
131
+ requirePlainFile(path.join(packageRoot, relative), "packaged steward policy");
132
+ const value = readObject(path.join(packageRoot, relative));
133
+ if (value.routineActionGrants && typeof value.routineActionGrants === "object" && !Array.isArray(value.routineActionGrants) && Object.keys(value.routineActionGrants).length > 0)
134
+ throw new Error("packaged steward policy must not carry routine action grants; authorize them through an authenticated owner session");
135
+ if (value.desiredStates && typeof value.desiredStates === "object" && !Array.isArray(value.desiredStates) && Object.keys(value.desiredStates).length > 0)
136
+ throw new Error("packaged steward policy must not carry desired state");
137
+ if (!isCanonicalEmptyPackagedPolicy(value))
138
+ throw new Error("packaged steward policy must be the canonical empty policy");
139
+ }
140
+ function requirePlainFile(filePath, label) {
141
+ let stat;
142
+ try {
143
+ stat = fs.lstatSync(filePath);
144
+ }
145
+ catch {
146
+ throw new Error(`${label} is missing`);
147
+ }
148
+ if (stat.isSymbolicLink())
149
+ throw new Error(`${label} must not be a symlink`);
150
+ if (!stat.isFile())
151
+ throw new Error(`${label} must be a regular file`);
152
+ }
153
+ function ensureSafeParent(agentRoot, relative) {
154
+ let current = agentRoot;
155
+ for (const segment of path.dirname(relative).split(path.sep).filter((value) => value !== ".")) {
156
+ current = path.join(current, segment);
157
+ if (!fs.existsSync(current))
158
+ fs.mkdirSync(current, { mode: 0o700 });
159
+ }
160
+ }
161
+ function validateDestination(agentRoot, relative) {
162
+ let current = agentRoot;
163
+ for (const segment of relative.split(path.sep)) {
164
+ current = path.join(current, segment);
165
+ let stat;
166
+ try {
167
+ stat = fs.lstatSync(current);
168
+ }
169
+ catch {
170
+ return;
171
+ }
172
+ if (stat.isSymbolicLink())
173
+ throw new Error(`package-managed destination must not be a symlink: ${relative}`);
174
+ if (current !== path.join(agentRoot, relative) && !stat.isDirectory())
175
+ throw new Error(`package-managed destination parent must be a directory: ${relative}`);
176
+ if (current === path.join(agentRoot, relative) && !stat.isFile())
177
+ throw new Error(`package-managed destination must be a regular file: ${relative}`);
178
+ }
179
+ }
180
+ function syncDirectory(directoryPath) {
181
+ const directory = fs.openSync(directoryPath, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
182
+ try {
183
+ fs.fsyncSync(directory);
184
+ }
185
+ finally {
186
+ fs.closeSync(directory);
187
+ }
188
+ }
189
+ function syncNearestExistingDirectory(directoryPath, agentRoot) {
190
+ let current = directoryPath;
191
+ while (current !== agentRoot && !fs.existsSync(current))
192
+ current = path.dirname(current);
193
+ syncDirectory(current);
194
+ }
195
+ function writeAtomic(filePath, content, mode = 0o600) {
196
+ const stagingDirectory = fs.mkdtempSync(`${filePath}.package-migration.`);
197
+ const temporary = path.join(stagingDirectory, "value");
198
+ try {
199
+ const fd = fs.openSync(temporary, "wx", 0o600);
200
+ try {
201
+ fs.writeFileSync(fd, content);
202
+ fs.fchmodSync(fd, mode);
203
+ fs.fsyncSync(fd);
204
+ }
205
+ finally {
206
+ fs.closeSync(fd);
207
+ }
208
+ fs.renameSync(temporary, filePath);
209
+ }
210
+ finally {
211
+ fs.rmSync(temporary, { force: true });
212
+ fs.rmdirSync(stagingDirectory);
213
+ }
214
+ syncDirectory(path.dirname(filePath));
215
+ }
216
+ const SNAPSHOT_RELATIVES = [...exports.SANCTUARY_PACKAGE_MANAGED_FILES, "bundle-meta.json"];
217
+ function packageManagedArtifactPaths(agentRoot) {
218
+ return SNAPSHOT_RELATIVES.map((relative) => path.join(agentRoot, relative));
219
+ }
220
+ function inspectInterruptedWrites(filePaths, restoredModes) {
221
+ const stages = [];
222
+ for (const filePath of [...filePaths].sort()) {
223
+ const parent = path.dirname(filePath);
224
+ const prefix = `${path.basename(filePath)}.package-migration.`;
225
+ let names;
226
+ try {
227
+ names = fs.readdirSync(parent).sort();
228
+ }
229
+ catch (error) {
230
+ if (isMissing(error))
231
+ continue;
232
+ throw error;
233
+ }
234
+ for (const name of names) {
235
+ if (!name.startsWith(prefix))
236
+ continue;
237
+ const stagingDirectory = path.join(parent, name);
238
+ const parentStat = fs.lstatSync(parent);
239
+ const stagingStat = fs.lstatSync(stagingDirectory);
240
+ if (parentStat.isSymbolicLink() || !parentStat.isDirectory() || stagingStat.isSymbolicLink() || !stagingStat.isDirectory() || (stagingStat.mode & 0o777) !== 0o700 || stagingStat.uid !== parentStat.uid || stagingStat.gid !== parentStat.gid)
241
+ throw new Error(`interrupted package migration stage is invalid: ${name}`);
242
+ const entries = fs.readdirSync(stagingDirectory);
243
+ if (entries.some((entry) => entry !== "value"))
244
+ throw new Error(`interrupted package migration stage contains unexpected entries: ${name}`);
245
+ const temporary = entries.includes("value") ? path.join(stagingDirectory, "value") : null;
246
+ if (temporary) {
247
+ const temporaryStat = fs.lstatSync(temporary);
248
+ const temporaryMode = temporaryStat.mode & 0o777;
249
+ if (temporaryStat.isSymbolicLink() || !temporaryStat.isFile() || (temporaryMode !== 0o600 && temporaryMode !== restoredModes?.get(filePath)) || temporaryStat.uid !== stagingStat.uid || temporaryStat.gid !== stagingStat.gid)
250
+ throw new Error(`interrupted package migration value is invalid: ${name}`);
251
+ }
252
+ stages.push({ stagingDirectory, temporary });
253
+ }
254
+ }
255
+ return stages;
256
+ }
257
+ function cleanupInterruptedWrites(filePaths, restoredModes) {
258
+ const stages = inspectInterruptedWrites(filePaths, restoredModes);
259
+ for (const stage of stages) {
260
+ if (stage.temporary)
261
+ fs.unlinkSync(stage.temporary);
262
+ fs.rmdirSync(stage.stagingDirectory);
263
+ }
264
+ for (const parent of [...new Set(stages.map((stage) => path.dirname(stage.stagingDirectory)))].sort()) {
265
+ syncDirectory(parent);
266
+ }
267
+ }
268
+ function snapshotDirectoryRelatives() {
269
+ const directories = new Set();
270
+ for (const relative of SNAPSHOT_RELATIVES) {
271
+ let directory = path.dirname(relative);
272
+ while (directory !== ".") {
273
+ directories.add(directory);
274
+ directory = path.dirname(directory);
275
+ }
276
+ }
277
+ return [...directories].sort((left, right) => left.length - right.length);
278
+ }
279
+ function captureMigrationSnapshot(agentRoot) {
280
+ const files = SNAPSHOT_RELATIVES.map((relative) => {
281
+ const filePath = path.join(agentRoot, relative);
282
+ if (!fs.existsSync(filePath))
283
+ return { path: filePath, content: null, mode: null };
284
+ const stat = fs.lstatSync(filePath);
285
+ return { path: filePath, content: fs.readFileSync(filePath), mode: stat.mode & 0o777 };
286
+ });
287
+ const directories = snapshotDirectoryRelatives().map((relative) => {
288
+ const directory = path.join(agentRoot, relative);
289
+ if (!fs.existsSync(directory))
290
+ return { path: directory, mode: null };
291
+ const stat = fs.lstatSync(directory);
292
+ return { path: directory, mode: stat.mode & 0o777 };
293
+ });
294
+ return { files, directories };
295
+ }
296
+ function rollbackPath(agentRoot) {
297
+ return path.join(agentRoot, exports.SANCTUARY_BUNDLE_ROLLBACK_FILE);
298
+ }
299
+ function durableSnapshot(agentRoot, snapshot, rollbackImageId, targetImageId) {
300
+ const payload = {
301
+ schemaVersion: 1,
302
+ rollbackImageId,
303
+ targetImageId,
304
+ files: snapshot.files.map((file) => ({ relative: path.relative(agentRoot, file.path), contentBase64: file.content?.toString("base64") ?? null, mode: file.mode })),
305
+ directories: snapshot.directories.map((directory) => ({ relative: path.relative(agentRoot, directory.path), mode: directory.mode })),
306
+ };
307
+ return { ...payload, snapshotDigest: (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(payload)).digest("hex") };
308
+ }
309
+ function readDurableRecord(agentRoot) {
310
+ const names = fs.readdirSync(agentRoot);
311
+ const stagePrefixes = [`${exports.SANCTUARY_BUNDLE_ROLLBACK_FILE}.package-migration.`, `${SANCTUARY_BUNDLE_COMMITTING_FILE}.package-migration.`];
312
+ if (names.some((name) => stagePrefixes.some((prefix) => name.startsWith(prefix))))
313
+ throw new Error("Sanctuary bundle journal staging residue requires verified recovery");
314
+ const candidates = [rollbackPath(agentRoot), path.join(agentRoot, SANCTUARY_BUNDLE_COMMITTING_FILE)].flatMap((filePath) => {
315
+ try {
316
+ return [{ filePath, stat: fs.lstatSync(filePath) }];
317
+ }
318
+ catch (error) {
319
+ if (isMissing(error))
320
+ return [];
321
+ throw error;
322
+ }
323
+ });
324
+ if (candidates.length === 0)
325
+ return null;
326
+ if (candidates.length !== 1)
327
+ throw new Error("Sanctuary bundle rollback record state is ambiguous");
328
+ const [{ filePath, stat }] = candidates;
329
+ if (stat.isSymbolicLink())
330
+ throw new Error("Sanctuary bundle rollback record must not be a symlink");
331
+ if (!stat.isFile() || (stat.mode & 0o777) !== 0o600)
332
+ throw new Error("Sanctuary bundle rollback record must be a mode-0600 regular file");
333
+ const serialized = fs.readFileSync(filePath, "utf8");
334
+ let value;
335
+ try {
336
+ value = JSON.parse(serialized);
337
+ }
338
+ catch {
339
+ throw new Error("Sanctuary bundle rollback record is invalid JSON");
340
+ }
341
+ if (!value || typeof value !== "object" || Array.isArray(value))
342
+ throw new Error("Sanctuary bundle rollback record is invalid");
343
+ const record = value;
344
+ if (record.schemaVersion !== 1 || typeof record.rollbackImageId !== "string" || !/^sha256:[0-9a-f]{64}$/u.test(record.rollbackImageId) || typeof record.targetImageId !== "string" || !/^sha256:[0-9a-f]{64}$/u.test(record.targetImageId) || record.targetImageId === record.rollbackImageId || typeof record.snapshotDigest !== "string" || !/^[0-9a-f]{64}$/u.test(record.snapshotDigest) || !Array.isArray(record.files) || !Array.isArray(record.directories))
345
+ throw new Error("Sanctuary bundle rollback record is invalid");
346
+ const fileRelatives = record.files.map((file) => file?.relative);
347
+ const directoryRelatives = record.directories.map((directory) => directory?.relative);
348
+ const expectedDirectories = snapshotDirectoryRelatives();
349
+ if (JSON.stringify(fileRelatives) !== JSON.stringify(SNAPSHOT_RELATIVES) || JSON.stringify(directoryRelatives) !== JSON.stringify(expectedDirectories))
350
+ throw new Error("Sanctuary bundle rollback record paths are invalid");
351
+ for (const relative of SNAPSHOT_RELATIVES)
352
+ validateDestination(agentRoot, relative);
353
+ const validMode = (mode) => mode === null || (Number.isInteger(mode) && mode >= 0 && mode <= 0o777);
354
+ const files = record.files.map((file) => {
355
+ if (!file || typeof file.relative !== "string" || !validMode(file.mode) || (file.contentBase64 !== null && typeof file.contentBase64 !== "string") || (file.contentBase64 === null) !== (file.mode === null))
356
+ throw new Error("Sanctuary bundle rollback record file is invalid");
357
+ const content = file.contentBase64 === null ? null : Buffer.from(file.contentBase64, "base64");
358
+ if (file.contentBase64 !== null && (!content || content.toString("base64") !== file.contentBase64))
359
+ throw new Error("Sanctuary bundle rollback record content is invalid");
360
+ return { path: path.join(agentRoot, file.relative), content, mode: file.mode };
361
+ });
362
+ const directories = record.directories.map((directory) => {
363
+ if (!directory || typeof directory.relative !== "string" || !validMode(directory.mode))
364
+ throw new Error("Sanctuary bundle rollback record directory is invalid");
365
+ return { path: path.join(agentRoot, directory.relative), mode: directory.mode };
366
+ });
367
+ const payload = { schemaVersion: record.schemaVersion, rollbackImageId: record.rollbackImageId, targetImageId: record.targetImageId, files: record.files, directories: record.directories };
368
+ if ((0, node_crypto_1.createHash)("sha256").update(JSON.stringify(payload)).digest("hex") !== record.snapshotDigest)
369
+ throw new Error("Sanctuary bundle rollback record digest is invalid");
370
+ return { snapshot: { files, directories }, rollbackImageId: record.rollbackImageId, targetImageId: record.targetImageId, filePath, state: filePath === rollbackPath(agentRoot) ? "rollback" : "committing" };
371
+ }
372
+ function removeRollbackRecord(agentRoot, filePath) {
373
+ fs.unlinkSync(filePath);
374
+ syncDirectory(agentRoot);
375
+ }
376
+ function validateAgentRoot(agentRoot) {
377
+ if (!path.isAbsolute(agentRoot))
378
+ throw new Error("agent root must be an absolute path");
379
+ if (!inspectStandaloneSanctuaryDirectory(agentRoot))
380
+ throw new Error("agent root must be a canonical real directory");
381
+ }
382
+ function inspectionError(code) {
383
+ if (code === "invalid_package_root" || code === "invalid_package_source" || code === "packaged_policy_not_empty" || code === "package_version_mismatch") {
384
+ return { ok: false, error: { code, message: "verified release contents are invalid", degraded: true, repair: { actor: "human-required", action: "roll_back_or_install_verified_release" } } };
385
+ }
386
+ if (code === "invalid_live_root" || code === "invalid_live_bundle") {
387
+ return { ok: false, error: { code, message: "installed Sanctuary bundle is invalid", degraded: true, repair: { actor: "human-required", action: "roll_back_or_install_verified_release" } } };
388
+ }
389
+ if (code === "invalid_journal") {
390
+ return { ok: false, error: { code, message: "Sanctuary update recovery is required", degraded: true, repair: { actor: "human-required", action: "run_verified_update_recovery" } } };
391
+ }
392
+ return { ok: false, error: { code, message: "Sanctuary install state is unavailable", degraded: true, repair: { actor: "human-required", action: "run_verified_update_recovery" } } };
393
+ }
394
+ function validateInspectionRoot(root, code) {
395
+ const identity = inspectStandaloneSanctuaryDirectory(root);
396
+ if (!identity)
397
+ throw new SanctuaryInspectionFault(code);
398
+ return identity;
399
+ }
400
+ function inspectRelativeFile(root, relative, code) {
401
+ let current = root;
402
+ let result = null;
403
+ const segments = relative.split(path.sep);
404
+ for (let index = 0; index < segments.length; index += 1) {
405
+ current = path.join(current, segments[index]);
406
+ let stat;
407
+ try {
408
+ stat = fs.lstatSync(current);
409
+ }
410
+ catch (error) {
411
+ if (isMissing(error))
412
+ return null;
413
+ throw error;
414
+ }
415
+ if (stat.isSymbolicLink())
416
+ throw new SanctuaryInspectionFault(code);
417
+ if (index < segments.length - 1 && !stat.isDirectory())
418
+ throw new SanctuaryInspectionFault(code);
419
+ if (index === segments.length - 1 && !stat.isFile())
420
+ throw new SanctuaryInspectionFault(code);
421
+ if (index === segments.length - 1)
422
+ result = stat;
423
+ }
424
+ return result;
425
+ }
426
+ function readInspectionObject(filePath, code) {
427
+ let value;
428
+ try {
429
+ value = JSON.parse(fs.readFileSync(filePath, "utf8"));
430
+ }
431
+ catch (error) {
432
+ if (error instanceof SyntaxError)
433
+ throw new SanctuaryInspectionFault(code);
434
+ throw error;
435
+ }
436
+ if (!value || typeof value !== "object" || Array.isArray(value))
437
+ throw new SanctuaryInspectionFault(code);
438
+ return value;
439
+ }
440
+ function inspectPackageSources(packageRoot, runtimePackageVersion) {
441
+ const managed = new Map();
442
+ for (const relative of exports.SANCTUARY_PACKAGE_MANAGED_FILES) {
443
+ if (!inspectRelativeFile(packageRoot, relative, "invalid_package_source"))
444
+ throw new SanctuaryInspectionFault("invalid_package_source");
445
+ managed.set(relative, fs.readFileSync(path.join(packageRoot, relative)));
446
+ }
447
+ if (!inspectRelativeFile(packageRoot, "bundle-meta.json", "invalid_package_source"))
448
+ throw new SanctuaryInspectionFault("invalid_package_source");
449
+ const metadata = readInspectionObject(path.join(packageRoot, "bundle-meta.json"), "invalid_package_source");
450
+ if (typeof metadata.runtimeVersion !== "string" || metadata.runtimeVersion.length === 0 || !Number.isInteger(metadata.bundleSchemaVersion) || typeof metadata.lastUpdated !== "string" || metadata.lastUpdated.length === 0)
451
+ throw new SanctuaryInspectionFault("invalid_package_source");
452
+ if (!inspectRelativeFile(packageRoot, "state/policy/steward.json", "invalid_package_source"))
453
+ throw new SanctuaryInspectionFault("invalid_package_source");
454
+ const policy = readInspectionObject(path.join(packageRoot, "state/policy/steward.json"), "invalid_package_source");
455
+ if (!isCanonicalEmptyPackagedPolicy(policy))
456
+ throw new SanctuaryInspectionFault("packaged_policy_not_empty");
457
+ if (runtimePackageVersion.length === 0 || metadata.runtimeVersion !== runtimePackageVersion)
458
+ throw new SanctuaryInspectionFault("package_version_mismatch");
459
+ return { managed, metadata, packagedBundleVersion: metadata.runtimeVersion };
460
+ }
461
+ function journalRepair(journalState, parity) {
462
+ if (parity === "exact" && journalState !== "committing")
463
+ return { actor: "none", action: "none" };
464
+ if (parity === "mismatch" && journalState === "absent")
465
+ return { actor: "human-required", action: "restart_from_verified_release" };
466
+ return { actor: "human-required", action: "run_verified_update_recovery" };
467
+ }
468
+ function inspectSanctuaryPackageManagedBundle(input) {
469
+ try {
470
+ const packageIdentity = validateInspectionRoot(input.packageRoot, "invalid_package_root");
471
+ const packaged = inspectPackageSources(input.packageRoot, input.runtimePackageVersion);
472
+ const agentIdentity = validateInspectionRoot(input.agentRoot, "invalid_live_root");
473
+ if (sanctuaryDirectoriesShareIdentity(packageIdentity, agentIdentity))
474
+ throw new SanctuaryInspectionFault("invalid_live_root");
475
+ let managedMissing = false;
476
+ let managedContent = false;
477
+ let managedMode = false;
478
+ for (const relative of exports.SANCTUARY_PACKAGE_MANAGED_FILES) {
479
+ const stat = inspectRelativeFile(input.agentRoot, relative, "invalid_live_bundle");
480
+ if (!stat) {
481
+ managedMissing = true;
482
+ continue;
483
+ }
484
+ if (!fs.readFileSync(path.join(input.agentRoot, relative)).equals(packaged.managed.get(relative)))
485
+ managedContent = true;
486
+ if ((stat.mode & 0o777) !== 0o600)
487
+ managedMode = true;
488
+ }
489
+ let liveBundleVersion = null;
490
+ let bundleMetaMissing = false;
491
+ let bundleMetaField = false;
492
+ let bundleMetaMode = false;
493
+ const liveMetaStat = inspectRelativeFile(input.agentRoot, "bundle-meta.json", "invalid_live_bundle");
494
+ if (!liveMetaStat) {
495
+ bundleMetaMissing = true;
496
+ }
497
+ else {
498
+ const liveMeta = readInspectionObject(path.join(input.agentRoot, "bundle-meta.json"), "invalid_live_bundle");
499
+ liveBundleVersion = typeof liveMeta.runtimeVersion === "string" ? liveMeta.runtimeVersion : null;
500
+ bundleMetaField = BUNDLE_META_VERSION_FIELDS.some((field) => liveMeta[field] !== packaged.metadata[field]);
501
+ bundleMetaMode = (liveMetaStat.mode & 0o777) !== 0o600;
502
+ }
503
+ let journalState = "absent";
504
+ try {
505
+ if (inspectInterruptedWrites(packageManagedArtifactPaths(input.agentRoot)).length > 0)
506
+ throw new Error("Sanctuary bundle staging residue requires verified recovery");
507
+ journalState = readDurableRecord(input.agentRoot)?.state ?? "absent";
508
+ }
509
+ catch (error) {
510
+ if (isFilesystemFailure(error))
511
+ throw error;
512
+ throw new SanctuaryInspectionFault("invalid_journal");
513
+ }
514
+ const mismatchCodes = [];
515
+ if (managedMissing)
516
+ mismatchCodes.push("managed_file_missing");
517
+ if (managedContent)
518
+ mismatchCodes.push("managed_file_content");
519
+ if (managedMode)
520
+ mismatchCodes.push("managed_file_mode");
521
+ if (bundleMetaMissing)
522
+ mismatchCodes.push("bundle_meta_missing");
523
+ if (bundleMetaField)
524
+ mismatchCodes.push("bundle_meta_field");
525
+ if (bundleMetaMode)
526
+ mismatchCodes.push("bundle_meta_mode");
527
+ const parity = mismatchCodes.length === 0 ? "exact" : "mismatch";
528
+ const ready = parity === "exact" && journalState !== "committing";
529
+ return {
530
+ ok: true,
531
+ data: {
532
+ runtimePackageVersion: input.runtimePackageVersion,
533
+ packagedBundleVersion: packaged.packagedBundleVersion,
534
+ liveBundleVersion,
535
+ parity,
536
+ mismatchCodes,
537
+ journalState,
538
+ ready,
539
+ repair: journalRepair(journalState, parity),
540
+ },
541
+ };
542
+ }
543
+ catch (error) {
544
+ return inspectionError(error instanceof SanctuaryInspectionFault ? error.code : "inspection_unavailable");
545
+ }
546
+ }
547
+ function ensureSanctuaryPackageManagedBundle(input, deps = {}) {
548
+ const inspect = deps.inspect ?? inspectSanctuaryPackageManagedBundle;
549
+ const before = inspect(input);
550
+ if (!before.ok) {
551
+ if (before.error.code !== "invalid_journal")
552
+ return before;
553
+ try {
554
+ (deps.migrate ?? migrateSanctuaryPackageManagedBundle)({ packageRoot: input.packageRoot, agentRoot: input.agentRoot });
555
+ }
556
+ catch {
557
+ return before;
558
+ }
559
+ }
560
+ else if (before.data.ready) {
561
+ return before;
562
+ }
563
+ else if (before.data.parity === "mismatch" && before.data.journalState !== "absent") {
564
+ return before;
565
+ }
566
+ else if (before.data.parity === "exact" && before.data.journalState === "committing") {
567
+ (deps.commit ?? commitSanctuaryPackageManagedBundle)(input.agentRoot);
568
+ }
569
+ else {
570
+ (deps.migrate ?? migrateSanctuaryPackageManagedBundle)({ packageRoot: input.packageRoot, agentRoot: input.agentRoot });
571
+ }
572
+ const after = inspect(input);
573
+ if (!after.ok || !after.data.ready)
574
+ return after;
575
+ if (after.data.parity !== "exact" || after.data.journalState !== "absent")
576
+ throw new Error("Sanctuary package-managed bundle did not converge");
577
+ return after;
578
+ }
579
+ function inspectSanctuaryPackageManagedBundleRollback(agentRoot) {
580
+ validateAgentRoot(agentRoot);
581
+ const record = readDurableRecord(agentRoot);
582
+ return record ? { rollbackImageId: record.rollbackImageId, targetImageId: record.targetImageId, state: record.state } : null;
583
+ }
584
+ function rollbackSanctuaryPackageManagedBundle(agentRoot, options = {}) {
585
+ validateAgentRoot(agentRoot);
586
+ const record = readDurableRecord(agentRoot);
587
+ if (!record)
588
+ return false;
589
+ if (record.state === "committing")
590
+ throw new Error("Sanctuary bundle commit is pending and cannot be rolled back");
591
+ restoreMigrationSnapshot(record.snapshot, agentRoot);
592
+ if (!options.retainRecord)
593
+ removeRollbackRecord(agentRoot, record.filePath);
594
+ return true;
595
+ }
596
+ function commitSanctuaryPackageManagedBundle(agentRoot) {
597
+ validateAgentRoot(agentRoot);
598
+ const record = readDurableRecord(agentRoot);
599
+ if (!record)
600
+ return false;
601
+ const committingPath = path.join(agentRoot, SANCTUARY_BUNDLE_COMMITTING_FILE);
602
+ if (record.filePath !== committingPath) {
603
+ fs.renameSync(record.filePath, committingPath);
604
+ syncDirectory(agentRoot);
605
+ }
606
+ removeRollbackRecord(agentRoot, committingPath);
607
+ return true;
608
+ }
609
+ function restoreMigrationSnapshot(snapshot, agentRoot) {
610
+ const restoredModes = new Map();
611
+ for (const file of snapshot.files)
612
+ if (file.mode !== null)
613
+ restoredModes.set(file.path, file.mode);
614
+ cleanupInterruptedWrites(snapshot.files.map((file) => file.path), restoredModes);
615
+ for (const file of snapshot.files) {
616
+ if (file.content === null) {
617
+ fs.rmSync(file.path, { force: true });
618
+ syncNearestExistingDirectory(path.dirname(file.path), agentRoot);
619
+ }
620
+ else {
621
+ writeAtomic(file.path, file.content, file.mode);
622
+ }
623
+ }
624
+ for (const directory of [...snapshot.directories].reverse()) {
625
+ if (directory.mode === null) {
626
+ if (!fs.existsSync(directory.path)) {
627
+ syncNearestExistingDirectory(path.dirname(directory.path), agentRoot);
628
+ }
629
+ else if (fs.readdirSync(directory.path).length === 0) {
630
+ fs.rmdirSync(directory.path);
631
+ syncNearestExistingDirectory(path.dirname(directory.path), agentRoot);
632
+ }
633
+ }
634
+ else {
635
+ const handle = fs.openSync(directory.path, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
636
+ try {
637
+ fs.fchmodSync(handle, directory.mode);
638
+ fs.fsyncSync(handle);
639
+ }
640
+ finally {
641
+ fs.closeSync(handle);
642
+ }
643
+ }
644
+ }
645
+ }
646
+ function migrateSanctuaryPackageManagedBundle(input) {
647
+ (0, runtime_1.emitNervesEvent)({ component: "daemon", event: "daemon.sanctuary_bundle_migration_start", message: "starting Sanctuary package-managed bundle migration", meta: { agentRoot: input.agentRoot } });
648
+ let snapshot = null;
649
+ try {
650
+ if (!path.isAbsolute(input.packageRoot) || !path.isAbsolute(input.agentRoot))
651
+ throw new Error("package and agent roots must be absolute paths");
652
+ const packageIdentity = inspectStandaloneSanctuaryDirectory(input.packageRoot);
653
+ const agentIdentity = inspectStandaloneSanctuaryDirectory(input.agentRoot);
654
+ if (!packageIdentity)
655
+ throw new Error("package root must be a canonical real directory");
656
+ if (!agentIdentity)
657
+ throw new Error("agent root must be a canonical real directory");
658
+ if (sanctuaryDirectoriesShareIdentity(packageIdentity, agentIdentity))
659
+ throw new Error("package and agent roots must be distinct real directories");
660
+ if (input.retainRollback && (!input.rollbackImageId || !/^sha256:[0-9a-f]{64}$/u.test(input.rollbackImageId) || !input.targetImageId || !/^sha256:[0-9a-f]{64}$/u.test(input.targetImageId) || input.targetImageId === input.rollbackImageId))
661
+ throw new Error("retained rollback requires distinct exact rollback and target image IDs");
662
+ const existingRollback = rollbackPath(input.agentRoot);
663
+ if (readDurableRecord(input.agentRoot))
664
+ throw new Error("Sanctuary bundle rollback is pending; rollback or commit it before another migration");
665
+ for (const relative of exports.SANCTUARY_PACKAGE_MANAGED_FILES) {
666
+ requirePlainFile(path.join(input.packageRoot, relative), `package-managed source ${relative}`);
667
+ validateDestination(input.agentRoot, relative);
668
+ }
669
+ requirePlainFile(path.join(input.packageRoot, "bundle-meta.json"), "packaged bundle-meta.json");
670
+ validateDestination(input.agentRoot, "bundle-meta.json");
671
+ const packagedMeta = readObject(path.join(input.packageRoot, "bundle-meta.json"));
672
+ for (const field of BUNDLE_META_VERSION_FIELDS)
673
+ if (!(field in packagedMeta))
674
+ throw new Error(`packaged bundle-meta.json is missing ${field}`);
675
+ validatePackagedPolicy(input.packageRoot);
676
+ cleanupInterruptedWrites(packageManagedArtifactPaths(input.agentRoot));
677
+ snapshot = captureMigrationSnapshot(input.agentRoot);
678
+ if (input.retainRollback) {
679
+ writeAtomic(existingRollback, `${JSON.stringify(durableSnapshot(input.agentRoot, snapshot, input.rollbackImageId, input.targetImageId))}\n`);
680
+ }
681
+ let managedFilesUpdated = 0;
682
+ for (const relative of exports.SANCTUARY_PACKAGE_MANAGED_FILES) {
683
+ const source = fs.readFileSync(path.join(input.packageRoot, relative), "utf8");
684
+ const destination = path.join(input.agentRoot, relative);
685
+ ensureSafeParent(input.agentRoot, relative);
686
+ if (fs.existsSync(destination) && fs.readFileSync(destination, "utf8") === source && (fs.statSync(destination).mode & 0o777) === 0o600)
687
+ continue;
688
+ writeAtomic(destination, source);
689
+ managedFilesUpdated += 1;
690
+ }
691
+ const metaPath = path.join(input.agentRoot, "bundle-meta.json");
692
+ const metaExists = fs.existsSync(metaPath);
693
+ const currentMeta = metaExists ? readObject(metaPath) : {};
694
+ const nextMeta = { ...currentMeta };
695
+ for (const field of BUNDLE_META_VERSION_FIELDS)
696
+ nextMeta[field] = packagedMeta[field];
697
+ if (!metaExists || BUNDLE_META_VERSION_FIELDS.some((field) => currentMeta[field] !== packagedMeta[field])) {
698
+ writeAtomic(metaPath, `${JSON.stringify(nextMeta, null, 2)}\n`);
699
+ }
700
+ else if ((fs.statSync(metaPath).mode & 0o777) !== 0o600) {
701
+ fs.chmodSync(metaPath, 0o600);
702
+ const meta = fs.openSync(metaPath, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
703
+ try {
704
+ fs.fsyncSync(meta);
705
+ }
706
+ finally {
707
+ fs.closeSync(meta);
708
+ }
709
+ }
710
+ const result = { managedFilesUpdated };
711
+ (0, runtime_1.emitNervesEvent)({ component: "daemon", event: "daemon.sanctuary_bundle_migration_end", message: "completed Sanctuary package-managed bundle migration", meta: result });
712
+ return result;
713
+ }
714
+ catch (error) {
715
+ let failure = error;
716
+ if (snapshot) {
717
+ try {
718
+ restoreMigrationSnapshot(snapshot, input.agentRoot);
719
+ if (fs.existsSync(rollbackPath(input.agentRoot)))
720
+ removeRollbackRecord(input.agentRoot, rollbackPath(input.agentRoot));
721
+ }
722
+ catch (restoreError) {
723
+ failure = new AggregateError([error, restoreError], "Sanctuary bundle migration and rollback both failed");
724
+ }
725
+ }
726
+ (0, runtime_1.emitNervesEvent)({ component: "daemon", event: "daemon.sanctuary_bundle_migration_error", level: "error", message: "Sanctuary package-managed bundle migration failed", meta: { error: String(failure), agentRoot: input.agentRoot } });
727
+ throw failure;
728
+ }
729
+ }