A single self-hosted Project Manager app for Zion's homelab. The PM brain is GLM (via the Z.ai Coding Plan subscription); it takes any task, decomposes it, delegates work to the worker fleet (Claude, Codex, local Ollama), supervises, and gates every outward action behind an ap...
A single self-hosted Project Manager app for Zion's homelab. The PM brain is GLM (via the Z.ai Coding Plan subscription); it takes any task, decomposes it, delegates work to the worker fleet (Claude, Codex, local Ollama), supervises, and gates every outward action behind an approval outbox.
One surface, three panes:
@mention any model mid-conversation.Built per SEED.md (the authoritative charter). Runs on CT120 (REDACTED-IP), fronted at https://REDACTED-HOST behind Authentik SSO.
REDACTED-HOST (Traefik + Authentik forwardAuth, CT244)
│
▼ http://REDACTED-IP:4100
Next.js app (App Router, port 4100)
│ REST API routes
▼
pmConductor (Mastra Agent, GLM via Z.ai Anthropic-compat)
│ tools: delegate / createTask / updateTask / draftApproval
▼
Worker adapters ──► claude (SSH root@CT215, claude -p)
──► codex (SSH zion@CT241, codex exec)
──► ollama (HTTP 3060 /api/chat)
shared memory ──► queryMemory (homelab-rag MCP :9876)
──► queryGraph (cbm-homelab MCP :9877)
store ───────────► better-sqlite3 at data/zionpm.db
GLM is the conductor, not a worker. Worker tier = claude / codex / ollama, with strong→weak fallback (claude → codex → ollama) when a model is capped.
| Path | Purpose |
|---|---|
lib/glm.ts |
GLM model via Z.ai Anthropic-compat (@ai-sdk/anthropic, custom baseURL) |
lib/mastra.ts |
pmConductor Mastra agent + tool registry + runConductor() |
lib/memory.ts |
queryMemory / queryGraph over the MCP SDK (SSE) |
lib/router.ts |
channel-default + @mention dispatch (§7) |
lib/db.ts |
SQLite schema + seed + accessors (§5) |
lib/workers/{delegate,claude,codex,ollama,ssh}.ts |
worker adapters + tier fallback (§6) |
app/api/** |
REST routes (channels, messages, tasks, outbox, fleet) |
app/page.tsx |
Chat / Board / Fleet UI |
.env.local, never committed)| Var | Default | Notes |
|---|---|---|
ZAI_API_KEY |
- | Z.ai Coding Plan subscription key (from .env.secrets, CRLF-stripped) |
PM_BRAIN_MODEL |
glm-4.6 |
conductor model (also glm-4.5, glm-5.2) |
ZAI_BASE_URL |
https://api.z.ai/api/anthropic/v1 |
Anthropic-compatible endpoint |
ZPM_OLLAMA_URL |
http://REDACTED-IP:11434 |
3060 Ollama (CT205 GPU node was offline at build) |
ZPM_CLAUDE_USER |
root |
root@CT215 has the working claude login |
ZPM_SSH_KEY |
/root/.ssh/id_ed25519 |
CT120 key, authorized on CT215 + CT241 |
ZPM_RAG_SSE / ZPM_CBM_SSE |
:9876 / :9877 |
MCP SSE endpoints |
Secrets live only in .env.local on CT120 and /shared/projects/.env.secrets. Never in code or git.
The canonical repo lives on the share at /shared/projects/zion-pm (committed + pushed from CT215; remote github.com/zionboggan/zion-pm, private). The app runs from CT120 local fs /opt/zion-pm (noexec CIFS rule - never execute from the share).
CT120 has no direct egress to github.com, so deploys are CT215-mediated (CT215 has GitHub access and syncs source to CT120 over SSH):
# on CT215: pull latest canonical, sync source to CT120, build + restart there
cd /shared/projects/zion-pm && git pull
tar czf - app lib public package.json pnpm-lock.yaml tsconfig.json next.config.ts \
postcss.config.mjs | ssh root@REDACTED-IP 'tar xzf - -C /opt/zion-pm'
ssh root@REDACTED-IP 'cd /opt/zion-pm && pnpm install && pnpm build && systemctl restart zion-pm'
Service: zion-pm.service (systemd, onboot). Logs: journalctl -u zion-pm -f.
#pm(glm) / #claude / #codex / #ollama seeded with model badges.@ollama:mistral-nemo:12b override → Ollama reply authored ollama.@claude → SSH CT215 → claude -p creates a file; path returned.create-mastra/Mastra require Node ≥22.13.create-next-app + @mastra/core (the --template nextjs flag was not usable non-interactively). Honors the locked "Mastra/TypeScript" decision.REDACTED-IP (has mistral-nemo:12b).root@CT215 with IS_SANDBOX=1 (zion's claude login returned 401; root's is valid; root needs the sandbox flag for --dangerously-skip-permissions).zion-pm application were added to the embedded outpost for pm.lab (mirrors the dashboard/notes apps).See OPS_RUNBOOK.md for operations and SEED.md for the full charter.