Commit graph

8 commits

Author SHA1 Message Date
Erik
15ae870117 docs: CLAUDE.md reflects env-based SHARED_SECRET and XFF internal-trust rule
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 17:08:39 +02:00
Erik
a28b61511c security: enforce real plugin secret, fix proxy auth bypass, loopback DB ports, nightly backups
- SHARED_SECRET now read from env and fail-closed: unset/placeholder refuses
  ALL plugin connections (constant-time compare). The old hardcoded
  'your_shared_secret' in this public repo was no auth at all. Dockerfile
  default removed; generate_data.py reads the env var.
- SECRET_KEY fails closed at startup (main.py and agent/auth.py) instead of
  falling back to a publicly-known signing key; agent systemd unit now
  requires /etc/overlord/agent.env (no '-' prefix).
- AuthMiddleware + /ws/live: replace the 172.x source-IP trust (which every
  nginx-proxied internet request satisfied via docker-proxy — full session
  bypass and unauthenticated in-game command injection) with
  private-source AND no X-Forwarded-For, i.e. only genuinely internal
  callers (overlord-agent on the host, compose-network services). Invariant
  documented in nginx/overlord.conf: every tracker-bound location must set
  X-Forwarded-For.
- /character-stats/test endpoints gated behind admin (they upsert real rows).
- docker-compose: bind 5432/5433 to 127.0.0.1 (both DBs were internet-
  reachable; active brute-force observed in dereth-db logs).
- discord-rare-monitor: drop dead SHARED_SECRET constant.
- scripts/backup-databases.sh + docs/backups.md: nightly pg_dump of both DBs
  (telemetry/spawn hypertable data excluded), 10MB canary, umask 077,
  TimescaleDB restore procedure.
- Remove stray mangled-path css file from repo root.

Adversarially reviewed pre-deploy (3-lens workflow): ship verdict; deploy-
sequencing blockers addressed (secret staged before enforcement, exec bit
set, cron uses bash).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 17:02:47 +02:00
Erik
c6a1af0c39 docs: rewrite CLAUDE.md from audit — drop stale 2025 fix journal
The old file was ~half September-2025 changelog with claims now wrong:
portal race condition (fixed via ON CONFLICT upsert), hypertable warning
(telemetry_events IS a hypertable on live), pool 5-20 (actually 5-100),
--no-cache rebuild for code changes (bind mounts + restart suffice),
/ws/live unauthenticated (cookie-authenticated since), static-HTML
frontend description (React since). Rewritten around current reality:
component map, WS endpoints + auth caveats, two-database schema-as-code
situation (alembic empty, manual ALTERs), route conventions, React
deploy flow, operational notes. Overlord Assistant Mode section
preserved verbatim (consumed at runtime by the agent service).

AGENTS.md: remove nonexistent GET /history, fix /ws/live auth claim.
Also delete stray mangled-path file from repo root.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 16:36:01 +02:00
Erik
88e9e88f46 docs(agent): brief Claude on AC rare tier classification
The user kept asking 'show me great rares' and Claude kept showing
Crystals/Pearls/Jewels because the rare_events table doesn't store the
tier — and Claude didn't know the distinction. Now CLAUDE.md spells out
the ~71-item common allowlist (matching discord-rare-monitor's regex)
plus example great-rare names. Includes a sample SQL query Claude can
adapt for tier filtering.
2026-04-25 23:07:57 +02:00
Erik
0633865598 fix(agent): block Agent + Gmail/Drive/Calendar tools, brief model not to probe
Two complementary changes after observing the model probe boundaries
(it tried mcp__claude_ai_Gmail__search_threads, then tried to delegate
to a subagent via the Agent tool, then suggested the user edit
settings.local.json to add Gmail tools):

1. claude_wrapper.py adds to --disallowed-tools:
   - Agent  (subagent spawning — should never delegate)
   - WebFetch (already; settings.json re-allows acpedia.org only)
   - Every Gmail/Calendar/Drive connector tool name we know about

2. CLAUDE.md adds a 'Non-negotiable scope rules' section:
   - Be a read-only game-state QA service, nothing else
   - Don't attempt tools outside your role
   - Don't explain how to bypass restrictions
   - Don't suggest settings.json edits
   - Don't enumerate hidden tools when asked

Soft (system-prompt) + hard (CLI flag) defenses combined.
2026-04-25 22:45:39 +02:00
Erik
4ae18536be feat(agent): cross-char search_items tool + bump timeouts
Adds an MCP tool wrapping the inventory-service /search/items endpoint
with include_all_characters=true, so questions like 'find me a bracelet
with Legendary Acid Ward on any unequipped char' resolve in ONE tool call
instead of looping get_inventory over 60+ chars (which timed out at 120s).

- agent/tools.py: search_items_global wrapper
- agent/mcp_overlord.py: register new tool with detailed schema doc
- agent/claude_wrapper.py: include in --allowed-tools whitelist;
  bump timeout 120s -> 240s
- nginx/overlord.conf: bump /api/agent/ proxy timeout 180s -> 300s
- CLAUDE.md: brief Claude to USE search_items for cross-char searches
2026-04-25 21:13:26 +02:00
Erik
79cf88d3f7 feat(agent): Phase 1 — chat-window AI assistant via Claude Code subprocess
Adds an in-dashboard AI assistant that answers questions about live game
state. Designed reactively (no background loops) — every user message in
the chat window or via /api/agent/ask runs one `claude -p` invocation.

Architecture:
- New host-side FastAPI service (agent/) on 127.0.0.1:8767, OUTSIDE the
  dereth-tracker Docker container because `claude` and ~/.claude
  credentials live on the host.
- nginx routes /api/agent/* to the host service.
- The same browser session cookie the tracker issues authenticates
  agent requests (shared SECRET_KEY).
- The agent shells out to `claude -p --session-id <uuid>` with
  cwd=/home/erik/MosswartOverlord. Sessions persist as JSONL on disk
  via Claude Code's built-in machinery.
- An MCP stdio server (agent/mcp_overlord.py) exposes tools to Claude:
  get_live_players, get_recent_rares, query_telemetry_db (read-only,
  parsed by sqlglot to reject DML/DDL), get_player_state, get_inventory,
  get_inventory_search, get_combat_stats, get_equipment_cantrips,
  get_quest_status, get_server_health, suitbuilder_search.
- Read-only PG role (overlord_agent_ro) is the second line of defense
  on the SQL tool — even a parser bypass can't mutate.

Frontend:
- AgentWindow.tsx — draggable chat window with localStorage-pinned
  session UUID, "New Chat" button, on-mount rehydration from
  /agent/sessions/{id}/history (parses Claude Code's JSONL).
- Wired into WindowRenderer + Sidebar (🤖 Assistant button).

Operational:
- systemd unit (overlord-agent.service) + install.sh.
- agent/README.md documents env vars, deploy flow, smoke tests.
- nginx/overlord.conf gets a new /api/agent/ location with 180s timeout.
- CLAUDE.md gets an "Overlord Assistant Mode" section briefing the
  agent on which tools to use and how to behave.

NOT YET DEPLOYED — server still needs:
1. Apply agent/sql/0001_overlord_agent_ro.sql + ALTER ROLE password
2. Add AGENT_DB_DSN to /home/erik/MosswartOverlord/.env
3. bash agent/install.sh (creates venv, installs unit, starts service)
4. sudo cp /home/erik/MosswartOverlord/nginx/overlord.conf to nginx + reload

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 20:43:59 +02:00
erik
850cd62d7b Update suitbuilder documentation to reflect production-ready status
- Replace outdated CLAUDE.md suitbuilder section with concise production-ready summary
- Remove incorrect claims about spell system not being implemented
- Create detailed architecture document at docs/plans/2026-02-09-suitbuilder-architecture.md
- Document spell bitmap system, locked slots, suit summary, and SSE streaming
- Add future enhancement roadmap (spell improvements, new builders, advanced features)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:44:00 +00:00