name: shadow-role
description: "Shadow is an application server, not a development host; cleanup on 2026-05-15 removed IDE tooling and dead cron entries"
metadata:
node_type: memory
type: project
originSessionId: 71d40fa2-b151-4c81-9821-f0dfeb7a0f66
---
As of 2026-05-15 the user reclassified shadow from "AI agent dev box" to
**application server**. Services kept and treated as load-bearing:
- Dify (API/Worker/Web on port 5001 etc., user 1001, `/app/api/.venv/...`)
- n8n (port 5678)
- Ollama (`/usr/local/bin/ollama serve`, model: `qwen2.5:3b` only)
- aider CLI (uses Ollama)
- AI agents: `ai-agents/openclaw/`, `ai-agents/openmanus/`
- `ai-agents/monitor/` daily report (cron `0 8 * * *`)
- VS Code remote server (`.vscode-server/`) for ops access
Removed in the same cleanup:
- IDE extension servers: `.cursor-server`, `.cursor`, `.gemini`, `.codex`,
`.codeium`, `.copilot` (~700 MB)
- Stale `.claude.json.before-playwright-persist-*` backup
- 4 foreground processes that I incorrectly classified as "ghosts"
(openclaw ×2, aider, openmanus main.py). One of them (PID 45328)
was actually the **production OpenClaw gateway** running inside
tmux session `ai-agents:crestodian`. See [[check-tmux-before-killing]]
for the lesson; user restarted via `node openclaw.mjs` in a fresh
tmux window. The aider/openmanus main.py kills appear to have been
genuinely idle.
- 10 dead cron entries — see [[dead-cron-entries]] for the full list;
they were preserved as `# DEAD_REMOVED 2026-05-15 ...` comments in
crontab so they can be revived if any of the missing scripts return.
Backup at `/tmp/crontab.before.
- Old poller data dirs `.claude-issue-poller/` (523 lock files) and
`.codex-pr-poller/` (1206 log files); the cron entries that fed them
remain disabled with `TEMP_DISABLED_CLAUDE_TOKEN_STOP`.
Added in the same cleanup:
- 8 GB `/swapfile`, registered in `/etc/fstab`. Before this, swap was 0
and `available` memory dropped under 1 GB at idle, so any small spike
was an OOM risk. A stale `/swap.img` line was also removed from fstab
(the file did not exist, so `swapon -a` had been failing).
- monitor sub-fix: `summarize_logs.py` now prefixes fallback summaries
with ⚠️, and `daily_bot_report.sh` distinguishes "Discord送信成功" vs
"Discord送信成功 (要約フォールバック)" in the log so a silent Ollama
failure no longer looks identical to a healthy run.
- Stale VNC log/pid for the previous tailscale hostname
(`shadow.taile6d59.ts.net:1.*`) deleted from `~/.vnc/`.
Kept on purpose despite being "dev-ish":
- VNC stack (`vncserver@1`, `novnc`/`websockify` bound to tailscale
`100.115.94.5:6080`, `lightdm` + `unity-greeter`). Confirmed in active
use — `~/.vnc/shadow:1.log` was being written into during the cleanup
session. Do not stop these without checking with the user.
**Why:** The host had been treated as a dev workstation (multiple IDE
remote servers, ghost terminal sessions, copy-pasted arcana cron) which
was wasting RAM and creating silent failures. The role change makes
"is this needed for serving?" the deciding question for anything new.
**How to apply:** Before installing or running anything new on shadow,
ask whether it serves the application workload. Dev-only tools (LSP
servers, language toolchains, language-specific IDE helpers) belong on
the operator's local machine, not here.