@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,552 @@
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.selectA003LegacyRequiredCorrections = selectA003LegacyRequiredCorrections;
37
+ exports.inspectA003SessionRepair = inspectA003SessionRepair;
38
+ exports.applyA003SessionRepair = applyA003SessionRepair;
39
+ exports.rollbackA003SessionRepair = rollbackA003SessionRepair;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const node_crypto_1 = require("node:crypto");
43
+ const node_util_1 = require("node:util");
44
+ const identity_1 = require("./identity");
45
+ const runtime_1 = require("../nerves/runtime");
46
+ const tool_arguments_1 = require("../repertoire/tool-arguments");
47
+ const session_events_1 = require("./session-events");
48
+ const structured_output_1 = require("./structured-output");
49
+ const session_transaction_1 = require("../mind/session-transaction");
50
+ const SCHEMA = "a003-sanctuary-session-repair-v1";
51
+ const SELECTOR = "a003-legacy-required-corrections-v1";
52
+ const TARGET_BINDINGS = [
53
+ { id: "evt-000347", sequence: 347 },
54
+ { id: "evt-000355", sequence: 355 },
55
+ { id: "evt-000363", sequence: 363 },
56
+ { id: "evt-000366", sequence: 366 },
57
+ { id: "evt-000369", sequence: 369 },
58
+ { id: "evt-000400", sequence: 400 },
59
+ { id: "evt-000447", sequence: 447 },
60
+ { id: "evt-000448", sequence: 448 },
61
+ ];
62
+ const SESSION_LIMIT = 32 * 1024 * 1024;
63
+ const MANIFEST_LIMIT = 1024 * 1024;
64
+ const HASH = /^[a-f0-9]{64}$/u;
65
+ function sha(bytes) {
66
+ return (0, node_crypto_1.createHash)("sha256").update(bytes).digest("hex");
67
+ }
68
+ function refuse(reason) {
69
+ (0, runtime_1.emitNervesEvent)({
70
+ level: "warn", component: "heart", event: "heart.session_redaction_repair_refused",
71
+ message: "fixed session repair refused", meta: { reason },
72
+ });
73
+ throw new Error(reason);
74
+ }
75
+ function exactKeys(value, keys) {
76
+ return value !== null && typeof value === "object" && !Array.isArray(value)
77
+ && Object.keys(value).length === keys.length && keys.every((key) => Object.prototype.hasOwnProperty.call(value, key));
78
+ }
79
+ function iso(value) {
80
+ return typeof value === "string" && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
81
+ }
82
+ function sameInode(a, b) {
83
+ return a.dev === b.dev && a.ino === b.ino;
84
+ }
85
+ function directoryChain(directory) {
86
+ if (!path.isAbsolute(directory) || path.resolve(directory) !== directory)
87
+ refuse("noncanonical directory path");
88
+ let current = path.parse(directory).root;
89
+ const parts = [current];
90
+ for (const part of directory.slice(current.length).split(path.sep).filter(Boolean)) {
91
+ current = path.join(current, part);
92
+ parts.push(current);
93
+ }
94
+ return parts.map((file) => {
95
+ const stat = fs.lstatSync(file, { bigint: true });
96
+ if (!stat.isDirectory() || stat.isSymbolicLink())
97
+ refuse("directory symlink or type mismatch");
98
+ return { path: file, dev: stat.dev, ino: stat.ino };
99
+ });
100
+ }
101
+ function checkDirectories(pin) {
102
+ for (const entry of pin) {
103
+ const stat = fs.lstatSync(entry.path, { bigint: true });
104
+ if (!stat.isDirectory() || stat.isSymbolicLink() || !sameInode(entry, stat))
105
+ refuse("directory identity changed");
106
+ }
107
+ }
108
+ function privateDirectory(directory) {
109
+ const pin = directoryChain(directory);
110
+ if ((fs.lstatSync(directory, { bigint: true }).mode & 511n) !== 448n)
111
+ refuse("artifact directory must have mode 0700");
112
+ return pin;
113
+ }
114
+ function privateFile(file, label, limit) {
115
+ if (!path.isAbsolute(file) || path.resolve(file) !== file)
116
+ refuse("noncanonical file path");
117
+ directoryChain(path.dirname(file));
118
+ const stat = fs.lstatSync(file, { bigint: true });
119
+ if (!stat.isFile() || stat.isSymbolicLink())
120
+ refuse(`${label} must be a regular file`);
121
+ if ((stat.mode & 511n) !== 384n)
122
+ refuse(`${label} must have mode 0600`);
123
+ if (stat.size > BigInt(limit))
124
+ refuse(`${label} exceeds ${limit / (1024 * 1024)} MiB`);
125
+ return stat;
126
+ }
127
+ function readArtifact(file, label, limit) {
128
+ const pin = privateDirectory(path.dirname(file));
129
+ const original = privateFile(file, label, limit);
130
+ const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
131
+ try {
132
+ const opened = fs.fstatSync(fd, { bigint: true });
133
+ if (!opened.isFile() || !sameInode(original, opened) || (opened.mode & 511n) !== 384n || opened.size > BigInt(limit))
134
+ refuse("artifact identity changed");
135
+ const bytes = fs.readFileSync(fd);
136
+ checkDirectories(pin);
137
+ if (bytes.length > limit || !sameInode(opened, fs.lstatSync(file, { bigint: true })))
138
+ refuse("artifact changed during read");
139
+ return bytes;
140
+ }
141
+ finally {
142
+ fs.closeSync(fd);
143
+ }
144
+ }
145
+ function sessionLocation(agent, sessionPath) {
146
+ if (agent !== "sanctuary")
147
+ refuse("repair agent must be sanctuary");
148
+ const root = path.join((0, identity_1.getAgentRoot)("sanctuary"), "state", "sessions");
149
+ directoryChain(root);
150
+ const relative = path.relative(root, sessionPath);
151
+ if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative))
152
+ refuse("session path escapes sanctuary");
153
+ privateFile(sessionPath, "session", SESSION_LIMIT);
154
+ return { root, relative: relative.split(path.sep).join("/") };
155
+ }
156
+ function manifestSessionPath(relative) {
157
+ if (!relative || relative.includes("\\") || relative.split("/").some((part) => !part || part === "." || part === ".."))
158
+ refuse("invalid session relative path");
159
+ const file = path.join((0, identity_1.getAgentRoot)("sanctuary"), "state", "sessions", relative);
160
+ sessionLocation("sanctuary", file);
161
+ return file;
162
+ }
163
+ function marker(target, sequence, capturedAt) {
164
+ return {
165
+ id: `evt-${String(sequence).padStart(6, "0")}`, sequence, role: "system", content: null,
166
+ name: null, toolCallId: null, toolCalls: [], attachments: [],
167
+ time: {
168
+ authoredAt: null, authoredAtSource: "migration", observedAt: null, observedAtSource: "migration",
169
+ recordedAt: capturedAt, recordedAtSource: "migration",
170
+ },
171
+ relations: {
172
+ replyToEventId: null, threadRootEventId: null, references: [], toolCallId: null,
173
+ supersedesEventId: null, redactsEventId: target.id,
174
+ },
175
+ provenance: { captureKind: "migration", legacyVersion: 2, sourceMessageIndex: null },
176
+ };
177
+ }
178
+ // Frozen constructor inputs, not a text/regex classifier and not live policy.
179
+ // The first media wording is the constructor shipped at 2efc01e5; the other
180
+ // finite variants are present in the P0 Sanctuary required-read contracts.
181
+ const LEGACY_CORRECTIONS = new Set();
182
+ for (const [text, names] of [
183
+ ["Before answering, read current active work, cares, system health, and service state. Then give Ari one compact household summary; do not ask him to choose a status slice.", ["query_active_work", "query_cares", "unraid_get_system", "unraid_list_containers"]],
184
+ ["Before answering, read current active work, cares, system health, service state, storage, and the download queue. Current tool facts outrank care history; a stale care is a recheck item, not a present-tense fact. Then give Ari one compact household summary; do not ask him to choose a status slice.", ["query_active_work", "query_cares", "unraid_get_system", "unraid_list_containers", "unraid_get_storage", "sanctuary_get_download_queue"]],
185
+ ["Run both safe reads now, identify the largest measured evidence, report Unmanic and Jellyfin findings, and propose a sample encode without inventing future savings. Do not ask permission or send Ari to a shell or QDirStat while these typed reads are available.", ["unraid_get_storage", "sanctuary_get_media_optimization"]],
186
+ ["Run both safe reads now, identify the largest measured evidence, report Unmanic and Jellyfin findings, and propose a sample encode without inventing future savings. If one read returns a degraded or partial result, continue with the other safe reads and bounded container/log tools before answering. Do not ask permission or send Ari to a shell, dashboard, logs, or QDirStat while these typed reads are available.", ["unraid_get_storage", "sanctuary_get_media_optimization"]],
187
+ ["Before answering, read current active work, cares, system health, service state, storage, notifications, and the download queue. Current tool facts outrank care history; a stale care is a recheck item, not a present-tense fact. Then give Ari one compact household summary; do not ask him to choose a status slice.", ["query_active_work", "query_cares", "unraid_get_system", "unraid_list_containers", "unraid_get_storage", "unraid_get_notifications", "sanctuary_get_download_queue"]],
188
+ ]) {
189
+ for (let bits = 1; bits < 2 ** names.length; bits++) {
190
+ LEGACY_CORRECTIONS.add(`${text} Missing required tool calls: ${names.filter((_name, index) => (bits & (1 << index)) !== 0).join(", ")}.`);
191
+ }
192
+ }
193
+ for (const text of [
194
+ "Use sanctuary_search_media_catalog before answering. If asked for taste or a favorite, form a light recommendation from returned catalog evidence instead of claiming you cannot have preferences. Keep it honest: say you cannot watch, but you can pick from the household shelf.",
195
+ "Use sanctuary_search_media_catalog before answering. If a broader media-optimization read fails or degrades, treat that as a diagnostic note and still use the catalog tool for ordinary library visibility questions. If asked for taste or a favorite, form a light recommendation from returned catalog evidence instead of claiming you cannot have preferences. Keep it honest: say you cannot watch, but you can pick from the household shelf.",
196
+ "Use sanctuary_search_media_catalog before answering, then report only the current shelf count in ordinary household language.",
197
+ "Use sanctuary_search_media_catalog before answering. Lead with the direct answer from current catalog evidence, report the shelf count in ordinary household language, and stop without sampled titles or a follow-up question.",
198
+ "Use sanctuary_search_media_catalog with the requested title before answering. Confirm its presence or absence directly from current catalog evidence.",
199
+ "Use sanctuary_search_media_catalog before answering. Make one concise, decisive choice grounded in returned catalog evidence; do not volunteer an AI or 'I cannot watch' disclaimer.",
200
+ "Use sanctuary_search_media_catalog before answering and base any named titles on the returned catalog evidence.",
201
+ ...Array.from({ length: 20 }, (_, index) => `Use sanctuary_search_media_catalog with limit ${index + 1} before answering, then name exactly the returned catalog titles.`),
202
+ ])
203
+ LEGACY_CORRECTIONS.add(`${text} Missing required tool calls: sanctuary_search_media_catalog.`);
204
+ function selectA003LegacyRequiredCorrections(rawEvents) {
205
+ if (!Array.isArray(rawEvents) || rawEvents.length === 0)
206
+ refuse("legacy event set is missing");
207
+ const events = rawEvents;
208
+ if (events.some((event) => !event || typeof event !== "object" || event.relations?.redactsEventId != null))
209
+ refuse("legacy event set has a redaction conflict");
210
+ const max = events.reduce((value, event) => Math.max(value, event.sequence), 0);
211
+ const targets = TARGET_BINDINGS.map(({ id, sequence }) => events.find((event) => event.id === id && event.sequence === sequence));
212
+ for (const target of targets) {
213
+ if (!target || typeof target.content !== "string" || !LEGACY_CORRECTIONS.has(target.content)
214
+ || !(0, session_events_1.isExactRawSessionRedactionMarker)(marker(target, max + 1, "1970-01-01T00:00:00.000Z"), [...events, marker(target, max + 1, "1970-01-01T00:00:00.000Z")])
215
+ || target.name !== null || target.toolCallId !== null || target.toolCalls.length !== 0 || target.attachments.length !== 0
216
+ || target.provenance.captureKind !== "live" || target.provenance.legacyVersion !== null || target.provenance.sourceMessageIndex !== null
217
+ || target.time.authoredAt !== null || target.time.authoredAtSource !== "unknown" || target.time.observedAtSource !== "ingest"
218
+ || target.time.recordedAtSource !== "save" || target.time.observedAt !== target.time.recordedAt
219
+ || !(0, node_util_1.isDeepStrictEqual)(target.relations, { replyToEventId: null, threadRootEventId: null, references: [], toolCallId: null, supersedesEventId: null, redactsEventId: null }))
220
+ refuse("legacy correction constructor mismatch");
221
+ }
222
+ if (events.filter((event) => typeof event.content === "string" && LEGACY_CORRECTIONS.has(event.content)).length !== TARGET_BINDINGS.length)
223
+ refuse("extra or ambiguous legacy corrections");
224
+ return targets;
225
+ }
226
+ function rawEnvelope(bytes) {
227
+ if (Buffer.byteLength(bytes) > SESSION_LIMIT)
228
+ refuse("session exceeds 32 MiB");
229
+ const value = JSON.parse(bytes);
230
+ const parsed = (0, session_events_1.parseSessionEnvelope)(value);
231
+ if (!parsed || !value || typeof value !== "object" || value.version !== 2)
232
+ refuse("session must be a v2 envelope");
233
+ const envelope = value;
234
+ if (JSON.stringify(value, null, 2) !== bytes)
235
+ refuse("session bytes are not canonical transaction serialization");
236
+ if (!(0, node_util_1.isDeepStrictEqual)(envelope.events, parsed.events))
237
+ refuse("session requires normalization");
238
+ const projection = envelope.projection;
239
+ if (!exactKeys(projection, ["eventIds", "trimmed", "maxTokens", "contextMargin", "inputTokens", "projectedAt"])
240
+ || !Array.isArray(projection.eventIds) || projection.eventIds.some((id) => typeof id !== "string")
241
+ || typeof projection.trimmed !== "boolean"
242
+ || ![projection.maxTokens, projection.contextMargin, projection.inputTokens].every((value) => value === null || typeof value === "number")
243
+ || !(projection.projectedAt === null || iso(projection.projectedAt)))
244
+ refuse("invalid session projection");
245
+ const byId = new Map(envelope.events.map((event) => [event.id, event]));
246
+ const seenIds = new Set();
247
+ let sequence = 0;
248
+ for (const [index, id] of projection.eventIds.entries()) {
249
+ const event = byId.get(id);
250
+ if (!event || seenIds.has(id))
251
+ refuse("invalid projection order or identity");
252
+ seenIds.add(id);
253
+ if (index === 0 && event.role === "system")
254
+ continue;
255
+ if (event.sequence <= sequence)
256
+ refuse("invalid projection order or identity");
257
+ sequence = event.sequence;
258
+ }
259
+ return envelope;
260
+ }
261
+ function projectedStructuredOutputs(envelope) {
262
+ const byId = new Map(envelope.events.map((event) => [event.id, event]));
263
+ const events = (0, session_events_1.projectedSessionEventIds)(envelope).map((id) => byId.get(id));
264
+ return (0, structured_output_1.extractStructuredOutputsFromEvents)(events, { emitTelemetry: false });
265
+ }
266
+ function compute(bytes, relative, capturedAt) {
267
+ const envelope = rawEnvelope(bytes);
268
+ const targets = selectA003LegacyRequiredCorrections(envelope.events);
269
+ const max = envelope.events.reduce((value, event) => Math.max(value, event.sequence), 0);
270
+ const entries = targets.map((target, index) => {
271
+ const position = envelope.events.indexOf(target);
272
+ return {
273
+ target, targetSha256: (0, tool_arguments_1.digestJson)(target),
274
+ previousEventId: envelope.events[position - 1]?.id ?? null,
275
+ nextEventId: envelope.events[position + 1]?.id ?? null,
276
+ marker: marker(target, max + index + 1, capturedAt),
277
+ };
278
+ });
279
+ const events = [...envelope.events, ...entries.map((entry) => entry.marker)];
280
+ if (!entries.every((entry) => (0, session_events_1.isExactRawSessionRedactionMarker)(entry.marker, events)))
281
+ refuse("invalid computed marker block");
282
+ const removed = new Set(entries.flatMap((entry) => [entry.target.id, entry.marker.id]));
283
+ const selected = new Set((0, session_events_1.projectedSessionEventIds)(envelope).filter((id) => !removed.has(id)));
284
+ const postimage = {
285
+ ...envelope, events,
286
+ projection: {
287
+ ...envelope.projection, eventIds: envelope.projection.eventIds.filter((id) => !removed.has(id)),
288
+ trimmed: envelope.projection.trimmed || (0, session_events_1.selectEffectiveSessionEvents)(events).some((event) => !selected.has(event.id)),
289
+ },
290
+ };
291
+ postimage.structuredOutputs = projectedStructuredOutputs(postimage);
292
+ const postBytes = JSON.stringify(postimage, null, 2);
293
+ if (Buffer.byteLength(postBytes) > SESSION_LIMIT)
294
+ refuse("postimage exceeds 32 MiB");
295
+ return {
296
+ manifest: { schemaVersion: SCHEMA, selectorVersion: SELECTOR, agent: "sanctuary", sessionRelativePath: relative, capturedAt, preimageRevision: sha(bytes), postimageRevision: sha(postBytes), entries },
297
+ postimage,
298
+ };
299
+ }
300
+ function readManifest(authority) {
301
+ if (typeof authority.manifestSha256 !== "string" || !HASH.test(authority.manifestSha256))
302
+ refuse("invalid manifest hash");
303
+ const bytes = readArtifact(authority.manifestPath, "manifest", MANIFEST_LIMIT);
304
+ if (sha(bytes) !== authority.manifestSha256)
305
+ refuse("manifest hash changed");
306
+ const value = JSON.parse(bytes.toString("utf8"));
307
+ if (!exactKeys(value, ["schemaVersion", "selectorVersion", "agent", "sessionRelativePath", "capturedAt", "preimageRevision", "postimageRevision", "entries"])
308
+ || value.schemaVersion !== SCHEMA || value.selectorVersion !== SELECTOR || value.agent !== "sanctuary"
309
+ || typeof value.sessionRelativePath !== "string" || !iso(value.capturedAt)
310
+ || typeof value.preimageRevision !== "string" || !HASH.test(value.preimageRevision)
311
+ || typeof value.postimageRevision !== "string" || !HASH.test(value.postimageRevision)
312
+ || !Array.isArray(value.entries) || value.entries.length !== TARGET_BINDINGS.length
313
+ || JSON.stringify(value, null, 2) !== bytes.toString("utf8"))
314
+ refuse("invalid closed repair manifest");
315
+ for (const entry of value.entries) {
316
+ if (!exactKeys(entry, ["target", "targetSha256", "previousEventId", "nextEventId", "marker"])
317
+ || typeof entry.targetSha256 !== "string" || !HASH.test(entry.targetSha256)
318
+ || ![entry.previousEventId, entry.nextEventId].every((id) => id === null || typeof id === "string" && id.trim().length > 0))
319
+ refuse("invalid manifest entry");
320
+ }
321
+ const manifest = value;
322
+ const targets = selectA003LegacyRequiredCorrections(manifest.entries.map((entry) => entry.target));
323
+ const block = manifest.entries.map((entry) => entry.marker);
324
+ for (let index = 0; index < manifest.entries.length; index++) {
325
+ const entry = manifest.entries[index];
326
+ if (!(0, node_util_1.isDeepStrictEqual)(entry.target, targets[index])
327
+ || entry.targetSha256 !== (0, tool_arguments_1.digestJson)(entry.target)
328
+ || !(0, session_events_1.isExactRawSessionRedactionMarker)(entry.marker, [...targets, ...block])
329
+ || !(0, node_util_1.isDeepStrictEqual)(entry.marker, marker(entry.target, block[0].sequence + index, manifest.capturedAt)))
330
+ refuse("manifest target or marker mismatch");
331
+ }
332
+ return manifest;
333
+ }
334
+ function publishArtifacts(directory, artifacts) {
335
+ const pin = privateDirectory(directory);
336
+ for (const artifact of artifacts) {
337
+ try {
338
+ fs.lstatSync(artifact.path, { bigint: true });
339
+ refuse("final artifact already exists");
340
+ }
341
+ catch (error) {
342
+ if (error.code !== "ENOENT")
343
+ throw error;
344
+ }
345
+ }
346
+ const created = [];
347
+ try {
348
+ for (const artifact of artifacts) {
349
+ checkDirectories(pin);
350
+ const record = { temporary: path.join(directory, `.${path.basename(artifact.path)}.${(0, node_crypto_1.randomUUID)()}`), final: artifact.path, identity: null, published: false };
351
+ created.push(record);
352
+ const fd = fs.openSync(record.temporary, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_NOFOLLOW, 0o600);
353
+ try {
354
+ record.identity = fs.fstatSync(fd, { bigint: true });
355
+ fs.writeFileSync(fd, artifact.bytes);
356
+ fs.fsyncSync(fd);
357
+ }
358
+ catch (error) {
359
+ try {
360
+ fs.closeSync(fd);
361
+ }
362
+ catch {
363
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "heart", event: "heart.session_repair_artifact_cleanup_refused", message: "artifact descriptor cleanup failed; primary error retained", meta: { stage: "descriptor" } });
364
+ }
365
+ throw error;
366
+ }
367
+ fs.closeSync(fd);
368
+ checkDirectories(pin);
369
+ fs.linkSync(record.temporary, record.final);
370
+ record.published = true;
371
+ const directoryFd = fs.openSync(directory, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
372
+ try {
373
+ fs.fsyncSync(directoryFd);
374
+ }
375
+ finally {
376
+ fs.closeSync(directoryFd);
377
+ }
378
+ checkDirectories(pin);
379
+ const readFd = fs.openSync(record.final, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
380
+ try {
381
+ const stat = fs.fstatSync(readFd, { bigint: true });
382
+ if (!stat.isFile() || !sameInode(record.identity, stat) || (stat.mode & 511n) !== 384n || stat.size !== BigInt(artifact.bytes.length)
383
+ || sha(fs.readFileSync(readFd)) !== sha(artifact.bytes))
384
+ refuse("published artifact identity or hash mismatch");
385
+ }
386
+ finally {
387
+ fs.closeSync(readFd);
388
+ }
389
+ }
390
+ }
391
+ catch (error) {
392
+ for (const record of created) {
393
+ if (!record.published || !record.identity)
394
+ continue;
395
+ try {
396
+ checkDirectories(pin);
397
+ const current = fs.lstatSync(record.final, { bigint: true });
398
+ if (current.isFile() && !current.isSymbolicLink() && sameInode(current, record.identity))
399
+ fs.unlinkSync(record.final);
400
+ }
401
+ catch {
402
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "heart", event: "heart.session_repair_artifact_cleanup_refused", message: "artifact cleanup could not safely address its original file", meta: { stage: "final" } });
403
+ }
404
+ }
405
+ throw error;
406
+ }
407
+ finally {
408
+ for (const record of created) {
409
+ if (!record.identity)
410
+ continue;
411
+ try {
412
+ checkDirectories(pin);
413
+ const current = fs.lstatSync(record.temporary, { bigint: true });
414
+ if (current.isFile() && !current.isSymbolicLink() && sameInode(current, record.identity))
415
+ fs.unlinkSync(record.temporary);
416
+ }
417
+ catch {
418
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "heart", event: "heart.session_repair_artifact_cleanup_refused", message: "artifact cleanup could not safely address its original file", meta: { stage: "sibling" } });
419
+ }
420
+ }
421
+ }
422
+ }
423
+ async function inspectA003SessionRepair(input) {
424
+ const location = sessionLocation(input.agent, input.sessionPath);
425
+ privateDirectory(input.artifactsDir);
426
+ return (0, session_transaction_1.withSessionTurnLease)(input.sessionPath, async (lease) => {
427
+ privateFile(input.sessionPath, "session", SESSION_LIMIT);
428
+ const current = (0, session_transaction_1.readSessionTransaction)(input.sessionPath, lease);
429
+ const { manifest } = compute(current.bytes, location.relative, new Date().toISOString());
430
+ const manifestBytes = Buffer.from(JSON.stringify(manifest, null, 2));
431
+ if (manifestBytes.length > MANIFEST_LIMIT)
432
+ refuse("manifest exceeds 1 MiB");
433
+ const manifestPath = path.join(input.artifactsDir, "a003-session-manifest.json");
434
+ const preimagePath = path.join(input.artifactsDir, "a003-session-preimage.json");
435
+ publishArtifacts(input.artifactsDir, [{ path: preimagePath, bytes: Buffer.from(current.bytes) }, { path: manifestPath, bytes: manifestBytes }]);
436
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.session_redaction_repair_inspected", message: "fixed repair inspected without session mutation", meta: { targetCount: manifest.entries.length } });
437
+ return { status: "inspected", manifestPath, preimagePath, manifestSha256: sha(manifestBytes), preimageRevision: manifest.preimageRevision, postimageRevision: manifest.postimageRevision };
438
+ }, { confinementRoot: location.root });
439
+ }
440
+ function alreadyApplied(envelope, manifest, currentRevision) {
441
+ const blockIndex = envelope.events.findIndex((event) => event.id === manifest.entries[0].marker.id);
442
+ if (blockIndex < 0 || !(0, node_util_1.isDeepStrictEqual)(envelope.events.slice(blockIndex, blockIndex + TARGET_BINDINGS.length), manifest.entries.map((entry) => entry.marker)))
443
+ return false;
444
+ if (currentRevision !== manifest.postimageRevision && envelope.events.at(-1).sequence <= manifest.entries.at(-1).marker.sequence)
445
+ return false;
446
+ try {
447
+ const targets = selectA003LegacyRequiredCorrections(envelope.events.slice(0, blockIndex));
448
+ if (!(0, node_util_1.isDeepStrictEqual)(targets, manifest.entries.map((entry) => entry.target)))
449
+ return false;
450
+ }
451
+ catch {
452
+ return false;
453
+ }
454
+ const marked = envelope.events.filter((event) => event.relations.redactsEventId !== null);
455
+ if (!(0, node_util_1.isDeepStrictEqual)(marked, manifest.entries.map((entry) => entry.marker))
456
+ || !marked.every((event) => (0, session_events_1.isExactRawSessionRedactionMarker)(event, envelope.events)))
457
+ return false;
458
+ const effective = (0, session_events_1.selectEffectiveSessionEvents)(envelope.events);
459
+ const visible = new Set(effective.map((event) => event.id));
460
+ return envelope.projection.eventIds.every((id) => visible.has(id))
461
+ && (0, node_util_1.isDeepStrictEqual)(envelope.structuredOutputs, projectedStructuredOutputs(envelope));
462
+ }
463
+ async function reconcileWrite(sessionPath, lease, value, before, after, success) {
464
+ try {
465
+ (0, session_transaction_1.writeSessionTransaction)(sessionPath, value, { lease, expectedRevision: before });
466
+ }
467
+ catch {
468
+ // A throw may occur after rename; only exact, still-confined readback decides.
469
+ }
470
+ try {
471
+ privateFile(sessionPath, "session", SESSION_LIMIT);
472
+ const current = (0, session_transaction_1.readSessionTransaction)(sessionPath, lease);
473
+ if (current.revision === after)
474
+ return { status: success, revision: after };
475
+ if (current.revision === before)
476
+ return { status: "not_applied", revision: before };
477
+ }
478
+ catch {
479
+ return { status: "indeterminate" };
480
+ }
481
+ return { status: "indeterminate" };
482
+ }
483
+ async function applyA003SessionRepair(authority) {
484
+ const manifest = readManifest(authority);
485
+ const sessionPath = manifestSessionPath(manifest.sessionRelativePath);
486
+ const { root } = sessionLocation("sanctuary", sessionPath);
487
+ let attemptedWrite = false;
488
+ try {
489
+ const result = await (0, session_transaction_1.withSessionTurnLease)(sessionPath, async (lease) => {
490
+ privateFile(sessionPath, "session", SESSION_LIMIT);
491
+ const current = (0, session_transaction_1.readSessionTransaction)(sessionPath, lease);
492
+ if (current.revision !== manifest.preimageRevision) {
493
+ let envelope;
494
+ try {
495
+ envelope = rawEnvelope(current.bytes);
496
+ }
497
+ catch {
498
+ return { status: "indeterminate" };
499
+ }
500
+ if (alreadyApplied(envelope, manifest, current.revision))
501
+ return { status: "already_applied", revision: current.revision };
502
+ if (!envelope.events.some((event) => event.relations.redactsEventId !== null))
503
+ refuse("session preimage revision changed");
504
+ return { status: "indeterminate" };
505
+ }
506
+ const computed = compute(current.bytes, manifest.sessionRelativePath, manifest.capturedAt);
507
+ if (!(0, node_util_1.isDeepStrictEqual)(computed.manifest, manifest))
508
+ refuse("manifest differs from independently computed repair");
509
+ attemptedWrite = true;
510
+ return reconcileWrite(sessionPath, lease, computed.postimage, manifest.preimageRevision, manifest.postimageRevision, "applied");
511
+ }, { confinementRoot: root });
512
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.session_redaction_repair_applied", message: "fixed repair apply readback classified", meta: { status: result.status } });
513
+ return result;
514
+ }
515
+ catch (error) {
516
+ if (attemptedWrite)
517
+ return { status: "indeterminate" };
518
+ throw error;
519
+ }
520
+ }
521
+ async function rollbackA003SessionRepair(authority) {
522
+ const manifest = readManifest(authority);
523
+ const preimage = readArtifact(authority.preimagePath, "preimage", SESSION_LIMIT);
524
+ if (sha(preimage) !== manifest.preimageRevision)
525
+ refuse("preimage digest mismatch");
526
+ const computed = compute(preimage.toString("utf8"), manifest.sessionRelativePath, manifest.capturedAt);
527
+ if (!(0, node_util_1.isDeepStrictEqual)(computed.manifest, manifest))
528
+ refuse("rollback manifest differs from preimage");
529
+ const value = JSON.parse(preimage.toString("utf8"));
530
+ const sessionPath = manifestSessionPath(manifest.sessionRelativePath);
531
+ const { root } = sessionLocation("sanctuary", sessionPath);
532
+ let attemptedWrite = false;
533
+ try {
534
+ const result = await (0, session_transaction_1.withSessionTurnLease)(sessionPath, async (lease) => {
535
+ privateFile(sessionPath, "session", SESSION_LIMIT);
536
+ const current = (0, session_transaction_1.readSessionTransaction)(sessionPath, lease);
537
+ if (current.revision === manifest.preimageRevision)
538
+ return { status: "already_rolled_back", revision: current.revision };
539
+ if (current.revision !== manifest.postimageRevision)
540
+ refuse("rollback requires the exact untouched postimage");
541
+ attemptedWrite = true;
542
+ return reconcileWrite(sessionPath, lease, value, manifest.postimageRevision, manifest.preimageRevision, "rolled_back");
543
+ }, { confinementRoot: root });
544
+ (0, runtime_1.emitNervesEvent)({ component: "heart", event: "heart.session_redaction_repair_rolled_back", message: "fixed repair rollback readback classified", meta: { status: result.status } });
545
+ return result;
546
+ }
547
+ catch (error) {
548
+ if (attemptedWrite)
549
+ return { status: "indeterminate" };
550
+ throw error;
551
+ }
552
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const session_stats_1 = require("./session-stats");
4
+ const code = (0, session_stats_1.runSessionStatsCli)(process.argv.slice(2));
5
+ process.exit(code);