diff --git a/infrastructure/vm-102-matrix-appservice.md b/infrastructure/vm-102-matrix-appservice.md new file mode 100644 index 0000000..0efe87c --- /dev/null +++ b/infrastructure/vm-102-matrix-appservice.md @@ -0,0 +1,154 @@ +--- +created: '2026-04-11T16:32:18+00:00' +id: 95ffbaa1-728e-434c-85d9-e82346f77d1e +keywords: +- matrix.pfi.local +- appservice +- as_token +- hs_token +- aipa-bridge +- matrix_bridge.py +- '8009' +- send_notification +- virtual-users +- room-routing +- element +links: [] +modified: '2026-04-11T16:32:18+00:00' +summary: AIPA Matrix Application Service bridge setup for VM 102. Covers appservice + registration, agent virtual users, room routing, env vars, operational notes, and + troubleshooting. +tags: +- infrastructure +- pfi +- pfi-ana +- matrix +- docker +- vm-102 +- appservice +- bridge +- aipa +- deployment +- integration +title: VM 102 — Matrix Appservice Configuration +--- + +The AIPA Matrix bridge registers with Synapse as an Application Service. Synapse pushes events to the bridge (no polling). The bridge manages virtual users for each agent. + +## Agent Virtual Users + +| Agent | Matrix ID | Display Name | +|---|---|---| +| Atlas | @atlas:matrix.pfi.local | Atlas | +| Linus | @linus:matrix.pfi.local | Linus | +| Hermione | @hermione:matrix.pfi.local | Hermione | + +These are virtual — managed entirely by the bridge. Do not register them as real Synapse accounts. + +## Setup Steps + +### 1. Generate tokens +```bash +python3 -c "import secrets; print(secrets.token_hex(32))" # as_token (bridge → Synapse) +python3 -c "import secrets; print(secrets.token_hex(32))" # hs_token (Synapse → bridge) +``` + +### 2. Create appservice registration + +File: /opt/docker/data/synapse/aipa_appservice.yaml + +```yaml +id: aipa-bridge +url: http://:8009 +as_token: "" +hs_token: "" +sender_localpart: aipa-bot +namespaces: + users: + - exclusive: true + regex: "@(atlas|linus|hermione):.*" + rooms: [] + aliases: [] +rate_limited: false +``` + +exclusive: true means only the bridge can act as those users. url must be reachable from inside the Synapse container. + +Restart Synapse: `cd /opt/docker/compose/synapse && docker compose restart synapse` + +### 3. Configure AIPA environment + +Add to env.sh: +```bash +export MATRIX_HOMESERVER_URL="http://localhost:8008" +export MATRIX_SERVER_NAME="matrix.pfi.local" +export MATRIX_AS_TOKEN="" +export MATRIX_HS_TOKEN="" +# export MATRIX_DEFAULT_ROOM="!roomid:matrix.pfi.local" +``` + +Uncomment matrix: block in config/providers.yaml: +```yaml +matrix: + homeserver_url: "${MATRIX_HOMESERVER_URL}" + server_name: "${MATRIX_SERVER_NAME}" + as_token: "${MATRIX_AS_TOKEN}" + hs_token: "${MATRIX_HS_TOKEN}" + bridge_host: "0.0.0.0" + bridge_port: 8009 + default_notification_room: "${MATRIX_DEFAULT_ROOM}" + agents: + atlas: + display_name: "Atlas" + linus: + display_name: "Linus" + hermione: + display_name: "Hermione" +``` + +### 4. Start bridge +```bash +source .venv/bin/activate && source env.sh +python -m core.matrix_bridge +``` + +### 5. First use +1. Open Element at http://10.250.50.70:8080 +2. Log in with admin account (server: matrix.pfi.local) +3. DM @atlas:matrix.pfi.local +4. Send a message — bridge routes to Atlas + +## Room Routing + +1. User invites agent to room → bridge receives m.room.member invite +2. Agent auto-joins +3. Room permanently mapped to that agent in sessions/matrix_rooms.json +4. All subsequent messages routed to mapped agent +5. Multiple agents in same room: first invite wins for session, others get their own session + +## Operational Notes + +- Session persistence: rooms mapped in sessions/matrix_rooms.json survive restarts. Reset with /reset or delete entry. +- Formatting: markdown→HTML conversion (format: org.matrix.custom.html) +- Typing indicators: bridge sends m.typing while agent processes +- Proactive notifications: agents call send_notification(content, channel="!roomid:matrix.pfi.local") +- Virtual users always show offline — expected, no presence for appservice users + +## Troubleshooting + +| Symptom | Cause | Fix | +|---|---|---| +| Synapse doesn't push events | Appservice URL wrong | Verify url reachable from Synapse container | +| Agent joins but doesn't respond | hs_token mismatch | Verify token matches MATRIX_HS_TOKEN | +| 401 errors from Synapse | as_token mismatch | Verify token matches MATRIX_AS_TOKEN | +| Messages loop | Bridge not filtering own messages | Check SENDER_LOCALPART filter | +| Agent always offline | Expected | Normal for virtual users | + +## Dependencies +- markdown (pip install markdown) +- fastapi, httpx + +## Security +- as_token and hs_token are admin-equivalent secrets +- Bridge authenticates Synapse pushes via MATRIX_HS_TOKEN (rejects 403 without it) +- Restrict port 8009 to internal access only \ No newline at end of file