7.4 KiB
Deployment V1
Target control plane: Portainer at https://docker.cin.su.
Recommended V1 deployment topology:
assistant-core-runtimeassistant-continuity-runtimeassistant-commit-runtime(isolated privileged runtime)assistant-cognitive-worker(replaceable, no canonical ownership)- PostgreSQL 18.6
- NATS as replaceable integration transport
Temporal is intentionally not the canonical owner of future obligations. If/when Temporal is added, loss of Temporal must be recoverable from canonical continuity state.
The initial stack definition is deploy/docker-compose.prod.yml. Portainer may deploy it from Git after the repository has been pushed.
Project-built production images receive org.opencontainers.image.revision and org.opencontainers.image.source OCI labels. Promotion must set ASSISTANT_SOURCE_REVISION to the full merged origin/main SHA before docker compose build/up; the default unknown is intentionally rejected by artifact confirmation. After all project containers are running, execute:
$revision = git rev-parse origin/main
powershell -ExecutionPolicy Bypass -File .\deploy\windows\Confirm-DomovoyProductionArtifact.ps1 -Revision $revision -DockerContext docker-prod
The confirmation script accepts the promotion only when every project-built container has that revision label, then atomically records its exact Docker image ID in %LOCALAPPDATA%\Domovoy\monitoring\deployment-manifest.json and the private NAS monitoring directory. Production health compares every running label and image ID to this manifest and becomes degraded on drift. The manifest is non-secret operational evidence; it is not canonical Assistant state.
The first external operation adds assistant-notification-receiver-1 on production host port 18081. Caddy applies deploy/caddy/assistent.caddy, routing only https://assistent.cin.su/delivery/* to that port and all other paths to Creator Web on 18080. The receiver has an isolated durable volume and no Assistant database access. Commit success means an immutable receiver receipt exists; Windows display and human reading are not Commit outcomes.
Migrations 010_capability_notification_binding.sql and 011_commit_notification_envelope.sql must be applied before the new runtimes start. The initial Capability binding is owner-local for domovoy-creator-principal, revision 1, capability prospective-notification-delivery, origin https://assistent.cin.su, delivery path /delivery/v1/deliveries, receipt path /delivery/v1/receipts, protocol IDEMPOTENT_RECEIPT_V1, and secret reference domovoy-notification-write-v1.
deploy/windows/Invoke-DomovoyNotificationReceiver.ps1 polls the receipt list with the read-only credential, displays up to three unseen local notifications, and records only rebuildable receipt IDs under %LOCALAPPDATA%\Domovoy. Register-DomovoyNotificationTask.ps1 registers the current-user task every two minutes and at logon. It requires an interactive session for display and never uses docker-test.
Credentials/API deployment automation is deliberately not embedded. Use PORTAINER_API_KEY from an external secret source or deploy through Portainer UI/API after authenticating.
The single Creator login is configured with external CREATOR_USERNAME and CREATOR_PASSWORD values. They issue the same bounded Creator session and never select Actor, Principal, Scope or Authority. Keep CREATOR_BOOTSTRAP_TOKEN as a separate recovery/automation credential; none of these values belongs in Git, compose defaults for production, image layers or logs.
In production, CREATOR_PASSWORD, CREATOR_BOOTSTRAP_TOKEN, and CREATOR_SESSION_SIGNING_KEY are materialized as files in the external assistant_core_secrets Docker volume. core-runtime receives only the corresponding _FILE paths and mounts that volume read-only. Direct environment values remain a development compatibility path and fail closed if combined with _FILE.
PostgreSQL recovery
Production backups run only on docker.cin.su; this project must not use the shared docker-test host. deploy/backup-postgres.sh creates an atomic, mode-0600 logical backup under /home/m/assistant-backups/postgres. Each completed directory contains the application database, cluster roles without role passwords, database/owner metadata, and SHA256SUMS. Partial output is never promoted to a completed backup directory, and no automatic retention deletion is performed.
deploy/verify-postgres-restore.sh <backup-directory> verifies all hashes and restores into an isolated PostgreSQL 18.6 container backed by tmpfs. It never mounts or writes assistant_assistant_pg, and removes its temporary container on exit. A backup is operationally accepted only after this restore check passes.
The production user crontab installs the single entry from deploy/cron/assistant-postgres-backup.crontab. It runs the backup and restore check daily at 00:15 UTC (03:15 Europe/Moscow), survives host reboot without a persistent login session, and writes a private operational log beside the backups.
Encrypted off-host backup
deploy/windows/Sync-PostgresBackupToNas.ps1 copies only a completed, hash-verified production backup over SSH, archives it locally, encrypts it with GnuPG AES-256, verifies an immediate decrypt round trip, and atomically publishes ciphertext plus a non-secret manifest under \\nas\MST\codex\_backups\domovoy\postgres. Temporary plaintext is removed on exit. The script is idempotent and never deletes existing backups.
deploy/windows/Test-PostgresBackupFromNas.ps1 -VerifyRemoteRestore verifies the NAS ciphertext hash, decrypts it with the DPAPI-protected recovery key, checks every source hash, and performs a full isolated PostgreSQL restore on docker.cin.su. deploy/windows/Register-PostgresBackupNasTask.ps1 generates the key when absent, atomically backs up only its DPAPI ciphertext to the NAS, and registers current-user daily and logon triggers. The task intentionally does not use docker-test.
Production health monitoring
deploy/windows/Test-DomovoyProductionHealth.ps1 is an external, rebuildable operational projection; it is not a canonical Core Monitor. It checks all expected production containers, HTTPS health, TLS expiry, public DNS agreement, production backup age and hashes, NAS backup age and ciphertext hash, cron, and the off-host backup task. Thresholds are 30 hours for the production backup, 36 hours for the NAS copy, and 21 remaining certificate days.
The script atomically writes the latest JSON snapshot to %LOCALAPPDATA%\Domovoy\monitoring\status.json and \\nas\MST\codex\_monitoring\domovoy\status.json, then exits nonzero when any check is degraded. deploy/windows/Register-DomovoyProductionHealthTask.ps1 registers a current-user execution every 15 minutes and at logon. Monitoring never uses docker-test and never mutates product state.
deploy/windows/Invoke-DomovoyProductionMonitoring.ps1 runs health collection in a child process and then evaluates deploy/windows/Send-DomovoyHealthNotification.ps1, including when health is degraded. The notifier shows a local Windows notification on the first degraded observation, recovery, and no more than one continuing-failure reminder per six hours. Its suppression state is an external, non-canonical JSON file at %LOCALAPPDATA%\Domovoy\monitoring\notification-state.json and may be regenerated. Notifications require the registered user to have an interactive Windows session; no external notification service or credential is used.