Phase 288 — Liv AI can deploy a custom app and get its DNS
Liv AI gains a gated deploy_app tool: hand it a Docker image (or an AI-authored docker-compose; Next.js via image-wrap) and it deploys onto the box, reachable at {slug}-{username}.livinity.io — reusing the existing install pipeline + Phase-287 verify-live DNS.
What shipped
apps.deployCustomtRPC mutation — stages an AI-authored compose/image, FORCES the non-builtin sanitizer (isGeneratedTemplate=false, never reassigned) so untrusted compose is always scrubbed (no docker.sock, no host-net/privileged, no host-path binds outside app-data), then reuses a factored#finishInstalltail →{slug}-{user}.livinity.io(username appended server-side, Phase-287 verify-live).liv-deployMCP tool (deploy_app, markedDESTRUCTIVE:→ user approval before any container launches), mirroringliv-apps; registered in the seed catalog +SYSTEM_MCP_NAMES.- Existing-box self-heal — boot-time HSETNX (no-clobber) backfill so boxes already running pick up
liv-deployon Update without losing operator-customized MCP entries. - Docs + assets — a Liv-facing compose/manifest schema (
LIV-DEPLOY.md) seeded to the box + a canned multi-stage Next.js Dockerfile (port 3000).
Scope / deferrals
- Identity (MVP): deploys as the box owner (same identity catalog installs use); true per-user isolation via
installForUseris a documented follow-up. - Next.js: image-wrap now; an on-box source builder is deferred.
Gates
livinityd tsc=305 (baseline held) · security-crux test 3/3 (docker.sock/host-bind rejected, privileged stripped) · self-heal HSETNX no-clobber 5/5 · existing install tests green · no DB migration · bash -n update.sh clean.
Full Changelog: v44.47...v44.48