Files
ThothII/.superpowers/sdd/task-7-report.md
T

3.7 KiB

Task 7 report — deployment contract and user-owned-session cutover

Scope

Implemented the deployment contract only. No Supabase migration, portal change, live-stack restart, session archive, or deletion was run.

  • backend/src/config.ts now makes the session-store deployment mode explicit. local is the default and cannot be publicly exposed. postgres requires AUTH_MODE=upstream, direct DB host/name/runtime user, an absolute runtime-password file, verify-ca or verify-full, and an absolute CA path.
  • docker-compose.dev.yml now publishes only loopback ports and explicitly selects local session storage rooted at /data/local-home.
  • deploy/compose.session-server.yaml.example separates the runtime and one-shot migrator secrets. The core gets only session_runtime_password and the CA; the profile-gated session-migrate service gets only session_migrator_password and the CA.
  • deploy/workspaces/server-sessions.yaml.example binds the runtime repository to the TLS-verified direct PostgreSQL configuration. The runtime password remains a file reference.
  • docker/cutover-legacy-sessions.sh archives/checksums exactly three reviewed legacy sessions and requires an explicit --delete rerun before deleting them.
  • README, secret guidance, environment examples, and PROJECT_STATE describe the maintenance sequence, Task 4+5 coordinated rollout, liveness vs storage 503 behavior, and the no-dual-write rollback rule.

TDD evidence

RED was established with:

cd backend && npx vitest run test/config.test.ts

The new tests failed because sessionStorage did not exist and public/local and unauthenticated server combinations were accepted. After implementing the minimal configuration contract, the same focused suite passed (7 tests). Updating the existing upstream-health fixture to supply the now-required server inputs confirmed that /health remains an unauthenticated 200 liveness endpoint under the valid server contract.

Verification

cd harness && .venv/bin/pytest -q
826 passed, 5 deselected, 67 warnings in 63.01s

cd backend && npx vitest run && npx tsc --noEmit -p . && npm run build
22 files / 215 tests passed; TypeScript check and production build passed

cd frontend && npx vitest run && npx tsc -b && npm run build
full Vitest suite, TypeScript build, and Vite production build passed

The frontend gate retained its pre-existing React-ref/MSW/act warnings and Vite chunk-size warning; none caused a test or build failure.

Additional static validation passed:

docker compose config --quiet (base plus copied session-server overlay with temporary empty secrets)
bash -n docker/cutover-legacy-sessions.sh
git diff --check

Manual gate remaining

An operator must still choose the three reviewed legacy IDs, materialize real runtime/migrator/CA secrets, deploy Task 4 and Task 5 together in a maintenance window, apply the one-shot migrator, and run the documented authenticated smoke. The guarded helper has not been invoked with --delete.

P1 correction — migrator TLS validation

The original migrator Compose command interpolated THT_SESSION_DB_SSLMODE into its URL without checking it. docker/session-migrate.sh now rejects every value except verify-ca and verify-full before reading the password file or building that URL; the Compose service invokes this helper. docker/session-migrate.test.sh first established RED because the helper did not exist, then verified that prefer is rejected before tht can run and that verify-full reaches a fake tht binary with the expected TLS URL. The helper and test pass bash -n; the focused backend config/health suite remains green, and the base-plus-overlay Compose configuration renders with temporary empty secret files.