Add MatrixTransport (A1) — step-2 PR B #9

Merged
dongar merged 1 commits from matrix-transport into main 2026-09-06 23:55:49 +00:00
Collaborator

Completes build-order step 2: the real transport behind the interface PR A established.

  • matrix.py — MatrixTransport implementing Transport over the Matrix client-server HTTP API directly: token auth, /sync long-poll in a background thread, /send with unique txn IDs. Deviation from the presented plan: I proposed matrix-nio, but the used surface is four endpoints, and going direct avoids both the SDK dependency and an asyncio-in-thread bridge around our synchronous orchestrator — httpx was already in the tree. If you'd rather have nio (its strongest argument: the [e2e] extra when encryption lands), the swap is contained in this one file.
  • A1 semantics honored: the first sync learns the stream position and never delivers backlog — room history cannot become load-bearing context. Own messages and non-message events are filtered; the sender MXID rides through for the orchestrator's operator allowlist.
  • Outage posture per B2: the sync loop backs off exponentially (capped 60s) and retries forever; an outage delays reactions, never fails anything.
  • Encrypted rooms are not supported — per operator decision the bot rooms are created unencrypted until E2E support lands (the original room was recreated; encryption can be turned on in-place later, since Matrix's switch is one-way in the safe direction).
  • Test-room isolation: the live smoke test binds only to NISSE_MATRIX_TEST_ROOM_ID (new, documented in .env.example) — never the production room. Verified against the real homeserver: the smoke test's message landed in nisse-dev-testing.
  • Deferred, will note in follow-ups: thread-relation support for plan discussions and reply-relation approval binding — the orchestrator only opens one gate at a time today, so bare approve is unambiguous by construction; threading lands when the executor loop makes multi-message plan discussions real.

8 new unit tests over a mocked HTTP layer (send shape/auth/txn uniqueness, backlog skip, self/non-message filtering, config errors). 75 unit + 7 integration green locally, both live smoke tests (LiteLLM and Matrix) included.

🤖 Generated with Claude Code

Completes build-order step 2: the real transport behind the interface PR A established. - **`matrix.py`** — `MatrixTransport` implementing `Transport` over the Matrix client-server HTTP API directly: token auth, `/sync` long-poll in a background thread, `/send` with unique txn IDs. **Deviation from the presented plan**: I proposed matrix-nio, but the used surface is four endpoints, and going direct avoids both the SDK dependency and an asyncio-in-thread bridge around our synchronous orchestrator — `httpx` was already in the tree. If you'd rather have nio (its strongest argument: the `[e2e]` extra when encryption lands), the swap is contained in this one file. - **A1 semantics honored**: the first sync learns the stream position and never delivers backlog — room history cannot become load-bearing context. Own messages and non-message events are filtered; the sender MXID rides through for the orchestrator's operator allowlist. - **Outage posture per B2**: the sync loop backs off exponentially (capped 60s) and retries forever; an outage delays reactions, never fails anything. - **Encrypted rooms are not supported** — per operator decision the bot rooms are created unencrypted until E2E support lands (the original room was recreated; encryption can be turned on in-place later, since Matrix's switch is one-way in the safe direction). - **Test-room isolation**: the live smoke test binds only to `NISSE_MATRIX_TEST_ROOM_ID` (new, documented in `.env.example`) — never the production room. Verified against the real homeserver: the smoke test's message landed in `nisse-dev-testing`. - **Deferred, will note in follow-ups**: thread-relation support for plan discussions and reply-relation approval binding — the orchestrator only opens one gate at a time today, so bare `approve` is unambiguous by construction; threading lands when the executor loop makes multi-message plan discussions real. 8 new unit tests over a mocked HTTP layer (send shape/auth/txn uniqueness, backlog skip, self/non-message filtering, config errors). 75 unit + 7 integration green locally, both live smoke tests (LiteLLM and Matrix) included. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
dev-agent added 1 commit 2026-09-06 23:53:00 +00:00
Add MatrixTransport (A1) — step-2 PR B
CI / checks (push) Successful in 10s
CI / checks (pull_request) Successful in 10s
5db6d9d96e
- matrix.py: Transport implementation over the Matrix client-server
  HTTP API directly (token auth, /sync long-poll, /send) using the
  existing httpx dependency — no Matrix SDK; four endpoints total.
  Deviation from the presented plan (matrix-nio) flagged in the PR
- First sync learns position and skips backlog, so room history is
  never delivered as context (A1); own messages and non-message
  events filtered; sender MXID passed through for the orchestrator's
  operator allowlist
- Sync loop backs off (capped at 60s) and retries indefinitely on
  homeserver errors, mirroring B2's polling posture
- Encrypted rooms unsupported: bot rooms are created unencrypted
  until E2E lands (operator decision; room recreated accordingly)
- NISSE_MATRIX_TEST_ROOM_ID added: the live smoke test binds only
  to the dedicated test room, never the production room
- 8 unit tests over a mocked HTTP layer; live integration test
  verified against the real homeserver

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dongar approved these changes 2026-09-06 23:54:42 +00:00
dongar merged commit daf1163b44 into main 2026-09-06 23:55:49 +00:00
dongar deleted branch matrix-transport 2026-09-06 23:55:50 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dev/nisse#9