@ouro.bot/cli 0.1.0-alpha.88 → 0.1.0-alpha.880

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 (669) 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 +5601 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2995 -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 +1197 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1127 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2085 -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 +27 -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 +29 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +238 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command.js +151 -0
  59. package/dist/a2a/delegation-stores.js +56 -0
  60. package/dist/a2a/did-resolution.js +93 -0
  61. package/dist/a2a/escalation-grants.js +122 -0
  62. package/dist/a2a/escalation-wiring.js +60 -0
  63. package/dist/a2a/identity.js +204 -0
  64. package/dist/a2a/inbound-share.js +110 -0
  65. package/dist/a2a/mission-result-wire.js +196 -0
  66. package/dist/a2a/onboarding.js +133 -0
  67. package/dist/a2a/outbox-client.js +57 -0
  68. package/dist/a2a/outbox-store.js +188 -0
  69. package/dist/a2a/outbox-wire.js +95 -0
  70. package/dist/a2a/pin-store.js +132 -0
  71. package/dist/a2a/replay-harness.js +175 -0
  72. package/dist/a2a/resolution-proof.js +53 -0
  73. package/dist/a2a/sealed-chat.js +113 -0
  74. package/dist/a2a/seen-ledger.js +120 -0
  75. package/dist/a2a/server.js +766 -0
  76. package/dist/a2a/task-store.js +69 -0
  77. package/dist/a2a/transport.js +45 -0
  78. package/dist/a2a/trusted-files.js +98 -0
  79. package/dist/a2a/types.js +3 -0
  80. package/dist/arc/attention-types.js +8 -0
  81. package/dist/arc/cares.js +360 -0
  82. package/dist/arc/episodes.js +118 -0
  83. package/dist/arc/evolution.js +490 -0
  84. package/dist/arc/flight-recorder.js +1034 -0
  85. package/dist/arc/intentions.js +134 -0
  86. package/dist/arc/json-store.js +117 -0
  87. package/dist/arc/obligations.js +386 -0
  88. package/dist/arc/packets.js +336 -0
  89. package/dist/arc/presence.js +185 -0
  90. package/dist/arc/task-lifecycle.js +57 -0
  91. package/dist/commerce/store.js +755 -0
  92. package/dist/commerce/types.js +3 -0
  93. package/dist/heart/active-work.js +798 -40
  94. package/dist/heart/agent-entry.js +252 -3
  95. package/dist/heart/approval-files.js +113 -0
  96. package/dist/heart/approval-store.js +960 -0
  97. package/dist/heart/attachments/image-normalize.js +194 -0
  98. package/dist/heart/attachments/materialize.js +97 -0
  99. package/dist/heart/attachments/originals.js +88 -0
  100. package/dist/heart/attachments/render.js +29 -0
  101. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  102. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  103. package/dist/heart/attachments/sources/index.js +18 -0
  104. package/dist/heart/attachments/sources/telegram.js +71 -0
  105. package/dist/heart/attachments/store.js +132 -0
  106. package/dist/heart/attachments/types.js +93 -0
  107. package/dist/heart/auth/auth-flow.js +495 -0
  108. package/dist/heart/autonomy-budget.js +478 -0
  109. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  110. package/dist/heart/awaiting/await-alert.js +152 -0
  111. package/dist/heart/awaiting/await-expiry.js +143 -0
  112. package/dist/heart/awaiting/await-loader.js +91 -0
  113. package/dist/heart/awaiting/await-parser.js +152 -0
  114. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  115. package/dist/heart/awaiting/await-scheduler.js +382 -0
  116. package/dist/heart/background-operations.js +281 -0
  117. package/dist/heart/bridges/manager.js +137 -17
  118. package/dist/heart/bridges/store.js +14 -2
  119. package/dist/heart/bundle-state.js +168 -0
  120. package/dist/heart/commitments.js +44 -18
  121. package/dist/heart/config-registry.js +331 -0
  122. package/dist/heart/config.js +174 -131
  123. package/dist/heart/context-loss-gauntlet.js +387 -0
  124. package/dist/heart/context-loss-sentinel.js +1157 -0
  125. package/dist/heart/core.js +2286 -580
  126. package/dist/heart/cross-chat-delivery.js +9 -22
  127. package/dist/heart/daemon/agent-config-check.js +451 -0
  128. package/dist/heart/daemon/agent-discovery.js +185 -3
  129. package/dist/heart/daemon/agent-service.js +542 -0
  130. package/dist/heart/daemon/agentic-repair.js +547 -0
  131. package/dist/heart/daemon/await-private-wake.js +59 -0
  132. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  133. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  134. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  135. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  136. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  137. package/dist/heart/daemon/cadence.js +180 -0
  138. package/dist/heart/daemon/cli-defaults.js +854 -0
  139. package/dist/heart/daemon/cli-desk.js +322 -0
  140. package/dist/heart/daemon/cli-exec.js +8951 -0
  141. package/dist/heart/daemon/cli-help.js +716 -0
  142. package/dist/heart/daemon/cli-parse.js +2941 -0
  143. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  144. package/dist/heart/daemon/cli-render.js +777 -0
  145. package/dist/heart/daemon/cli-types.js +8 -0
  146. package/dist/heart/daemon/connect-bay.js +323 -0
  147. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  148. package/dist/heart/daemon/container-healthcheck.js +112 -0
  149. package/dist/heart/daemon/container-runtime.js +97 -0
  150. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  151. package/dist/heart/daemon/container-spec-auditor.js +232 -0
  152. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  153. package/dist/heart/daemon/daemon-cli.js +29 -2349
  154. package/dist/heart/daemon/daemon-entry.js +932 -11
  155. package/dist/heart/daemon/daemon-health.js +186 -0
  156. package/dist/heart/daemon/daemon-rollup.js +57 -0
  157. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  158. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  159. package/dist/heart/daemon/daemon.js +2084 -105
  160. package/dist/heart/daemon/dns-workflow.js +394 -0
  161. package/dist/heart/daemon/doctor-types.js +8 -0
  162. package/dist/heart/daemon/doctor.js +1755 -0
  163. package/dist/heart/daemon/freshness.js +345 -0
  164. package/dist/heart/daemon/habit-private-wake.js +61 -0
  165. package/dist/heart/daemon/health-monitor.js +142 -11
  166. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  167. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  168. package/dist/heart/daemon/http-health-probe.js +80 -0
  169. package/dist/heart/daemon/human-command-screens.js +234 -0
  170. package/dist/heart/daemon/human-readiness.js +114 -0
  171. package/dist/heart/daemon/inner-status.js +78 -0
  172. package/dist/heart/daemon/interactive-repair.js +394 -0
  173. package/dist/heart/daemon/launchd.js +37 -8
  174. package/dist/heart/daemon/log-tailer.js +79 -10
  175. package/dist/heart/daemon/logs-prune.js +132 -0
  176. package/dist/heart/daemon/mcp-canary.js +524 -0
  177. package/dist/heart/daemon/message-router.js +65 -5
  178. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  179. package/dist/heart/daemon/os-cron-deps.js +135 -0
  180. package/dist/heart/daemon/os-cron.js +22 -14
  181. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  182. package/dist/heart/daemon/ouro-entry.js +3 -1
  183. package/dist/heart/daemon/plugin-cli.js +432 -0
  184. package/dist/heart/daemon/process-manager.js +733 -61
  185. package/dist/heart/daemon/provider-discovery.js +137 -0
  186. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  187. package/dist/heart/daemon/prunable-bundle.js +144 -0
  188. package/dist/heart/daemon/pulse.js +511 -0
  189. package/dist/heart/daemon/readiness-repair.js +365 -0
  190. package/dist/heart/daemon/run-hooks.js +2 -0
  191. package/dist/heart/daemon/runtime-logging.js +47 -14
  192. package/dist/heart/daemon/runtime-metadata.js +2 -30
  193. package/dist/heart/daemon/runtime-mode.js +13 -2
  194. package/dist/heart/daemon/safe-mode.js +161 -0
  195. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  196. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  197. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  198. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  199. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  200. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  201. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  202. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  203. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1310 -0
  204. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  205. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  206. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  207. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  208. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  209. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  210. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  211. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  212. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  213. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  214. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  215. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  216. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  217. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  218. package/dist/heart/daemon/sense-manager.js +699 -48
  219. package/dist/heart/daemon/session-id-resolver.js +131 -0
  220. package/dist/heart/daemon/skill-management-installer.js +1 -1
  221. package/dist/heart/daemon/socket-client.js +180 -12
  222. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  223. package/dist/heart/daemon/startup-tui.js +339 -0
  224. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  225. package/dist/heart/daemon/task-scheduler.js +117 -39
  226. package/dist/heart/daemon/terminal-ui.js +499 -0
  227. package/dist/heart/daemon/thoughts.js +138 -54
  228. package/dist/heart/daemon/up-progress.js +366 -0
  229. package/dist/heart/daemon/vault-items.js +56 -0
  230. package/dist/heart/delegation.js +1 -4
  231. package/dist/heart/external-events/router.js +1516 -0
  232. package/dist/heart/failure-reports.js +335 -0
  233. package/dist/heart/file-lock.js +109 -0
  234. package/dist/heart/frontend-approval-runtime.js +506 -0
  235. package/dist/heart/frontend-journal.js +215 -0
  236. package/dist/heart/frontend-session-service.js +237 -0
  237. package/dist/heart/frontend-socket-client.js +164 -0
  238. package/dist/heart/frontend-socket.js +400 -0
  239. package/dist/heart/habits/habit-cancel.js +810 -0
  240. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  241. package/dist/heart/habits/habit-migration.js +194 -0
  242. package/dist/heart/habits/habit-parser.js +278 -0
  243. package/dist/heart/habits/habit-runtime-state.js +93 -0
  244. package/dist/heart/habits/habit-scheduler.js +653 -0
  245. package/dist/heart/habits/habit-session-summary.js +318 -0
  246. package/dist/heart/habits/habit-session.js +636 -0
  247. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  248. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  249. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  250. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  251. package/dist/heart/identity.js +196 -59
  252. package/dist/heart/kept-notes.js +289 -0
  253. package/dist/heart/kicks.js +1 -1
  254. package/dist/heart/machine-identity.js +161 -0
  255. package/dist/heart/mail-import-discovery.js +356 -0
  256. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  257. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  258. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  259. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  260. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  261. package/dist/heart/mailbox/mailbox-http.js +99 -0
  262. package/dist/heart/mailbox/mailbox-read.js +39 -0
  263. package/dist/heart/mailbox/mailbox-types.js +27 -0
  264. package/dist/heart/mailbox/mailbox-view.js +197 -0
  265. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  266. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  267. package/dist/heart/mailbox/readers/mail.js +375 -0
  268. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  269. package/dist/heart/mailbox/readers/sessions.js +231 -0
  270. package/dist/heart/mailbox/readers/shared.js +111 -0
  271. package/dist/heart/mcp/mcp-server.js +696 -0
  272. package/dist/heart/migrate-config.js +100 -0
  273. package/dist/heart/model-capabilities.js +11 -0
  274. package/dist/heart/orientation-frame.js +345 -0
  275. package/dist/heart/platform.js +81 -0
  276. package/dist/heart/primitives.js +1 -1
  277. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  278. package/dist/heart/private-runtime/index.js +18 -0
  279. package/dist/heart/private-runtime/ledger.js +221 -0
  280. package/dist/heart/private-runtime/policy.js +252 -0
  281. package/dist/heart/private-runtime/types.js +2 -0
  282. package/dist/heart/progress-story.js +1 -1
  283. package/dist/heart/provider-attempt.js +137 -0
  284. package/dist/heart/provider-binding-resolver.js +273 -0
  285. package/dist/heart/provider-credentials.js +449 -0
  286. package/dist/heart/provider-failover.js +311 -0
  287. package/dist/heart/provider-models.js +96 -0
  288. package/dist/heart/provider-ping.js +265 -0
  289. package/dist/heart/provider-readiness-cache.js +119 -0
  290. package/dist/heart/provider-visibility.js +188 -0
  291. package/dist/heart/providers/anthropic-token.js +131 -0
  292. package/dist/heart/providers/anthropic.js +173 -60
  293. package/dist/heart/providers/azure.js +23 -11
  294. package/dist/heart/providers/error-classification.js +127 -0
  295. package/dist/heart/providers/github-copilot.js +34 -38
  296. package/dist/heart/providers/minimax-vlm.js +189 -0
  297. package/dist/heart/providers/minimax.js +26 -8
  298. package/dist/heart/providers/openai-codex-token.js +349 -0
  299. package/dist/heart/providers/openai-codex.js +55 -40
  300. package/dist/heart/providers/openai-compatible.js +177 -0
  301. package/dist/heart/reply-style.js +56 -0
  302. package/dist/heart/run-ledger.js +247 -0
  303. package/dist/heart/runtime-capability-check.js +170 -0
  304. package/dist/heart/runtime-credentials.js +607 -0
  305. package/dist/heart/runtime-cwd.js +87 -0
  306. package/dist/heart/sense-truth.js +22 -4
  307. package/dist/heart/session-activity.js +92 -24
  308. package/dist/heart/session-events.js +1504 -0
  309. package/dist/heart/session-playback-cli-main.js +5 -0
  310. package/dist/heart/session-playback-cli.js +36 -0
  311. package/dist/heart/session-playback.js +231 -0
  312. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  313. package/dist/heart/session-redaction-repair.js +552 -0
  314. package/dist/heart/session-stats-cli-main.js +5 -0
  315. package/dist/heart/session-stats.js +183 -0
  316. package/dist/heart/session-transcript.js +133 -0
  317. package/dist/heart/source-grounding.js +194 -0
  318. package/dist/heart/start-of-turn-packet.js +372 -0
  319. package/dist/heart/steward-policy.js +656 -0
  320. package/dist/heart/streaming.js +604 -207
  321. package/dist/heart/structured-output.js +196 -0
  322. package/dist/heart/sync-classification.js +176 -0
  323. package/dist/heart/sync.js +505 -0
  324. package/dist/heart/target-resolution.js +11 -7
  325. package/dist/heart/tempo.js +93 -0
  326. package/dist/heart/temporal-view.js +41 -0
  327. package/dist/heart/timeouts.js +101 -0
  328. package/dist/heart/tool-activity-callbacks.js +59 -0
  329. package/dist/heart/tool-approval.js +382 -0
  330. package/dist/heart/tool-description.js +155 -0
  331. package/dist/heart/tool-friction.js +55 -0
  332. package/dist/heart/tool-loop.js +206 -0
  333. package/dist/heart/turn-context.js +487 -0
  334. package/dist/heart/turn-execution-lease.js +30 -0
  335. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  336. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  337. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  338. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  339. package/dist/heart/versioning/ouro-version-manager.js +409 -0
  340. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  341. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  342. package/dist/heart/versioning/update-hooks.js +154 -0
  343. package/dist/heart/versioning/version-intent.js +114 -0
  344. package/dist/heart/work-card.js +380 -0
  345. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  346. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  347. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  348. package/dist/mailbox-ui/index.html +16 -0
  349. package/dist/mailroom/attention.js +167 -0
  350. package/dist/mailroom/autonomy.js +209 -0
  351. package/dist/mailroom/blob-store.js +889 -0
  352. package/dist/mailroom/body-cache.js +61 -0
  353. package/dist/mailroom/cache-sync-cli.js +58 -0
  354. package/dist/mailroom/core.js +803 -0
  355. package/dist/mailroom/entry.js +160 -0
  356. package/dist/mailroom/file-store.js +568 -0
  357. package/dist/mailroom/hosted-cache-sync.js +384 -0
  358. package/dist/mailroom/mbox-import.js +393 -0
  359. package/dist/mailroom/migration.js +164 -0
  360. package/dist/mailroom/outbound.js +380 -0
  361. package/dist/mailroom/policy.js +263 -0
  362. package/dist/mailroom/reader.js +292 -0
  363. package/dist/mailroom/search-cache.js +513 -0
  364. package/dist/mailroom/search-relevance.js +319 -0
  365. package/dist/mailroom/smtp-ingress.js +176 -0
  366. package/dist/mailroom/source-state.js +176 -0
  367. package/dist/mailroom/thread.js +109 -0
  368. package/dist/mailroom/travel-extract.js +89 -0
  369. package/dist/mind/bundle-manifest.js +24 -2
  370. package/dist/mind/context.js +307 -139
  371. package/dist/mind/desk-section.js +362 -0
  372. package/dist/mind/diary-integrity.js +60 -0
  373. package/dist/mind/{memory.js → diary.js} +68 -77
  374. package/dist/mind/embedding-provider.js +60 -0
  375. package/dist/mind/file-state.js +179 -0
  376. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  377. package/dist/mind/obligation-steering.js +199 -3
  378. package/dist/mind/pending.js +36 -10
  379. package/dist/mind/prompt-budget.js +479 -0
  380. package/dist/mind/prompt-refresh.js +3 -2
  381. package/dist/mind/prompt.js +1048 -198
  382. package/dist/mind/provenance-trust.js +26 -0
  383. package/dist/mind/record-paths.js +312 -0
  384. package/dist/mind/scrutiny.js +173 -0
  385. package/dist/mind/session-transaction.js +564 -0
  386. package/dist/nerves/cli-logging.js +7 -1
  387. package/dist/nerves/coverage/audit-rules.js +15 -6
  388. package/dist/nerves/coverage/audit.js +28 -2
  389. package/dist/nerves/coverage/cli.js +1 -1
  390. package/dist/nerves/coverage/contract.js +5 -5
  391. package/dist/nerves/coverage/file-completeness.js +139 -5
  392. package/dist/nerves/coverage/run-artifacts.js +55 -35
  393. package/dist/nerves/coverage/source-scanner.js +4 -4
  394. package/dist/nerves/event-buffer.js +111 -0
  395. package/dist/nerves/index.js +293 -9
  396. package/dist/nerves/observation.js +20 -0
  397. package/dist/nerves/redact.js +79 -0
  398. package/dist/nerves/review/cli-main.js +5 -0
  399. package/dist/nerves/review/cli.js +156 -0
  400. package/dist/nerves/review/core.js +159 -0
  401. package/dist/nerves/runtime.js +17 -1
  402. package/dist/repertoire/ado-client.js +15 -56
  403. package/dist/repertoire/ado-semantic.js +16 -10
  404. package/dist/repertoire/api-client.js +97 -0
  405. package/dist/repertoire/bitwarden-store.js +1045 -0
  406. package/dist/repertoire/bundle-templates.js +71 -0
  407. package/dist/repertoire/bw-installer.js +180 -0
  408. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  409. package/dist/repertoire/coding/context-pack.js +331 -0
  410. package/dist/repertoire/coding/feedback.js +174 -32
  411. package/dist/repertoire/coding/index.js +15 -3
  412. package/dist/repertoire/coding/manager.js +159 -10
  413. package/dist/repertoire/coding/spawner.js +58 -11
  414. package/dist/repertoire/coding/tools.js +221 -15
  415. package/dist/repertoire/coding/workbench-client.js +272 -0
  416. package/dist/repertoire/coding/workbench-manager.js +346 -0
  417. package/dist/repertoire/commerce-errors.js +109 -0
  418. package/dist/repertoire/commerce-self-test.js +156 -0
  419. package/dist/repertoire/credential-access.js +178 -0
  420. package/dist/repertoire/desk/classifier.js +362 -0
  421. package/dist/repertoire/duffel-client.js +185 -0
  422. package/dist/repertoire/github-client.js +14 -55
  423. package/dist/repertoire/graph-client.js +11 -52
  424. package/dist/repertoire/guardrails.js +873 -19
  425. package/dist/repertoire/house-sweep.js +466 -0
  426. package/dist/repertoire/mcp-client.js +58 -5
  427. package/dist/repertoire/mcp-manager.js +427 -139
  428. package/dist/repertoire/mcp-tools.js +132 -0
  429. package/dist/repertoire/mcp-write-guard.js +46 -0
  430. package/dist/repertoire/plugin-mcp.js +175 -0
  431. package/dist/repertoire/plugins.js +253 -0
  432. package/dist/repertoire/relationship-authorization.js +322 -0
  433. package/dist/repertoire/shell-sessions.js +134 -0
  434. package/dist/repertoire/skills.js +48 -4
  435. package/dist/repertoire/stripe-client.js +131 -0
  436. package/dist/repertoire/tool-arguments.js +182 -0
  437. package/dist/repertoire/tool-results.js +29 -0
  438. package/dist/repertoire/tools-a2a.js +699 -0
  439. package/dist/repertoire/tools-attachments.js +322 -0
  440. package/dist/repertoire/tools-awaiting.js +870 -0
  441. package/dist/repertoire/tools-base.js +79 -1168
  442. package/dist/repertoire/tools-bluebubbles.js +2 -0
  443. package/dist/repertoire/tools-bridge.js +144 -0
  444. package/dist/repertoire/tools-bundle.js +993 -0
  445. package/dist/repertoire/tools-commerce.js +253 -0
  446. package/dist/repertoire/tools-config.js +186 -0
  447. package/dist/repertoire/tools-continuity.js +575 -0
  448. package/dist/repertoire/tools-credential.js +383 -0
  449. package/dist/repertoire/tools-escalation.js +84 -0
  450. package/dist/repertoire/tools-evolution.js +527 -0
  451. package/dist/repertoire/tools-files.js +344 -0
  452. package/dist/repertoire/tools-flight.js +290 -0
  453. package/dist/repertoire/tools-flow.js +119 -0
  454. package/dist/repertoire/tools-github.js +3 -8
  455. package/dist/repertoire/tools-habits.js +103 -0
  456. package/dist/repertoire/tools-house-care.js +138 -0
  457. package/dist/repertoire/tools-mail.js +1828 -0
  458. package/dist/repertoire/tools-notes.js +496 -0
  459. package/dist/repertoire/tools-obligations.js +182 -0
  460. package/dist/repertoire/tools-orientation.js +31 -0
  461. package/dist/repertoire/tools-record.js +482 -0
  462. package/dist/repertoire/tools-rsvp.js +139 -0
  463. package/dist/repertoire/tools-runtime.js +238 -0
  464. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  465. package/dist/repertoire/tools-session.js +1133 -0
  466. package/dist/repertoire/tools-shell.js +149 -0
  467. package/dist/repertoire/tools-steward-policy.js +147 -0
  468. package/dist/repertoire/tools-stripe.js +224 -0
  469. package/dist/repertoire/tools-surface.js +369 -0
  470. package/dist/repertoire/tools-teams.js +12 -39
  471. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  472. package/dist/repertoire/tools-travel.js +125 -0
  473. package/dist/repertoire/tools-trip.js +982 -0
  474. package/dist/repertoire/tools-unraid.js +556 -0
  475. package/dist/repertoire/tools-user-profile.js +146 -0
  476. package/dist/repertoire/tools-vault.js +40 -0
  477. package/dist/repertoire/tools-voice.js +145 -0
  478. package/dist/repertoire/tools.js +509 -156
  479. package/dist/repertoire/travel-api-client.js +360 -0
  480. package/dist/repertoire/unraid-client.js +155 -0
  481. package/dist/repertoire/unraid-restart.js +339 -0
  482. package/dist/repertoire/user-profile.js +131 -0
  483. package/dist/repertoire/vault-setup.js +246 -0
  484. package/dist/repertoire/vault-unlock.js +628 -0
  485. package/dist/rsvp/aisleplanner-client.js +354 -0
  486. package/dist/rsvp/cli.js +926 -0
  487. package/dist/rsvp/config.js +327 -0
  488. package/dist/rsvp/cutover.js +433 -0
  489. package/dist/rsvp/diagnostics.js +232 -0
  490. package/dist/rsvp/diff-renderer.js +176 -0
  491. package/dist/rsvp/habit-policy.js +110 -0
  492. package/dist/rsvp/habit-stage.js +123 -0
  493. package/dist/rsvp/incident-bundle.js +97 -0
  494. package/dist/rsvp/migration.js +204 -0
  495. package/dist/rsvp/native-habit-runner.js +630 -0
  496. package/dist/rsvp/outbound-state.js +628 -0
  497. package/dist/rsvp/query.js +118 -0
  498. package/dist/rsvp/replay.js +233 -0
  499. package/dist/rsvp/snapshot.js +232 -0
  500. package/dist/rsvp/spend-ledger.js +175 -0
  501. package/dist/scripts/claude-code-hook.js +41 -0
  502. package/dist/scripts/claude-code-stop-hook.js +47 -0
  503. package/dist/senses/a2a-entry.js +131 -0
  504. package/dist/senses/acp-server.js +386 -0
  505. package/dist/senses/attention-queue.js +186 -0
  506. package/dist/senses/await-turn-message.js +65 -0
  507. package/dist/senses/bluebubbles/active-turns.js +216 -0
  508. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  509. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  510. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
  511. package/dist/senses/bluebubbles/context-packet.js +207 -0
  512. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  513. package/dist/senses/bluebubbles/entry.js +90 -0
  514. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  515. package/dist/senses/bluebubbles/index.js +3841 -0
  516. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  517. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  518. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  519. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  520. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  521. package/dist/senses/bluebubbles/processed-log.js +133 -0
  522. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  523. package/dist/senses/bluebubbles/replay.js +284 -0
  524. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  525. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  526. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  527. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  528. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  529. package/dist/senses/cli/bracketed-paste.js +82 -0
  530. package/dist/senses/cli/image-paste.js +287 -0
  531. package/dist/senses/cli/image-ref-navigation.js +75 -0
  532. package/dist/senses/cli/ink-app.js +156 -0
  533. package/dist/senses/cli/inline-diff.js +64 -0
  534. package/dist/senses/cli/input-keys.js +174 -0
  535. package/dist/senses/cli/kill-ring.js +86 -0
  536. package/dist/senses/cli/message-list.js +51 -0
  537. package/dist/senses/cli/ouro-tui.js +607 -0
  538. package/dist/senses/cli/spinner-imperative.js +135 -0
  539. package/dist/senses/cli/spinner.js +101 -0
  540. package/dist/senses/cli/status-line.js +60 -0
  541. package/dist/senses/cli/streaming-markdown.js +526 -0
  542. package/dist/senses/cli/tool-display.js +85 -0
  543. package/dist/senses/cli/tool-render.js +85 -0
  544. package/dist/senses/cli/tui-store.js +241 -0
  545. package/dist/senses/cli/virtual-list.js +35 -0
  546. package/dist/senses/cli-entry.js +60 -8
  547. package/dist/senses/cli.js +601 -304
  548. package/dist/senses/commands.js +66 -3
  549. package/dist/senses/context-packet-ledger.js +371 -0
  550. package/dist/senses/context-packets.js +154 -0
  551. package/dist/senses/habit-lifecycle-guard.js +24 -0
  552. package/dist/senses/habit-turn-message.js +160 -0
  553. package/dist/senses/ingress-evidence.js +2 -0
  554. package/dist/senses/mail-entry.js +66 -0
  555. package/dist/senses/mail.js +524 -0
  556. package/dist/senses/pipeline.js +1115 -204
  557. package/dist/senses/private-runtime-worker.js +859 -0
  558. package/dist/senses/private-runtime.js +1619 -0
  559. package/dist/senses/proactive-content-guard.js +51 -0
  560. package/dist/senses/root-host-approval-port.js +345 -0
  561. package/dist/senses/root-host-approval-runtime.js +393 -0
  562. package/dist/senses/sanctuary-authority-resident.js +102 -0
  563. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  564. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  565. package/dist/senses/sanctuary-grounding.js +118 -0
  566. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  567. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  568. package/dist/senses/sanctuary-health-runner.js +104 -0
  569. package/dist/senses/sanctuary-health.js +422 -0
  570. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  571. package/dist/senses/sanctuary-interactive-control.js +410 -0
  572. package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
  573. package/dist/senses/sanctuary-media-optimization.js +514 -0
  574. package/dist/senses/sanctuary-runtime.js +347 -0
  575. package/dist/senses/sanctuary-sab.js +85 -0
  576. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  577. package/dist/senses/shared-turn.js +789 -0
  578. package/dist/senses/surface-tool.js +109 -0
  579. package/dist/senses/teams-entry.js +60 -8
  580. package/dist/senses/teams.js +519 -218
  581. package/dist/senses/telegram-admission.js +718 -0
  582. package/dist/senses/telegram-approval-runtime.js +793 -0
  583. package/dist/senses/telegram-attachments.js +186 -0
  584. package/dist/senses/telegram-audit-ledger.js +220 -0
  585. package/dist/senses/telegram-authority-transport.js +231 -0
  586. package/dist/senses/telegram-client.js +1749 -0
  587. package/dist/senses/telegram-effect-adapter.js +900 -0
  588. package/dist/senses/telegram-entry.js +83 -0
  589. package/dist/senses/telegram.js +2349 -0
  590. package/dist/senses/trust-gate.js +104 -9
  591. package/dist/senses/voice/audio-playback.js +237 -0
  592. package/dist/senses/voice/audio-routing.js +119 -0
  593. package/dist/senses/voice/elevenlabs.js +202 -0
  594. package/dist/senses/voice/floor-control.js +431 -0
  595. package/dist/senses/voice/floor-controller.js +115 -0
  596. package/dist/senses/voice/golden-path.js +116 -0
  597. package/dist/senses/voice/index.js +29 -0
  598. package/dist/senses/voice/meeting.js +113 -0
  599. package/dist/senses/voice/outbound.js +190 -0
  600. package/dist/senses/voice/phone.js +33 -0
  601. package/dist/senses/voice/playback.js +139 -0
  602. package/dist/senses/voice/realtime-eval.js +496 -0
  603. package/dist/senses/voice/realtime-trace.js +531 -0
  604. package/dist/senses/voice/transcript.js +70 -0
  605. package/dist/senses/voice/turn.js +191 -0
  606. package/dist/senses/voice/twilio-phone-runtime.js +807 -0
  607. package/dist/senses/voice/twilio-phone.js +5031 -0
  608. package/dist/senses/voice/types.js +2 -0
  609. package/dist/senses/voice/whisper.js +161 -0
  610. package/dist/senses/voice-entry.js +81 -0
  611. package/dist/senses/voice-realtime-eval-command.js +99 -0
  612. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  613. package/dist/senses/voice-twilio-entry.js +87 -0
  614. package/dist/trips/core.js +138 -0
  615. package/dist/trips/store.js +265 -0
  616. package/dist/util/frontmatter.js +69 -0
  617. package/npm-shrinkwrap.json +8100 -0
  618. package/package.json +73 -13
  619. package/skills/agent-commerce.md +113 -0
  620. package/skills/browser-navigation.md +117 -0
  621. package/skills/commerce-setup-guide.md +116 -0
  622. package/skills/commerce-setup.md +84 -0
  623. package/skills/configure-dev-tools.md +99 -0
  624. package/skills/travel-planning.md +138 -0
  625. package/dist/heart/daemon/auth-flow.js +0 -430
  626. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  627. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  628. package/dist/heart/daemon/update-hooks.js +0 -138
  629. package/dist/heart/obligations.js +0 -191
  630. package/dist/heart/safe-workspace.js +0 -362
  631. package/dist/heart/session-recall.js +0 -116
  632. package/dist/mind/friends/channel.js +0 -84
  633. package/dist/mind/friends/group-context.js +0 -144
  634. package/dist/mind/friends/resolver.js +0 -84
  635. package/dist/mind/friends/store-file.js +0 -190
  636. package/dist/mind/friends/store.js +0 -4
  637. package/dist/mind/friends/tokens.js +0 -26
  638. package/dist/mind/friends/trust-explanation.js +0 -74
  639. package/dist/mind/friends/types.js +0 -29
  640. package/dist/repertoire/tasks/board.js +0 -134
  641. package/dist/repertoire/tasks/index.js +0 -224
  642. package/dist/repertoire/tasks/lifecycle.js +0 -80
  643. package/dist/repertoire/tasks/middleware.js +0 -65
  644. package/dist/repertoire/tasks/parser.js +0 -173
  645. package/dist/repertoire/tasks/scanner.js +0 -132
  646. package/dist/repertoire/tasks/transitions.js +0 -144
  647. package/dist/senses/bluebubbles-entry.js +0 -13
  648. package/dist/senses/bluebubbles.js +0 -1181
  649. package/dist/senses/debug-activity.js +0 -154
  650. package/dist/senses/inner-dialog-worker.js +0 -90
  651. package/dist/senses/inner-dialog.js +0 -525
  652. package/subagents/README.md +0 -7
  653. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  654. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  655. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  656. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  657. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  658. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  659. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  660. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  661. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  662. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  663. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  664. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  665. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  666. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  667. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  668. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  669. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cardDid = cardDid;
4
+ exports.endpointForCard = endpointForCard;
5
+ exports.fetchA2AAgentCard = fetchA2AAgentCard;
6
+ exports.postJsonRpc = postJsonRpc;
7
+ exports.sendA2AMessage = sendA2AMessage;
8
+ exports.postA2AMessageEnvelope = postA2AMessageEnvelope;
9
+ exports.getA2ATask = getA2ATask;
10
+ exports.sendSealedA2AChat = sendSealedA2AChat;
11
+ const node_crypto_1 = require("node:crypto");
12
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
13
+ const runtime_1 = require("../nerves/runtime");
14
+ const sealed_chat_1 = require("./sealed-chat");
15
+ /** The trimmed `did:key` a card serves, or undefined when the card is did-less. */
16
+ function cardDid(card) {
17
+ const did = card.did;
18
+ return typeof did === "string" && did.trim() ? did.trim() : undefined;
19
+ }
20
+ function endpointForCard(card) {
21
+ const jsonRpc = card.supportedInterfaces?.find((entry) => (entry.protocolBinding ?? entry.transport)?.toUpperCase() === "JSONRPC");
22
+ if (jsonRpc?.url)
23
+ return jsonRpc.url;
24
+ if (card.preferredTransport?.toUpperCase() === "JSONRPC" && card.url)
25
+ return card.url;
26
+ const legacyJsonRpc = card.additionalInterfaces?.find((entry) => entry.transport.toUpperCase() === "JSONRPC");
27
+ return legacyJsonRpc?.url ?? card.url;
28
+ }
29
+ async function fetchA2AAgentCard(cardUrl, fetchImpl = fetch) {
30
+ (0, runtime_1.emitNervesEvent)({
31
+ component: "channels",
32
+ event: "channel.a2a_card_fetch_start",
33
+ message: "fetching A2A agent card",
34
+ meta: { cardUrl },
35
+ });
36
+ const response = await fetchImpl(cardUrl);
37
+ if (!response.ok) {
38
+ throw new Error(`A2A card fetch failed (${response.status} ${response.statusText})`);
39
+ }
40
+ const parsed = await response.json();
41
+ const endpoint = endpointForCard(parsed);
42
+ if (!parsed || typeof parsed !== "object" || typeof endpoint !== "string" || typeof parsed.name !== "string") {
43
+ throw new Error("A2A card is missing required name or JSONRPC endpoint fields");
44
+ }
45
+ (0, runtime_1.emitNervesEvent)({
46
+ component: "channels",
47
+ event: "channel.a2a_card_fetch_end",
48
+ message: "fetched A2A agent card",
49
+ meta: { cardUrl, endpoint, name: parsed.name },
50
+ });
51
+ return parsed;
52
+ }
53
+ async function postJsonRpc(endpointUrl, request, fetchImpl, protocolVersion = "1.0") {
54
+ const response = await fetchImpl(endpointUrl, {
55
+ method: "POST",
56
+ headers: { "content-type": "application/json", "A2A-Version": protocolVersion },
57
+ body: JSON.stringify(request),
58
+ });
59
+ if (!response.ok) {
60
+ throw new Error(`A2A JSON-RPC request failed (${response.status} ${response.statusText})`);
61
+ }
62
+ return await response.json();
63
+ }
64
+ function methodNotFound(response) {
65
+ return "error" in response && response.error.code === -32601;
66
+ }
67
+ function senderMetadata(input) {
68
+ return {
69
+ ...(input.senderAgentId ? { senderAgentId: input.senderAgentId } : {}),
70
+ ...(input.senderName ? { senderName: input.senderName } : {}),
71
+ ...(input.senderCardUrl ? { senderCardUrl: input.senderCardUrl } : {}),
72
+ };
73
+ }
74
+ async function sendA2AMessage(input) {
75
+ const fetchImpl = input.fetchImpl ?? fetch;
76
+ const messageId = (0, node_crypto_1.randomUUID)();
77
+ const request = {
78
+ jsonrpc: "2.0",
79
+ id: (0, node_crypto_1.randomUUID)(),
80
+ method: "message/send",
81
+ params: {
82
+ message: {
83
+ kind: "message",
84
+ role: "user",
85
+ messageId,
86
+ ...(input.taskId ? { taskId: input.taskId } : {}),
87
+ contextId: input.sessionKey ?? "default",
88
+ parts: [{ kind: "text", text: input.message }],
89
+ metadata: senderMetadata(input),
90
+ },
91
+ ...(input.accessToken ? { accessToken: input.accessToken } : {}),
92
+ },
93
+ };
94
+ (0, runtime_1.emitNervesEvent)({
95
+ component: "channels",
96
+ event: "channel.a2a_message_send_start",
97
+ message: "sending A2A message",
98
+ meta: { endpointUrl: input.endpointUrl, messageId },
99
+ });
100
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
101
+ if (methodNotFound(rpc)) {
102
+ rpc = await postJsonRpc(input.endpointUrl, {
103
+ ...request,
104
+ method: "SendMessage",
105
+ params: {
106
+ ...request.params,
107
+ message: {
108
+ ...(request.params.message),
109
+ role: "ROLE_USER",
110
+ },
111
+ },
112
+ }, fetchImpl);
113
+ }
114
+ if ("error" in rpc) {
115
+ throw new Error(`A2A error ${rpc.error.code}: ${rpc.error.message}`);
116
+ }
117
+ const result = rpc.result;
118
+ const task = "task" in result && result.task ? result.task : result;
119
+ (0, runtime_1.emitNervesEvent)({
120
+ component: "channels",
121
+ event: "channel.a2a_message_send_end",
122
+ message: "sent A2A message",
123
+ meta: { endpointUrl: input.endpointUrl, messageId, taskId: task.id },
124
+ });
125
+ return task;
126
+ }
127
+ /**
128
+ * POST a pre-built friends A2A message (a `wrapInDataPart` sealed-envelope message)
129
+ * to a peer endpoint as a JSON-RPC `message/send`. This is the `direct`-rung wire
130
+ * the harness `A2ATransport` uses: friends' `sendShare` builds the sealed message and
131
+ * hands it to the transport, which delivers it here. Unlike `sendA2AMessage` (which
132
+ * builds a text part), this carries the caller's exact `message` (the sealed DataPart)
133
+ * untouched. Throws on a non-2xx response (transport failure).
134
+ */
135
+ async function postA2AMessageEnvelope(input) {
136
+ const fetchImpl = input.fetchImpl ?? fetch;
137
+ const request = {
138
+ jsonrpc: "2.0",
139
+ id: (0, node_crypto_1.randomUUID)(),
140
+ method: "message/send",
141
+ params: { message: input.message },
142
+ };
143
+ (0, runtime_1.emitNervesEvent)({
144
+ component: "channels",
145
+ event: "channel.a2a_envelope_post_start",
146
+ message: "posting sealed A2A message envelope (direct rung)",
147
+ meta: { endpointUrl: input.endpointUrl },
148
+ });
149
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
150
+ if (methodNotFound(rpc)) {
151
+ rpc = await postJsonRpc(input.endpointUrl, { ...request, method: "SendMessage" }, fetchImpl);
152
+ }
153
+ if ("error" in rpc) {
154
+ throw new Error(`A2A error ${rpc.error.code}: ${rpc.error.message}`);
155
+ }
156
+ (0, runtime_1.emitNervesEvent)({
157
+ component: "channels",
158
+ event: "channel.a2a_envelope_post_end",
159
+ message: "posted sealed A2A message envelope",
160
+ meta: { endpointUrl: input.endpointUrl },
161
+ });
162
+ }
163
+ async function getA2ATask(input) {
164
+ const fetchImpl = input.fetchImpl ?? fetch;
165
+ const metadata = senderMetadata(input);
166
+ const request = {
167
+ jsonrpc: "2.0",
168
+ id: (0, node_crypto_1.randomUUID)(),
169
+ method: "tasks/get",
170
+ params: {
171
+ id: input.taskId,
172
+ ...(input.accessToken ? { accessToken: input.accessToken } : {}),
173
+ ...(Object.keys(metadata).length > 0 ? { metadata } : {}),
174
+ },
175
+ };
176
+ (0, runtime_1.emitNervesEvent)({
177
+ component: "channels",
178
+ event: "channel.a2a_task_get",
179
+ message: "fetching A2A task",
180
+ meta: { endpointUrl: input.endpointUrl, taskId: input.taskId },
181
+ });
182
+ let rpc = await postJsonRpc(input.endpointUrl, request, fetchImpl, "0.3");
183
+ if (methodNotFound(rpc)) {
184
+ rpc = await postJsonRpc(input.endpointUrl, { ...request, method: "GetTask" }, fetchImpl);
185
+ }
186
+ if ("error" in rpc) {
187
+ throw new Error(`A2A error ${rpc.error.code}: ${rpc.error.message}`);
188
+ }
189
+ return rpc.result;
190
+ }
191
+ /**
192
+ * Talk to an A2A agent as a verified friend: seal `text` to the agent's card DID,
193
+ * signed by `identity`, send it, and open the sealed reply. The card must serve a
194
+ * did:key bound to it (the same check onboarding applies), so the reply can only be
195
+ * accepted from that key. Neither direction ever travels in plaintext.
196
+ */
197
+ async function sendSealedA2AChat(input) {
198
+ const fetchImpl = input.fetchImpl ?? fetch;
199
+ const sodium = input.sodium ?? await (0, a2a_client_1.ready)();
200
+ const card = await fetchA2AAgentCard(input.cardUrl, fetchImpl);
201
+ const peerDid = cardDid(card);
202
+ if (!peerDid)
203
+ throw new Error(`A2A card ${input.cardUrl} serves no DID; sealed chat needs one`);
204
+ const parsed = (0, a2a_client_1.parseDidKey)(peerDid);
205
+ if (!parsed || !(0, a2a_client_1.verifyCardDidBinding)({ card: { did: peerDid, url: input.cardUrl }, did: peerDid, didDoc: null })) {
206
+ throw new Error(`A2A card↔DID binding failed for ${peerDid}`);
207
+ }
208
+ const endpointUrl = endpointForCard(card);
209
+ const conversationId = input.conversationId ?? (0, node_crypto_1.randomUUID)();
210
+ const sealed = (0, sealed_chat_1.sealChatMessage)({
211
+ sodium,
212
+ from: input.identity,
213
+ recipientDid: peerDid,
214
+ recipientEd25519Pub: parsed.ed25519Pub,
215
+ text: input.text,
216
+ conversationId,
217
+ ...(input.onBehalfOf ? { onBehalfOf: input.onBehalfOf } : {}),
218
+ });
219
+ const request = {
220
+ jsonrpc: "2.0",
221
+ id: (0, node_crypto_1.randomUUID)(),
222
+ method: "SendMessage",
223
+ params: { message: { kind: "message", role: "ROLE_USER", messageId: (0, node_crypto_1.randomUUID)(), contextId: conversationId, parts: sealed.parts } },
224
+ };
225
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_chat_send_start", message: "sending sealed A2A chat message", meta: { endpointUrl, peerDid } });
226
+ const rpc = await postJsonRpc(endpointUrl, request, fetchImpl);
227
+ if ("error" in rpc)
228
+ throw new Error(`A2A error ${rpc.error.code}: ${rpc.error.message}`);
229
+ const task = rpc.result;
230
+ const replyMessage = task?.status?.message;
231
+ if (!replyMessage)
232
+ throw new Error("A2A chat returned no reply message");
233
+ const opened = await (0, sealed_chat_1.openChatMessage)({ sodium, self: input.identity, message: replyMessage, senderDid: peerDid, senderEd25519Pub: parsed.ed25519Pub });
234
+ if (!opened.ok)
235
+ throw new Error(`A2A chat reply rejected: ${opened.reason}`);
236
+ (0, runtime_1.emitNervesEvent)({ component: "channels", event: "channel.a2a_chat_send_end", message: "received sealed A2A chat reply", meta: { endpointUrl, peerDid, taskId: task.id } });
237
+ return { text: opened.text, conversationId, taskId: task.id, peerDid, peerName: card.name };
238
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.A2A_DEFAULT_PATH = exports.A2A_DEFAULT_HOST = exports.A2A_DEFAULT_PROTOCOL_VERSION = void 0;
4
+ exports.defaultA2APort = defaultA2APort;
5
+ exports.normalizeA2APath = normalizeA2APath;
6
+ exports.a2aEndpointFromBaseUrl = a2aEndpointFromBaseUrl;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const runtime_1 = require("../nerves/runtime");
9
+ exports.A2A_DEFAULT_PROTOCOL_VERSION = "1.0";
10
+ exports.A2A_DEFAULT_HOST = "127.0.0.1";
11
+ exports.A2A_DEFAULT_PATH = "/a2a";
12
+ function defaultA2APort(agentName) {
13
+ const digest = (0, node_crypto_1.createHash)("sha256").update(agentName).digest();
14
+ const port = 18920 + (digest[0] % 60);
15
+ (0, runtime_1.emitNervesEvent)({
16
+ component: "channels",
17
+ event: "channel.a2a_default_port",
18
+ message: "computed default A2A port",
19
+ meta: { agentName, port },
20
+ });
21
+ return port;
22
+ }
23
+ function normalizeA2APath(value) {
24
+ const trimmed = value?.trim();
25
+ const normalized = !trimmed
26
+ ? exports.A2A_DEFAULT_PATH
27
+ : trimmed.startsWith("/")
28
+ ? trimmed
29
+ : `/${trimmed}`;
30
+ (0, runtime_1.emitNervesEvent)({
31
+ component: "channels",
32
+ event: "channel.a2a_path_normalized",
33
+ message: "normalized A2A path",
34
+ meta: { normalized },
35
+ });
36
+ return normalized;
37
+ }
38
+ function a2aEndpointFromBaseUrl(baseUrl, a2aPath = exports.A2A_DEFAULT_PATH) {
39
+ const url = new URL(baseUrl);
40
+ url.pathname = normalizeA2APath(a2aPath);
41
+ url.search = "";
42
+ url.hash = "";
43
+ (0, runtime_1.emitNervesEvent)({
44
+ component: "channels",
45
+ event: "channel.a2a_endpoint_built",
46
+ message: "built A2A endpoint URL",
47
+ meta: { endpoint: url.toString() },
48
+ });
49
+ return url.toString();
50
+ }
@@ -0,0 +1,151 @@
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.DELEGATED_BANNER = exports.A2A_PRINCIPAL_PROFILE_ID = void 0;
37
+ exports.delegatedCommandWasNoticed = delegatedCommandWasNoticed;
38
+ exports.delegatedCommandNotice = delegatedCommandNotice;
39
+ exports.admitDelegatedCommand = admitDelegatedCommand;
40
+ const crypto_1 = require("crypto");
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const runtime_1 = require("../nerves/runtime");
44
+ const replay_harness_1 = require("./replay-harness");
45
+ const relationship_authorization_1 = require("../repertoire/relationship-authorization");
46
+ const NOTICE_EXCERPT_CHARS = 200;
47
+ /** The relationship profile that names the principal a delegated peer acts for. */
48
+ exports.A2A_PRINCIPAL_PROFILE_ID = "sanctuary-owner";
49
+ /**
50
+ * True when the owner was told about delegated command `commandId` in their own chat: admission only runs a command
51
+ * after that notice is delivered, and the Telegram effect journal keeps the notice under a key derived from the
52
+ * command id. A request id with no such record never came through a signed, owner-notified delegated command.
53
+ * A missing record is `false`; an unreadable or malformed one throws, so the caller retries instead of deciding.
54
+ */
55
+ function delegatedCommandWasNoticed(agentRoot, commandId, principalFriendId, delegateFriendId) {
56
+ const idempotencyKey = `owner-notice:delegated:${commandId}`;
57
+ const file = path.join(agentRoot, "state", "telegram", "effects", `${(0, crypto_1.createHash)("sha256").update(idempotencyKey).digest("hex")}.json`);
58
+ let raw;
59
+ try {
60
+ raw = fs.readFileSync(file, "utf8");
61
+ }
62
+ catch (error) {
63
+ if (error.code === "ENOENT")
64
+ return delegateFriendId !== undefined && (0, replay_harness_1.isReplayWindowOpen)(agentRoot, delegateFriendId) && (0, replay_harness_1.replayNoticeRecorded)(agentRoot, `delegated:${commandId}`, delegateFriendId);
65
+ throw error;
66
+ }
67
+ const artifact = JSON.parse(raw);
68
+ return artifact.idempotencyKey === idempotencyKey && artifact.authorClass === "butler" && artifact.target?.friendId === principalFriendId;
69
+ }
70
+ /** Matches the banner only the server may put in front of an admitted command. */
71
+ exports.DELEGATED_BANNER = /^\s*\[\s*delegated command/iu;
72
+ function delegatedCommandNotice(input) {
73
+ const flat = input.text.replace(/\s+/gu, " ").trim();
74
+ const excerpt = flat.length > NOTICE_EXCERPT_CHARS ? `${flat.slice(0, NOTICE_EXCERPT_CHARS)}…` : flat;
75
+ return `Delegated command from you via ${input.delegateName}: "${excerpt}". If this wasn't you, say so here: it is on record, and the grant can be revoked.`;
76
+ }
77
+ function hasPrincipalGrant(friend) {
78
+ return friend.delegationGrant?.scope === "principal_commands";
79
+ }
80
+ async function resolvePrincipal(store, profileId) {
81
+ const friends = await store.listAll?.() ?? [];
82
+ const matches = friends.filter((friend) => friend.capabilityProfileId === profileId
83
+ && friend.trustLevel === "family" && friend.admissionState === "active");
84
+ return matches.length === 1 ? matches[0] : null;
85
+ }
86
+ async function admitDelegatedCommand(input) {
87
+ const refuse = (reason) => {
88
+ (0, runtime_1.emitNervesEvent)({
89
+ level: "warn",
90
+ component: "senses",
91
+ event: "senses.a2a_delegated_command_refused",
92
+ message: "refused a delegated A2A command",
93
+ meta: { reason, delegateFriendId: input.friend.id, commandId: input.commandId },
94
+ });
95
+ return { ok: false, reason };
96
+ };
97
+ if (!input.options)
98
+ return refuse("not_enabled");
99
+ if (!hasPrincipalGrant(input.friend))
100
+ return refuse("no_grant");
101
+ if (input.friend.trustLevel !== "family" || input.friend.admissionState === "revoked")
102
+ return refuse("not_family");
103
+ const registry = input.registry;
104
+ if (!registry)
105
+ return refuse("principal_unresolved");
106
+ const principal = await resolvePrincipal(input.store, input.options.principalProfileId);
107
+ if (!principal || principal.id === input.friend.id)
108
+ return refuse("principal_unresolved");
109
+ const noticeId = `delegated:${input.commandId}`;
110
+ try {
111
+ const text = delegatedCommandNotice({ delegateName: input.friend.name, text: input.text });
112
+ const agentRoot = input.options.agentRoot;
113
+ if (agentRoot && (0, replay_harness_1.isReplayWindowOpen)(agentRoot, input.friend.id))
114
+ (0, replay_harness_1.appendReplayNotice)(agentRoot, { noticeId, text, friendId: input.friend.id });
115
+ else
116
+ await input.options.notifyPrincipal({ noticeId, text });
117
+ }
118
+ catch {
119
+ return refuse("notice_failed");
120
+ }
121
+ // Owner-gated tools (steward policy) bind the mutation to `requestId` on the tool
122
+ // context's relationship, as the Telegram owner turn does; the evaluator alone
123
+ // only scopes its receipts by it, so carry it on the relationship itself.
124
+ const relationship = {
125
+ ...(0, relationship_authorization_1.createRelationshipAuthorizationEvaluator)({
126
+ friend: principal,
127
+ registry,
128
+ requestId: input.commandId,
129
+ requestPhase: "inbound",
130
+ sessionEventId: `a2a-delegated:${input.commandId}`,
131
+ }),
132
+ requestId: input.commandId,
133
+ };
134
+ const context = {
135
+ principalFriendId: principal.id,
136
+ principalName: principal.name,
137
+ delegateFriendId: input.friend.id,
138
+ delegateName: input.friend.name,
139
+ delegateDid: input.did,
140
+ commandId: input.commandId,
141
+ noticeId,
142
+ };
143
+ (0, runtime_1.emitNervesEvent)({
144
+ component: "senses",
145
+ event: "senses.a2a_delegated_command_admitted",
146
+ message: "admitted a delegated A2A command after notifying the principal",
147
+ meta: { delegateFriendId: context.delegateFriendId, principalFriendId: context.principalFriendId, commandId: context.commandId },
148
+ });
149
+ const turnText = `[delegated command from ${principal.name} via ${input.friend.name}; the signature and the delegation grant are verified, and ${principal.name} has been notified; act on it as ${principal.name}'s own request]\n\n${input.text}`;
150
+ return { ok: true, relationship, context, turnText };
151
+ }
@@ -0,0 +1,56 @@
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.delegationStoresFor = delegationStoresFor;
37
+ const path = __importStar(require("node:path"));
38
+ const friends_1 = require("@ouro.bot/friends");
39
+ const runtime_1 = require("../nerves/runtime");
40
+ function delegationStoresFor(agentRoot) {
41
+ const friendsDir = path.join(agentRoot, "friends");
42
+ const missionsDir = (0, friends_1.missionsDirFor)(friendsDir);
43
+ const grantsDir = (0, friends_1.grantsDirFor)(friendsDir);
44
+ (0, runtime_1.emitNervesEvent)({
45
+ component: "channels",
46
+ event: "channel.a2a_delegation_stores_init",
47
+ message: "initialized A2A delegation stores (mission + grant)",
48
+ meta: { missionsDir, grantsDir },
49
+ });
50
+ return {
51
+ missionStore: new friends_1.FileMissionStore(missionsDir),
52
+ grantStore: new friends_1.FileGrantStore(grantsDir),
53
+ missionsDir,
54
+ grantsDir,
55
+ };
56
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeDidResolution = makeDidResolution;
4
+ const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
5
+ const runtime_1 = require("../nerves/runtime");
6
+ /**
7
+ * Build the friends `DidResolution` for did:key peers. `resolveAndPin` is the
8
+ * verify-and-pin core the inbound bridge consumes:
9
+ * parse the did:key → derive the presented Ed25519 key →
10
+ * first contact (no pin under `fromAgentId`) → TOFU `pinOnFirstContact`
11
+ * already pinned → `evaluateRotation` against the pin:
12
+ * unchanged → pin-hit, return the pinned key
13
+ * accepted → (re-pinned by evaluateRotation) return the NEW key
14
+ * rejected → loud security event, return null
15
+ *
16
+ * The pin is keyed by the STABLE `fromAgentId` (NOT the did:key string), so a
17
+ * rotation is "same `fromAgentId`, new (did, key)". An unparseable or empty DID is
18
+ * refused (null) and never matchable. The crypto is the friends primitives' — this
19
+ * only sequences them.
20
+ */
21
+ function makeDidResolution(input) {
22
+ const { sodium, rotationProofFor } = input;
23
+ return {
24
+ async resolveAndPin(args) {
25
+ const { fromAgentId, did, pinStore, trustOfSource } = args;
26
+ // Empty DID is never a matchable key.
27
+ if (!did) {
28
+ (0, runtime_1.emitNervesEvent)({
29
+ component: "channels",
30
+ event: "channel.a2a_did_resolve_refused",
31
+ message: "A2A DID resolve refused (empty DID)",
32
+ meta: { fromAgentId, reason: "empty_did" },
33
+ });
34
+ return null;
35
+ }
36
+ const parsed = (0, a2a_client_1.parseDidKey)(did);
37
+ if (!parsed) {
38
+ (0, runtime_1.emitNervesEvent)({
39
+ component: "channels",
40
+ event: "channel.a2a_did_resolve_refused",
41
+ message: "A2A DID resolve refused (unparseable did:key)",
42
+ meta: { fromAgentId, reason: "parse_failed" },
43
+ });
44
+ return null;
45
+ }
46
+ const pinned = pinStore.get(fromAgentId);
47
+ if (!pinned) {
48
+ // First contact (TOFU): accept + pin the (did, key) under fromAgentId.
49
+ (0, a2a_client_1.pinOnFirstContact)({ pinStore, fromAgentId, did, ed25519Pub: parsed.ed25519Pub });
50
+ (0, runtime_1.emitNervesEvent)({
51
+ component: "channels",
52
+ event: "channel.a2a_pin_first_contact",
53
+ message: "A2A DID pinned on first contact",
54
+ meta: { fromAgentId, did },
55
+ });
56
+ return { ed25519Pub: parsed.ed25519Pub };
57
+ }
58
+ // Already pinned: evaluate the presented key against the pin.
59
+ const rotationProof = rotationProofFor?.(fromAgentId, did, parsed.ed25519Pub);
60
+ const decision = (0, a2a_client_1.evaluateRotation)({
61
+ sodium,
62
+ pinStore,
63
+ fromAgentId,
64
+ trustOfSource,
65
+ newDid: did,
66
+ newEd25519Pub: parsed.ed25519Pub,
67
+ rotationProof,
68
+ });
69
+ if (decision.decision === "unchanged") {
70
+ // Same key — pin-hit. (FileA2APinStore.get already emitted a2a_pin_hit.)
71
+ return { ed25519Pub: parsed.ed25519Pub };
72
+ }
73
+ if (decision.decision === "accepted") {
74
+ // evaluateRotation already re-pinned to the new key under fromAgentId.
75
+ (0, runtime_1.emitNervesEvent)({
76
+ component: "channels",
77
+ event: "channel.a2a_rotation_accepted",
78
+ message: "A2A signed key rotation accepted",
79
+ meta: { fromAgentId, newDid: did, trustOfSource },
80
+ });
81
+ return { ed25519Pub: parsed.ed25519Pub };
82
+ }
83
+ // Rejected — loud security signal (carries the reason).
84
+ (0, runtime_1.emitNervesEvent)({
85
+ component: "channels",
86
+ event: "channel.a2a_rotation_rejected",
87
+ message: "A2A key rotation rejected",
88
+ meta: { fromAgentId, newDid: did, trustOfSource, reason: decision.reason },
89
+ });
90
+ return null;
91
+ },
92
+ };
93
+ }