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.
4.7 KiB
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)
- Branch is
main, notmaster. The Update button runsgit reset --hard origin/<branch>— it MUST bemainfor ten31-database, or Update silently resets to the wrong/empty ref. - Project dir is
/home/modelo/ten31-database(the CRM monorepo clone), not~/matrix-intake. - Coupling caveat: because the bot lives in the CRM monorepo, the Update one-liner does
git reset --hard origin/mainon the whole CRM clone. Safe today (.envis 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-databaseROADMAP.md). If that extraction happens first, point dir/branch/remote at the new repo instead.
Edits in spark-control (mirror the matrix-bridge wiring)
image/app/config.py(matrix-bridge entry ~lines 99–111): addmatrix_intake_host(defaultspark2_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 aMATRIX_INTAKE_*env fallback.image/app/services.py(matrix-bridge ServiceDef ~lines 95–102): 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.image/app/matrix_intake.py(new): copymatrix_bridge.py, renamematrix_bridge→matrix_intakethroughout. 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.image/app/server.py: (a) add"matrix-intake"to theservice_actionwhitelist (~line 621); (b)from .matrix_intake import MatrixIntakeManager+ instantiatematrix_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.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. readnameoff the card, call/api/<name>/updateand/api/<name>/logs). Start/Stop/Restart are already generic. Regression-check that the existing matrix-bridge card still updates + tails logs after this change.package/startos/fileModels/sparkConfig.yaml.ts(~lines 27–32): addmatrix_intake_user: z.string().catch('').package/startos/main.ts(~line 68): injectMATRIX_INTAKE_USER: cfg.matrix_intake_user.- (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 thematrix-intakecontainer 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.