For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [x]) syntax for tracking.
Goal: Deliver a checksum-verifiable Compose offline package, upgrade preflight, consistent backup, guarded restore, and rollback rehearsal for the DataOps first-phase demonstration environment.
Architecture: app/, database/, and migrations/ remain the only development sources of truth and are synchronised into deployment/ before packaging. A small Bash operations layer wraps Docker Compose without embedding production secrets: it builds an image archive and release manifest on the connected build host, validates the bundle on the offline host, snapshots all Compose-managed volumes during a bounded maintenance window, and restores only after checksum and explicit target confirmation. The recovery rehearsal uses another Compose project and a separate port environment so the source volumes are never overwritten.
Tech Stack: Bash 3.2+, Docker Engine, Docker Compose v2, PostgreSQL/pgvector 16, SHA-256, tar/gzip, pytest contract tests.
Files:
tests/test_wp13_delivery_contract.pydeploy/docker/docker-compose.ymlModify: deploy/docker/.env.example
[x] Step 1: Write failing contract tests
Add tests that require:
image: name;deployment/app, deployment/database, and deployment/migrations to match their source-of-truth trees byte-for-byte, excluding Python caches;--help;restore to reject a missing or mismatched confirmation token.
[x] Step 2: Run the tests and verify RED
Run:
PYTHONPATH=. .venv/bin/pytest -q tests/test_wp13_delivery_contract.py
Expected: failures for release-copy drift, missing stable image declarations, and missing scripts.
Give backend, runner, frontend, MCP, and LightRAG projector images stable local names. Replace fixed host ports with ${NAME:-default} expressions so a recovery project can use isolated ports without changing the canonical Compose file.
Run:
bash deployment/sync_release.sh
Remove generated Python caches from the release copy, then verify all three source trees match.
Run:
PYTHONPATH=. .venv/bin/pytest -q \
tests/test_wp13_delivery_contract.py \
tests/runner/test_compose_contract.py \
tests/mcp/test_deployment_contract.py
Expected: only tests for not-yet-created WP13 scripts remain failing.
Files:
deployment/compose/wp13-common.shdeployment/compose/preflight.shdeployment/compose/install_offline.shdeployment/compose/package_offline.shdeployment/compose/README.mddeployment/package_release.shModify: deployment/MANIFEST.md
[x] Step 1: Extend tests for package contents and checksum failure
Use a temporary output directory and a no-image test mode. Require the package to contain the Compose definition, bind-mounted configuration, database migrations, .env.example, install/preflight scripts, release-manifest.txt, and checksums.sha256. Mutating one packaged file must make preflight fail before any Docker mutation.
Run the two named package tests and confirm the failure is caused by missing commands.
The common layer must:
compare Alembic current/head during upgrade checks and never run a downgrade.
[x] Step 4: Implement offline packaging
package_offline.sh must copy only runtime-required files, record the Git commit and image IDs, save all default-profile images into images/dataops-images.tar unless --skip-images is used by contract tests, generate checksums, and create dataops-platform-offline-<version>.tar.gz.
install_offline.sh must verify checksums, load images, run preflight, start with --no-build, wait for Compose health, and record the installed manifest. It must not print environment values or create an administrator.
Run:
PYTHONPATH=. .venv/bin/pytest -q tests/test_wp13_delivery_contract.py -k 'package or preflight or install'
Expected: PASS.
Files:
deployment/compose/backup.shdeployment/compose/restore.shdeployment/compose/rollback.shdeployment/compose/README.mdModify: tests/test_wp13_delivery_contract.py
[x] Step 1: Write failing safety and manifest tests
Require backup to name every Compose-managed volume, include a logical PostgreSQL export and Alembic revision, and checksum every payload. Require restore to fail before mutation when checksums fail, the destination project is already running, the destination is the source project, or --confirm-project does not exactly match.
Run:
PYTHONPATH=. .venv/bin/pytest -q tests/test_wp13_delivery_contract.py -k 'backup or restore or rollback'
Expected: failures for missing backup and restore commands.
Create a logical PostgreSQL export first, stop the source project for a consistent volume snapshot, archive every volume discovered by Compose labels, restart the source project through a trap, write a non-secret manifest, and checksum all payloads. Refuse to proceed when the project is unhealthy unless --allow-degraded is explicit.
Verify checksums and manifest first, require an exact new project confirmation, refuse existing/running destinations, create labelled destination volumes, restore each archive, then start Compose with --no-build. A same-project restore remains disabled by default.
Rollback must be an explicit restore of a named pre-upgrade backup; it may roll back application images and persisted state together but must never call alembic downgrade.
Run the complete WP13 contract test and the existing Compose contracts.
Files:
deployment/compose/.env.rehearsal.exampleCreate: docs/validation/WP13_DEPLOYMENT_BACKUP_RECOVERY_EVIDENCE.md
[x] Step 1: Run upgrade preflight on the current stack
Record Docker/Compose versions, clean release-copy status, required image availability, Compose resolution, Alembic current/head, and source health without exposing credentials.
Use a temporary directory outside Git, accept the bounded maintenance window, and record backup size, payload count, manifest hash, and restart health.
Use project dataops-wp13-restore and the rehearsal environment port overrides. Do not allow in-place restore.
Verify:
source and recovered volume names are disjoint.
[x] Step 5: Remove only the rehearsal project
Resolve containers and volumes by the exact dataops-wp13-restore Compose label, stop the rehearsal project, and remove only its temporary volumes. Confirm the original dataops-test project is still healthy.
Files:
docs/DATAOPS_PHASE1_3_MONTH_WORK_PLAN_20260729.mddocs/FUNCTION_MODULE_CENSUS_20260726.mddeployment/README.mddeployment/DEPLOYMENT_GUIDE.mddeployment/CHECKLIST.mddeployment/MANIFEST.mdCreate: docs/validation/WP13_DEPLOYMENT_BACKUP_RECOVERY_EVIDENCE.md
[x] Step 1: Record evidence and boundaries
Distinguish local engineering completion from enterprise acceptance. Keep enterprise image-signing/notarisation, external backup storage, key custody, production RPO/RTO, real clean host, disaster-domain separation, and production change approval as remaining gates.
Only advance ledger items directly evidenced by the WP13 scripts and rehearsal. Do not mark SSO, production disaster recovery, external WORM storage, or production release complete.
Run:
PYTHONPATH=. .venv/bin/pytest -q \
tests/test_wp13_delivery_contract.py \
tests/runner/test_compose_contract.py \
tests/mcp/test_deployment_contract.py \
tests/test_database_migrations.py
bash -n deployment/compose/*.sh
docker compose -f deploy/docker/docker-compose.yml config --quiet
Also inspect the generated package checksums, backup checksums, recovery report, release-copy diff, Git diff, and working-tree scope.
Stage only WP13 files and synchronised release-copy changes, then create:
git commit -m "feat: add offline deployment and recovery workflow"
Do not push or deploy to production.