@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -23
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/assets/bluebubbles-host +264 -0
- package/assets/sanctuary-host-launcher.sh +16 -0
- package/changelog.json +5308 -16
- package/deploy/unraid/Dockerfile +54 -0
- package/deploy/unraid/README.txt +2983 -0
- package/deploy/unraid/audit-container-spec.sh +4 -0
- package/deploy/unraid/container-runtime.json +1 -0
- package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
- package/deploy/unraid/docker-man-template-xml.cjs +105 -0
- package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
- package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
- package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
- package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
- package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
- package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
- package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
- package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
- package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
- package/deploy/unraid/sanctuary-authority-installation.json +36 -0
- package/deploy/unraid/sanctuary-authority-service.sh +30 -0
- package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
- package/deploy/unraid/sanctuary-safe-rename.py +24 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
- package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
- package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
- package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
- package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
- package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
- package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
- package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
- package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
- package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
- package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
- package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
- package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
- package/deploy/unraid/sanctuary.xml +28 -0
- package/dist/a2a/card.js +57 -0
- package/dist/a2a/client.js +180 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/delegation-stores.js +56 -0
- package/dist/a2a/did-resolution.js +93 -0
- package/dist/a2a/identity.js +170 -0
- package/dist/a2a/inbound-share.js +107 -0
- package/dist/a2a/mission-result-wire.js +196 -0
- package/dist/a2a/onboarding.js +115 -0
- package/dist/a2a/pin-store.js +132 -0
- package/dist/a2a/seen-ledger.js +120 -0
- package/dist/a2a/server.js +604 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/transport.js +45 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +360 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +490 -0
- package/dist/arc/flight-recorder.js +1034 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +386 -0
- package/dist/arc/packets.js +336 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +57 -0
- package/dist/commerce/store.js +755 -0
- package/dist/commerce/types.js +3 -0
- package/dist/heart/active-work.js +798 -40
- package/dist/heart/agent-entry.js +252 -3
- package/dist/heart/approval-files.js +113 -0
- package/dist/heart/approval-store.js +960 -0
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +18 -0
- package/dist/heart/attachments/sources/telegram.js +71 -0
- package/dist/heart/attachments/store.js +132 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +495 -0
- package/dist/heart/autonomy-budget.js +478 -0
- package/dist/heart/awaiting/await-alert.js +148 -0
- package/dist/heart/awaiting/await-expiry.js +143 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +149 -0
- package/dist/heart/awaiting/await-runtime-state.js +111 -0
- package/dist/heart/awaiting/await-scheduler.js +382 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +137 -17
- package/dist/heart/bridges/store.js +14 -2
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +44 -18
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +174 -131
- package/dist/heart/context-loss-gauntlet.js +387 -0
- package/dist/heart/context-loss-sentinel.js +1157 -0
- package/dist/heart/core.js +2169 -581
- package/dist/heart/cross-chat-delivery.js +9 -22
- package/dist/heart/daemon/agent-config-check.js +451 -0
- package/dist/heart/daemon/agent-discovery.js +185 -3
- package/dist/heart/daemon/agent-service.js +542 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/await-private-wake.js +59 -0
- package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
- package/dist/heart/daemon/bluebubbles-host.js +273 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +180 -0
- package/dist/heart/daemon/cli-defaults.js +854 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +8822 -0
- package/dist/heart/daemon/cli-help.js +716 -0
- package/dist/heart/daemon/cli-parse.js +2771 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +777 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
- package/dist/heart/daemon/container-healthcheck.js +112 -0
- package/dist/heart/daemon/container-runtime.js +97 -0
- package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
- package/dist/heart/daemon/container-spec-auditor.js +229 -0
- package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
- package/dist/heart/daemon/daemon-cli.js +29 -2349
- package/dist/heart/daemon/daemon-entry.js +930 -11
- package/dist/heart/daemon/daemon-health.js +186 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +2084 -105
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +1755 -0
- package/dist/heart/daemon/freshness.js +345 -0
- package/dist/heart/daemon/habit-private-wake.js +61 -0
- package/dist/heart/daemon/health-monitor.js +142 -11
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +78 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +79 -10
- package/dist/heart/daemon/logs-prune.js +132 -0
- package/dist/heart/daemon/mcp-canary.js +524 -0
- package/dist/heart/daemon/message-router.js +65 -5
- package/dist/heart/daemon/migrate-to-desk.js +848 -0
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +22 -14
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +733 -61
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/prunable-bundle.js +144 -0
- package/dist/heart/daemon/pulse.js +511 -0
- package/dist/heart/daemon/readiness-repair.js +365 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +47 -14
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/runtime-mode.js +13 -2
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
- package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
- package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
- package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
- package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
- package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
- package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
- package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
- package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
- package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
- package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
- package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
- package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
- package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
- package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
- package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
- package/dist/heart/daemon/sanctuary-package-management.js +103 -0
- package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
- package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
- package/dist/heart/daemon/sense-manager.js +699 -48
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +1 -1
- package/dist/heart/daemon/socket-client.js +180 -12
- package/dist/heart/daemon/stale-bundle-prune.js +113 -0
- package/dist/heart/daemon/startup-tui.js +339 -0
- package/dist/heart/daemon/supercronic-supervisor.js +282 -0
- package/dist/heart/daemon/task-scheduler.js +117 -39
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +138 -54
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -4
- package/dist/heart/external-events/router.js +1430 -0
- package/dist/heart/frontend-approval-runtime.js +506 -0
- package/dist/heart/frontend-journal.js +215 -0
- package/dist/heart/frontend-session-service.js +237 -0
- package/dist/heart/frontend-socket-client.js +164 -0
- package/dist/heart/frontend-socket.js +400 -0
- package/dist/heart/habits/habit-cancel.js +810 -0
- package/dist/heart/habits/habit-lifecycle.js +1327 -0
- package/dist/heart/habits/habit-migration.js +194 -0
- package/dist/heart/habits/habit-parser.js +278 -0
- package/dist/heart/habits/habit-runtime-state.js +93 -0
- package/dist/heart/habits/habit-scheduler.js +653 -0
- package/dist/heart/habits/habit-session-summary.js +318 -0
- package/dist/heart/habits/habit-session.js +636 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
- package/dist/heart/identity.js +196 -59
- package/dist/heart/kept-notes.js +289 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +356 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +39 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +197 -0
- package/dist/heart/mailbox/readers/agent-machine.js +428 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
- package/dist/heart/mailbox/readers/sessions.js +231 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +11 -0
- package/dist/heart/orientation-frame.js +345 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/primitives.js +1 -1
- package/dist/heart/private-runtime/decision-renderer.js +158 -0
- package/dist/heart/private-runtime/index.js +18 -0
- package/dist/heart/private-runtime/ledger.js +221 -0
- package/dist/heart/private-runtime/policy.js +252 -0
- package/dist/heart/private-runtime/types.js +2 -0
- package/dist/heart/progress-story.js +1 -1
- package/dist/heart/provider-attempt.js +137 -0
- package/dist/heart/provider-binding-resolver.js +273 -0
- package/dist/heart/provider-credentials.js +449 -0
- package/dist/heart/provider-failover.js +311 -0
- package/dist/heart/provider-models.js +96 -0
- package/dist/heart/provider-ping.js +265 -0
- package/dist/heart/provider-readiness-cache.js +119 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +173 -60
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +34 -38
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex-token.js +349 -0
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/providers/openai-compatible.js +177 -0
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +607 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +22 -4
- package/dist/heart/session-activity.js +92 -24
- package/dist/heart/session-events.js +1504 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-redaction-repair-cli-main.js +31 -0
- package/dist/heart/session-redaction-repair.js +552 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +183 -0
- package/dist/heart/session-transcript.js +133 -0
- package/dist/heart/start-of-turn-packet.js +372 -0
- package/dist/heart/steward-policy.js +618 -0
- package/dist/heart/streaming.js +604 -207
- package/dist/heart/structured-output.js +196 -0
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +11 -7
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-approval.js +382 -0
- package/dist/heart/tool-description.js +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +482 -0
- package/dist/heart/turn-execution-lease.js +30 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +432 -0
- package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
- package/dist/heart/versioning/ouro-version-manager.js +409 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/versioning/update-hooks.js +154 -0
- package/dist/heart/versioning/version-intent.js +114 -0
- package/dist/heart/work-card.js +380 -0
- package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
- package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
- package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
- package/dist/mailbox-ui/index.html +16 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +889 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/cache-sync-cli.js +58 -0
- package/dist/mailroom/core.js +803 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +568 -0
- package/dist/mailroom/hosted-cache-sync.js +384 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +292 -0
- package/dist/mailroom/search-cache.js +513 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +24 -2
- package/dist/mind/context.js +309 -111
- package/dist/mind/desk-section.js +362 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -77
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +199 -3
- package/dist/mind/pending.js +36 -10
- package/dist/mind/prompt-budget.js +479 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1050 -189
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/record-paths.js +312 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/session-transaction.js +564 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +139 -5
- package/dist/nerves/coverage/run-artifacts.js +55 -35
- package/dist/nerves/coverage/source-scanner.js +4 -4
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +293 -9
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +159 -0
- package/dist/nerves/runtime.js +17 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +16 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +1045 -0
- package/dist/repertoire/bundle-templates.js +71 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +331 -0
- package/dist/repertoire/coding/feedback.js +174 -32
- package/dist/repertoire/coding/index.js +15 -3
- package/dist/repertoire/coding/manager.js +159 -10
- package/dist/repertoire/coding/spawner.js +58 -11
- package/dist/repertoire/coding/tools.js +221 -15
- package/dist/repertoire/coding/workbench-client.js +272 -0
- package/dist/repertoire/coding/workbench-manager.js +346 -0
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +178 -0
- package/dist/repertoire/desk/classifier.js +362 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +811 -18
- package/dist/repertoire/mcp-client.js +44 -3
- package/dist/repertoire/mcp-manager.js +427 -139
- package/dist/repertoire/mcp-tools.js +124 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/relationship-authorization.js +322 -0
- package/dist/repertoire/shell-sessions.js +134 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-arguments.js +170 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +699 -0
- package/dist/repertoire/tools-attachments.js +322 -0
- package/dist/repertoire/tools-awaiting.js +575 -0
- package/dist/repertoire/tools-base.js +77 -1138
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +993 -0
- package/dist/repertoire/tools-commerce.js +253 -0
- package/dist/repertoire/tools-config.js +186 -0
- package/dist/repertoire/tools-continuity.js +575 -0
- package/dist/repertoire/tools-credential.js +383 -0
- package/dist/repertoire/tools-evolution.js +527 -0
- package/dist/repertoire/tools-files.js +344 -0
- package/dist/repertoire/tools-flight.js +290 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +3 -8
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools-mail.js +1828 -0
- package/dist/repertoire/tools-notes.js +485 -0
- package/dist/repertoire/tools-obligations.js +182 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +482 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/repertoire/tools-runtime.js +150 -0
- package/dist/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools-session.js +1133 -0
- package/dist/repertoire/tools-shell.js +149 -0
- package/dist/repertoire/tools-steward-policy.js +119 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +369 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-telegram-contacts.js +37 -0
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -0
- package/dist/repertoire/tools-unraid.js +531 -0
- package/dist/repertoire/tools-user-profile.js +146 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +145 -0
- package/dist/repertoire/tools.js +494 -148
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/unraid-client.js +155 -0
- package/dist/repertoire/unraid-restart.js +339 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +628 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +926 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +433 -0
- package/dist/rsvp/diagnostics.js +232 -0
- package/dist/rsvp/diff-renderer.js +176 -0
- package/dist/rsvp/habit-policy.js +110 -0
- package/dist/rsvp/habit-stage.js +123 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/native-habit-runner.js +630 -0
- package/dist/rsvp/outbound-state.js +628 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/rsvp/spend-ledger.js +175 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/a2a-entry.js +115 -0
- package/dist/senses/acp-server.js +386 -0
- package/dist/senses/attention-queue.js +186 -0
- package/dist/senses/await-turn-message.js +58 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +355 -40
- package/dist/senses/bluebubbles/context-packet.js +207 -0
- package/dist/senses/bluebubbles/context-smoke.js +144 -0
- package/dist/senses/bluebubbles/entry.js +90 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
- package/dist/senses/bluebubbles/index.js +3841 -0
- package/dist/senses/bluebubbles/latest-turn.js +311 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
- package/dist/senses/bluebubbles/outbound-state.js +308 -0
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/reaction-policy.js +47 -0
- package/dist/senses/bluebubbles/replay.js +284 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles/webhook-registration.js +228 -0
- package/dist/senses/bluebubbles-meta-guard.js +39 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +607 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +85 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +241 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli.js +604 -320
- package/dist/senses/commands.js +66 -3
- package/dist/senses/context-packet-ledger.js +371 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/habit-lifecycle-guard.js +24 -0
- package/dist/senses/habit-turn-message.js +160 -0
- package/dist/senses/ingress-evidence.js +2 -0
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +524 -0
- package/dist/senses/pipeline.js +1115 -204
- package/dist/senses/private-runtime-worker.js +859 -0
- package/dist/senses/private-runtime.js +1517 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/root-host-approval-port.js +345 -0
- package/dist/senses/root-host-approval-runtime.js +393 -0
- package/dist/senses/sanctuary-authority-resident.js +102 -0
- package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
- package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
- package/dist/senses/sanctuary-grounding.js +118 -0
- package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
- package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
- package/dist/senses/sanctuary-health-runner.js +100 -0
- package/dist/senses/sanctuary-health.js +408 -0
- package/dist/senses/sanctuary-install-state-contract.js +126 -0
- package/dist/senses/sanctuary-interactive-control.js +410 -0
- package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
- package/dist/senses/sanctuary-media-optimization.js +514 -0
- package/dist/senses/sanctuary-runtime.js +340 -0
- package/dist/senses/sanctuary-sab.js +85 -0
- package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
- package/dist/senses/shared-turn.js +772 -0
- package/dist/senses/surface-tool.js +109 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +519 -218
- package/dist/senses/telegram-admission.js +718 -0
- package/dist/senses/telegram-approval-runtime.js +793 -0
- package/dist/senses/telegram-attachments.js +186 -0
- package/dist/senses/telegram-audit-ledger.js +220 -0
- package/dist/senses/telegram-authority-transport.js +231 -0
- package/dist/senses/telegram-client.js +1749 -0
- package/dist/senses/telegram-effect-adapter.js +896 -0
- package/dist/senses/telegram-entry.js +83 -0
- package/dist/senses/telegram.js +2324 -0
- package/dist/senses/trust-gate.js +104 -9
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +807 -0
- package/dist/senses/voice/twilio-phone.js +5031 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/dist/util/frontmatter.js +69 -0
- package/npm-shrinkwrap.json +8138 -0
- package/package.json +72 -13
- package/skills/agent-commerce.md +113 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -430
- package/dist/heart/daemon/ouro-path-installer.js +0 -260
- package/dist/heart/daemon/ouro-version-manager.js +0 -171
- package/dist/heart/daemon/update-hooks.js +0 -138
- package/dist/heart/obligations.js +0 -191
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/friends/channel.js +0 -84
- package/dist/mind/friends/group-context.js +0 -144
- package/dist/mind/friends/resolver.js +0 -84
- package/dist/mind/friends/store-file.js +0 -190
- package/dist/mind/friends/store.js +0 -4
- package/dist/mind/friends/tokens.js +0 -26
- package/dist/mind/friends/trust-explanation.js +0 -74
- package/dist/mind/friends/types.js +0 -29
- package/dist/repertoire/tasks/board.js +0 -134
- package/dist/repertoire/tasks/index.js +0 -224
- package/dist/repertoire/tasks/lifecycle.js +0 -80
- package/dist/repertoire/tasks/middleware.js +0 -65
- package/dist/repertoire/tasks/parser.js +0 -173
- package/dist/repertoire/tasks/scanner.js +0 -132
- package/dist/repertoire/tasks/transitions.js +0 -144
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1181
- package/dist/senses/debug-activity.js +0 -154
- package/dist/senses/inner-dialog-worker.js +0 -90
- package/dist/senses/inner-dialog.js +0 -525
- package/subagents/README.md +0 -7
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
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.readStoredA2ASeed = readStoredA2ASeed;
|
|
37
|
+
exports.loadOrMintA2AIdentity = loadOrMintA2AIdentity;
|
|
38
|
+
exports.loadSelfA2AIdentity = loadSelfA2AIdentity;
|
|
39
|
+
const crypto = __importStar(require("node:crypto"));
|
|
40
|
+
const os = __importStar(require("node:os"));
|
|
41
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
const runtime_credentials_1 = require("../heart/runtime-credentials");
|
|
44
|
+
const machine_identity_1 = require("../heart/machine-identity");
|
|
45
|
+
/** The number of raw bytes in an Ed25519 seed. */
|
|
46
|
+
const ED25519_SEED_BYTES = 32;
|
|
47
|
+
/** The machine-config key path for the persisted seed: `a2a.identity.ed25519Seed`. */
|
|
48
|
+
function a2aIdentityConfig(config) {
|
|
49
|
+
const a2a = config.a2a;
|
|
50
|
+
if (!a2a || typeof a2a !== "object" || Array.isArray(a2a))
|
|
51
|
+
return undefined;
|
|
52
|
+
const identity = a2a.identity;
|
|
53
|
+
if (!identity || typeof identity !== "object" || Array.isArray(identity))
|
|
54
|
+
return undefined;
|
|
55
|
+
return identity;
|
|
56
|
+
}
|
|
57
|
+
/** Read the stored Ed25519 seed string from a machine-config object, or undefined. */
|
|
58
|
+
function readStoredA2ASeed(config) {
|
|
59
|
+
const identity = a2aIdentityConfig(config);
|
|
60
|
+
const seed = identity?.ed25519Seed;
|
|
61
|
+
return typeof seed === "string" && seed.length > 0 ? seed : undefined;
|
|
62
|
+
}
|
|
63
|
+
/** Decode + validate a stored seed string into 32 raw bytes. Throws on malformed. */
|
|
64
|
+
function decodeSeed(seedString) {
|
|
65
|
+
let decoded;
|
|
66
|
+
try {
|
|
67
|
+
decoded = Buffer.from(seedString, "base64url");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
/* v8 ignore next -- Buffer.from(base64url) does not throw on bad chars; this guards future decoders @preserve */
|
|
71
|
+
throw new Error("malformed A2A identity seed: not decodable");
|
|
72
|
+
}
|
|
73
|
+
// base64url is lenient (it silently drops invalid chars), so the length check is
|
|
74
|
+
// the real gate: a real Ed25519 seed is exactly 32 bytes.
|
|
75
|
+
if (decoded.length !== ED25519_SEED_BYTES) {
|
|
76
|
+
throw new Error(`malformed A2A identity seed: expected ${ED25519_SEED_BYTES}-byte seed, got ${decoded.length}`);
|
|
77
|
+
}
|
|
78
|
+
return new Uint8Array(decoded);
|
|
79
|
+
}
|
|
80
|
+
/** Mint a fresh 32-byte Ed25519 seed (Node keygen → JWK `d`, the raw seed). */
|
|
81
|
+
function mintSeed() {
|
|
82
|
+
const { privateKey } = crypto.generateKeyPairSync("ed25519");
|
|
83
|
+
const jwk = privateKey.export({ format: "jwk" });
|
|
84
|
+
/* v8 ignore next -- Node always emits the `d` field for an Ed25519 private JWK; guard protects future runtimes @preserve */
|
|
85
|
+
if (typeof jwk.d !== "string")
|
|
86
|
+
throw new Error("failed to mint A2A identity seed: missing JWK d");
|
|
87
|
+
return decodeSeed(jwk.d);
|
|
88
|
+
}
|
|
89
|
+
/** Derive the full did:key identity from a 32-byte seed (deterministic). */
|
|
90
|
+
function deriveIdentity(sodium, seed) {
|
|
91
|
+
const keypair = sodium.crypto_sign_seed_keypair(seed);
|
|
92
|
+
const didIdentity = (0, a2a_client_1.didKeyIdentityFromEd25519)({
|
|
93
|
+
sodium,
|
|
94
|
+
ed25519Pub: keypair.publicKey,
|
|
95
|
+
ed25519Priv: keypair.privateKey,
|
|
96
|
+
});
|
|
97
|
+
return { ...didIdentity, seed: Buffer.from(seed).toString("base64url") };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Load the agent's A2A identity from the machine-local config, or mint + persist
|
|
101
|
+
* one on first use. A malformed stored seed FAILS FAST (it never silently
|
|
102
|
+
* re-mints, which would change the agent's DID). The mint path persists the new
|
|
103
|
+
* seed via `upsert` before deriving; the load path performs no writes.
|
|
104
|
+
*/
|
|
105
|
+
async function loadOrMintA2AIdentity(input) {
|
|
106
|
+
const stored = readStoredA2ASeed(input.config);
|
|
107
|
+
if (stored) {
|
|
108
|
+
// Load path: a malformed seed throws (no re-mint).
|
|
109
|
+
const seed = decodeSeed(stored);
|
|
110
|
+
const identity = deriveIdentity(input.sodium, seed);
|
|
111
|
+
(0, runtime_1.emitNervesEvent)({
|
|
112
|
+
component: "channels",
|
|
113
|
+
event: "channel.a2a_identity_loaded",
|
|
114
|
+
message: "loaded A2A identity from machine config",
|
|
115
|
+
meta: { agentName: input.agentName, did: identity.did },
|
|
116
|
+
});
|
|
117
|
+
return identity;
|
|
118
|
+
}
|
|
119
|
+
// Mint path: generate a seed, persist it under a2a.identity.*, then derive.
|
|
120
|
+
const seed = mintSeed();
|
|
121
|
+
const seedString = Buffer.from(seed).toString("base64url");
|
|
122
|
+
const a2a = (input.config.a2a && typeof input.config.a2a === "object" && !Array.isArray(input.config.a2a)
|
|
123
|
+
? input.config.a2a
|
|
124
|
+
: {});
|
|
125
|
+
const identityBlock = (a2a.identity && typeof a2a.identity === "object" && !Array.isArray(a2a.identity)
|
|
126
|
+
? a2a.identity
|
|
127
|
+
: {});
|
|
128
|
+
const nextConfig = {
|
|
129
|
+
...input.config,
|
|
130
|
+
a2a: { ...a2a, identity: { ...identityBlock, ed25519Seed: seedString } },
|
|
131
|
+
};
|
|
132
|
+
await input.upsert(nextConfig);
|
|
133
|
+
const identity = deriveIdentity(input.sodium, seed);
|
|
134
|
+
(0, runtime_1.emitNervesEvent)({
|
|
135
|
+
component: "channels",
|
|
136
|
+
event: "channel.a2a_identity_minted",
|
|
137
|
+
message: "minted new A2A identity and persisted seed to machine config",
|
|
138
|
+
meta: { agentName: input.agentName, did: identity.did },
|
|
139
|
+
});
|
|
140
|
+
return identity;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Load (or mint-on-first-use) THIS agent's own A2A identity from the machine-local
|
|
144
|
+
* runtime config — the convenience entry the main-process tools use to obtain the
|
|
145
|
+
* self identity that signs outbound sealed envelopes. Mirrors the a2a sense
|
|
146
|
+
* entrypoint's load (use a cached seed when present, otherwise refresh machine
|
|
147
|
+
* config → `loadOrMintA2AIdentity` → merge a fresh seed under the right machine
|
|
148
|
+
* id). `sodium` is optional (defaults to `ready()`).
|
|
149
|
+
*/
|
|
150
|
+
async function loadSelfA2AIdentity(input) {
|
|
151
|
+
const sodium = input.sodium ?? await (0, a2a_client_1.ready)();
|
|
152
|
+
const machineId = (0, machine_identity_1.loadOrCreateMachineIdentity)({ homeDir: os.homedir() }).machineId;
|
|
153
|
+
const cached = (0, runtime_credentials_1.readMachineRuntimeCredentialConfig)(input.agentName);
|
|
154
|
+
const read = cached.ok && readStoredA2ASeed(cached.config)
|
|
155
|
+
? cached
|
|
156
|
+
: await (0, runtime_credentials_1.refreshMachineRuntimeCredentialConfig)(input.agentName, machineId);
|
|
157
|
+
if (!read.ok && read.reason !== "missing") {
|
|
158
|
+
throw new Error(`A2A identity requires readable machine runtime config at ${read.itemPath}: ${read.error}`);
|
|
159
|
+
}
|
|
160
|
+
const config = read.ok ? read.config : {};
|
|
161
|
+
return loadOrMintA2AIdentity({
|
|
162
|
+
agentName: input.agentName,
|
|
163
|
+
sodium,
|
|
164
|
+
config,
|
|
165
|
+
upsert: async (next) => {
|
|
166
|
+
const seed = readStoredA2ASeed(next);
|
|
167
|
+
await (0, runtime_credentials_1.mergeMachineRuntimeCredentialConfig)(input.agentName, machineId, { a2a: { identity: { ed25519Seed: seed } } });
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.receiveInboundShare = receiveInboundShare;
|
|
4
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
5
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
6
|
+
const runtime_1 = require("../nerves/runtime");
|
|
7
|
+
/** Whether the inbound message carries a friends data part (kind:"data"). */
|
|
8
|
+
function hasDataPart(message) {
|
|
9
|
+
return Array.isArray(message.parts) && message.parts.some((p) => p && p.kind === "data");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Bridge an inbound A2A message through friends' `receiveShare`, keying the result
|
|
13
|
+
* on the VERIFIED sender DID.
|
|
14
|
+
*
|
|
15
|
+
* Ordering (the security-critical trap — `trustOfSource` is read from the store BY
|
|
16
|
+
* the just-verified DID, never defaulted, never from the envelope):
|
|
17
|
+
* 1. `unwrapDataPart` — no friends part ⇒ `not-a-share` (caller does text path).
|
|
18
|
+
* 2. `openSealedEnvelope` (pre-unseal) — extract the SIGNED sender DID. Unseal /
|
|
19
|
+
* recipient-mismatch failures ⇒ `rejected` (no turn). (This open does NOT
|
|
20
|
+
* verify the signature; the real auth gate is the `DidVerifier` inside
|
|
21
|
+
* `receiveShare`, so a forged-high-trust claim here is harmless — the forge is
|
|
22
|
+
* rejected by the verifier regardless of the trust we read.)
|
|
23
|
+
* 3. `findFriendByDid(store, verifiedDid)` — read trust off that record; an
|
|
24
|
+
* unknown DID ⇒ `stranger` (never a default-up).
|
|
25
|
+
* 4. `receiveShare({ ..., trustOfSource })` — re-unseal (deterministic) + resolve
|
|
26
|
+
* & pin + run `DidVerifier` (forge fails HERE) + replay-dedup + import.
|
|
27
|
+
* 5. Map the result. `completed` ⇒ run the turn at `verifiedDid`/`trust`.
|
|
28
|
+
*/
|
|
29
|
+
async function receiveInboundShare(message, deps) {
|
|
30
|
+
const friendsMessage = message;
|
|
31
|
+
const payload = (0, a2a_client_1.unwrapDataPart)(friendsMessage);
|
|
32
|
+
if (!payload) {
|
|
33
|
+
// No (valid) friends part. If there was a data part at all, it was a malformed
|
|
34
|
+
// friends attempt → reject; otherwise it's a legacy text message → not-a-share.
|
|
35
|
+
if (hasDataPart(message)) {
|
|
36
|
+
(0, runtime_1.emitNervesEvent)({
|
|
37
|
+
component: "channels",
|
|
38
|
+
event: "channel.a2a_inbound_rejected",
|
|
39
|
+
message: "rejected malformed inbound A2A data part",
|
|
40
|
+
meta: { reason: "malformed_message" },
|
|
41
|
+
});
|
|
42
|
+
return { outcome: "rejected", reason: "malformed_message" };
|
|
43
|
+
}
|
|
44
|
+
return { outcome: "not-a-share" };
|
|
45
|
+
}
|
|
46
|
+
const recipientIdentity = {
|
|
47
|
+
x25519Priv: deps.identity.x25519Priv,
|
|
48
|
+
x25519Pub: deps.identity.x25519Pub,
|
|
49
|
+
};
|
|
50
|
+
// Pre-unseal to learn the SIGNED sender DID before we can read its trust.
|
|
51
|
+
const opened = (0, a2a_client_1.openSealedEnvelope)({
|
|
52
|
+
sodium: deps.sodium,
|
|
53
|
+
sealedEnvelope: { v: payload.v, sealed: payload.sealed },
|
|
54
|
+
recipientDid: deps.identity.did,
|
|
55
|
+
recipientIdentity,
|
|
56
|
+
});
|
|
57
|
+
if (!opened.ok) {
|
|
58
|
+
(0, runtime_1.emitNervesEvent)({
|
|
59
|
+
component: "channels",
|
|
60
|
+
event: "channel.a2a_inbound_rejected",
|
|
61
|
+
message: "rejected inbound A2A envelope (unseal/recipient)",
|
|
62
|
+
meta: { reason: opened.error },
|
|
63
|
+
});
|
|
64
|
+
return { outcome: "rejected", reason: opened.error };
|
|
65
|
+
}
|
|
66
|
+
const verifiedDid = opened.fromAgentId;
|
|
67
|
+
// Read trust from the friend store BY the verified DID — never defaulted, never
|
|
68
|
+
// from the envelope. Unknown (or empty) DID ⇒ stranger. `findFriendByDid` itself
|
|
69
|
+
// refuses a falsy did (never matches a did-less record), so this is safe to call
|
|
70
|
+
// unconditionally.
|
|
71
|
+
const record = await (0, friends_1.findFriendByDid)(deps.store, verifiedDid);
|
|
72
|
+
const trust = record?.trustLevel ?? "stranger";
|
|
73
|
+
const result = await (0, a2a_client_1.receiveShare)({
|
|
74
|
+
sodium: deps.sodium,
|
|
75
|
+
store: deps.store,
|
|
76
|
+
missionStore: deps.missionStore,
|
|
77
|
+
pinStore: deps.pinStore,
|
|
78
|
+
didResolution: deps.didResolution,
|
|
79
|
+
seen: deps.seen,
|
|
80
|
+
a2aMessage: friendsMessage,
|
|
81
|
+
recipientDid: deps.identity.did,
|
|
82
|
+
recipientIdentity,
|
|
83
|
+
trustOfSource: trust,
|
|
84
|
+
});
|
|
85
|
+
if (result.state === "completed") {
|
|
86
|
+
(0, runtime_1.emitNervesEvent)({
|
|
87
|
+
component: "channels",
|
|
88
|
+
event: "channel.a2a_inbound_verified",
|
|
89
|
+
message: "verified inbound A2A share; keying turn on sender DID",
|
|
90
|
+
meta: { verifiedDid, trust, friendsKind: result.friendsKind, status: result.status },
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
outcome: "completed",
|
|
94
|
+
verifiedDid,
|
|
95
|
+
trust,
|
|
96
|
+
friendsKind: result.friendsKind,
|
|
97
|
+
status: result.status,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
(0, runtime_1.emitNervesEvent)({
|
|
101
|
+
component: "channels",
|
|
102
|
+
event: "channel.a2a_inbound_rejected",
|
|
103
|
+
message: "rejected inbound A2A share",
|
|
104
|
+
meta: { reason: result.reason, verifiedDid, trust },
|
|
105
|
+
});
|
|
106
|
+
return { outcome: "rejected", reason: result.reason };
|
|
107
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapMissionResultDataPart = wrapMissionResultDataPart;
|
|
4
|
+
exports.isMissionResultDataPart = isMissionResultDataPart;
|
|
5
|
+
exports.receiveInboundMissionResult = receiveInboundMissionResult;
|
|
6
|
+
const a2a_client_1 = require("@ouro.bot/friends/a2a-client");
|
|
7
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
8
|
+
const runtime_1 = require("../nerves/runtime");
|
|
9
|
+
/**
|
|
10
|
+
* THE HARNESS-OWNED RESULT WIRE.
|
|
11
|
+
*
|
|
12
|
+
* A mission RESULT is NOT a `FriendsKind` (`FriendsKind` = profile_share |
|
|
13
|
+
* mission_share | coordination) — `prepareMissionResult`/`importMissionResult` are
|
|
14
|
+
* transport-agnostic + store-only, and the result does NOT ride `sendShare`/
|
|
15
|
+
* `receiveShare`. So the HARNESS owns the wire: the result envelope is sealed (reusing
|
|
16
|
+
* the sign-then-seal crypto) and wrapped in a DataPart carrying a distinct `ouroKind:
|
|
17
|
+
* "mission_result"` discriminator. The inbound bridge recognizes that tag and routes
|
|
18
|
+
* it to `importMissionResult` — NEVER to `receiveShare`, which would mis-route a
|
|
19
|
+
* non-`FriendsKind` envelope. This is "a DataPart variant + an inbound route branch"
|
|
20
|
+
* (the carrier is the friends `unwrapDataPart` shape + one extra tag field — no
|
|
21
|
+
* structural change beyond that).
|
|
22
|
+
*
|
|
23
|
+
* SECURITY — the wire AUTHENTICATES the sender exactly like the share path
|
|
24
|
+
* (`receiveShare` in friends' `adapter.ts`). `openSealedEnvelope` does AEAD
|
|
25
|
+
* decryption ONLY — it does NOT verify the signature (its docstring names the
|
|
26
|
+
* adapter's `DidVerifier` as "the single authentication gate"). The decrypted
|
|
27
|
+
* `envelope.fromAgentId` is therefore attacker-controlled plaintext: the recipient's
|
|
28
|
+
* X25519 pubkey is public (derived from the published DID), so any party can SEAL a
|
|
29
|
+
* forged result to us. Authentication is the ONLY barrier. Before trusting the
|
|
30
|
+
* claimed sender we therefore replicate `receiveShare`'s gate:
|
|
31
|
+
* 1. binding check — `opened.signerDid === opened.fromAgentId` (and non-empty),
|
|
32
|
+
* 2. resolve + pin the sender DID (TOFU pin + signed-rotation evaluation),
|
|
33
|
+
* 3. hand `importMissionResult` a REAL `DidVerifier` bound to the pinned key, so
|
|
34
|
+
* `verifier.verify(fromAgentId, proof)` runs the Ed25519 signature check against
|
|
35
|
+
* the pinned key — NOT the no-op `tofuVerifier` the importer defaults to.
|
|
36
|
+
* Replay is deduped on the seal nonce (durable `SeenLedger`), matching the share path.
|
|
37
|
+
*/
|
|
38
|
+
const OURO_RESULT_KIND = "mission_result";
|
|
39
|
+
/** Wrap a sealed result envelope into the harness-owned `mission_result` DataPart. */
|
|
40
|
+
function wrapMissionResultDataPart(input) {
|
|
41
|
+
return {
|
|
42
|
+
messageId: `result-${Math.random().toString(36).slice(2)}`,
|
|
43
|
+
role: "agent",
|
|
44
|
+
parts: [{
|
|
45
|
+
kind: "data",
|
|
46
|
+
data: {
|
|
47
|
+
v: input.sealedEnvelope.v,
|
|
48
|
+
sealed: input.sealedEnvelope.sealed,
|
|
49
|
+
recipientDid: input.recipientDid,
|
|
50
|
+
ouroKind: OURO_RESULT_KIND,
|
|
51
|
+
},
|
|
52
|
+
}],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Whether an inbound message carries the harness-owned `mission_result` DataPart. */
|
|
56
|
+
function isMissionResultDataPart(message) {
|
|
57
|
+
if (!Array.isArray(message.parts))
|
|
58
|
+
return false;
|
|
59
|
+
return message.parts.some((p) => p && p.kind === "data" && typeof p.data === "object" && p.data !== null
|
|
60
|
+
&& p.data.ouroKind === OURO_RESULT_KIND);
|
|
61
|
+
}
|
|
62
|
+
/** Extract the sealed envelope from a `mission_result` DataPart, or null. */
|
|
63
|
+
function unwrapMissionResultDataPart(message) {
|
|
64
|
+
if (!Array.isArray(message.parts) || message.parts.length !== 1)
|
|
65
|
+
return null;
|
|
66
|
+
const part = message.parts[0];
|
|
67
|
+
if (!part || part.kind !== "data" || !part.data)
|
|
68
|
+
return null;
|
|
69
|
+
const data = part.data;
|
|
70
|
+
if (data.ouroKind !== OURO_RESULT_KIND)
|
|
71
|
+
return null;
|
|
72
|
+
if (typeof data.v !== "number" || typeof data.recipientDid !== "string" || !data.sealed)
|
|
73
|
+
return null;
|
|
74
|
+
return { sealed: { v: data.v, sealed: data.sealed }, recipientDid: data.recipientDid };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Route an inbound `mission_result` DataPart to `importMissionResult`, AUTHENTICATING
|
|
78
|
+
* the sender exactly like `receiveShare` does for every other inbound kind.
|
|
79
|
+
*
|
|
80
|
+
* Ordering (mirrors the share bridge's trust trap + authentication gate):
|
|
81
|
+
* 1. recognize + unwrap the harness `mission_result` carrier (else `not-a-result`).
|
|
82
|
+
* 2. replay dedup on the seal nonce (durable `SeenLedger`) — before any state change.
|
|
83
|
+
* 3. `openSealedEnvelope` → AEAD-decrypt only (unseal/recipient failures → reject).
|
|
84
|
+
* 4. binding check — reject unless `opened.signerDid === opened.fromAgentId` (and
|
|
85
|
+
* non-empty): the advisory `signerDid` (outer, unsigned) must match the claimed
|
|
86
|
+
* sender. A divergence is a forged/spoofed bundle (`sender_binding_mismatch`).
|
|
87
|
+
* 5. `resolveAndPin` the sender DID (TOFU pin / signed-rotation) → the pinned key
|
|
88
|
+
* (unresolvable/failed-binding/failed-rotation → `resolve_failed`).
|
|
89
|
+
* 6. build a `DidVerifier` bound to THIS envelope + the pinned key, mark the nonce
|
|
90
|
+
* seen, then call `importMissionResult({ envelope, fromAgentId: <signed DID>,
|
|
91
|
+
* trustOfSource }, { verifier })`. The verifier runs the REAL signature check
|
|
92
|
+
* against the pinned key — a result signed with a key that is not the pinned key
|
|
93
|
+
* for the claimed DID is rejected (`untrusted_source`). Every authorization gate
|
|
94
|
+
* (no_mission / no_delegation / assignee_mismatch, fail-closed on a legacy
|
|
95
|
+
* assignee-less delegation) is still enforced by the importer.
|
|
96
|
+
*/
|
|
97
|
+
async function receiveInboundMissionResult(message, deps) {
|
|
98
|
+
const payload = unwrapMissionResultDataPart(message);
|
|
99
|
+
if (!payload)
|
|
100
|
+
return { outcome: "not-a-result" };
|
|
101
|
+
// Replay dedup BEFORE any state change, keyed on the seal nonce (matches receiveShare).
|
|
102
|
+
if (deps.seen.isSeen(payload.sealed.sealed.n)) {
|
|
103
|
+
(0, runtime_1.emitNervesEvent)({
|
|
104
|
+
component: "channels",
|
|
105
|
+
event: "channel.a2a_result_rejected",
|
|
106
|
+
message: "rejected inbound mission_result (replayed seal nonce)",
|
|
107
|
+
meta: { reason: "replayed" },
|
|
108
|
+
});
|
|
109
|
+
return { outcome: "rejected", reason: "replayed" };
|
|
110
|
+
}
|
|
111
|
+
const recipientIdentity = { x25519Priv: deps.identity.x25519Priv, x25519Pub: deps.identity.x25519Pub };
|
|
112
|
+
const opened = (0, a2a_client_1.openSealedEnvelope)({
|
|
113
|
+
sodium: deps.sodium,
|
|
114
|
+
sealedEnvelope: payload.sealed,
|
|
115
|
+
recipientDid: deps.identity.did,
|
|
116
|
+
recipientIdentity,
|
|
117
|
+
});
|
|
118
|
+
if (!opened.ok) {
|
|
119
|
+
(0, runtime_1.emitNervesEvent)({
|
|
120
|
+
component: "channels",
|
|
121
|
+
event: "channel.a2a_result_rejected",
|
|
122
|
+
message: "rejected inbound mission_result (unseal/recipient)",
|
|
123
|
+
meta: { reason: opened.error },
|
|
124
|
+
});
|
|
125
|
+
return { outcome: "rejected", reason: opened.error };
|
|
126
|
+
}
|
|
127
|
+
// SECURITY (binding): the trustworthy sender identity is the SIGNED `fromAgentId`.
|
|
128
|
+
// `openSealedEnvelope` does NOT verify the signature, so `fromAgentId` is untrusted
|
|
129
|
+
// until the DidVerifier confirms the pinned key signed THIS envelope. The advisory
|
|
130
|
+
// `signerDid` (from the outer, unsigned sealed plaintext) must match the claimed
|
|
131
|
+
// sender; a divergence is a forged/spoofed bundle (e.g. an attacker signing with its
|
|
132
|
+
// OWN key while claiming a victim's DID). Reject before resolving or importing.
|
|
133
|
+
const senderDid = opened.fromAgentId;
|
|
134
|
+
if (senderDid.length === 0 || opened.signerDid !== senderDid) {
|
|
135
|
+
(0, runtime_1.emitNervesEvent)({
|
|
136
|
+
component: "channels",
|
|
137
|
+
event: "channel.a2a_result_rejected",
|
|
138
|
+
message: "rejected inbound mission_result (sender binding mismatch — forged sender)",
|
|
139
|
+
meta: { reason: "sender_binding_mismatch", claimedDid: senderDid, signerDid: opened.signerDid },
|
|
140
|
+
});
|
|
141
|
+
return { outcome: "rejected", reason: "sender_binding_mismatch" };
|
|
142
|
+
}
|
|
143
|
+
// Read trust from the friend store BY the verified DID — never defaulted, never from
|
|
144
|
+
// the envelope. Unknown (or empty) DID ⇒ stranger.
|
|
145
|
+
const record = await (0, friends_1.findFriendByDid)(deps.store, senderDid);
|
|
146
|
+
const trust = record?.trustLevel ?? "stranger";
|
|
147
|
+
// Resolve + pin the SENDER's DID (async — BEFORE the sync verifier/importer).
|
|
148
|
+
const resolved = await deps.didResolution.resolveAndPin({
|
|
149
|
+
fromAgentId: senderDid,
|
|
150
|
+
did: senderDid,
|
|
151
|
+
pinStore: deps.pinStore,
|
|
152
|
+
trustOfSource: trust,
|
|
153
|
+
});
|
|
154
|
+
if (!resolved) {
|
|
155
|
+
(0, runtime_1.emitNervesEvent)({
|
|
156
|
+
component: "channels",
|
|
157
|
+
event: "channel.a2a_result_rejected",
|
|
158
|
+
message: "rejected inbound mission_result (sender DID resolve/pin failed)",
|
|
159
|
+
meta: { reason: "resolve_failed", verifiedDid: senderDid, trust },
|
|
160
|
+
});
|
|
161
|
+
return { outcome: "rejected", reason: "resolve_failed" };
|
|
162
|
+
}
|
|
163
|
+
// Build the sync verifier bound to THIS envelope + the pinned sender key. This is the
|
|
164
|
+
// single authentication gate (the importer would otherwise default to the no-op TOFU
|
|
165
|
+
// verifier). `verify` confirms the agentId===did binding AND the Ed25519 signature
|
|
166
|
+
// over the envelope against the pinned key.
|
|
167
|
+
const verifier = new a2a_client_1.DidVerifier({
|
|
168
|
+
sodium: deps.sodium,
|
|
169
|
+
pinnedEd25519Pub: resolved.ed25519Pub,
|
|
170
|
+
pinnedDid: senderDid,
|
|
171
|
+
envelope: opened.envelope,
|
|
172
|
+
});
|
|
173
|
+
// Mark seen now (idempotent imports + the replay guard above keep this safe).
|
|
174
|
+
deps.seen.markSeen(payload.sealed.sealed.n);
|
|
175
|
+
const result = await (0, friends_1.importMissionResult)(deps.missionStore, {
|
|
176
|
+
envelope: opened.envelope,
|
|
177
|
+
fromAgentId: senderDid,
|
|
178
|
+
trustOfSource: trust,
|
|
179
|
+
}, { verifier });
|
|
180
|
+
if (result.ok) {
|
|
181
|
+
(0, runtime_1.emitNervesEvent)({
|
|
182
|
+
component: "channels",
|
|
183
|
+
event: "channel.a2a_result_imported",
|
|
184
|
+
message: "imported inbound mission_result (authenticated, quarantined, attributed)",
|
|
185
|
+
meta: { verifiedDid: senderDid, trust, status: result.status },
|
|
186
|
+
});
|
|
187
|
+
return { outcome: "imported", verifiedDid: senderDid };
|
|
188
|
+
}
|
|
189
|
+
(0, runtime_1.emitNervesEvent)({
|
|
190
|
+
component: "channels",
|
|
191
|
+
event: "channel.a2a_result_rejected",
|
|
192
|
+
message: "rejected inbound mission_result (import gate)",
|
|
193
|
+
meta: { reason: result.status, verifiedDid: senderDid, trust },
|
|
194
|
+
});
|
|
195
|
+
return { outcome: "rejected", reason: result.status };
|
|
196
|
+
}
|