# 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/<service>/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=<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=<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 <rg> --nsg-name <nsg> -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
```
