@ouro.bot/cli 0.1.0-alpha.95 → 0.1.0-alpha.950

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 (755) 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 +6015 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1274 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1586 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +399 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +201 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +497 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2356 -586
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +474 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +881 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9235 -0
  148. package/dist/heart/daemon/cli-help.js +742 -0
  149. package/dist/heart/daemon/cli-parse.js +3236 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2360
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2110 -104
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +9 -3
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1282 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +786 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1523 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +271 -0
  244. package/dist/heart/frontend-socket-client.js +173 -0
  245. package/dist/heart/frontend-socket.js +434 -0
  246. package/dist/heart/frontend-turn-errors.js +20 -0
  247. package/dist/heart/habits/habit-cancel.js +810 -0
  248. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  249. package/dist/heart/habits/habit-migration.js +194 -0
  250. package/dist/heart/habits/habit-parser.js +278 -0
  251. package/dist/heart/habits/habit-runtime-state.js +93 -0
  252. package/dist/heart/habits/habit-scheduler.js +653 -0
  253. package/dist/heart/habits/habit-session-summary.js +318 -0
  254. package/dist/heart/habits/habit-session.js +636 -0
  255. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  256. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  257. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  258. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  259. package/dist/heart/identity.js +239 -59
  260. package/dist/heart/kept-notes.js +289 -0
  261. package/dist/heart/kicks.js +1 -1
  262. package/dist/heart/machine-identity.js +175 -0
  263. package/dist/heart/mail-import-discovery.js +356 -0
  264. package/dist/heart/mailbox/mailbox-http-hooks.js +99 -0
  265. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  266. package/dist/heart/mailbox/mailbox-http-routes.js +406 -0
  267. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  268. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  269. package/dist/heart/mailbox/mailbox-http.js +99 -0
  270. package/dist/heart/mailbox/mailbox-read.js +41 -0
  271. package/dist/heart/mailbox/mailbox-supervision.js +131 -0
  272. package/dist/heart/mailbox/mailbox-types.js +27 -0
  273. package/dist/heart/mailbox/mailbox-view.js +197 -0
  274. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  275. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  276. package/dist/heart/mailbox/readers/mail.js +375 -0
  277. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  278. package/dist/heart/mailbox/readers/sessions.js +231 -0
  279. package/dist/heart/mailbox/readers/shared.js +111 -0
  280. package/dist/heart/mcp/mcp-server.js +760 -0
  281. package/dist/heart/migrate-config.js +100 -0
  282. package/dist/heart/model-capabilities.js +83 -16
  283. package/dist/heart/orientation-frame.js +345 -0
  284. package/dist/heart/platform.js +81 -0
  285. package/dist/heart/primitives.js +1 -1
  286. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  287. package/dist/heart/private-runtime/index.js +18 -0
  288. package/dist/heart/private-runtime/ledger.js +221 -0
  289. package/dist/heart/private-runtime/policy.js +260 -0
  290. package/dist/heart/private-runtime/types.js +2 -0
  291. package/dist/heart/progress-story.js +1 -1
  292. package/dist/heart/provider-attempt.js +137 -0
  293. package/dist/heart/provider-binding-resolver.js +273 -0
  294. package/dist/heart/provider-credentials.js +449 -0
  295. package/dist/heart/provider-failover.js +311 -0
  296. package/dist/heart/provider-models.js +96 -0
  297. package/dist/heart/provider-ping.js +265 -0
  298. package/dist/heart/provider-readiness-cache.js +119 -0
  299. package/dist/heart/provider-visibility.js +188 -0
  300. package/dist/heart/providers/anthropic-token.js +131 -0
  301. package/dist/heart/providers/anthropic.js +176 -60
  302. package/dist/heart/providers/azure.js +23 -11
  303. package/dist/heart/providers/error-classification.js +129 -0
  304. package/dist/heart/providers/github-copilot.js +38 -39
  305. package/dist/heart/providers/minimax-vlm.js +189 -0
  306. package/dist/heart/providers/minimax.js +26 -8
  307. package/dist/heart/providers/openai-codex-token.js +349 -0
  308. package/dist/heart/providers/openai-codex.js +55 -40
  309. package/dist/heart/providers/openai-compatible.js +177 -0
  310. package/dist/heart/reach-channel.js +85 -0
  311. package/dist/heart/reply-style.js +52 -0
  312. package/dist/heart/run-ledger.js +247 -0
  313. package/dist/heart/runtime-capability-check.js +170 -0
  314. package/dist/heart/runtime-credentials.js +607 -0
  315. package/dist/heart/runtime-cwd.js +87 -0
  316. package/dist/heart/sense-truth.js +24 -4
  317. package/dist/heart/session-activity.js +94 -24
  318. package/dist/heart/session-events.js +1521 -0
  319. package/dist/heart/session-playback-cli-main.js +5 -0
  320. package/dist/heart/session-playback-cli.js +36 -0
  321. package/dist/heart/session-playback.js +231 -0
  322. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  323. package/dist/heart/session-redaction-repair.js +552 -0
  324. package/dist/heart/session-stats-cli-main.js +5 -0
  325. package/dist/heart/session-stats.js +183 -0
  326. package/dist/heart/session-transcript.js +133 -0
  327. package/dist/heart/shelf-claims.js +78 -0
  328. package/dist/heart/shepherd/custody-types.js +2 -0
  329. package/dist/heart/shepherd/mandates.js +352 -0
  330. package/dist/heart/shepherd/operation-commands.js +19 -0
  331. package/dist/heart/shepherd/operations.js +135 -0
  332. package/dist/heart/shepherd/supervision.js +114 -0
  333. package/dist/heart/shepherd/types.js +2 -0
  334. package/dist/heart/shepherd-config.js +113 -0
  335. package/dist/heart/source-grounding.js +297 -0
  336. package/dist/heart/start-of-turn-packet.js +372 -0
  337. package/dist/heart/steward-policy.js +656 -0
  338. package/dist/heart/streaming.js +631 -207
  339. package/dist/heart/structured-output.js +196 -0
  340. package/dist/heart/sync-classification.js +176 -0
  341. package/dist/heart/sync-health.js +152 -0
  342. package/dist/heart/sync.js +726 -0
  343. package/dist/heart/target-resolution.js +11 -7
  344. package/dist/heart/tempo.js +93 -0
  345. package/dist/heart/temporal-view.js +41 -0
  346. package/dist/heart/timeouts.js +101 -0
  347. package/dist/heart/tool-activity-callbacks.js +59 -0
  348. package/dist/heart/tool-approval.js +382 -0
  349. package/dist/heart/tool-description.js +155 -0
  350. package/dist/heart/tool-friction.js +55 -0
  351. package/dist/heart/tool-loop.js +206 -0
  352. package/dist/heart/turn-context.js +496 -0
  353. package/dist/heart/turn-execution-lease.js +30 -0
  354. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  355. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  356. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  357. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  358. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  359. package/dist/heart/versioning/release-sources.js +173 -0
  360. package/dist/heart/versioning/self-update-defaults.js +294 -0
  361. package/dist/heart/versioning/self-update.js +196 -0
  362. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  363. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  364. package/dist/heart/versioning/update-hooks.js +154 -0
  365. package/dist/heart/versioning/update-state.js +126 -0
  366. package/dist/heart/versioning/updater-launchd.js +150 -0
  367. package/dist/heart/versioning/version-intent.js +114 -0
  368. package/dist/heart/work-card.js +380 -0
  369. package/dist/mailbox-ui/assets/index-Dbska1tZ.js +1 -0
  370. package/dist/mailbox-ui/assets/index-DsiKaPyH.css +1 -0
  371. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  372. package/dist/mailbox-ui/index.html +16 -0
  373. package/dist/mailroom/attention.js +167 -0
  374. package/dist/mailroom/autonomy.js +209 -0
  375. package/dist/mailroom/blob-store.js +889 -0
  376. package/dist/mailroom/body-cache.js +61 -0
  377. package/dist/mailroom/cache-sync-cli.js +58 -0
  378. package/dist/mailroom/core.js +803 -0
  379. package/dist/mailroom/entry.js +160 -0
  380. package/dist/mailroom/file-store.js +568 -0
  381. package/dist/mailroom/hosted-cache-sync.js +384 -0
  382. package/dist/mailroom/mbox-import.js +393 -0
  383. package/dist/mailroom/migration.js +164 -0
  384. package/dist/mailroom/outbound.js +380 -0
  385. package/dist/mailroom/policy.js +263 -0
  386. package/dist/mailroom/reader.js +292 -0
  387. package/dist/mailroom/search-cache.js +513 -0
  388. package/dist/mailroom/search-relevance.js +319 -0
  389. package/dist/mailroom/smtp-ingress.js +176 -0
  390. package/dist/mailroom/source-state.js +176 -0
  391. package/dist/mailroom/thread.js +109 -0
  392. package/dist/mailroom/travel-extract.js +89 -0
  393. package/dist/mind/bundle-manifest.js +24 -2
  394. package/dist/mind/context.js +328 -139
  395. package/dist/mind/desk-section.js +362 -0
  396. package/dist/mind/diary-integrity.js +60 -0
  397. package/dist/mind/{memory.js → diary.js} +68 -77
  398. package/dist/mind/embedding-provider.js +60 -0
  399. package/dist/mind/file-state.js +179 -0
  400. package/dist/mind/friend-link-codes.js +209 -0
  401. package/dist/mind/friend-merge.js +330 -0
  402. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  403. package/dist/mind/obligation-steering.js +199 -3
  404. package/dist/mind/outbound-record.js +165 -0
  405. package/dist/mind/pending.js +36 -10
  406. package/dist/mind/prompt-budget.js +479 -0
  407. package/dist/mind/prompt-refresh.js +3 -2
  408. package/dist/mind/prompt.js +1085 -198
  409. package/dist/mind/provenance-trust.js +26 -0
  410. package/dist/mind/record-paths.js +312 -0
  411. package/dist/mind/scrutiny.js +173 -0
  412. package/dist/mind/session-transaction.js +622 -0
  413. package/dist/nerves/cli-logging.js +7 -1
  414. package/dist/nerves/coverage/audit-rules.js +15 -6
  415. package/dist/nerves/coverage/audit.js +28 -2
  416. package/dist/nerves/coverage/cli.js +1 -1
  417. package/dist/nerves/coverage/contract.js +5 -5
  418. package/dist/nerves/coverage/file-completeness.js +143 -5
  419. package/dist/nerves/coverage/run-artifacts.js +55 -35
  420. package/dist/nerves/coverage/source-scanner.js +4 -4
  421. package/dist/nerves/event-buffer.js +111 -0
  422. package/dist/nerves/index.js +293 -9
  423. package/dist/nerves/observation.js +20 -0
  424. package/dist/nerves/redact.js +79 -0
  425. package/dist/nerves/review/cli-main.js +5 -0
  426. package/dist/nerves/review/cli.js +156 -0
  427. package/dist/nerves/review/core.js +159 -0
  428. package/dist/nerves/runtime.js +17 -1
  429. package/dist/repertoire/ado-client.js +15 -56
  430. package/dist/repertoire/ado-semantic.js +16 -10
  431. package/dist/repertoire/api-client.js +97 -0
  432. package/dist/repertoire/bitwarden-store.js +1201 -0
  433. package/dist/repertoire/bundle-templates.js +71 -0
  434. package/dist/repertoire/bw-installer.js +231 -0
  435. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  436. package/dist/repertoire/coding/context-pack.js +331 -0
  437. package/dist/repertoire/coding/feedback.js +174 -32
  438. package/dist/repertoire/coding/index.js +15 -3
  439. package/dist/repertoire/coding/manager.js +159 -10
  440. package/dist/repertoire/coding/spawner.js +40 -11
  441. package/dist/repertoire/coding/tools.js +182 -18
  442. package/dist/repertoire/coding/workbench-client.js +272 -0
  443. package/dist/repertoire/coding/workbench-manager.js +346 -0
  444. package/dist/repertoire/commerce-errors.js +109 -0
  445. package/dist/repertoire/commerce-self-test.js +156 -0
  446. package/dist/repertoire/credential-access.js +183 -0
  447. package/dist/repertoire/desk/classifier.js +362 -0
  448. package/dist/repertoire/duffel-client.js +185 -0
  449. package/dist/repertoire/github-client.js +14 -55
  450. package/dist/repertoire/graph-client.js +11 -52
  451. package/dist/repertoire/guardrails.js +971 -20
  452. package/dist/repertoire/house-sweep.js +469 -0
  453. package/dist/repertoire/mcp-client.js +58 -5
  454. package/dist/repertoire/mcp-manager.js +427 -139
  455. package/dist/repertoire/mcp-tools.js +132 -0
  456. package/dist/repertoire/mcp-write-guard.js +46 -0
  457. package/dist/repertoire/plugin-mcp.js +175 -0
  458. package/dist/repertoire/plugins.js +253 -0
  459. package/dist/repertoire/relationship-authorization.js +322 -0
  460. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  461. package/dist/repertoire/shell-sessions.js +134 -0
  462. package/dist/repertoire/skills.js +48 -4
  463. package/dist/repertoire/stripe-client.js +131 -0
  464. package/dist/repertoire/tool-arguments.js +182 -0
  465. package/dist/repertoire/tool-results.js +29 -0
  466. package/dist/repertoire/tools-a2a.js +699 -0
  467. package/dist/repertoire/tools-attachments.js +322 -0
  468. package/dist/repertoire/tools-awaiting.js +872 -0
  469. package/dist/repertoire/tools-base.js +83 -1168
  470. package/dist/repertoire/tools-bluebubbles.js +2 -0
  471. package/dist/repertoire/tools-bridge.js +144 -0
  472. package/dist/repertoire/tools-bundle.js +995 -0
  473. package/dist/repertoire/tools-commerce.js +253 -0
  474. package/dist/repertoire/tools-config.js +186 -0
  475. package/dist/repertoire/tools-continuity.js +582 -0
  476. package/dist/repertoire/tools-credential.js +383 -0
  477. package/dist/repertoire/tools-escalation.js +84 -0
  478. package/dist/repertoire/tools-evolution.js +527 -0
  479. package/dist/repertoire/tools-files.js +344 -0
  480. package/dist/repertoire/tools-flight.js +290 -0
  481. package/dist/repertoire/tools-flow.js +119 -0
  482. package/dist/repertoire/tools-friend-link.js +57 -0
  483. package/dist/repertoire/tools-github.js +3 -8
  484. package/dist/repertoire/tools-habits.js +103 -0
  485. package/dist/repertoire/tools-house-care.js +174 -0
  486. package/dist/repertoire/tools-mail.js +1828 -0
  487. package/dist/repertoire/tools-notes.js +501 -0
  488. package/dist/repertoire/tools-obligations.js +182 -0
  489. package/dist/repertoire/tools-orientation.js +31 -0
  490. package/dist/repertoire/tools-record.js +482 -0
  491. package/dist/repertoire/tools-rsvp.js +139 -0
  492. package/dist/repertoire/tools-runtime.js +238 -0
  493. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  494. package/dist/repertoire/tools-session.js +1141 -0
  495. package/dist/repertoire/tools-shell.js +154 -0
  496. package/dist/repertoire/tools-shepherd-guidance.js +171 -0
  497. package/dist/repertoire/tools-shepherd.js +323 -0
  498. package/dist/repertoire/tools-steward-policy.js +147 -0
  499. package/dist/repertoire/tools-stripe.js +224 -0
  500. package/dist/repertoire/tools-surface.js +369 -0
  501. package/dist/repertoire/tools-teams.js +50 -39
  502. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  503. package/dist/repertoire/tools-travel.js +125 -0
  504. package/dist/repertoire/tools-trip.js +982 -0
  505. package/dist/repertoire/tools-unraid.js +556 -0
  506. package/dist/repertoire/tools-user-profile.js +146 -0
  507. package/dist/repertoire/tools-vault.js +40 -0
  508. package/dist/repertoire/tools-voice-local.js +198 -0
  509. package/dist/repertoire/tools-voice.js +145 -0
  510. package/dist/repertoire/tools.js +518 -156
  511. package/dist/repertoire/travel-api-client.js +360 -0
  512. package/dist/repertoire/unraid-client.js +155 -0
  513. package/dist/repertoire/unraid-restart.js +339 -0
  514. package/dist/repertoire/user-profile.js +131 -0
  515. package/dist/repertoire/vault-setup.js +246 -0
  516. package/dist/repertoire/vault-unlock.js +686 -0
  517. package/dist/rsvp/aisleplanner-client.js +354 -0
  518. package/dist/rsvp/cli.js +936 -0
  519. package/dist/rsvp/config.js +327 -0
  520. package/dist/rsvp/cutover.js +433 -0
  521. package/dist/rsvp/diagnostics.js +232 -0
  522. package/dist/rsvp/diff-renderer.js +176 -0
  523. package/dist/rsvp/habit-policy.js +110 -0
  524. package/dist/rsvp/habit-stage.js +123 -0
  525. package/dist/rsvp/incident-bundle.js +97 -0
  526. package/dist/rsvp/migration.js +204 -0
  527. package/dist/rsvp/native-habit-runner.js +630 -0
  528. package/dist/rsvp/outbound-state.js +628 -0
  529. package/dist/rsvp/query.js +118 -0
  530. package/dist/rsvp/replay.js +233 -0
  531. package/dist/rsvp/snapshot.js +232 -0
  532. package/dist/rsvp/spend-ledger.js +175 -0
  533. package/dist/scripts/claude-code-hook.js +41 -0
  534. package/dist/scripts/claude-code-stop-hook.js +47 -0
  535. package/dist/senses/a2a-entry.js +132 -0
  536. package/dist/senses/acp-server.js +386 -0
  537. package/dist/senses/attention-queue.js +186 -0
  538. package/dist/senses/await-turn-message.js +65 -0
  539. package/dist/senses/bluebubbles/active-turns.js +216 -0
  540. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  541. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  542. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +385 -43
  543. package/dist/senses/bluebubbles/context-packet.js +207 -0
  544. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  545. package/dist/senses/bluebubbles/entry.js +90 -0
  546. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  547. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  548. package/dist/senses/bluebubbles/index.js +3940 -0
  549. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  550. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  551. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  552. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  553. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  554. package/dist/senses/bluebubbles/processed-log.js +133 -0
  555. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  556. package/dist/senses/bluebubbles/replay.js +284 -0
  557. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  558. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  559. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  560. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  561. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  562. package/dist/senses/cli/bracketed-paste.js +82 -0
  563. package/dist/senses/cli/image-paste.js +287 -0
  564. package/dist/senses/cli/image-ref-navigation.js +75 -0
  565. package/dist/senses/cli/ink-app.js +156 -0
  566. package/dist/senses/cli/inline-diff.js +64 -0
  567. package/dist/senses/cli/input-keys.js +174 -0
  568. package/dist/senses/cli/kill-ring.js +86 -0
  569. package/dist/senses/cli/message-list.js +51 -0
  570. package/dist/senses/cli/ouro-tui.js +607 -0
  571. package/dist/senses/cli/spinner-imperative.js +135 -0
  572. package/dist/senses/cli/spinner.js +101 -0
  573. package/dist/senses/cli/status-line.js +60 -0
  574. package/dist/senses/cli/streaming-markdown.js +526 -0
  575. package/dist/senses/cli/tool-display.js +85 -0
  576. package/dist/senses/cli/tool-render.js +85 -0
  577. package/dist/senses/cli/tui-store.js +241 -0
  578. package/dist/senses/cli/virtual-list.js +35 -0
  579. package/dist/senses/cli-entry.js +60 -8
  580. package/dist/senses/cli.js +570 -309
  581. package/dist/senses/commands.js +66 -3
  582. package/dist/senses/context-packet-ledger.js +371 -0
  583. package/dist/senses/context-packets.js +154 -0
  584. package/dist/senses/habit-lifecycle-guard.js +24 -0
  585. package/dist/senses/habit-turn-message.js +160 -0
  586. package/dist/senses/ingress-evidence.js +2 -0
  587. package/dist/senses/mail-entry.js +66 -0
  588. package/dist/senses/mail.js +524 -0
  589. package/dist/senses/pipeline.js +1158 -204
  590. package/dist/senses/private-runtime-worker.js +805 -0
  591. package/dist/senses/private-runtime.js +1627 -0
  592. package/dist/senses/proactive-content-guard.js +51 -0
  593. package/dist/senses/root-host-approval-port.js +345 -0
  594. package/dist/senses/root-host-approval-runtime.js +393 -0
  595. package/dist/senses/sanctuary-authority-resident.js +102 -0
  596. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  597. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  598. package/dist/senses/sanctuary-grounding.js +118 -0
  599. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  600. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  601. package/dist/senses/sanctuary-health-runner.js +104 -0
  602. package/dist/senses/sanctuary-health.js +422 -0
  603. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  604. package/dist/senses/sanctuary-interactive-control.js +410 -0
  605. package/dist/senses/sanctuary-media-catalog-contract.js +268 -0
  606. package/dist/senses/sanctuary-media-optimization.js +514 -0
  607. package/dist/senses/sanctuary-runtime.js +369 -0
  608. package/dist/senses/sanctuary-sab.js +85 -0
  609. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  610. package/dist/senses/shared-turn.js +804 -0
  611. package/dist/senses/shepherd/agent-presentation.js +88 -0
  612. package/dist/senses/shepherd/attention-page.js +166 -0
  613. package/dist/senses/shepherd/attention-sidebar.js +76 -0
  614. package/dist/senses/shepherd/attention.js +295 -0
  615. package/dist/senses/shepherd/checkin-config.js +76 -0
  616. package/dist/senses/shepherd/checkin-store.js +386 -0
  617. package/dist/senses/shepherd/client.js +196 -0
  618. package/dist/senses/shepherd/cmux.js +483 -0
  619. package/dist/senses/shepherd/composer.js +336 -0
  620. package/dist/senses/shepherd/feedback-reply.js +108 -0
  621. package/dist/senses/shepherd/feedback-source.js +20 -0
  622. package/dist/senses/shepherd/feedback-store.js +331 -0
  623. package/dist/senses/shepherd/feedback-submit.js +182 -0
  624. package/dist/senses/shepherd/feedback-worker.js +208 -0
  625. package/dist/senses/shepherd/guidance.js +273 -0
  626. package/dist/senses/shepherd/herdr.js +427 -0
  627. package/dist/senses/shepherd/host.js +14 -0
  628. package/dist/senses/shepherd/human-decision-guard.js +29 -0
  629. package/dist/senses/shepherd/judge-evaluation-command.js +183 -0
  630. package/dist/senses/shepherd/judge-evaluation-entry.js +13 -0
  631. package/dist/senses/shepherd/judge-evaluation.js +155 -0
  632. package/dist/senses/shepherd/judge.js +202 -0
  633. package/dist/senses/shepherd/notice-outbox.js +262 -0
  634. package/dist/senses/shepherd/observation-publisher.js +320 -0
  635. package/dist/senses/shepherd/operations-defaults.js +86 -0
  636. package/dist/senses/shepherd/operations.js +159 -0
  637. package/dist/senses/shepherd/owner-notice.js +465 -0
  638. package/dist/senses/shepherd/prompt-state.js +60 -0
  639. package/dist/senses/shepherd/recovery.js +543 -0
  640. package/dist/senses/shepherd/redact.js +66 -0
  641. package/dist/senses/shepherd/returns.js +79 -0
  642. package/dist/senses/shepherd/sense.js +821 -0
  643. package/dist/senses/shepherd/shepherd-judge-corpus-v1.json +170 -0
  644. package/dist/senses/shepherd/surface.js +123 -0
  645. package/dist/senses/shepherd/target-binding.js +13 -0
  646. package/dist/senses/shepherd/terminal-process.js +147 -0
  647. package/dist/senses/shepherd-entry.js +98 -0
  648. package/dist/senses/surface-tool.js +109 -0
  649. package/dist/senses/teams-entry.js +68 -8
  650. package/dist/senses/teams-image.js +119 -0
  651. package/dist/senses/teams.js +949 -337
  652. package/dist/senses/telegram-admission.js +718 -0
  653. package/dist/senses/telegram-approval-runtime.js +793 -0
  654. package/dist/senses/telegram-attachments.js +186 -0
  655. package/dist/senses/telegram-audit-ledger.js +220 -0
  656. package/dist/senses/telegram-authority-transport.js +231 -0
  657. package/dist/senses/telegram-client.js +1749 -0
  658. package/dist/senses/telegram-effect-adapter.js +904 -0
  659. package/dist/senses/telegram-entry.js +83 -0
  660. package/dist/senses/telegram-handoff.js +80 -0
  661. package/dist/senses/telegram.js +2435 -0
  662. package/dist/senses/trust-gate.js +104 -9
  663. package/dist/senses/voice/audio-playback.js +237 -0
  664. package/dist/senses/voice/audio-routing.js +119 -0
  665. package/dist/senses/voice/call-auth.js +250 -0
  666. package/dist/senses/voice/elevenlabs.js +202 -0
  667. package/dist/senses/voice/floor-control.js +431 -0
  668. package/dist/senses/voice/floor-controller.js +115 -0
  669. package/dist/senses/voice/golden-path.js +116 -0
  670. package/dist/senses/voice/index.js +29 -0
  671. package/dist/senses/voice/local-audio-control.js +344 -0
  672. package/dist/senses/voice/local-audio-devices.js +516 -0
  673. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  674. package/dist/senses/voice/local-audio-identity.js +103 -0
  675. package/dist/senses/voice/local-audio-join.js +325 -0
  676. package/dist/senses/voice/local-audio-mute.js +199 -0
  677. package/dist/senses/voice/local-audio-notify.js +124 -0
  678. package/dist/senses/voice/local-audio-prompts.js +116 -0
  679. package/dist/senses/voice/local-audio-transport.js +427 -0
  680. package/dist/senses/voice/local-audio.js +281 -0
  681. package/dist/senses/voice/local-media-stream.js +145 -0
  682. package/dist/senses/voice/meeting.js +113 -0
  683. package/dist/senses/voice/outbound.js +190 -0
  684. package/dist/senses/voice/phone.js +33 -0
  685. package/dist/senses/voice/playback.js +139 -0
  686. package/dist/senses/voice/process-guards.js +51 -0
  687. package/dist/senses/voice/realtime-eval.js +496 -0
  688. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  689. package/dist/senses/voice/realtime-trace.js +531 -0
  690. package/dist/senses/voice/transcript.js +70 -0
  691. package/dist/senses/voice/turn.js +191 -0
  692. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  693. package/dist/senses/voice/twilio-phone.js +5454 -0
  694. package/dist/senses/voice/types.js +2 -0
  695. package/dist/senses/voice/whisper.js +161 -0
  696. package/dist/senses/voice-entry.js +83 -0
  697. package/dist/senses/voice-realtime-eval-command.js +99 -0
  698. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  699. package/dist/senses/voice-twilio-entry.js +87 -0
  700. package/dist/trips/core.js +138 -0
  701. package/dist/trips/store.js +265 -0
  702. package/dist/util/frontmatter.js +69 -0
  703. package/npm-shrinkwrap.json +8165 -0
  704. package/package.json +75 -13
  705. package/skills/agent-commerce.md +113 -0
  706. package/skills/browser-navigation.md +117 -0
  707. package/skills/commerce-setup-guide.md +116 -0
  708. package/skills/commerce-setup.md +84 -0
  709. package/skills/configure-dev-tools.md +99 -0
  710. package/skills/travel-planning.md +138 -0
  711. package/dist/heart/daemon/auth-flow.js +0 -430
  712. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  713. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  714. package/dist/heart/daemon/update-hooks.js +0 -138
  715. package/dist/heart/obligations.js +0 -191
  716. package/dist/heart/safe-workspace.js +0 -362
  717. package/dist/heart/session-recall.js +0 -116
  718. package/dist/mind/friends/channel.js +0 -84
  719. package/dist/mind/friends/group-context.js +0 -144
  720. package/dist/mind/friends/resolver.js +0 -84
  721. package/dist/mind/friends/store-file.js +0 -190
  722. package/dist/mind/friends/store.js +0 -4
  723. package/dist/mind/friends/tokens.js +0 -26
  724. package/dist/mind/friends/trust-explanation.js +0 -74
  725. package/dist/mind/friends/types.js +0 -29
  726. package/dist/repertoire/tasks/board.js +0 -134
  727. package/dist/repertoire/tasks/index.js +0 -224
  728. package/dist/repertoire/tasks/lifecycle.js +0 -80
  729. package/dist/repertoire/tasks/middleware.js +0 -65
  730. package/dist/repertoire/tasks/parser.js +0 -173
  731. package/dist/repertoire/tasks/scanner.js +0 -132
  732. package/dist/repertoire/tasks/transitions.js +0 -144
  733. package/dist/senses/bluebubbles-entry.js +0 -13
  734. package/dist/senses/bluebubbles.js +0 -1181
  735. package/dist/senses/debug-activity.js +0 -154
  736. package/dist/senses/inner-dialog-worker.js +0 -90
  737. package/dist/senses/inner-dialog.js +0 -525
  738. package/subagents/README.md +0 -7
  739. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  740. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  741. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  742. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  743. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  744. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  745. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  746. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  747. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  748. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  749. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  750. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  751. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  752. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  753. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  754. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  755. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,543 @@
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.readCheckInSnapshot = readCheckInSnapshot;
37
+ exports.readMaintenanceCheckInSnapshot = readMaintenanceCheckInSnapshot;
38
+ exports.reconcileShepherdDispatch = reconcileShepherdDispatch;
39
+ exports.maintainShepherdCustody = maintainShepherdCustody;
40
+ const node_crypto_1 = require("node:crypto");
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const file_lock_1 = require("../../heart/file-lock");
44
+ const runtime_1 = require("../../nerves/runtime");
45
+ const checkin_store_1 = require("./checkin-store");
46
+ const redact_1 = require("./redact");
47
+ const refuse = checkin_store_1.refuseCustody;
48
+ const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
49
+ const identity = (value) => typeof value === "string" && value.length > 0 && value.length <= 256 && value === value.trim() && !/[\x00-\x1f\x7f-\x9f]/.test(value);
50
+ const timestamp = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
51
+ const digest = (value) => (0, node_crypto_1.createHash)("sha256").update(value).digest("hex");
52
+ function canonical(value) {
53
+ return JSON.stringify(value, (_name, item) => object(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))) : item);
54
+ }
55
+ function validActor(request) {
56
+ return object(request.actor) && request.actor.kind === "local_owner_administration" && identity(request.actor.actorId)
57
+ && identity(request.requestId) && typeof request.expectedRevision === "number" && Number.isSafeInteger(request.expectedRevision) && request.expectedRevision >= 0;
58
+ }
59
+ function fresh(value) {
60
+ return timestamp(value) && Date.parse(value) <= Date.now() && Date.now() - Date.parse(value) <= 30_000;
61
+ }
62
+ function validRetirementShape(value) {
63
+ return object(value) && value.kind === "host_process_inventory" && identity(value.host) && identity(value.session)
64
+ && (value.instance === null || identity(value.instance)) && timestamp(value.checkedAt) && value.gone === true && typeof value.wholeSessionRetired === "boolean";
65
+ }
66
+ const validRetirement = (value) => validRetirementShape(value) && fresh(value.checkedAt);
67
+ function copyRetirement(proof) {
68
+ const { kind, host, session, instance, checkedAt, gone, wholeSessionRetired } = proof;
69
+ return { kind, host, session, instance, checkedAt, gone, wholeSessionRetired };
70
+ }
71
+ function parseJson(value, maxBytes = 8192) {
72
+ if (Buffer.byteLength(value) > maxBytes)
73
+ refuse("recovery record byte limit");
74
+ return JSON.parse(value);
75
+ }
76
+ function validRecoveryReceipt(value) {
77
+ return object(value) && Number.isSafeInteger(value.revision) && Number(value.revision) > 0 && identity(value.dispatchId)
78
+ && ["acknowledged_delivery", "retired_instance"].includes(String(value.resolution))
79
+ && ["claimed", "sent", "unknown"].includes(String(value.originalState)) && timestamp(value.at) && identity(value.actorId) && identity(value.requestId);
80
+ }
81
+ function auditRow(data) {
82
+ const parsed = parseJson(data);
83
+ if (!object(parsed) || !validRecoveryReceipt(parsed.receipt))
84
+ refuse("invalid recovery audit schema");
85
+ return { receipt: parsed.receipt, evidence: parsed.evidence };
86
+ }
87
+ function reconciliationRows(db, claim) {
88
+ const dispatchId = claim.id;
89
+ const count = db.prepare("SELECT COUNT(*) AS count FROM reconciliations WHERE dispatch_id=?").get(dispatchId);
90
+ const rows = db.prepare("SELECT data FROM reconciliations WHERE dispatch_id=? ORDER BY rowid DESC LIMIT 20").all(dispatchId);
91
+ let receipt = null;
92
+ const receipts = rows.map(row => {
93
+ const audit = auditRow(row.data);
94
+ if (audit.receipt.dispatchId !== dispatchId)
95
+ refuse("recovery dispatch identity mismatch");
96
+ if (audit.receipt.resolution === "acknowledged_delivery") {
97
+ if (!matchesReceipt(claim, audit.evidence, false))
98
+ refuse("invalid recovery host receipt schema");
99
+ receipt ??= (0, checkin_store_1.copyCustodyInputReceipt)(audit.evidence.receipt);
100
+ }
101
+ else if (!validRetirementShape(audit.evidence) || audit.evidence.host !== claim.host || audit.evidence.session !== claim.session
102
+ || audit.evidence.instance !== claim.instance || audit.evidence.instance === null && !audit.evidence.wholeSessionRetired) {
103
+ refuse("invalid recovery retirement proof schema");
104
+ }
105
+ return audit.receipt;
106
+ });
107
+ return { receipts, count: count.count, receipt };
108
+ }
109
+ function readCheckInSnapshot(file, options) {
110
+ return readCustodySnapshot(file, options, "read");
111
+ }
112
+ /** Recovery may inspect a held marker only after trusted daemon quiescence; this never opens a writer. */
113
+ function readMaintenanceCheckInSnapshot(file, options, sense) {
114
+ requireStoppedSense({ sense });
115
+ return readCustodySnapshot(file, options, "maintenance-read");
116
+ }
117
+ function readCustodySnapshot(file, options, mode) {
118
+ if (!Number.isSafeInteger(options.limit) || options.limit < 1 || options.limit > 200)
119
+ refuse("inspection limit must be 1..200");
120
+ if (options.id !== undefined && (!/^[a-f0-9]{64}$/.test(options.id) || options.cursor !== undefined))
121
+ refuse("invalid inspection ID or conflicting cursor");
122
+ let cursor = null;
123
+ if (options.cursor !== undefined) {
124
+ let parsed;
125
+ try {
126
+ parsed = JSON.parse(Buffer.from(options.cursor, "base64url").toString("utf8"));
127
+ }
128
+ catch {
129
+ refuse("invalid inspection cursor");
130
+ }
131
+ if (options.cursor.length > 200 || !object(parsed) || typeof parsed.after !== "string" || !/^[a-f0-9]{64}$/.test(parsed.after)
132
+ || typeof parsed.revision !== "number" || !Number.isSafeInteger(parsed.revision) || parsed.revision < 0)
133
+ refuse("invalid inspection cursor");
134
+ cursor = { after: parsed.after, revision: parsed.revision };
135
+ }
136
+ const db = (0, checkin_store_1.openCustodyDatabase)(file, mode);
137
+ if (!db)
138
+ return {
139
+ state: "missing", schemaVersion: null, revision: null, bytes: null, capacity: "unknown",
140
+ totalCount: null, noticeCount: null, counts: null, entries: [], nextCursor: null,
141
+ };
142
+ try {
143
+ return db.transaction(() => {
144
+ const schemaVersion = Number(db.pragma("user_version", { simple: true }));
145
+ const revision = schemaVersion === 2 ? (0, checkin_store_1.custodyRevision)(db) : 0;
146
+ if (cursor && cursor.revision !== revision)
147
+ refuse("inspection cursor revision conflict");
148
+ const capacity = (0, checkin_store_1.custodyCapacity)(db);
149
+ const total = db.prepare("SELECT COUNT(*) AS count FROM dispatches").get();
150
+ const notices = db.prepare("SELECT COUNT(*) AS count FROM notices").get();
151
+ const grouped = db.prepare("SELECT json_extract(data,'$.state') AS state,COUNT(*) AS count FROM dispatches GROUP BY json_extract(data,'$.state')").all();
152
+ const counts = { claimed: 0, sent: 0, not_sent: 0, unknown: 0 };
153
+ for (const group of grouped) {
154
+ if (!["claimed", "sent", "not_sent", "unknown"].includes(group.state))
155
+ refuse("invalid custody state schema");
156
+ counts[group.state] = group.count;
157
+ }
158
+ const rows = (options.id !== undefined
159
+ ? db.prepare("SELECT id,host,session,instance,data FROM dispatches WHERE id=?").all(options.id)
160
+ : db.prepare("SELECT id,host,session,instance,data FROM dispatches WHERE id>? ORDER BY id LIMIT ?").all(cursor?.after ?? "", options.limit + 1));
161
+ const page = rows.slice(0, options.limit);
162
+ const entries = page.map(row => {
163
+ const claim = (0, checkin_store_1.parseCustodyDispatch)(row);
164
+ const audit = schemaVersion === 2 ? reconciliationRows(db, claim) : { receipts: [], count: 0, receipt: null };
165
+ const retired = schemaVersion === 2 && (0, checkin_store_1.hasRetiredCustodyInstance)(db, claim);
166
+ const entry = {
167
+ id: claim.id, host: claim.host, session: claim.session, instance: claim.instance, state: claim.state, trigger: claim.trigger,
168
+ claimedAt: claim.at, reason: claim.reason === undefined ? null : (0, redact_1.redactSecrets)(claim.reason), retired,
169
+ receipt: claim.receipt ? (0, checkin_store_1.copyCustodyInputReceipt)(claim.receipt) : audit.receipt, reconciliations: audit.receipts, reconciliationCount: audit.count,
170
+ };
171
+ return entry;
172
+ });
173
+ return {
174
+ state: "ready", schemaVersion, revision, ...capacity, totalCount: total.count, noticeCount: notices.count, counts, entries,
175
+ nextCursor: rows.length > options.limit ? Buffer.from(JSON.stringify({ after: page.at(-1).id, revision })).toString("base64url") : null,
176
+ };
177
+ })();
178
+ }
179
+ finally {
180
+ db.close();
181
+ }
182
+ }
183
+ function priorRequest(db, request, hash, validate) {
184
+ const row = db.prepare("SELECT hash,receipt FROM custody_requests WHERE actor_id=? AND request_id=?").get(request.actor.actorId, request.requestId);
185
+ if (!row)
186
+ return null;
187
+ if (row.hash !== hash)
188
+ refuse("owner request ID was already used with different arguments");
189
+ const receipt = parseJson(row.receipt);
190
+ if (!validate(receipt))
191
+ refuse("invalid owner request receipt schema");
192
+ return receipt;
193
+ }
194
+ function rememberRequest(db, request, hash, receipt) {
195
+ const serialized = JSON.stringify(receipt);
196
+ db.prepare("INSERT INTO custody_requests(actor_id,request_id,hash,receipt) VALUES(?,?,?,?)").run(request.actor.actorId, request.requestId, hash, serialized);
197
+ }
198
+ function retireInstance(db, proof, provenance, archive) {
199
+ if (proof.instance === null && !proof.wholeSessionRetired)
200
+ refuse("null instance requires whole session retirement proof");
201
+ const prior = (0, checkin_store_1.readRetiredCustodyRecord)(db, proof);
202
+ if (prior && !archive)
203
+ return;
204
+ if (prior?.archive !== undefined && canonical(prior.archive) !== canonical(archive))
205
+ refuse("retired instance archive reference already assigned; manual maintenance required");
206
+ if (Buffer.byteLength(JSON.stringify({ ...(prior ?? { proof, provenance }), ...(archive === undefined ? {} : { archive }) })) > 4096)
207
+ refuse("retired instance index capacity");
208
+ const data = JSON.stringify({ ...(prior ?? { proof: copyRetirement(proof), provenance }), ...(archive === undefined ? {} : { archive }) });
209
+ db.prepare(`INSERT INTO retired_instances(key,host,session,instance,data) VALUES(?,?,?,?,?)
210
+ ON CONFLICT(key) DO UPDATE SET data=excluded.data`).run((0, checkin_store_1.retiredCustodyKey)(proof), proof.host, proof.session, proof.instance, data);
211
+ }
212
+ function matchesReceipt(claim, evidence, requireFresh = true) {
213
+ return object(evidence) && evidence.kind === "guarded_host_receipt_v1" && timestamp(evidence.checkedAt) && (!requireFresh || fresh(evidence.checkedAt))
214
+ && evidence.host === claim.host && (0, checkin_store_1.validCustodyInputReceipt)(evidence.receipt)
215
+ && evidence.receipt.requestId === claim.id && evidence.receipt.surfaceId === claim.session
216
+ && evidence.receipt.processInstance === claim.instance && evidence.receipt.pasteAdmitted && evidence.receipt.submitAdmitted;
217
+ }
218
+ async function reconcileShepherdDispatch(root, request) {
219
+ if (!object(request) || !validActor(request) || !identity(request.id))
220
+ refuse("invalid owner reconciliation request");
221
+ request = structuredClone(request);
222
+ const hash = digest(canonical({ operation: "reconcile", request: { ...request, evidence: { ...request.evidence, checkedAt: undefined } } }));
223
+ const file = (0, checkin_store_1.checkInStorePath)(root);
224
+ // Do not turn a missing ledger into a new source of authority.
225
+ const inspection = readCheckInSnapshot(file, { limit: 1 });
226
+ if (inspection.state === "missing")
227
+ refuse("custody store is missing");
228
+ return (0, file_lock_1.withFileLock)(path.dirname(file), "operations", () => {
229
+ const db = (0, checkin_store_1.openCustodyDatabase)(file, "write");
230
+ try {
231
+ let mutated = false;
232
+ const result = db.transaction(() => {
233
+ (0, checkin_store_1.custodyCapacity)(db, true);
234
+ const prior = priorRequest(db, request, hash, validRecoveryReceipt);
235
+ if (prior)
236
+ return prior;
237
+ if ((0, checkin_store_1.custodyRevision)(db) !== request.expectedRevision)
238
+ refuse("reconciliation revision conflict");
239
+ const row = db.prepare("SELECT id,host,session,instance,data FROM dispatches WHERE id=?").get(request.id);
240
+ if (!row)
241
+ refuse("dispatch not found");
242
+ const claim = (0, checkin_store_1.parseCustodyDispatch)(row);
243
+ if (claim.state === "not_sent")
244
+ refuse("definite not-sent dispatch requires no reconciliation");
245
+ let resolution;
246
+ let retirement = null;
247
+ let verifiedEvidence;
248
+ if (matchesReceipt(claim, request.evidence)) {
249
+ resolution = "acknowledged_delivery";
250
+ verifiedEvidence = {
251
+ kind: request.evidence.kind, host: request.evidence.host, checkedAt: request.evidence.checkedAt,
252
+ receipt: (0, checkin_store_1.copyCustodyInputReceipt)(request.evidence.receipt),
253
+ };
254
+ }
255
+ else if (validRetirement(request.evidence) && request.evidence.host === claim.host
256
+ && request.evidence.session === claim.session && request.evidence.instance === claim.instance) {
257
+ resolution = "retired_instance";
258
+ retirement = request.evidence;
259
+ verifiedEvidence = copyRetirement(request.evidence);
260
+ }
261
+ else
262
+ refuse("matching confirmed host receipt or fresh exact gone-instance proof required");
263
+ const receipt = {
264
+ revision: (0, checkin_store_1.advanceCustodyRevision)(db), dispatchId: claim.id, resolution, originalState: claim.state,
265
+ at: new Date(Date.now()).toISOString(), actorId: request.actor.actorId, requestId: request.requestId,
266
+ };
267
+ if (retirement)
268
+ retireInstance(db, retirement, receipt);
269
+ if (Buffer.byteLength(JSON.stringify({ receipt, evidence: request.evidence })) > 8192)
270
+ refuse("recovery record byte limit");
271
+ const audit = JSON.stringify({ receipt, evidence: verifiedEvidence });
272
+ db.prepare("INSERT INTO reconciliations(id,dispatch_id,data) VALUES(?,?,?)").run(digest(JSON.stringify([request.actor.actorId, request.requestId])), claim.id, audit);
273
+ rememberRequest(db, request, hash, receipt);
274
+ mutated = true;
275
+ return receipt;
276
+ }).immediate();
277
+ if (mutated)
278
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_dispatch_reconciled", message: "appended custody reconciliation without rewriting original outcome", meta: { resolution: result.resolution, revision: result.revision } });
279
+ return result;
280
+ }
281
+ finally {
282
+ db.close();
283
+ }
284
+ });
285
+ }
286
+ function syncFile(file) {
287
+ const handle = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
288
+ try {
289
+ fs.fsyncSync(handle);
290
+ }
291
+ finally {
292
+ fs.closeSync(handle);
293
+ }
294
+ }
295
+ function syncDirectory(dir) {
296
+ const handle = fs.openSync(dir, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
297
+ try {
298
+ fs.fsyncSync(handle);
299
+ }
300
+ finally {
301
+ fs.closeSync(handle);
302
+ }
303
+ }
304
+ function privateRegular(file, maxBytes) {
305
+ const stat = fs.lstatSync(file);
306
+ if (!stat.isFile() || stat.nlink !== 1 || stat.uid !== process.getuid() || (stat.mode & 0o7777) !== 0o600 || stat.size > maxBytes)
307
+ refuse("maintenance private file ownership, mode, link or byte limit");
308
+ }
309
+ function fileDigest(file) {
310
+ privateRegular(file, 64 * 1024 * 1024);
311
+ const handle = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
312
+ try {
313
+ const hash = (0, node_crypto_1.createHash)("sha256");
314
+ const buffer = Buffer.alloc(65536);
315
+ for (;;) {
316
+ const count = fs.readSync(handle, buffer, 0, buffer.length, null);
317
+ if (!count)
318
+ break;
319
+ hash.update(buffer.subarray(0, count));
320
+ }
321
+ return hash.digest("hex");
322
+ }
323
+ finally {
324
+ fs.closeSync(handle);
325
+ }
326
+ }
327
+ function writePrivateJson(file, value) {
328
+ const temp = `${file}.${(0, node_crypto_1.randomUUID)()}.tmp`;
329
+ fs.writeFileSync(temp, JSON.stringify(value), { flag: "wx", mode: 0o600 });
330
+ syncFile(temp);
331
+ fs.renameSync(temp, file);
332
+ syncDirectory(path.dirname(file));
333
+ }
334
+ function maintenanceDirectory(dir, create) {
335
+ if (!path.isAbsolute(dir) || path.normalize(dir) !== dir)
336
+ refuse("maintenance destination must be an exact absolute path");
337
+ (0, checkin_store_1.validateCustodyDirectory)(dir, create);
338
+ }
339
+ function validMaintenanceReceipt(value) {
340
+ return object(value) && Number.isSafeInteger(value.revision) && Number(value.revision) > 0 && identity(value.requestId) && identity(value.actorId)
341
+ && Number.isSafeInteger(value.archivedCount) && Number(value.archivedCount) >= 0 && Number.isSafeInteger(value.retainedCount) && Number(value.retainedCount) >= 0
342
+ && typeof value.archive === "string" && path.isAbsolute(value.archive) && typeof value.archiveDigest === "string" && /^[a-f0-9]{64}$/.test(value.archiveDigest) && timestamp(value.at);
343
+ }
344
+ function readIntent(file, hash, archive, replacementPrefix) {
345
+ if (!fs.lstatSync(file, { throwIfNoEntry: false }))
346
+ return null;
347
+ privateRegular(file, 8192);
348
+ const value = parseJson(fs.readFileSync(file, "utf8"));
349
+ if (!object(value) || value.version !== 1 || value.hash !== hash || typeof value.sourceRevision !== "number" || !Number.isSafeInteger(value.sourceRevision) || value.sourceRevision < 0
350
+ || typeof value.sourceDigest !== "string" || !/^[a-f0-9]{64}$/.test(value.sourceDigest) || value.archive !== archive
351
+ || typeof value.replacement !== "string" || !value.replacement.startsWith(replacementPrefix)
352
+ || path.dirname(value.replacement) !== path.dirname(replacementPrefix)
353
+ || !["copying", "prepared"].includes(String(value.stage)))
354
+ refuse("interrupted maintenance belongs to a different request or has invalid schema");
355
+ const base = { version: 1, hash, sourceDigest: value.sourceDigest, sourceRevision: value.sourceRevision, archive, replacement: value.replacement };
356
+ if (value.stage === "prepared") {
357
+ if (!validMaintenanceReceipt(value.receipt) || value.archiveDigest !== value.receipt.archiveDigest
358
+ || typeof value.replacementDigest !== "string" || !/^[a-f0-9]{64}$/.test(value.replacementDigest))
359
+ refuse("invalid prepared maintenance schema");
360
+ return { ...base, stage: "prepared", archiveDigest: value.receipt.archiveDigest, replacementDigest: value.replacementDigest, receipt: value.receipt };
361
+ }
362
+ if (value.archiveDigest !== null || value.replacementDigest !== null || value.receipt !== null)
363
+ refuse("invalid copying maintenance schema");
364
+ return { ...base, stage: "copying", archiveDigest: null, replacementDigest: null, receipt: null };
365
+ }
366
+ function targetsClaim(proof, claim) {
367
+ return proof.host === claim.host && proof.session === claim.session && (proof.instance === null && proof.wholeSessionRetired || proof.instance === claim.instance);
368
+ }
369
+ function archiveCandidates(db, proofs) {
370
+ const ids = [];
371
+ for (const row of db.prepare("SELECT id,host,session,instance,data FROM dispatches").iterate()) {
372
+ const claim = (0, checkin_store_1.parseCustodyDispatch)(row);
373
+ if (!proofs.some(proof => targetsClaim(proof, claim)))
374
+ continue;
375
+ const retired = (0, checkin_store_1.hasRetiredCustodyInstance)(db, claim);
376
+ if ((claim.state === "claimed" || claim.state === "unknown") && !retired)
377
+ refuse("unresolved attempt must be reconciled before archive");
378
+ ids.push(claim.id);
379
+ }
380
+ return ids;
381
+ }
382
+ function validateArchive(file, expectedCount) {
383
+ const db = (0, checkin_store_1.openCustodyDatabase)(file, "read");
384
+ try {
385
+ if (db.pragma("integrity_check", { simple: true }) !== "ok")
386
+ refuse("archive integrity check failed");
387
+ const count = db.prepare("SELECT COUNT(*) AS count FROM dispatches").get();
388
+ if (count.count !== expectedCount)
389
+ refuse("archive dispatch count mismatch");
390
+ for (const row of db.prepare("SELECT id,host,session,instance,data FROM dispatches").iterate())
391
+ (0, checkin_store_1.parseCustodyDispatch)(row);
392
+ }
393
+ finally {
394
+ db.close();
395
+ }
396
+ }
397
+ function verifyPrepared(intent) {
398
+ if (intent.stage !== "prepared" || !intent.receipt || fileDigest(intent.archive) !== intent.archiveDigest
399
+ || fileDigest(intent.replacement) !== intent.replacementDigest)
400
+ refuse("prepared maintenance payload digest mismatch");
401
+ const manifest = `${intent.archive}.json`;
402
+ privateRegular(manifest, 8192);
403
+ const value = parseJson(fs.readFileSync(manifest, "utf8"));
404
+ if (!object(value) || value.archiveDigest !== intent.archiveDigest || value.requestHash !== intent.hash
405
+ || canonical(value.receipt) !== canonical(intent.receipt))
406
+ refuse("archive manifest mismatch");
407
+ }
408
+ function requireStoppedSense(request) {
409
+ if (!object(request.sense) || request.sense.kind !== "daemon_lifecycle" || request.sense.enabled !== false || request.sense.processState !== "stopped" || !fresh(request.sense.checkedAt)) {
410
+ refuse("maintenance requires a fresh disabled and stopped sense proof");
411
+ }
412
+ }
413
+ /** Fresh lifecycle observations are preconditions, not a change to the operator's archival intent. */
414
+ async function maintainShepherdCustody(root, request) {
415
+ if (!object(request) || !validActor(request) || typeof request.destination !== "string" || request.destination.length > 2000
416
+ || !Array.isArray(request.retiredInstances) || request.retiredInstances.length > 200
417
+ || request.requestFingerprint !== undefined && !/^[a-f0-9]{64}$/.test(request.requestFingerprint))
418
+ refuse("invalid owner maintenance request");
419
+ request = structuredClone(request);
420
+ const hash = request.requestFingerprint ?? digest(canonical({ operation: "maintenance", request: {
421
+ ...request, sense: undefined, retiredInstances: request.retiredInstances.map(proof => ({ ...proof, checkedAt: undefined })),
422
+ } }));
423
+ const file = (0, checkin_store_1.checkInStorePath)(root);
424
+ const marker = `${file}.maintenance.json`;
425
+ const archive = path.join(request.destination, `custody-${hash}.sqlite`);
426
+ const replacementPrefix = `${file}.replacement-${hash}-`;
427
+ maintenanceDirectory(request.destination, false);
428
+ if (!fs.lstatSync(file, { throwIfNoEntry: false }))
429
+ refuse("custody store is missing");
430
+ return (0, file_lock_1.withFileLock)(path.dirname(file), "operations", async () => {
431
+ let intent = readIntent(marker, hash, archive, replacementPrefix);
432
+ const db = (0, checkin_store_1.openCustodyDatabase)(file, "maintenance");
433
+ try {
434
+ const prior = priorRequest(db, request, hash, validMaintenanceReceipt);
435
+ if (prior) {
436
+ if (intent) {
437
+ if (intent.stage !== "prepared" || fileDigest(file) !== intent.replacementDigest || fileDigest(archive) !== prior.archiveDigest)
438
+ refuse("completed maintenance does not match recovery marker");
439
+ fs.unlinkSync(marker);
440
+ syncDirectory(path.dirname(file));
441
+ }
442
+ return prior;
443
+ }
444
+ requireStoppedSense(request);
445
+ if (!request.retiredInstances.length || !request.retiredInstances.every(validRetirement)
446
+ || request.retiredInstances.some(proof => proof.instance === null && !proof.wholeSessionRetired))
447
+ refuse("maintenance requires fresh exact retired-instance proofs");
448
+ if ((0, checkin_store_1.custodyRevision)(db) !== request.expectedRevision)
449
+ refuse("maintenance revision conflict");
450
+ if (intent) {
451
+ if (intent.sourceRevision !== (0, checkin_store_1.custodyRevision)(db) || fileDigest(file) !== intent.sourceDigest)
452
+ refuse("maintenance source changed; manual recovery required");
453
+ if (intent.stage === "prepared") {
454
+ verifyPrepared(intent);
455
+ requireStoppedSense(request);
456
+ db.close();
457
+ fs.renameSync(intent.replacement, file);
458
+ syncDirectory(path.dirname(file));
459
+ fs.unlinkSync(marker);
460
+ syncDirectory(path.dirname(file));
461
+ return intent.receipt;
462
+ }
463
+ }
464
+ const ids = archiveCandidates(db, request.retiredInstances);
465
+ if (!ids.length)
466
+ refuse("no settled retired-instance payloads are eligible for archive");
467
+ const total = db.prepare("SELECT COUNT(*) AS count FROM dispatches").get();
468
+ maintenanceDirectory(request.destination, true);
469
+ if (fs.lstatSync(archive, { throwIfNoEntry: false })) {
470
+ if (!intent || intent.stage !== "copying")
471
+ refuse("archive destination already exists; resume its exact prepared request");
472
+ privateRegular(archive, 64 * 1024 * 1024);
473
+ fs.renameSync(archive, `${archive}.interrupted-${(0, node_crypto_1.randomUUID)()}`);
474
+ if (fs.lstatSync(`${archive}.json`, { throwIfNoEntry: false })) {
475
+ privateRegular(`${archive}.json`, 8192);
476
+ fs.renameSync(`${archive}.json`, `${archive}.json.interrupted-${(0, node_crypto_1.randomUUID)()}`);
477
+ }
478
+ syncDirectory(request.destination);
479
+ (0, runtime_1.emitNervesEvent)({ level: "warn", component: "senses", event: "senses.shepherd_custody_archive_resumed", message: "preserved an interrupted archive publication before rebuilding from unchanged custody", meta: { stage: "copying" } });
480
+ }
481
+ intent = {
482
+ version: 1, hash, sourceDigest: fileDigest(file), sourceRevision: (0, checkin_store_1.custodyRevision)(db), stage: "copying", archive,
483
+ replacement: `${replacementPrefix}${(0, node_crypto_1.randomUUID)()}.sqlite`, archiveDigest: null, replacementDigest: null, receipt: null,
484
+ };
485
+ writePrivateJson(marker, intent);
486
+ const archiveTemp = `${archive}.${(0, node_crypto_1.randomUUID)()}.tmp`;
487
+ fs.writeFileSync(archiveTemp, "", { flag: "wx", mode: 0o600 });
488
+ await db.backup(archiveTemp);
489
+ syncFile(archiveTemp);
490
+ validateArchive(archiveTemp, total.count);
491
+ const archiveDigest = fileDigest(archiveTemp);
492
+ fs.writeFileSync(intent.replacement, "", { flag: "wx", mode: 0o600 });
493
+ await db.backup(intent.replacement);
494
+ const replacement = (0, checkin_store_1.openCustodyDatabase)(intent.replacement, "write");
495
+ let receipt;
496
+ try {
497
+ receipt = replacement.transaction(() => {
498
+ for (const id of ids) {
499
+ replacement.prepare("DELETE FROM reconciliations WHERE dispatch_id=?").run(id);
500
+ replacement.prepare("DELETE FROM dispatches WHERE id=?").run(id);
501
+ }
502
+ for (const proof of request.retiredInstances)
503
+ retireInstance(replacement, proof, { actorId: request.actor.actorId, requestId: request.requestId }, { path: archive, digest: archiveDigest });
504
+ const result = {
505
+ revision: (0, checkin_store_1.advanceCustodyRevision)(replacement), requestId: request.requestId, actorId: request.actor.actorId,
506
+ archivedCount: ids.length, retainedCount: total.count - ids.length, archive, archiveDigest, at: new Date(Date.now()).toISOString(),
507
+ };
508
+ rememberRequest(replacement, request, hash, result);
509
+ return result;
510
+ }).immediate();
511
+ replacement.exec("VACUUM");
512
+ (0, checkin_store_1.custodyCapacity)(replacement, true);
513
+ if (replacement.pragma("integrity_check", { simple: true }) !== "ok")
514
+ refuse("replacement custody integrity check failed");
515
+ }
516
+ finally {
517
+ replacement.close();
518
+ }
519
+ syncFile(intent.replacement);
520
+ validateArchive(intent.replacement, receipt.retainedCount);
521
+ fs.renameSync(archiveTemp, archive);
522
+ syncDirectory(request.destination);
523
+ writePrivateJson(`${archive}.json`, { version: 1, requestHash: hash, archiveDigest, receipt });
524
+ intent = { ...intent, stage: "prepared", archiveDigest, replacementDigest: fileDigest(intent.replacement), receipt };
525
+ writePrivateJson(marker, intent);
526
+ verifyPrepared(intent);
527
+ requireStoppedSense(request);
528
+ if (fileDigest(file) !== intent.sourceDigest)
529
+ refuse("maintenance source changed before swap");
530
+ db.close();
531
+ fs.renameSync(intent.replacement, file);
532
+ syncDirectory(path.dirname(file));
533
+ fs.unlinkSync(marker);
534
+ syncDirectory(path.dirname(file));
535
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_custody_archived", message: "archived settled retired custody and retained replay tombstones", meta: { archivedCount: receipt.archivedCount, retainedCount: receipt.retainedCount, revision: receipt.revision } });
536
+ return receipt;
537
+ }
538
+ finally {
539
+ if (db.open)
540
+ db.close();
541
+ }
542
+ });
543
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FINGERPRINT_READ_LINES = exports.FINGERPRINT_LINES = void 0;
4
+ exports.redactSecrets = redactSecrets;
5
+ exports.screenTail = screenTail;
6
+ exports.withoutNumbers = withoutNumbers;
7
+ exports.screenFingerprint = screenFingerprint;
8
+ const node_crypto_1 = require("node:crypto");
9
+ const runtime_1 = require("../../nerves/runtime");
10
+ /**
11
+ * Terminal screens and agents' last messages can show credentials. Everything Shepherd hands to a
12
+ * model or a tool result (screen text, last messages) goes through this first. It is a best-effort net for
13
+ * secret-shaped strings, not a guarantee, so callers also keep their output bounded.
14
+ */
15
+ const REDACTED = "[redacted]";
16
+ const WHOLE_MATCH = [
17
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
18
+ /\bsk-[A-Za-z0-9_-]{16,}/g,
19
+ /\bgh[pousr]_[A-Za-z0-9]{20,}/g,
20
+ /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
21
+ /\bAKIA[0-9A-Z]{16}\b/g,
22
+ /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,
23
+ /\bv1\.[A-Za-z0-9_-]{40,}\.[A-Za-z0-9_-]{40,}/g,
24
+ /\bxox[abprs]-[A-Za-z0-9-]{10,}/g,
25
+ ];
26
+ /** Keep the label (group 1), redact the value. */
27
+ const LABELLED_VALUE = [
28
+ /(\b(?:Bearer|Basic)\s+)[A-Za-z0-9._~+/=-]{6,}/gi,
29
+ /(\b(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|client[_-]?secret)\s*[=:]\s*)(?:"[^"]*"|'[^']*'|[^\s'"&]+)/gi,
30
+ /([?&](?:token|key|api_key|access_token|sig|signature)=)[^&\s]+/gi,
31
+ ];
32
+ function redactSecrets(text) {
33
+ let result = text;
34
+ for (const pattern of WHOLE_MATCH)
35
+ result = result.replace(pattern, REDACTED);
36
+ for (const pattern of LABELLED_VALUE)
37
+ result = result.replace(pattern, `$1${REDACTED}`);
38
+ if (result !== text) {
39
+ (0, runtime_1.emitNervesEvent)({ component: "senses", event: "senses.shepherd_redacted", message: "redacted secret-shaped text from cmux output", meta: { removedChars: text.length - result.length } });
40
+ }
41
+ return result;
42
+ }
43
+ /** The last `lines` lines of a screen, without its trailing blank space. */
44
+ function screenTail(text, lines) {
45
+ return text.replace(/\s+$/, "").split("\n").slice(-lines).join("\n");
46
+ }
47
+ /**
48
+ * A screen with its numbers taken out: a timer or token counter at a waiting prompt is not the
49
+ * screen moving on. A timer can tick, grow a unit (`59s` to `1m 0s`), and come and go between
50
+ * redraws, shifting the padding beside it, so runs of numbers with time units vanish along with
51
+ * the space around them, and runs of spaces and line-end padding do not count.
52
+ */
53
+ function withoutNumbers(screen) {
54
+ return screen.replace(/[ \t]*(\d+[hms]?[ \t]*)+/g, " ").replace(/[ \t]+/g, " ").replace(/ $/gm, "");
55
+ }
56
+ /** Lines a screen fingerprint covers, and the fewest lines a read must take to compute one. */
57
+ exports.FINGERPRINT_LINES = 20;
58
+ exports.FINGERPRINT_READ_LINES = 40;
59
+ /**
60
+ * A short fingerprint of what a terminal shows now: its last lines, redacted, with numbers blanked so a ticking timer does
61
+ * not count as a change. `shepherd_read` hands it out and `shepherd_send` compares it, so a key is pressed only on the
62
+ * screen someone actually saw.
63
+ */
64
+ function screenFingerprint(text) {
65
+ return (0, node_crypto_1.createHash)("sha256").update(withoutNumbers(screenTail(redactSecrets(text), exports.FINGERPRINT_LINES))).digest("hex").slice(0, 16);
66
+ }