Files
ten31-database/docs/handoffs/add-intake-bot-to-spark-control.md
T
Keysat b470ea2659 Containerize the Matrix intake bot as a managed service (restart: unless-stopped)
Turn the bot from a bare nohup process (silently dies on a Spark reboot) into a docker-compose service. Dockerfile bundles backend/matrix_intake + the stdlib backend/ingest Spark client it reuses; .env is mounted read-only at runtime, never baked. The existing repo-root .dockerignore (shared with the s9pk build) already keeps data/ and .env out of context. Also adds a handoff doc for wiring a spark-control dashboard card in a later session.
2026-06-17 20:10:16 -05:00

4.7 KiB
Raw Blame History

Handoff: add the Matrix intake bot as a spark-control dashboard card

Do this work in the spark-control repo (~/Projects/spark-control), in a separate session. This repo (ten31-database) only owns the bot + its container; the dashboard card is driven entirely by spark-control code. Prereq (DONE 2026-06-17): the bot already runs as a docker container named matrix-intake on the Spark (spark-32d0, user modelo), via docker-compose.yml at this repo's root. spark-control reaches it over the same SSH channel it already uses for matrix-bridge (modelo@spark-32d0) — no new key/host needed.

The card is a near-exact clone of the existing matrix-bridge card. Mirror that, with three deltas (below). File paths/line numbers are from the 2026-06-17 review; reconfirm against the current code.

Deltas from matrix-bridge (do NOT copy these blindly)

  1. Branch is main, not master. The Update button runs git reset --hard origin/<branch> — it MUST be main for ten31-database, or Update silently resets to the wrong/empty ref.
  2. Project dir is /home/modelo/ten31-database (the CRM monorepo clone), not ~/matrix-intake.
  3. Coupling caveat: because the bot lives in the CRM monorepo, the Update one-liner does git reset --hard origin/main on the whole CRM clone. Safe today (.env is gitignored, the clone has no needed local edits), but this is exactly the blast-radius smell that motivates eventually extracting the bot to its own repo (logged in ten31-database ROADMAP.md). If that extraction happens first, point dir/branch/remote at the new repo instead.

Edits in spark-control (mirror the matrix-bridge wiring)

  1. image/app/config.py (matrix-bridge entry ~lines 99111): add matrix_intake_host (default spark2_host), matrix_intake_user, matrix_intake_container (default "matrix-intake"), matrix_intake_dir (default "/home/modelo/ten31-database"), matrix_intake_branch (default "main"), each with a MATRIX_INTAKE_* env fallback.
  2. image/app/services.py (matrix-bridge ServiceDef ~lines 95102): add a "matrix-intake": ServiceDef(name="matrix-intake", kind="bot", host=…, user=…, container=…, port=0) entry. port=0 → judged by docker state alone (no HTTP probe), same as matrix-bridge.
  3. image/app/matrix_intake.py (new): copy matrix_bridge.py, rename matrix_bridgematrix_intake throughout. The Update command (build_update_command) must produce: cd /home/modelo/ten31-database && git fetch origin && git reset --hard origin/main && docker compose up -d --build.
  4. image/app/server.py: (a) add "matrix-intake" to the service_action whitelist (~line 621); (b) from .matrix_intake import MatrixIntakeManager + instantiate matrix_intake = MatrixIntakeManager(settings) (~line 47); (c) add the 4 endpoints mirroring matrix-bridge: POST /api/matrix-intake/update, GET …/update/{job_id}, GET …/update/{job_id}/stream, GET /api/matrix-intake/logs.
  5. image/app/static/app.js — THE RISKY EDIT. The Update/View-logs handlers are hardcoded to matrix-bridge (data-mb-update, onMatrixBridgeUpdate, /api/matrix-bridge/...). Generalize them to dispatch by the card's bot name (e.g. read name off the card, call /api/<name>/update and /api/<name>/logs). Start/Stop/Restart are already generic. Regression-check that the existing matrix-bridge card still updates + tails logs after this change.
  6. package/startos/fileModels/sparkConfig.yaml.ts (~lines 2732): add matrix_intake_user: z.string().catch('').
  7. package/startos/main.ts (~line 68): inject MATRIX_INTAKE_USER: cfg.matrix_intake_user.
  8. (optional) package/startos/actions/configureSparks.ts: add the intake-bot SSH-user field to the form.

Deploy + ops

  • spark-control is itself an s9pk: bump its version, rebuild, reinstall per spark-control's own packaging docs (don't forget — same "0.4.x ignores same-version" rule).
  • One-time: run Configure Sparks → set the intake bot's SSH user to modelo (same as matrix-bridge → key already authorized). The card appears once the matrix-intake container exists and the user is set; it hides itself if the container is absent or the user is blank.
  • Status pill = docker inspect matrix-intake .State.Status (running→Healthy). No Matrix-liveness check — a running-but-silent bot still shows Healthy (same limitation as matrix-bridge).

Done when

The dashboard shows a matrix-intake card alongside matrix-bridge with a Healthy pill and working Update / Start / Restart / Stop / View-logs buttons — and the matrix-bridge card is unregressed.