@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,112 @@
|
|
|
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.runContainerHealthcheck = runContainerHealthcheck;
|
|
37
|
+
exports.runContainerHealthcheckMain = runContainerHealthcheckMain;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const os = __importStar(require("node:os"));
|
|
40
|
+
const path = __importStar(require("node:path"));
|
|
41
|
+
const node_child_process_1 = require("node:child_process");
|
|
42
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
43
|
+
const identity_1 = require("../identity");
|
|
44
|
+
const bundle_manifest_1 = require("../../mind/bundle-manifest");
|
|
45
|
+
const container_runtime_1 = require("./container-runtime");
|
|
46
|
+
const sanctuary_bundle_migration_1 = require("./sanctuary-bundle-migration");
|
|
47
|
+
const sanctuary_package_management_1 = require("./sanctuary-package-management");
|
|
48
|
+
function fail(reason) {
|
|
49
|
+
(0, runtime_1.emitNervesEvent)({ level: "error", component: "daemon", event: "daemon.container_healthcheck_error", message: "container healthcheck failed", meta: { reason } });
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
throw new Error(reason);
|
|
52
|
+
}
|
|
53
|
+
function runContainerHealthcheck(options = {}) {
|
|
54
|
+
const argv = options.argv ?? process.argv;
|
|
55
|
+
const now = options.now ?? Date.now;
|
|
56
|
+
const index = argv.indexOf("--agent");
|
|
57
|
+
const agent = index >= 0 ? argv[index + 1] : undefined;
|
|
58
|
+
if (!agent)
|
|
59
|
+
fail("missing agent");
|
|
60
|
+
const packageManagement = (0, sanctuary_package_management_1.resolveSanctuaryPackageManagementActivation)({ mode: "production", argv, managedAgents: [agent], repoRoot: (0, identity_1.getRepoRoot)(), bundlesRoot: (0, identity_1.getAgentBundlesRoot)(), runtimePackageVersion: (0, bundle_manifest_1.getPackageVersion)() });
|
|
61
|
+
if (packageManagement.kind !== "active")
|
|
62
|
+
fail("invalid package-managed Sanctuary activation");
|
|
63
|
+
let installState;
|
|
64
|
+
try {
|
|
65
|
+
installState = (0, sanctuary_bundle_migration_1.inspectSanctuaryPackageManagedBundle)(packageManagement);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
fail("package-managed Sanctuary inspection unavailable");
|
|
69
|
+
}
|
|
70
|
+
if (!installState.ok || !installState.data.ready)
|
|
71
|
+
fail("package-managed Sanctuary bundle is not ready");
|
|
72
|
+
const healthPath = path.join(os.homedir(), ".ouro-cli", "daemon-health.json");
|
|
73
|
+
let stat;
|
|
74
|
+
let health;
|
|
75
|
+
try {
|
|
76
|
+
stat = fs.statSync(healthPath);
|
|
77
|
+
health = JSON.parse(fs.readFileSync(healthPath, "utf8"));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
fail("health state unavailable");
|
|
81
|
+
}
|
|
82
|
+
const checkedAt = now();
|
|
83
|
+
if (checkedAt - stat.mtimeMs > 90_000 || stat.mtimeMs > checkedAt + 1_000)
|
|
84
|
+
fail("health state stale");
|
|
85
|
+
if (health.pid !== 1 || !fs.existsSync("/proc/1"))
|
|
86
|
+
fail("daemon is not PID 1");
|
|
87
|
+
if (health.status !== "healthy" && health.status !== "partial")
|
|
88
|
+
fail("daemon status is not ready");
|
|
89
|
+
const agents = health.agents;
|
|
90
|
+
const managed = agents?.[agent];
|
|
91
|
+
if (!managed || managed.status !== "running" || typeof managed.pid !== "number" || managed.pid <= 0)
|
|
92
|
+
fail("managed agent is not running");
|
|
93
|
+
let processArguments = "";
|
|
94
|
+
try {
|
|
95
|
+
processArguments = (0, node_child_process_1.execFileSync)("ps", ["-eo", "args="], { encoding: "utf8", timeout: 2_000 });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
fail("managed process inventory is unavailable");
|
|
99
|
+
}
|
|
100
|
+
if (!(0, container_runtime_1.hasManagedAgentProcess)(processArguments, agent))
|
|
101
|
+
fail("managed agent is not running exactly once");
|
|
102
|
+
if (!(0, container_runtime_1.hasManagedTelegramProcess)(processArguments, agent))
|
|
103
|
+
fail("managed Telegram sense is not running exactly once");
|
|
104
|
+
if (!(0, container_runtime_1.hasManagedSupercronicProcess)(processArguments, agent))
|
|
105
|
+
fail("managed Supercronic scheduler is not running exactly once");
|
|
106
|
+
(0, runtime_1.emitNervesEvent)({ component: "daemon", event: "daemon.container_healthcheck_end", message: "container healthcheck passed", meta: { agent } });
|
|
107
|
+
}
|
|
108
|
+
function runContainerHealthcheckMain(isMain, runner) {
|
|
109
|
+
if (isMain)
|
|
110
|
+
runner();
|
|
111
|
+
}
|
|
112
|
+
runContainerHealthcheckMain(require.main === module, runContainerHealthcheck);
|
|
@@ -0,0 +1,97 @@
|
|
|
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.hasManagedAgentProcess = hasManagedAgentProcess;
|
|
37
|
+
exports.hasManagedTelegramProcess = hasManagedTelegramProcess;
|
|
38
|
+
exports.hasManagedSupercronicProcess = hasManagedSupercronicProcess;
|
|
39
|
+
exports.readContainerRuntimePolicy = readContainerRuntimePolicy;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
42
|
+
function hasManagedAgentProcess(processArguments, agent) {
|
|
43
|
+
const wanted = agent.trim();
|
|
44
|
+
if (!wanted)
|
|
45
|
+
return false;
|
|
46
|
+
const matches = processArguments.split("\n").filter((line) => {
|
|
47
|
+
const fields = line.trim().split(/\s+/u);
|
|
48
|
+
const entryIndex = fields.findIndex((field) => field === "/opt/ouro/dist/heart/agent-entry.js");
|
|
49
|
+
const agentIndex = fields.findIndex((field) => field === "--agent");
|
|
50
|
+
return entryIndex >= 0 && agentIndex >= 0 && fields[agentIndex + 1] === wanted;
|
|
51
|
+
});
|
|
52
|
+
return matches.length === 1;
|
|
53
|
+
}
|
|
54
|
+
function hasManagedTelegramProcess(processArguments, agent) {
|
|
55
|
+
const wanted = agent.trim();
|
|
56
|
+
if (!wanted)
|
|
57
|
+
return false;
|
|
58
|
+
const matches = processArguments.split("\n").filter((line) => {
|
|
59
|
+
const fields = line.trim().split(/\s+/u);
|
|
60
|
+
const entryIndex = fields.findIndex((field) => field === "/opt/ouro/dist/senses/telegram-entry.js");
|
|
61
|
+
const agentIndex = fields.findIndex((field) => field === "--agent");
|
|
62
|
+
return entryIndex >= 0 && agentIndex >= 0 && fields[agentIndex + 1] === wanted;
|
|
63
|
+
});
|
|
64
|
+
return matches.length === 1;
|
|
65
|
+
}
|
|
66
|
+
function hasManagedSupercronicProcess(processArguments, agent) {
|
|
67
|
+
const expected = [
|
|
68
|
+
"/usr/local/bin/supercronic",
|
|
69
|
+
"-split-logs",
|
|
70
|
+
"-inotify",
|
|
71
|
+
`/home/ouro/.ouro-cli/scheduler/${agent}.crontab`,
|
|
72
|
+
];
|
|
73
|
+
const matches = processArguments.split("\n").filter((line) => {
|
|
74
|
+
const fields = line.trim().split(/\s+/u);
|
|
75
|
+
return fields.length === expected.length && fields.every((field, index) => field === expected[index]);
|
|
76
|
+
});
|
|
77
|
+
return matches.length === 1;
|
|
78
|
+
}
|
|
79
|
+
function readContainerRuntimePolicy(options = {}) {
|
|
80
|
+
const filePath = options.path ?? "/opt/ouro/container-runtime.json";
|
|
81
|
+
const readFile = options.readFile ?? ((target) => fs.readFileSync(target, "utf8"));
|
|
82
|
+
let raw;
|
|
83
|
+
try {
|
|
84
|
+
raw = readFile(filePath);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
|
|
88
|
+
return null;
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
const value = JSON.parse(raw);
|
|
92
|
+
if (value.scheduler !== "supercronic" || value.updates !== "disabled" || Object.keys(value).sort().join(",") !== "scheduler,updates") {
|
|
93
|
+
throw new Error("container runtime policy is invalid");
|
|
94
|
+
}
|
|
95
|
+
(0, runtime_1.emitNervesEvent)({ component: "daemon", event: "daemon.container_runtime_policy_loaded", message: "container runtime policy loaded", meta: { scheduler: value.scheduler, updates: value.updates } });
|
|
96
|
+
return { scheduler: "supercronic", updates: "disabled" };
|
|
97
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
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.runContainerSpecAuditorCli = runContainerSpecAuditorCli;
|
|
37
|
+
exports.runContainerSpecAuditorMain = runContainerSpecAuditorMain;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
40
|
+
const container_spec_auditor_1 = require("./container-spec-auditor");
|
|
41
|
+
const { decodeUtf8 } = require("../../../deploy/unraid/docker-man-template-xml.cjs");
|
|
42
|
+
function parseModeArguments(args, flags) {
|
|
43
|
+
if (args.length !== flags.length * 2)
|
|
44
|
+
return null;
|
|
45
|
+
const allowed = new Set(flags);
|
|
46
|
+
const parsed = {};
|
|
47
|
+
for (let index = 0; index < args.length; index += 2) {
|
|
48
|
+
const flag = args[index];
|
|
49
|
+
const value = args[index + 1];
|
|
50
|
+
if (!allowed.has(flag) || Object.prototype.hasOwnProperty.call(parsed, flag) || !value)
|
|
51
|
+
return null;
|
|
52
|
+
parsed[flag] = value;
|
|
53
|
+
}
|
|
54
|
+
return parsed;
|
|
55
|
+
}
|
|
56
|
+
function parseSingleInspect(raw) {
|
|
57
|
+
try {
|
|
58
|
+
const value = JSON.parse(raw);
|
|
59
|
+
if (!Array.isArray(value) || value.length !== 1)
|
|
60
|
+
return null;
|
|
61
|
+
const item = value[0];
|
|
62
|
+
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
63
|
+
return null;
|
|
64
|
+
return item;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function runContainerSpecAuditorCli(args, deps = {}) {
|
|
71
|
+
const readFile = deps.readFile ?? ((filePath) => fs.readFileSync(filePath));
|
|
72
|
+
const readText = (filePath) => decodeUtf8(readFile(filePath));
|
|
73
|
+
const write = deps.write ?? ((text) => process.stdout.write(text));
|
|
74
|
+
const staged = parseModeArguments(args, ["--template", "--runtime-policy", "--expected-image", "--mount-contract"]);
|
|
75
|
+
const persistent = parseModeArguments(args, ["--persistent-template", "--runtime-policy", "--expected-image-reference", "--mount-contract"]);
|
|
76
|
+
const effective = parseModeArguments(args, ["--inspect", "--image-inspect", "--expected-image", "--expected-image-reference", "--expected-icon", "--mount-contract"]);
|
|
77
|
+
const sourceCandidate = parseModeArguments(args, ["--inspect", "--image-inspect", "--expected-image", "--mount-contract"]);
|
|
78
|
+
const sourceContract = sourceCandidate?.["--mount-contract"];
|
|
79
|
+
const sourceEffective = sourceContract === "legacy-alpha742" ? sourceCandidate : null;
|
|
80
|
+
const selectedEffective = effective ?? sourceEffective;
|
|
81
|
+
if (!staged && !persistent && !selectedEffective) {
|
|
82
|
+
write(JSON.stringify({ ok: false, error: "usage: all modes require --mount-contract canonical-pre-gateway|canonical-gateway; staged --template <path> --runtime-policy <path> --expected-image <id>; persistent --persistent-template <path> --runtime-policy <path> --expected-image-reference <tag>; effective --inspect <path> --image-inspect <path> --expected-image <id> --expected-image-reference <tag> --expected-icon <url>; source compatibility effective --inspect <path> --image-inspect <path> --expected-image <id> --mount-contract legacy-alpha742" }) + "\n");
|
|
83
|
+
(0, runtime_1.emitNervesEvent)({
|
|
84
|
+
level: "error",
|
|
85
|
+
component: "daemon",
|
|
86
|
+
event: "daemon.container_spec_auditor_cli_error",
|
|
87
|
+
message: "container spec auditor arguments were invalid",
|
|
88
|
+
meta: { argumentCount: args.length },
|
|
89
|
+
});
|
|
90
|
+
return 2;
|
|
91
|
+
}
|
|
92
|
+
if (selectedEffective) {
|
|
93
|
+
let containerText;
|
|
94
|
+
let imageText;
|
|
95
|
+
try {
|
|
96
|
+
containerText = readText(selectedEffective["--inspect"]);
|
|
97
|
+
imageText = readText(selectedEffective["--image-inspect"]);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
write(JSON.stringify({ ok: false, error: "effective audit inputs are unreadable" }) + "\n");
|
|
101
|
+
(0, runtime_1.emitNervesEvent)({
|
|
102
|
+
level: "error",
|
|
103
|
+
component: "daemon",
|
|
104
|
+
event: "daemon.container_spec_auditor_cli_error",
|
|
105
|
+
message: "container spec auditor could not read effective inputs",
|
|
106
|
+
meta: { reason: error instanceof Error ? error.message : String(error) },
|
|
107
|
+
});
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
const containerInspect = parseSingleInspect(containerText);
|
|
111
|
+
const imageInspect = parseSingleInspect(imageText);
|
|
112
|
+
const imageConfig = imageInspect?.Config;
|
|
113
|
+
const expectedEnvironment = imageConfig && typeof imageConfig === "object" && !Array.isArray(imageConfig)
|
|
114
|
+
? imageConfig.Env
|
|
115
|
+
: null;
|
|
116
|
+
if (!containerInspect || !imageInspect || !Array.isArray(expectedEnvironment) || !expectedEnvironment.every((entry) => typeof entry === "string")) {
|
|
117
|
+
write(JSON.stringify({ ok: false, error: "effective audit inputs must each contain exactly one canonical inspect record" }) + "\n");
|
|
118
|
+
(0, runtime_1.emitNervesEvent)({
|
|
119
|
+
level: "error",
|
|
120
|
+
component: "daemon",
|
|
121
|
+
event: "daemon.container_spec_auditor_cli_error",
|
|
122
|
+
message: "container spec auditor effective inputs were invalid",
|
|
123
|
+
meta: { containerValid: !!containerInspect, imageValid: !!imageInspect },
|
|
124
|
+
});
|
|
125
|
+
return 2;
|
|
126
|
+
}
|
|
127
|
+
const result = (0, container_spec_auditor_1.auditSanctuaryContainerSpec)(containerInspect, {
|
|
128
|
+
expectedImage: selectedEffective["--expected-image"],
|
|
129
|
+
expectedEnvironment,
|
|
130
|
+
expectedImageReference: selectedEffective["--expected-image-reference"],
|
|
131
|
+
expectedIcon: selectedEffective["--expected-icon"],
|
|
132
|
+
mountContract: selectedEffective["--mount-contract"],
|
|
133
|
+
});
|
|
134
|
+
if (imageInspect.Id !== selectedEffective["--expected-image"]) {
|
|
135
|
+
result.ok = false;
|
|
136
|
+
result.violations.unshift("reviewed image inspect identity does not match the expected local image ID");
|
|
137
|
+
}
|
|
138
|
+
write(JSON.stringify(result) + "\n");
|
|
139
|
+
return result.ok ? 0 : 1;
|
|
140
|
+
}
|
|
141
|
+
const templateArguments = persistent ?? staged;
|
|
142
|
+
const mountContract = templateArguments["--mount-contract"];
|
|
143
|
+
const templatePath = persistent ? templateArguments["--persistent-template"] : templateArguments["--template"];
|
|
144
|
+
let templateXml;
|
|
145
|
+
let runtimePolicyText;
|
|
146
|
+
try {
|
|
147
|
+
templateXml = readText(templatePath);
|
|
148
|
+
runtimePolicyText = readText(templateArguments["--runtime-policy"]);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
write(JSON.stringify({ ok: false, error: "staged audit inputs are unreadable" }) + "\n");
|
|
152
|
+
(0, runtime_1.emitNervesEvent)({
|
|
153
|
+
level: "error",
|
|
154
|
+
component: "daemon",
|
|
155
|
+
event: "daemon.container_spec_auditor_cli_error",
|
|
156
|
+
message: "container spec auditor could not read staged files",
|
|
157
|
+
meta: { reason: error instanceof Error ? error.message : String(error) },
|
|
158
|
+
});
|
|
159
|
+
return 2;
|
|
160
|
+
}
|
|
161
|
+
const result = persistent
|
|
162
|
+
? (0, container_spec_auditor_1.auditSanctuaryPersistentTemplate)({ templateXml, runtimePolicyText, expectedImageReference: persistent["--expected-image-reference"], mountContract })
|
|
163
|
+
: (0, container_spec_auditor_1.auditSanctuaryStagedFiles)({ templateXml, runtimePolicyText, expectedImage: staged["--expected-image"], mountContract });
|
|
164
|
+
write(JSON.stringify(result) + "\n");
|
|
165
|
+
return result.ok ? 0 : 1;
|
|
166
|
+
}
|
|
167
|
+
function runContainerSpecAuditorMain(isMain, args, runner) {
|
|
168
|
+
if (isMain)
|
|
169
|
+
process.exitCode = runner(args);
|
|
170
|
+
}
|
|
171
|
+
runContainerSpecAuditorMain(require.main === module, process.argv.slice(2), runContainerSpecAuditorCli);
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.auditSanctuaryContainerSpec = auditSanctuaryContainerSpec;
|
|
4
|
+
exports.auditSanctuaryStagedFiles = auditSanctuaryStagedFiles;
|
|
5
|
+
exports.auditSanctuaryPersistentTemplate = auditSanctuaryPersistentTemplate;
|
|
6
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
7
|
+
const { parseDockerManTemplateXml } = require("../../../deploy/unraid/docker-man-template-xml.cjs");
|
|
8
|
+
const EXPECTED_BINDS = [
|
|
9
|
+
"/mnt/user/appdata/ouro-butler/runtime/.ouro-cli:/home/ouro/.ouro-cli:rw",
|
|
10
|
+
"/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro:/home/ouro/AgentBundles/sanctuary.ouro:rw",
|
|
11
|
+
"/boot/config/custom/ouro-events/spool:/run/ouro-events:ro",
|
|
12
|
+
"/run/ouro-authority:/run/ouro-authority:ro",
|
|
13
|
+
];
|
|
14
|
+
const EXPECTED_MOUNTS = [
|
|
15
|
+
["/mnt/user/appdata/ouro-butler/runtime/.ouro-cli", "/home/ouro/.ouro-cli", true, "rprivate"],
|
|
16
|
+
["/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro", "/home/ouro/AgentBundles/sanctuary.ouro", true, "rprivate"],
|
|
17
|
+
["/boot/config/custom/ouro-events/spool", "/run/ouro-events", false, "rprivate"],
|
|
18
|
+
["/run/ouro-authority", "/run/ouro-authority", false, "rprivate"],
|
|
19
|
+
];
|
|
20
|
+
const PRE_GATEWAY_BINDS = EXPECTED_BINDS.slice(0, 3);
|
|
21
|
+
const PRE_GATEWAY_MOUNTS = EXPECTED_MOUNTS.slice(0, 3);
|
|
22
|
+
const LEGACY_ALPHA742_IMAGE = "sha256:681449ad47a2621705cd339b481e6339236b31dc65e195b1cf5025d0f2191d7d";
|
|
23
|
+
const LEGACY_ALPHA742_MOUNTS = EXPECTED_MOUNTS.slice(0, 2);
|
|
24
|
+
const EXPECTED_EXTRA_PARAMS = "--restart=unless-stopped --user=10001:10001";
|
|
25
|
+
const EXPECTED_NAME = "ouro-butler";
|
|
26
|
+
const EXPECTED_TEMPLATE_URL = "https://raw.githubusercontent.com/ourostack/ouroboros/main/deploy/unraid/sanctuary.xml";
|
|
27
|
+
const EXPECTED_ICON = "https://raw.githubusercontent.com/ourostack/ouroboros/main/assets/ouroboros.png";
|
|
28
|
+
const EXACT_IMAGE = /^sha256:[a-f0-9]{64}$/u;
|
|
29
|
+
const VERSION_REFERENCE = /^ghcr\.io\/ourostack\/ouroboros-butler:[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/u;
|
|
30
|
+
const PACKAGE_DAEMON_ARGS = ["/opt/ouro/dist/heart/daemon/daemon-entry.js", "--package-managed-agent", "sanctuary"];
|
|
31
|
+
const PACKAGE_ENTRYPOINT = ["node", ...PACKAGE_DAEMON_ARGS];
|
|
32
|
+
const LEGACY_DAEMON_ARGS = ["/opt/ouro/dist/heart/daemon/daemon-entry.js"];
|
|
33
|
+
const LEGACY_ENTRYPOINT = ["node", ...LEGACY_DAEMON_ARGS];
|
|
34
|
+
function record(value) {
|
|
35
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
36
|
+
? value
|
|
37
|
+
: null;
|
|
38
|
+
}
|
|
39
|
+
function stringArray(value) {
|
|
40
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : null;
|
|
41
|
+
}
|
|
42
|
+
function isEmptyRecord(value) {
|
|
43
|
+
const candidate = record(value);
|
|
44
|
+
return candidate !== null && Object.keys(candidate).length === 0;
|
|
45
|
+
}
|
|
46
|
+
function auditSanctuaryContainerSpec(value, options) {
|
|
47
|
+
const violations = [];
|
|
48
|
+
const root = record(value);
|
|
49
|
+
const config = record(root?.Config);
|
|
50
|
+
const host = record(root?.HostConfig);
|
|
51
|
+
const network = record(root?.NetworkSettings);
|
|
52
|
+
if (!root || !config || !host) {
|
|
53
|
+
violations.push("inspect payload must contain object Config and HostConfig records");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (!EXACT_IMAGE.test(options.expectedImage))
|
|
57
|
+
violations.push("expected image must be an exact local Docker image ID");
|
|
58
|
+
const mountContract = options.mountContract;
|
|
59
|
+
if (mountContract !== "canonical-pre-gateway" && mountContract !== "canonical-gateway" && mountContract !== "legacy-alpha742")
|
|
60
|
+
violations.push("unsupported mount contract");
|
|
61
|
+
if (mountContract === "legacy-alpha742" && options.expectedImage !== LEGACY_ALPHA742_IMAGE)
|
|
62
|
+
violations.push("legacy mount exception requires the pinned alpha.742 image ID");
|
|
63
|
+
const expectedMounts = mountContract === "legacy-alpha742" ? LEGACY_ALPHA742_MOUNTS : mountContract === "canonical-pre-gateway" ? PRE_GATEWAY_MOUNTS : EXPECTED_MOUNTS;
|
|
64
|
+
const expectedArgs = mountContract !== "legacy-alpha742" ? PACKAGE_DAEMON_ARGS : LEGACY_DAEMON_ARGS;
|
|
65
|
+
const expectedEntrypoint = mountContract !== "legacy-alpha742" ? PACKAGE_ENTRYPOINT : LEGACY_ENTRYPOINT;
|
|
66
|
+
if (root.Image !== options.expectedImage)
|
|
67
|
+
violations.push("image does not match the reviewed exact local Docker image ID");
|
|
68
|
+
if (root.Path !== "node")
|
|
69
|
+
violations.push("effective container path must be node");
|
|
70
|
+
if (JSON.stringify(root.Args) !== JSON.stringify(expectedArgs))
|
|
71
|
+
violations.push("effective container arguments must be the reviewed direct daemon entry");
|
|
72
|
+
if (config.User !== "10001:10001")
|
|
73
|
+
violations.push("container user must be 10001:10001");
|
|
74
|
+
if (JSON.stringify(config.Entrypoint) !== JSON.stringify(expectedEntrypoint))
|
|
75
|
+
violations.push("entrypoint must be the reviewed direct daemon entry");
|
|
76
|
+
if (!(config.Cmd === null || (Array.isArray(config.Cmd) && config.Cmd.length === 0)))
|
|
77
|
+
violations.push("container command must be empty");
|
|
78
|
+
const environment = stringArray(config.Env);
|
|
79
|
+
if (!environment || JSON.stringify(environment) !== JSON.stringify(options.expectedEnvironment))
|
|
80
|
+
violations.push("container environment must exactly match the reviewed image environment");
|
|
81
|
+
if (!(config.ExposedPorts === null || config.ExposedPorts === undefined || isEmptyRecord(config.ExposedPorts)))
|
|
82
|
+
violations.push("container must expose no ports");
|
|
83
|
+
if (host.NetworkMode !== "host")
|
|
84
|
+
violations.push("network mode must be host");
|
|
85
|
+
if (host.PidMode !== "")
|
|
86
|
+
violations.push("PID namespace must be private");
|
|
87
|
+
if (host.IpcMode !== "private")
|
|
88
|
+
violations.push("IPC namespace must be private");
|
|
89
|
+
if (host.Privileged !== false)
|
|
90
|
+
violations.push("container must not be privileged");
|
|
91
|
+
if (host.ReadonlyRootfs !== false)
|
|
92
|
+
violations.push("root filesystem mode must match the reviewed runtime");
|
|
93
|
+
if (!(host.SecurityOpt === null || (Array.isArray(host.SecurityOpt) && host.SecurityOpt.length === 0)))
|
|
94
|
+
violations.push("container must set no security options");
|
|
95
|
+
const restart = record(host.RestartPolicy);
|
|
96
|
+
if (restart?.Name !== "unless-stopped" || restart.MaximumRetryCount !== 0)
|
|
97
|
+
violations.push("restart policy must be unless-stopped");
|
|
98
|
+
if (!isEmptyRecord(host.PortBindings))
|
|
99
|
+
violations.push("container must publish no ports");
|
|
100
|
+
if (!Array.isArray(host.Devices) || host.Devices.length !== 0)
|
|
101
|
+
violations.push("container must have no devices");
|
|
102
|
+
if (!(host.CapAdd === null || (Array.isArray(host.CapAdd) && host.CapAdd.length === 0)))
|
|
103
|
+
violations.push("container must add no capabilities");
|
|
104
|
+
if (!(host.CapDrop === null || (Array.isArray(host.CapDrop) && host.CapDrop.length === 0)))
|
|
105
|
+
violations.push("container must drop no capabilities");
|
|
106
|
+
if (host.PublishAllPorts !== false)
|
|
107
|
+
violations.push("container must not publish all exposed ports");
|
|
108
|
+
if (!isEmptyRecord(network?.Ports))
|
|
109
|
+
violations.push("effective network ports must be empty");
|
|
110
|
+
if (mountContract !== "legacy-alpha742" && root.Name !== `/${EXPECTED_NAME}`)
|
|
111
|
+
violations.push("container name must be /ouro-butler");
|
|
112
|
+
if (mountContract !== "legacy-alpha742") {
|
|
113
|
+
if (!options.expectedImageReference || !VERSION_REFERENCE.test(options.expectedImageReference))
|
|
114
|
+
violations.push("expected image reference must be the canonical package-version tag");
|
|
115
|
+
if (config.Image !== options.expectedImageReference)
|
|
116
|
+
violations.push("configured image must equal the canonical package-version tag");
|
|
117
|
+
if (options.expectedIcon !== EXPECTED_ICON)
|
|
118
|
+
violations.push("expected icon must equal the canonical template icon");
|
|
119
|
+
const labels = record(config.Labels);
|
|
120
|
+
if (labels?.["net.unraid.docker.managed"] !== "dockerman")
|
|
121
|
+
violations.push("container must carry the DockerMan managed label");
|
|
122
|
+
if (labels?.["net.unraid.docker.icon"] !== options.expectedIcon)
|
|
123
|
+
violations.push("container icon label must equal the canonical template icon");
|
|
124
|
+
if (labels && Object.prototype.hasOwnProperty.call(labels, "net.unraid.docker.webui"))
|
|
125
|
+
violations.push("container must not carry a DockerMan WebUI label");
|
|
126
|
+
}
|
|
127
|
+
const mounts = Array.isArray(root.Mounts) ? root.Mounts : [];
|
|
128
|
+
const normalizedMounts = mounts.map((mount) => {
|
|
129
|
+
const item = record(mount);
|
|
130
|
+
return item && item.Type === "bind" && typeof item.RW === "boolean" && typeof item.Source === "string" && typeof item.Destination === "string" && item.Propagation === "rprivate"
|
|
131
|
+
? [item.Source, item.Destination, item.RW, item.Propagation]
|
|
132
|
+
: null;
|
|
133
|
+
});
|
|
134
|
+
if (normalizedMounts.some((mount) => mount === null)
|
|
135
|
+
|| JSON.stringify(normalizedMounts.sort()) !== JSON.stringify(expectedMounts.map((mount) => [...mount]).sort())) {
|
|
136
|
+
violations.push("effective mounts do not match the selected Sanctuary mount contract");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const result = { ok: violations.length === 0, violations };
|
|
140
|
+
if (result.ok) {
|
|
141
|
+
(0, runtime_1.emitNervesEvent)({
|
|
142
|
+
component: "daemon",
|
|
143
|
+
event: "daemon.container_spec_audit_end",
|
|
144
|
+
message: "Sanctuary container spec audit passed",
|
|
145
|
+
meta: { violationCount: 0 },
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
(0, runtime_1.emitNervesEvent)({
|
|
150
|
+
level: "error",
|
|
151
|
+
component: "daemon",
|
|
152
|
+
event: "daemon.container_spec_audit_error",
|
|
153
|
+
message: "Sanctuary container spec audit failed",
|
|
154
|
+
meta: { violationCount: violations.length },
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
function directChildren(document, name) {
|
|
160
|
+
return document?.children.filter((child) => child.name === name) ?? [];
|
|
161
|
+
}
|
|
162
|
+
function singleTextChild(document, name) {
|
|
163
|
+
const children = directChildren(document, name);
|
|
164
|
+
const child = children.length === 1 ? children[0] : undefined;
|
|
165
|
+
return child?.form === "text" && Object.keys(child.attributes).length === 0 ? child.text : undefined;
|
|
166
|
+
}
|
|
167
|
+
function auditTemplate(input, expectedRepository, repositoryIsValid, repositoryViolation) {
|
|
168
|
+
const violations = [];
|
|
169
|
+
if (input.mountContract !== "canonical-pre-gateway" && input.mountContract !== "canonical-gateway")
|
|
170
|
+
violations.push("unsupported template mount contract");
|
|
171
|
+
const expectedBinds = input.mountContract === "canonical-pre-gateway" ? PRE_GATEWAY_BINDS : EXPECTED_BINDS;
|
|
172
|
+
const template = parseDockerManTemplateXml(input.templateXml);
|
|
173
|
+
if (!template)
|
|
174
|
+
violations.push("canonical DockerMan XML structure is invalid");
|
|
175
|
+
let runtimePolicy;
|
|
176
|
+
try {
|
|
177
|
+
runtimePolicy = JSON.parse(input.runtimePolicyText);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
runtimePolicy = null;
|
|
181
|
+
}
|
|
182
|
+
const policy = record(runtimePolicy);
|
|
183
|
+
if (policy?.scheduler !== "supercronic" || policy.updates !== "disabled" || Object.keys(policy).sort().join(",") !== "scheduler,updates") {
|
|
184
|
+
violations.push("container runtime policy must be exactly scheduler=supercronic and updates=disabled");
|
|
185
|
+
}
|
|
186
|
+
const configEntries = directChildren(template, "Config");
|
|
187
|
+
const pathConfigs = configEntries.map((entry) => {
|
|
188
|
+
const { Type: type, Target: target, Mode: mode } = entry.attributes;
|
|
189
|
+
return entry.form === "text" && type === "Path" && target && mode ? `${entry.text}:${target}:${mode}` : "invalid";
|
|
190
|
+
});
|
|
191
|
+
if (configEntries.length !== expectedBinds.length
|
|
192
|
+
|| JSON.stringify([...pathConfigs].sort()) !== JSON.stringify([...expectedBinds].sort())) {
|
|
193
|
+
violations.push("template Config entries must equal the canonical path binds");
|
|
194
|
+
}
|
|
195
|
+
const postArgs = directChildren(template, "PostArgs");
|
|
196
|
+
if (postArgs.length !== 1 || postArgs[0].text !== "" || Object.keys(postArgs[0].attributes).length !== 0) {
|
|
197
|
+
violations.push("template PostArgs must be present exactly once and empty");
|
|
198
|
+
}
|
|
199
|
+
const extraParams = singleTextChild(template, "ExtraParams");
|
|
200
|
+
if (extraParams !== EXPECTED_EXTRA_PARAMS)
|
|
201
|
+
violations.push("template ExtraParams must equal the canonical user and restart flags");
|
|
202
|
+
const repository = singleTextChild(template, "Repository");
|
|
203
|
+
if (!repositoryIsValid)
|
|
204
|
+
violations.push(repositoryViolation);
|
|
205
|
+
if (repository !== expectedRepository)
|
|
206
|
+
violations.push("template repository does not match the reviewed image identity");
|
|
207
|
+
if (singleTextChild(template, "Name") !== EXPECTED_NAME)
|
|
208
|
+
violations.push("template technical name must be exactly ouro-butler");
|
|
209
|
+
if (singleTextChild(template, "TemplateURL") !== EXPECTED_TEMPLATE_URL)
|
|
210
|
+
violations.push("template URL must equal the canonical release template");
|
|
211
|
+
if (singleTextChild(template, "Icon") !== EXPECTED_ICON)
|
|
212
|
+
violations.push("template icon must equal the canonical release icon");
|
|
213
|
+
const webUi = directChildren(template, "WebUI");
|
|
214
|
+
if (webUi.length !== 1 || webUi[0].form !== "empty" || Object.keys(webUi[0].attributes).length !== 0)
|
|
215
|
+
violations.push("template WebUI must be present exactly once and empty");
|
|
216
|
+
if (singleTextChild(template, "Network") !== "host")
|
|
217
|
+
violations.push("network mode must be host");
|
|
218
|
+
if (singleTextChild(template, "Privileged") !== "false")
|
|
219
|
+
violations.push("container must not be privileged");
|
|
220
|
+
return violations;
|
|
221
|
+
}
|
|
222
|
+
function auditSanctuaryStagedFiles(input) {
|
|
223
|
+
const violations = auditTemplate(input, input.expectedImage, EXACT_IMAGE.test(input.expectedImage), "expected image must be an exact local Docker image ID");
|
|
224
|
+
return { ok: violations.length === 0, violations };
|
|
225
|
+
}
|
|
226
|
+
function auditSanctuaryPersistentTemplate(input) {
|
|
227
|
+
const violations = auditTemplate(input, input.expectedImageReference, VERSION_REFERENCE.test(input.expectedImageReference), "expected image reference must be the canonical package-version tag");
|
|
228
|
+
return { ok: violations.length === 0, violations };
|
|
229
|
+
}
|