Stage 1 finish — verification record (2026-10-20, Sol, t_f66c75c0)
Stage 1 finish — verification record (2026-10-20, Sol, t_f66c75c0)
Scope (derived from title + delay-analysis + stages doc; registry = source)
- Compose render (template → rendered project, validates)
- arm64 pulls (all images linux/arm64)
- Delay-analysis (the 2 pseudo-blockers were already-locked registry facts — resolved)
- Registry = source of truth (roles/planes read from cortex/registry/agents.yaml)
Live probe (prod 161.33.71.67, aarch64, Docker 29.7.2, Compose 5.4.0)
Compose render — PASS
- Template renders via sed (///…);
docker compose configexit 0, 0 unsubstituted placeholders, 0 warnings. - 6 services: postgres, redis, medusa-server, medusa-worker, storefront, eve-agent.
- Network: fixed name
tenant-{{SLUG}}, bridge, internal:false, compose-owned + labelled (com.docker.compose.project/.network/.version). - No
container_name:(grep = 0); containers named<project>-<service>-1, resolved via network aliases (pg-{{SLUG}},medusa-{{SLUG}},redis-{{SLUG}}, …). Verified: pg-test-tenant → 172.19.0.3. - Resource limits match design doc §2 exactly.
- PROVEN contract: hand-created network (labels={}) is NOT adoptable by compose — compose up runs but leaves it unlabelled and orphaned on down. Template's "let compose create it" rule is load-bearing and correct.
arm64 pulls — PASS
All images linux/arm64:
- solos-medusa:latest 1.32GB (Medusa 2.21.2)
- solos-storefront:latest 242MB
- solos-eve:latest 250MB
- solos-pulse:latest 263MB
- postgres:15-alpine 408MB
- redis:7-alpine 58.7MB
- authelia/authelia:latest 104MB
Delay-analysis — RESOLVED (per delay-analysis doc)
- Roles/scope = cortex/registry/agents.yaml (plane heart/brain/pulse + per-agent role/port). No new ruling needed.
- Pulse vs LAB placement = ruled 2026-10-17/18, recorded in ssh-access-matrix + three-units-topology. Brain+Heart live on LAB; Pulse on laptop; prod = hosting only.
- Heart (Ace/Alpha/Atlas) sequenced per stages doc rows. Ace = Stage 1 renders + Stage 2; Alpha = ports/isolation; Atlas = health-gate/rollback.
Registry = source — VERIFIED
- Registry read at /home/lab/.solos/cortex/registry/agents.yaml. Ace/Alpha/Atlas all plane=heart, host=lab, ports 8301/8302/8303, model opencode/longcat-2.5-preview-free, billing none, retention zero-retention. Matches the doc's assignment.
Gaps found (Stage 1 finish blockers — code/build, not infra)
A. medusa-server crash-loops (Restarting, 12+ restarts). Root cause: empty Postgres (0 tables). Medusa v2.21.2 requires medusa db:migrate predeploy (design doc §"update/rollback loop" step 6). Neither onboard_tenant.sh nor the template runs migrate. Verified fix: throwaway probe with medusa db:migrate created 148 tables and medusa booted. This is the real "Stage 1 finish" gap — compose render + pulls are done; the migrate/predeploy contract is missing from the Stage 1 artifact.
B. REDIS_PASSWORD generated + stored (secrets.env) but never consumed — compose sets no REDIS_PASSWORD on redis and REDIS_URL has no password. Redis answers PONG with no auth. Minor; dead secret.
C. medusa- alias NXDOMAIN while medusa-server is crash-looping (alias only registered when Up). Resolves once migrate runs. Not a template bug.
D. Redis volume declared (redis-data:) but service has no volumes: mount — redis is ephemeral/stateless. Design doc promises nightly Redis SAVE snapshot weekly. Either mount redis-data or drop the volume.
E. Three compose copies: template (5822 B), test-tenant (6261 B), /tmp/stage1-final/compose.yml (identical md5 to test-tenant, and is the file the running containers were actually launched from). Single source of truth is template + sed render; /tmp copy is an orphaned launch artifact. Provenance note only.
Recommendation
Stage 1 mechanical work (render + arm64 + isolation) is DONE and verified on disk. The one thing that actually stops "Stage 1 finish" is the missing db:migrate predeploy step. Add it (one-shot compose service medusa-migrate with restart:"no" depending on postgres healthy, OR an onboard step before up -d of medusa) and re-run the test tenant. That step is currently Stage 2 scope per the stages doc, but the gap is visible now and belongs in the Stage 1 finish record. No infra change required; no new ruling needed (registry = source).
Stage ground-truth (2026-10-19, Tam census for "any progress?")
Stage 2 completion — health gate, LIVE marker, soak on a real tenant (2026-10-21, Sol, t_c1cb1012)
Card: t_c1cb1012 — Stage 2 completion: prove the health gate + LIVE marker + soak on test-tenant Split from: t_3f8c9735 (criteria 1, 2, 4, 5 already proven there) Host: prod 161.33.71.67 (aarch64, Docker 29.7.2, Compose 5.4.0) Script: /home/ubuntu/.solos-infra/onboard_tenant.sh — final sha256 b7af1f2d283848f4addb8d2127cdddd337522f67e5498bb11d6afeb9b9e56d18 (36,974 B) Status: ✅ all five acceptance criteria proven by live probe. One real defect was found and fixed in the process.

