Skip to content

Implementation Log: ANU-6 - Add the containerized local CMS development stack

Changes and decisions

  • 2026-07-21: Validated ANU-6 as Ready for anuvax-cms, with no blockers and complete Product Main, scope, acceptance, docs, and verification inputs.
  • 2026-07-21: Started the issue through anuva work start; Linear moved to In Progress and the dedicated implementation branch was created from main.
  • 2026-07-21: Confirmed the approved three-service boundary and kept the real database migration explicitly outside this issue.
  • 2026-07-21: Added pinned development images, a three-service Compose model, loopback bindings, health gates, hot reload, and persistent named volumes.
  • 2026-07-21: Removed the Supabase-hostname schema-push exception; local schema push is now governed only by the explicit PAYLOAD_DB_PUSH flag.
  • 2026-07-21: Added guarded export, restore, parity, and volume-reset tooling. Every destructive or connecting operation requires explicit inputs and execution flags; real migration execution remains deferred.
  • 2026-07-21: Verified the smoke implementation against installed Mastra PgVector docs and types before using create/upsert/query/delete APIs.
  • 2026-07-21: The first no-cache web build reached the pinned Node base image but its bundled Corepack rejected pnpm's current signing key. Replaced the Corepack prepare step with a direct, version-pinned npm install --global pnpm@10.7.0 bootstrap and repeated the clean build.
  • 2026-07-21: Playwright verification exposed two pre-existing harness gaps: dotenv/config lacked a direct dependency and the web-server command used POSIX-only environment syntax. Added the direct dev dependency and changed the command to the repository's existing cross-platform cross-env runner.
  • 2026-07-21: The first browser assertion run showed that the active hosted .env still requested Payload schema push. Made the e2e boundary explicit with PAYLOAD_DB_PUSH=0, while Compose continues to opt into push for its empty local database.
  • 2026-07-21: Rebuilt the web image against the final lockfile. The build completed with local manifest-list digest sha256:73f45d1e6555d88c3cbdf8b99c1f012c08c29395247fd21b8b65036da74107bc.
  • 2026-07-21: After Docker Desktop was changed to use the classic image store, the pinned pgvector and pgAdmin images pulled successfully. A Docker Desktop restart repaired a transient Windows bind-mount bridge error introduced by the engine setting change.
  • 2026-07-21: Runtime startup exposed and fixed three local-stack lifecycle defects: pgAdmin 9.16 rejected the special-use .invalid example address, Payload schema push was unsafe on a populated restart, and the standalone smoke needed independent pool cleanup/termination. Added regression coverage for the accepted pgAdmin address and restart/smoke boundaries.
  • 2026-07-21: Added a web launcher that waits for PostgreSQL, inspects the local Payload schema with psql, enables push only for an empty first boot, and disables repeat push on restart. Connection credentials remain in libpq environment variables rather than process arguments or logs.
  • 2026-07-21: Completed runtime acceptance. All services became healthy on loopback ports; running versions matched the pinned baselines; Payload, Mastra, pgvector, and authenticated worker API smoke passed; PostgreSQL and pgAdmin sentinels survived restart and routine down/up and were then removed.
  • 2026-07-21: Repository-wide checks exposed unrelated existing failures: the full Biome check reports historical/generated files, one integration test expects an obsolete combined narrative-agent call, and all six Playwright cases wait for a use-case selector absent from the current Video Setup page. Targeted ANU-6 lint, typecheck, 10 local-stack tests, strict MkDocs, Compose validation, and diff sanity pass.
  • 2026-07-21: Acceptance review confirmed the PR head is clean and mergeable, has no review comments or requested changes, maps every ANU-6 acceptance item to runtime evidence, and preserves the ANU-7 migration boundary. The known repository-wide lint, integration, and E2E failures remain documented as out-of-scope follow-ups rather than being folded into this child.
  • 2026-07-21: Created draft PR #30 through the Anuva CLI. The CLI linked the PR and moved ANU-6 from In Progress to In Review (receipt 20260721T073343Z-pr-create-da06).

Files and documentation updated

  • Initial change-folder index, implementation plan, implementation log, and completion-report shell.
  • Change navigation and recursive index coverage.
  • Dockerfile.dev, .dockerignore, compose.yaml, and safe environment examples.
  • scripts/local-stack/** for initialization, pgAdmin registration, runtime smoke, migration guards, parity summaries, and reset confirmation.
  • tests/unit/local-stack.test.ts for immutable references, configuration boundaries, path/target guards, plan mode, and reset refusal.
  • Payload/Mastra wording and schema-push configuration.
  • Repository README plus bootstrap, architecture, environment, command, testing, API, and known-gap documentation.

Verification evidence

  • Planning docs recursive index validation: passed.
  • Planning preview: all change overview/plan/log/report pages returned HTTP 200.
  • docker compose --env-file .env.compose config --quiet: passed; Docker CLI warned that the user Docker config was unreadable in the sandbox.
  • Targeted Biome check: passed after formatting and guard cleanup.
  • TypeScript tsc --noEmit: passed.
  • Local-stack Vitest file: 10 tests passed.
  • Final web image build against the updated lockfile: passed.
  • pnpm stack:up, pnpm stack:restart, pnpm stack:down/stack:up, runtime version/port probes, named-volume sentinels, and pnpm stack:verify: passed.
  • git diff --check: passed.
  • Strict MkDocs build: passed with existing informational warnings.

Deviations, risks, and follow-ups

  • The Docker Hub pull blocker is resolved by the Docker Desktop image-store setting change. The local stack remains intentionally separate from the real Supabase export/restore/parity work owned by the dependent migration issue.
  • Immutable manifest and Linux amd64 child digests were resolved from the Docker Hub tag API. Running version commands remain required before accepting the dependent migration issue.