diff --git a/docs/devops/vercel/CODEX_AGENT_PROMPTS.md b/docs/devops/vercel/CODEX_AGENT_PROMPTS.md new file mode 100644 index 00000000..96981072 --- /dev/null +++ b/docs/devops/vercel/CODEX_AGENT_PROMPTS.md @@ -0,0 +1,408 @@ +# Codex Agent Prompts — Vercel Deployment Readiness + +> **Purpose:** Ready-to-paste prompts for Codex agents to complete all remaining work items from the Vercel deployment audit. +> **Dependency order:** Run prompts 1→2 first (infra), then 3→4→5 (code fixes) in any order, then 6 (`.npmrc` updates) last. +> **Reference:** See [`ECOSYSTEM_WEB_APPS_INVENTORY.md`](./ECOSYSTEM_WEB_APPS_INVENTORY.md) for full audit context. + +--- + +## Prompt 1: Caddy Gateway — Replace Traefik with Caddy on Azure VM + +> **Runs on:** Azure VM +> **Depends on:** Nothing +> **Blocks:** Prompt 2, Prompt 6 + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Replace the existing Traefik gateway container with Caddy to provide HTTPS termination and path-based routing for all backend services. + +CONTEXT: +- The decision doc is at docs/devops/single_azure_vm/docker/SECURE_API_EXPOSURE.md in the learning_ai_common_plat repo +- The domain is bytelyst.com +- API hostname: api.bytelyst.com +- Currently 13 backend services are healthy on ports 4003, 4005, 4007, 4010-4019 +- Traefik is running but only as a passthrough — no TLS, no path routing hardened +- All backend containers are on a Docker network + +DELIVERABLES: +1. Create a Caddyfile with: + - api.bytelyst.com as the main host (automatic Let's Encrypt TLS) + - Path-based routing to all 13 backends: + /platform/* → platform-service:4003 + /extraction/* → extraction-service:4005 + /mcp/* → mcp-server:4007 + /peakpulse/* → peakpulse:4010 + /chronomind/* → chronomind:4011 + /jarvisjr/* → jarvisjr:4012 + /nomgap/* → nomgap:4013 + /mindlyst/* → mindlyst:4014 + /lysnrai/* → lysnrai:4015 + /notelett/* → notelett:4016 + /flowmonk/* → flowmonk:4017 + /actiontrail/* → actiontrail:4018 + /localmemgpt/* → localmemgpt:4019 + - Strip the path prefix before forwarding (backends expect / not /platform/) +2. Add a caddy service to docker-compose replacing or alongside the gateway service +3. Stop publishing backend ports (4003, 4005, 4007, 4010-4019) publicly — only expose 80/443 +4. Verify all 13 backends respond via https://api.bytelyst.com//health +5. Update docs/devops/single_azure_vm/docker/README.md with the new access model + +DO NOT: +- Delete the existing Traefik config — just stop using it +- Expose any backend port publicly +- Hardcode IP addresses in the Caddyfile + +COMMIT: Use conventional commits: feat(gateway): replace Traefik with Caddy for HTTPS path routing +``` + +--- + +## Prompt 2: Gitea HTTPS Exposure via Caddy + +> **Runs on:** Azure VM +> **Depends on:** Prompt 1 (Caddy must be running) +> **Blocks:** Prompt 6 + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Expose the Gitea npm registry over HTTPS via the Caddy gateway so that external build systems (Vercel) can install @bytelyst/* packages. + +CONTEXT: +- Gitea is running on port 3300 inside the Docker network +- Caddy is already configured for api.bytelyst.com (from the previous task) +- The Gitea npm registry URL pattern is: /api/packages/ByteLyst/npm/ +- Gitea needs its own subdomain because its internal routing expects to be at root +- Target URL: https://gitea.bytelyst.com + +DELIVERABLES: +1. Add a gitea.bytelyst.com block to the Caddyfile: + gitea.bytelyst.com { + reverse_proxy gitea:3300 + } +2. Ensure Gitea's ROOT_URL / SERVER__ROOT_URL is updated to https://gitea.bytelyst.com +3. Verify https://gitea.bytelyst.com loads the Gitea web UI +4. Verify npm registry is accessible: + curl -s https://gitea.bytelyst.com/api/packages/ByteLyst/npm/@bytelyst%2ferrors | head +5. Remove port 3300 from public NSG rules (Gitea only accessible via Caddy now) +6. Lock down other operational ports from public access where possible: + - 8025 (Mailpit) + - 8080 (Traefik dashboard — no longer needed) + - 10000 (Azurite) + +DO NOT: +- Break existing Docker-internal Gitea access (other containers still use gitea:3300) +- Remove the Gitea container or change its internal port + +COMMIT: feat(gateway): expose Gitea npm registry via HTTPS at gitea.bytelyst.com +``` + +--- + +## Prompt 3: Fix `file:` References Across 7 Repos + +> **Runs on:** Any agent with repo access (can be local or cloud) +> **Depends on:** Nothing (packages are already published to Gitea) +> **Blocks:** Nothing directly + +``` +TASK: Convert all file: references to @bytelyst/* packages into semver ^0.1.0 references across 7 web app repos. + +CONTEXT: +- 7 repos have web/package.json files that use file: references to ../../learning_ai_common_plat/packages/* +- These fail on Vercel because the sibling repo doesn't exist +- The packages are already published to the Gitea npm registry +- Each fix is: change "file:../../learning_ai_common_plat/packages/X" to "^0.1.0" +- After changing, run pnpm install to update the lockfile, then verify pnpm build passes + +REPOS AND FILES TO FIX: + +1. learning_ai_clock/web/package.json + - "@bytelyst/design-tokens": "file:..." → "^0.1.0" + - "@bytelyst/ui": "file:..." → "^0.1.0" + +2. learning_ai_jarvis_jr/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +3. learning_ai_fastgap/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +4. learning_ai_flowmonk/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +5. learning_ai_notes/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +6. learning_ai_local_memory_gpt/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +7. learning_ai_local_llms/dashboard/package.json + - "@bytelyst/design-tokens": "file:..." → "^0.1.0" + - "@bytelyst/ui": "file:..." → "^0.1.0" + +FOR EACH REPO: +1. Edit the package.json — replace file: refs with ^0.1.0 +2. Run: cd web && pnpm install (or cd dashboard for LLM Lab) +3. Run: pnpm build +4. If build passes, commit: fix(web): convert file: refs to registry semver for Vercel compatibility +5. Push to origin main + +DO NOT: +- Change any other dependencies +- Modify any source code +- Skip the build verification step +``` + +--- + +## Prompt 4: Fix Hardcoded `output: standalone` in 4 Repos + +> **Runs on:** Any agent with repo access +> **Depends on:** Nothing +> **Blocks:** Nothing directly + +``` +TASK: Make the Next.js output mode Vercel-aware in 4 repos that currently hardcode output: 'standalone'. + +CONTEXT: +- Vercel manages its own output mode — hardcoded standalone breaks Vercel builds +- The fix is: wrap standalone output in a process.env.VERCEL conditional +- Docker builds (which don't set VERCEL env var) will still get standalone mode +- 4 repos need this fix + +REPOS AND FILES: + +1. learning_ai_fastgap/web/next.config.ts + Change: + output: "standalone", + outputFileTracingRoot: path.join(process.cwd(), ".."), + To: + ...(process.env.VERCEL ? {} : { + output: "standalone", + outputFileTracingRoot: path.join(process.cwd(), ".."), + }), + +2. learning_ai_notes/web/next.config.ts + Same pattern as above. + +3. learning_ai_trails/web/next.config.ts + Change: + output: 'standalone', + To: + ...(process.env.VERCEL ? {} : { output: 'standalone' }), + +4. learning_ai_local_memory_gpt/web/next.config.ts + Same pattern as #3. + +NOTE: learning_ai_local_llms/dashboard/next.config.ts also has this but LLM Lab is NOT viable on Vercel (needs local Ollama), so skip it. + +FOR EACH REPO: +1. Edit next.config.ts with the conditional +2. Verify Docker build still works: pnpm build (standalone should still activate without VERCEL env) +3. Verify VERCEL=1 pnpm build also works (output should be default, not standalone) +4. Commit: fix(web): make output mode Vercel-aware — conditional standalone +5. Push to origin main + +DO NOT: +- Change any other config options in next.config.ts +- Remove the standalone output entirely — Docker builds still need it +- Touch the LLM Lab dashboard (not viable on Vercel) +``` + +--- + +## Prompt 5: Create vercel.json for EffoRise (Vite SPA) + +> **Runs on:** Any agent with repo access to learning_ai_efforise +> **Depends on:** Nothing +> **Blocks:** Nothing + +``` +TASK: Create a vercel.json file for the EffoRise Vite SPA to handle client-side routing and API proxy configuration. + +CONTEXT: +- EffoRise is a Vite + React 19 SPA (not Next.js) in the learning_ai_efforise repo +- The Vite config is at the repo root (vite.config.ts) +- Build output goes to dist/public/ (custom, not default dist/) +- Uses wouter for client-side routing — all routes must serve index.html +- The backend API is at https://api.bytelyst.com/efforise +- Currently uses a dev proxy /api → localhost:4020 + +DELIVERABLES: +1. Create vercel.json at the repo root with: + { + "$schema": "https://openapi.vercel.sh/vercel.json", + "framework": "vite", + "buildCommand": "pnpm build", + "outputDirectory": "dist/public", + "rewrites": [ + { "source": "/api/(.*)", "destination": "https://api.bytelyst.com/efforise/$1" }, + { "source": "/(.*)", "destination": "/index.html" } + ] + } + +2. Verify pnpm build still works locally +3. Commit: feat(web): add vercel.json for Vite SPA deployment +4. Push to origin main + +DO NOT: +- Modify vite.config.ts +- Change any source code +- Add Vercel-specific code to the application +``` + +--- + +## Prompt 6: Update .npmrc Across All Product Repos + +> **Runs on:** Any agent with repo access +> **Depends on:** Prompt 2 (gitea.bytelyst.com must be live and accessible) +> **Blocks:** Vercel deployment + +``` +TASK: Update .npmrc files in all product repos to point to the public Gitea npm registry at gitea.bytelyst.com. + +CONTEXT: +- All product repos currently have .npmrc pointing to http://localhost:3300 (local Gitea) +- Gitea is now accessible at https://gitea.bytelyst.com via Caddy reverse proxy +- The npm registry URL is: https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ +- Auth token is passed via GITEA_NPM_TOKEN env var +- This change enables Vercel builds to install @bytelyst/* packages + +NEW .npmrc CONTENT (same for all repos): +@bytelyst:registry=https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ +//gitea.bytelyst.com/api/packages/ByteLyst/npm/:_authToken=${GITEA_NPM_TOKEN} + +REPOS TO UPDATE (12 total): + +1. learning_voice_ai_agent (user-dashboard-web, backend) +2. learning_ai_clock (web, backend) +3. learning_ai_jarvis_jr (web, backend) +4. learning_ai_fastgap (web, backend) +5. learning_ai_flowmonk (web, backend, mobile) +6. learning_ai_notes (web, backend, mobile) +7. learning_ai_trails (web, backend, sdk) +8. learning_multimodal_memory_agents (mindlyst-native/web, backend) +9. learning_ai_local_memory_gpt (web, backend) +10. learning_ai_efforise (root, backend, mobile) +11. learning_ai_local_llms (dashboard) +12. learning_ai_peakpulse (backend) + +FOR EACH REPO: +1. Find all .npmrc files (there may be multiple — root, web/, backend/, mobile/) +2. Update the @bytelyst registry line to use gitea.bytelyst.com +3. Add the auth token line if not present +4. Run: GITEA_NPM_TOKEN= pnpm install (verify packages resolve) +5. Commit: chore: update .npmrc to public Gitea registry at gitea.bytelyst.com +6. Push to origin main + +VERIFICATION: +After updating all repos, verify one end-to-end: + cd learning_ai_clock/web + GITEA_NPM_TOKEN= pnpm install + pnpm build + +DO NOT: +- Change any package versions +- Remove any other registry configurations (e.g., npmjs.org for non-@bytelyst packages) +- Hardcode the auth token — always use ${GITEA_NPM_TOKEN} +``` + +--- + +## Prompt 7: Complete admin-web and tracker-web on Azure VM + +> **Runs on:** Azure VM +> **Depends on:** Prompt 1 (Caddy gateway) +> **Blocks:** Nothing (independent of Vercel work) + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Resolve the remaining admin-web and tracker-web containers so they are running and healthy. + +CONTEXT: +- Per DEPLOYMENT_STATUS_2026-03-29.md, all 13 backend services are healthy +- admin-web and tracker-web are the two remaining unresolved containers +- Both are Next.js 16 apps from the learning_ai_common_plat repo under dashboards/ +- Both use workspace:* dependencies resolved by pnpm +- Both use the --webpack build flag +- admin-web runs on port 3001, tracker-web on port 3003 +- The Docker build context is dashboards/admin-web/ and dashboards/tracker-web/ + +DELIVERABLES: +1. Diagnose why admin-web and tracker-web builds failed +2. Fix the build issues (likely @bytelyst/* package resolution or standalone entrypoint) +3. Rebuild and start both containers +4. Verify health: + curl -s http://127.0.0.1:3001 | head + curl -s http://127.0.0.1:3003 | head +5. Add Caddy routes for the dashboards: + - https://admin.bytelyst.com → admin-web:3001 + - https://tracker.bytelyst.com → tracker-web:3003 +6. Update DEPLOYMENT_STATUS_2026-03-29.md to reflect the fix +7. Mark Phase 7 as DONE if all services are now healthy + +COMMIT: fix(deployment): resolve admin-web and tracker-web containers +``` + +--- + +## Prompt 8: NSG Lockdown — Reduce Public Port Exposure + +> **Runs on:** Azure VM (or Azure CLI from anywhere) +> **Depends on:** Prompts 1 + 2 (Caddy handling all traffic) +> **Blocks:** Nothing + +``` +TASK: Reduce the Azure NSG (Network Security Group) rules so only ports 80, 443, and 22 are publicly accessible. + +CONTEXT: +- The Azure VM currently exposes many service ports publicly (3000-3300, 4003-4019, 8025, 8080, 10000, 11434) +- Caddy now handles all public HTTPS traffic on 80/443 +- Backend services, Gitea, Grafana, Mailpit, and Azurite are all accessed through Caddy +- Only SSH (22) and HTTP/HTTPS (80/443) should remain publicly open +- This follows the recommendation in SECURE_API_EXPOSURE.md + +DELIVERABLES: +1. List current NSG rules: az network nsg rule list --resource-group --nsg-name -o table +2. Remove or deny inbound rules for all ports except 22, 80, 443 +3. Verify Caddy still serves all routes correctly +4. Verify SSH access still works +5. Document the changes in DEPLOYMENT_STATUS_2026-03-29.md + +DO NOT: +- Remove the SSH (22) rule +- Remove the HTTP (80) or HTTPS (443) rules +- Make changes without first listing the current rules + +COMMIT: chore(security): lock down Azure NSG to 22/80/443 only +``` + +--- + +## Execution Order + +``` +Phase 1 — Infrastructure (Azure VM agent) + ├── Prompt 1: Caddy Gateway Setup + ├── Prompt 2: Gitea HTTPS Exposure (after Prompt 1) + └── Prompt 7: Fix admin-web + tracker-web (after Prompt 1) + +Phase 2 — Code Fixes (any agent with repo access, all independent) + ├── Prompt 3: Fix file: refs (7 repos) + ├── Prompt 4: Fix output: standalone (4 repos) + └── Prompt 5: EffoRise vercel.json + +Phase 3 — Registry Migration (after Prompt 2 is verified) + └── Prompt 6: Update .npmrc (12 repos) + +Phase 4 — Security Hardening (after all Caddy routes confirmed) + └── Prompt 8: NSG Lockdown + +After all prompts complete: + → Vercel project creation (manual — Vercel UI) + → Set GITEA_NPM_TOKEN + other env vars per project (manual — Vercel UI) + → Trigger first deploys and verify +```