diff --git a/deploy/docker-compose.prod.yml b/deploy/docker-compose.prod.yml index c90aef1..794be2d 100644 --- a/deploy/docker-compose.prod.yml +++ b/deploy/docker-compose.prod.yml @@ -8,8 +8,8 @@ services: restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-assistant} - POSTGRES_USER: ${POSTGRES_SUPERUSER} - POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD} + POSTGRES_USER: ${POSTGRES_SUPERUSER:?POSTGRES_SUPERUSER is required} + POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD:?POSTGRES_SUPERUSER_PASSWORD is required} CONTINUITY_DB_PASSWORD: ${CONTINUITY_DB_PASSWORD} IDENTITY_DB_PASSWORD: ${IDENTITY_DB_PASSWORD} AUTHORITY_DB_PASSWORD: ${AUTHORITY_DB_PASSWORD} @@ -23,7 +23,7 @@ services: - assistant_pg:/var/lib/postgresql - assistant_core_secrets:/run/secrets:ro healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_SUPERUSER} -d ${POSTGRES_DB:-assistant}"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_SUPERUSER:?POSTGRES_SUPERUSER is required} -d ${POSTGRES_DB:-assistant}"] interval: 10s timeout: 5s retries: 20 @@ -95,7 +95,7 @@ services: POSTGRES_USER: continuity_role POSTGRES_PASSWORD: ${CONTINUITY_DB_PASSWORD} CORE_RUNTIME_URL: http://core-runtime:8080 - COMMIT_EXECUTOR_TOKEN: ${COMMIT_EXECUTOR_TOKEN} + COMMIT_EXECUTOR_TOKEN: ${COMMIT_EXECUTOR_TOKEN:?COMMIT_EXECUTOR_TOKEN is required} commit-runtime: build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: commit-runtime, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } } @@ -111,7 +111,7 @@ services: AUTHORITY_POSTGRES_PASSWORD: ${AUTHORITY_DB_PASSWORD} CORE_RUNTIME_URL: http://core-runtime:8080 CONTINUITY_RUNTIME_URL: http://continuity-runtime:8081 - COMMIT_EXECUTOR_TOKEN: ${COMMIT_EXECUTOR_TOKEN} + COMMIT_EXECUTOR_TOKEN: ${COMMIT_EXECUTOR_TOKEN:?COMMIT_EXECUTOR_TOKEN is required} NOTIFICATION_WRITE_TOKEN_FILE: /run/notification-writer/token NOTIFICATION_WRITE_SECRET_REF: domovoy-notification-write-v1 # External mutation credentials belong here only via Portainer/Docker secrets/env injection. diff --git a/dev/ACTIVE_TASK.json b/dev/ACTIVE_TASK.json index 3052249..268f982 100644 --- a/dev/ACTIVE_TASK.json +++ b/dev/ACTIVE_TASK.json @@ -1,5 +1,5 @@ { - "task_file": "dev/tasks/DEV-000072-semantic-interpretation-deferral-boundary.json", - "task_id": "DEV-000072", + "task_file": "dev/tasks/DEV-000073-production-compose-fail-closed.json", + "task_id": "DEV-000073", "task_revision": 1 } diff --git a/dev/tasks/DEV-000073-production-compose-fail-closed.json b/dev/tasks/DEV-000073-production-compose-fail-closed.json new file mode 100644 index 0000000..23a69bf --- /dev/null +++ b/dev/tasks/DEV-000073-production-compose-fail-closed.json @@ -0,0 +1,96 @@ +{ + "task_id": "DEV-000073", + "task_revision": 1, + "architecture_revision": "DEV-000072-baseline", + "base_repo_revision": "da94ed1", + "risk_tier": "E", + "intent": "Make Assistant production Compose fail closed when required PostgreSQL and executor inputs are absent, without mutating neighboring projects or storing secrets in the repository.", + "requirement_ids": [ + "Production missing inputs must fail before container startup", + "Assistant-only deployment scope", + "No secret values in Git", + "No neighboring project mutation" + ], + "allowed_change_scope": { + "modules": [], + "paths": [ + "deploy/docker-compose.prod.yml", + "docs/PROJECT_STATUS.md", + "dev/ACTIVE_TASK.json", + "dev/tasks/DEV-000073-production-compose-fail-closed.json" + ] + }, + "forbidden_change_scope": { + "paths": [ + "architecture/**", + "security/**", + "modules/**", + "contracts/**", + "database/migrations/**", + "deploy/docker-compose.dev.yml", + ".gitea/**" + ] + }, + "allowed_architecture_delta": { + "new_cross_module_dependencies": 0, + "new_canonical_owners": 0, + "new_privileges": 0, + "new_third_party_dependencies": 0, + "new_provider_adapters": 0, + "new_database_owner_roles": 0 + }, + "contracts": { + "consume": [ + "existing production Compose topology", + "existing external secret injection" + ], + "may_change": [] + }, + "semantic_owner": "none-production-configuration", + "canonical_state": [], + "state_transitions": [ + "missing required production input -> Compose validation failure", + "all required inputs present -> existing Assistant stack topology remains unchanged" + ], + "side_effects_and_privileges": [ + "No secret creation or storage in Git", + "No deployment of neighboring projects", + "Promotion only after exact artifact and health checks" + ], + "persistence_and_migrations": [ + "No database migration", + "No canonical state change" + ], + "failure_retry_restart": [ + "Missing required input fails before Compose startup", + "Existing Assistant containers remain untouched until explicit promotion" + ], + "assumptions": [ + "Production control plane is docker-prod / docker.cin.su", + "Required secret values remain external to the repository", + "Neighboring Docker projects must not be included in any Compose operation" + ], + "acceptance_scenarios": [ + "Compose rejects missing POSTGRES_SUPERUSER", + "Compose rejects missing POSTGRES_SUPERUSER_PASSWORD", + "Compose rejects missing COMMIT_EXECUTOR_TOKEN", + "Compose renders with synthetic non-secret values", + "scope check passes", + "Assistant-only production inspection identifies exact artifact and health state" + ], + "required_tests": [ + "docker compose config -q with missing inputs", + "docker compose config -q with synthetic inputs", + "go test ./...", + "go vet ./...", + "go run ./cmd/devctl preflight -active dev/ACTIVE_TASK.json", + "go run ./cmd/devctl check-diff -active dev/ACTIVE_TASK.json", + "go run ./cmd/devctl check-architecture", + "production Assistant-only health and artifact inspection" + ], + "terminal_gap_states": [ + "BLOCKED_BY_MISSING_CAPABILITY", + "BLOCKED_BY_CONFLICT", + "REQUIRES_MIGRATION_DECISION" + ] +}