# OpenCode Lifecycle Follow-ups These are non-blocking improvements deferred during the time-crunch pass. ## Architecture split Longer term, keep these concerns independently scalable: - **Frontend**: Next.js app, hosted separately. - **Core backend/API**: auth, DB, workflows, user-facing routes. - **Actor runtime**: Rivet user actors; actors orchestrate work and call control-plane APIs. - **OpenCode lifecycle/control plane**: Docker/Kubernetes/Fly/Nomad manager that creates, health-checks, upgrades, and tears down per-user OpenCode runtimes. - **Git service**: Gitea or hosted Git provider, reachable through a public URL. Today, `src/docker/manager.ts` is not a separate service. It is an internal module inside `growqr-backend`; authenticated HTTP routes under `/opencode` and `/actors` call into it, and the user actor calls into it directly through imports. ## Deferred hardening - Add a dedicated OpenCode lifecycle service/API instead of embedding Docker control in the backend process. - Add admin rollout endpoints for image/prompt upgrades: - recreate one user's OpenCode container - recreate all stale containers - inspect container version/labels/health - Make `provisionUserStack` validate existing `running` rows instead of trusting DB state. - Make `startOpencodeContainer` inspect existing containers and recreate them if image/version/labels/env are stale. - Make `reconcileOnBoot` mark stale containers as stopped/needs migration instead of only logging. - Add explicit migration state to `user_stacks` if rollouts need to be asynchronous. - Attach spawned OpenCode containers to a controlled Docker network or move to an orchestrator-native network model. - Split service URLs consistently for every external dependency: - public browser URL - backend internal URL - OpenCode/container egress URL - Add rate limits and stricter resource quotas per user/container. - Encrypt stored OpenCode per-container passwords or move them to a secrets manager.