# Arrowstack Character deployment Production: https://dnd.arrowstack.dev Canonical source: private Admin/dnd-character-pwa. Temporary deployment mirror: public Admin/dnd-character-deploy, main branch. Coolify application: vfzhl6jql5vrzevm6yk1pvav (dnd-character). Project: 9ax6f4a6yn1h6gi7jgiihjhs; production environment; server: t6bzdsemktk6j3fxuzjlzkjg. Build: repository Dockerfile, HTTPS mirror clone, port 8080. Health: http://127.0.0.1:8080/health. Use IPv4 explicitly: BusyBox wget with localhost failed against the IPv4 listener. Keycloak: confidential dnd-character client, dev realm, exact callback https://dnd.arrowstack.dev/auth/callback. Runtime issuer/client credentials are handed directly to Coolify. Never commit credentials or character data. ## Release steps 1. Change the canonical private source; run npm ci, npm test and npm run build. 2. Copy the tested source and lockfile into the deployment mirror. Exclude node_modules, dist, .env files, test output and credentials. Retain private canonical provenance in commit messages. 3. Set the runtime SOURCE_COMMIT to the mirror revision being deployed. 4. Check active deployment jobs, deploy the application once, inspect the terminal build/runtime status, and verify /health and the Keycloak redirect on the live origin. 5. Roll back by pinning a prior known-good mirror commit and deploying it. Retain the PostgreSQL database during rollback. v0.2 initializes additive character/OAuth tables at startup; old versions only see local device saves. The mirror is a temporary fallback authorized by the user. The private repository deploy key workflow failed at git.arrowstack.dev port 22 with Permission denied (publickey); investigate the Gitea SSH/deploy-key listener before removing the mirror. Do not make canonical source public. Earlier inline-source test applications cbnkwtdve2fzumnxnz0jqupb and cdr9ivftpqqzdakmfuq0r5yz are inactive and have no domain. They are not production targets. ## Verification boundaries Fifteen focused tests cover HP/temp HP, proficiency/expertise, declared rest resets, JSON validation, IndexedDB account separation/persistence, encrypted session integrity/expiry and fail-closed missing secrets, plus MCP HTTP/consent/PKCE, token lifecycle, account isolation, revision conflicts and offline sync. Production TypeScript checks and Vite build also run in the Docker image build. Authenticated browser creation/reload and installed iPhone offline behavior require a signed-in device smoke test; build and health alone do not prove those interactions. ## v0.2 storage and MCP Arrowstack provisions database-per-tenant storage using the application UUID and tenant id `dnd-character`, injecting restricted DATABASE_URL credentials directly. The server creates additive character_sheets, mcp_clients, mcp_codes and mcp_grants tables. Character rows are keyed by Keycloak subject and character id. Preserve the database and secret across redeploys. MCP endpoint: https://dnd.arrowstack.dev/mcp (Streamable HTTP POST). OAuth discovery and dynamic registration are public; sheet operations require audience-bound tokens. Keycloak callback remains /auth/callback. Do not add auth bypasses or secrets to the mirror. Verify discovery, 401 bearer challenge, account API denial and deployed revision after release. Authenticated live consent and device sync require a signed-in user check; local tests cover the complete app-side OAuth/MCP flow.