Files
ThothII/.superpowers/sdd/2026-08-04-unified-compose-deployment/task-2-report.md
T

5.9 KiB
Raw Blame History

Task 2 report — portable Compose contract

Status

Completed. The root Compose file is now a portable two-service base, with explicit local and server overrides. Workspace-registry configuration remains generic and continues to require an installation-provided Git remote.

Changed files

  • .env.example — shared non-secret, generic endpoint and registry examples.
  • compose.yaml — portable core and frontend base, owned thothii network, health checks, named settings/Pi/registry/session volumes, and generic external endpoint variables.
  • deploy/compose.local.yaml — loopback core/frontend ports, AUTH_MODE=none, local installation identity, and non-persistent restart policy.
  • deploy/compose.server.yaml — frontend-only configurable host bind, AUTH_MODE=upstream, server identity, host-root data/Pi/registry mounts, and restart policy.
  • deploy/env/local.env.example and deploy/env/server.env.example — safe profile-specific values using .example.invalid documentation domains.
  • scripts/test-default-compose.sh — default local portable Compose assertion.
  • scripts/test-unified-compose.sh — JSON structural assertions for base/local/server plus the required missing-remote failure checks.

RED evidence

Before changing Compose, bash scripts/test-unified-compose.sh exited 1 with:

Error: forbidden application coupling

The failure was raised by the required assertion while the rendered root config still contained the portal-specific networks and host paths.

GREEN evidence

The following fresh commands completed with exit status 0:

bash scripts/test-default-compose.sh
# default Compose contract passed.

bash scripts/test-unified-compose.sh
# unified Compose contract passed.

bash -lc 'set -a; source deploy/env/local.env.example; set +a; docker compose -f compose.yaml -f deploy/compose.local.yaml config --quiet'

bash -lc 'set -a; source deploy/env/server.env.example; set +a; docker compose -f compose.yaml -f deploy/compose.server.yaml config --quiet'

bash scripts/verify-line-endings.sh
git diff --check

The two config --quiet invocations source only their non-secret profile example so the requested commands can validate the required Git-remote interpolation without an operator .env file.

Self-review

  • The base renders exactly core and frontend; it has no portal, Chirone, local-LLM-network, or host-path coupling.
  • Local publishing is loopback-only; server has no core host port and publishes the frontend bind.
  • The core retains outbound access for configured external DWH, vector, Git, embedding, and LLM endpoints; the owned Compose network is private to this stack but is not marked Docker-internal.
  • The structural test validates the exact required service assertion, forbidden-coupling assertion, required base network/volumes, profile port policy, and THT_WORKSPACE_GIT_REMOTE failure.
  • All new YAML and shell files were checked by the repository line-ending verifier.

Commit

2595d35682a5200b877acb71764b4eb195a39ea4 — deploy: unify local and server compose stack

Concerns

None for Task 2. Git and connector secret transport remains intentionally outside this base/profile contract and is addressed by the next scoped task.


Fix round 1/5 — Pi auth mount and generic LLM endpoint

Status

Completed. Pi’s mutable state remains writable, while provider authentication is supplied only by the deterministic PI_AUTH_FILE host-file contract mounted read-only at Pi’s canonical /home/thoth/.pi/agent/auth.json path. The base now exposes the generic THT_LLM_URL contract; the local and server examples set only documentation endpoint values.

Changed files

  • compose.yaml — adds THT_LLM_URL and a read-only PI_AUTH_FILE bind while retaining the writable pi-state volume for non-secret runtime state.
  • deploy/compose.server.yaml — retains the auth-file bind when its storage mounts override the portable base.
  • .env.example, deploy/env/local.env.example, and deploy/env/server.env.example — document the generic https://llm.example.invalid endpoint; profile examples also document the required host auth-file path without including a secret.
  • scripts/test-unified-compose.sh — asserts generic LLM contract presence, no Docker socket/daemon mount, and exactly one read-only Pi auth file bind in the base and both profiles.

RED evidence

Before the Compose changes, this command exited 1:

bash scripts/test-unified-compose.sh

Error: core must expose a generic THT_LLM_URL endpoint contract

The failure was raised by the new structural assertion against the previous rendered base.

GREEN evidence

The following focused commands completed with exit status 0 after the fix:

bash scripts/test-unified-compose.sh
# unified Compose contract passed.

bash scripts/test-default-compose.sh
# default Compose contract passed.

docker compose --env-file deploy/env/local.env.example -f compose.yaml -f deploy/compose.local.yaml config --quiet

docker compose --env-file deploy/env/server.env.example -f compose.yaml -f deploy/compose.server.yaml config --quiet

bash scripts/verify-line-endings.sh
git diff --check

Self-review

  • Both rendered profile contracts carry a single bind mount to the Pi auth.json file with read_only: true; no auth value appears in Compose or the environment examples.
  • The writable Pi-state mount does not replace the read-only auth file, and the server override explicitly retains that file bind after replacing the base storage list.
  • The structural regression test rejects any Docker socket/daemon mount and validates the generic LLM endpoint contract without adding provider-specific endpoints or hostnames.
  • The deferred Minor report-wording finding was not changed.

Commit

2ce2e0089a66ca508db041a71db9807f66d0bf24 — fix: harden compose Pi auth mounts

Concerns

None for this focused round.