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.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# 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 99–111): 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 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.
|
||||
3. **`image/app/matrix_intake.py`** (new): copy `matrix_bridge.py`, rename
|
||||
`matrix_bridge`→`matrix_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 27–32): 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.
|
||||
Reference in New Issue
Block a user