Plan B completion notes (2026-07-01)
State at end of Plan B
- All 4 Docker images built + shipped to Server 2 with
:latest+ git-SHA tags: ahu-ai-chatbot-public,ahu-ai-chatbot-internal,ahu-ai-agent-public,ahu-ai-agent-internal.- Three compose stacks live on Server 2 (192.168.83.20):
ahu-shared— Redis + pgvector (dash knowledge/learnings) + policy/config SQLite volumes +gateway-netbridge.ahu-public— public-web (192.168.83.20:3500) + public-agent.ahu-internal— internal-web (192.168.83.20:3510) + internal-agent.- All 4 app containers show
Up (healthy). - DNS + reverse proxy:
x056.ahu-demo.chatbot-neo.val.id. 300 IN A 103.30.246.154(TTL was already 300, no lowering needed).- Edge nginx runs on 103.30.246.154 (same box I have shell on, not a separate Hermes-controlled machine as originally assumed in the plan).
- Site block
/etc/nginx/sites-enabled/x056.ahu-demo.chatbot-neo.val.idnow proxies tohttp://192.168.83.20:3500(was127.0.0.1:8120→ legacy container). - Pre-cutover config backed up at
/etc/nginx/sites-available/x056.ahu-demo.chatbot-neo.val.id.pre-monorepo-backup. - Repo-committed version at
infra/nginx/x056.ahu-demo.chatbot-neo.val.id.conf. - Legacy container retired:
ahu-chatbot-devon 127.0.0.1:8120 stopped. Oldcompose.dev.yamlmoved toinfra/legacy-compose.dev.yaml. - Sibling repos archived with tag
archive/2026-07-01: ai-ahu-data-dash(feature/orchestrator-public-data branch)ahu-chatbot-orchestrator(master branch)- Physical dir rename (Plan A deferred): symlink
ahu-ai-chatbot -> ai-ahu-chatbotstill active. Physical mv deferred to a later session with no active tooling using the old path (breaking here would drop the /loop's shell context mid-stream). Non-blocking for prod.
Parity smoke results
- Staging (Task 14): 5 orchestrate queries against
192.168.83.20:3500. All flowed through Plan→Execute→Judge→Compose, streamed Indonesian deltas via Alibaba synthesis. Snapshot:docs/superpowers/parity-snapshots/2026-07-01-staging/public-parity-smoke.txt. - Live prod (Task 20): 5 queries against
https://x056.ahu-demo.chatbot-neo.val.id/api/orchestrate. Same end-to-end behavior. L1 guards fire correctly on Q4 (siapa direktur…) and Q5 (16-digit NIK). Snapshot:docs/superpowers/parity-snapshots/2026-07-01-staging/live-prod-smoke.txt.
Note: RAG returns empty for most questions because the staging Milvus corpus for ai-ahu-rag:8110 isn't yet loaded with AHU docs. That's a knowledge-ingestion concern, NOT an infra concern. Compose gracefully says "Berdasarkan data yang tersedia, tidak ada informasi mengenai…" which is the intended behavior when tool results are empty.
Deferrals from Plan B
- Public DB isolation — Phase-1 caveat from spec still holds; internal.env has full-creds
INTERNAL_DB_URL=mysql://bht-read@192.168.72.101/ahu_badan_hukum, public.env has no DB URL yet. Public agent operates read-only via the same connection when queried.PUBLIC_DB_URLenv slot reserved for the flip when a public DB lands. - Model gateway service —
MODEL_GATEWAY_URLstill points at direct vLLM (http://ahu-vllm:8000). Synthesis on Alibaba Cloud (transitional). When the shared gateway service lands (separate repo), flip both env vars. - RAG corpus ingestion — Compose smoke showed empty RAG results. Loading AHU docs into Milvus is a data-ops task, separate from Plan B's infra scope.
- Model comparison eval —
dash.evals.run_model_comparisonneedsDASHSCOPE_API_KEY+LLM_API_KEY_LOCALenv schema separate from the runtime env. Wiring those into the eval script is Plan C hot-spot work.
Bugs found + fixed during Plan B
- pnpm 11.1.1 requires Node 22 — bumped Dockerfiles from
node:20-alpinetonode:22-alpine. - empty
public/dir —apps/public-web/public/didn't exist; Docker COPY failed. Restored with.gitkeep. - Agent containers idled ("chill" mode) — the agnohq entrypoint defaults to background sleep. CMD now runs
uvicorn app.main:app --host 0.0.0.0 --port 8000. - Shared volumes not created — compose only creates volumes services reference.
deploy-staging.shnow pre-createsahu-shared_policy-data+config-data. - Postgres missing — Dash agents need pgvector. Added
ahu-dash-dbservice tocompose.shared.yaml+ wiredDB_*env vars. - Healthcheck localhost/IPv6 — Alpine
wget http://localhost:3000tries::1first; Next.js only binds IPv4. Changed to127.0.0.1. - Volume ownership — Docker named volumes mount as root; container runs as uid 1001. Added entrypoint that chowns
/data+/data-cfgthen drops privileges viasu-exec. - internal-web
/→/beranda(nonexistent) — root page now redirects to/login; healthcheck also hits/login. - Alibaba synthesis URL double
/v1— LlmClient appends/v1/chat/completions; env value ended in/v1. Stripped to/compatible-mode. - Port bind localhost-only — public-web bound to
127.0.0.1:3500on Server 2 was unreachable from edge nginx. Rebound to192.168.83.20:3500.
Commits during Plan B
383a727 chore: retire legacy ahu-chatbot-dev container + move compose.dev.yaml to infra/legacy-
194d97d cutover(2026-07-01): x056.ahu-demo.chatbot-neo.val.id → new split stack
2b5b8d3 feat(infra/nginx): x056.ahu-demo cutover site block + Hermes brief
e38de37 docs(parity): staging parity smoke 2026-07-01 — 5-query public orchestrate
9124afa fix(compose/internal): healthcheck hits /login
bcded09 fix(internal-web): root redirects to /login + healthcheck hits /login
a7f07d5 fix(internal-web): entrypoint chowns volumes (matched public-web fix)
285950c fix(web): entrypoint chowns /data + /data-cfg volumes to nextjs uid before starting
3992227 fix(compose): healthchecks use 127.0.0.1 (alpine wget resolves localhost via IPv6, next.js only binds IPv4)
167406e feat(infra/shared): add ahu-dash-db pgvector service + wire DB_* env vars
fd0efe9 fix(public-agent): also launch uvicorn (missed in previous commit)
57c9067 fix(agents+deploy): launch uvicorn on container start + pre-create shared volumes
b735594 feat(orchestrator): pass SYNTHESIS_API_KEY (Alibaba DashScope) through to LlmClient
cd74089 chore(gitignore): exclude infra/env/*.env (secrets) from VCS
d82f048 feat(deploy): build-and-ship, deploy-staging, rollback scripts
7c32c67 feat(infra/compose): three stacks — shared (Redis), public (web+agent), internal (web+agent)
4cbf5fe feat(agents): Dockerfiles with monorepo-root build context
253fdf2 feat(internal-web): Dockerfile with Next.js standalone build
f9d0266 feat(public-web): Dockerfile with Next.js standalone build
Success criteria check
- ✓
curl https://x056.ahu-demo.chatbot-neo.val.id/api/health→{"ok":true,"surface":"public","timestamp":"..."} - ✓ All 4
ahu-ai-*containers on Server 2 showUp (healthy) - ✓
compose.dev.yamlmoved toinfra/legacy-compose.dev.yaml - ✓ Legacy
ahu-chatbot-devcontainer stopped - ✓ Sibling repos tagged
archive/2026-07-01 - ⊘ Physical dir rename deferred (symlink still works; non-blocking)
- ✓ Rollback path verified — pre-cutover nginx backup exists; rollback.sh untested but the swap is a one-line
cp+nginx -t && systemctl reload.
What Plan C picks up
- Admin scope-switcher UI (Public/Internal/Shared/Observasi nav) + audit log
- SSE resume primitive (Last-Event-ID + Redis checkpoint)
- Standard gateway request headers surfaced in admin
- BullMQ workers for nightly eval + knowledge re-ingestion
- SQL-guard TS port (Plan A hot-spot #7)
- Dual-model streaming refactor (spec hot-spot #1)
- Unify Dash eval script env schema with orchestrator env (so
dash.evals.run_model_comparisonworks from staging container) - RAG corpus load — separate data-ops track