Fix 429 (model pin) and bot ignoring encrypted admin replies

Two independent bugs:

1. 429 "long context" — agentic sessions read enough files to exceed the
   200K standard window; on the default [1m] model Synapse escalates into
   the paid 1M tier. Pin claude_model to claude-opus-4-8 (200K window)
   so Claude Code compacts context instead. Updated config.example.json
   and the maintainer.py default / comment accordingly.

2. Bot silently ignores operator replies — the DM room was created with
   is_direct:true, causing Element to auto-enable E2E encryption. This
   stdlib-only bot cannot decrypt m.room.encrypted events, so all admin
   messages were dropped without any log output. Fix:
   - register-matrix-bot.sh now creates rooms with is_direct:false and
     preset:private_chat (Synapse does not force encryption on non-DM
     rooms).
   - matrix_poll_admin() now logs a loud WARN if an encrypted event
     arrives, instead of silently skipping it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 18:46:33 +12:00
co-authored by Claude Sonnet 4.6
parent d6c315d353
commit e14c21fab5
3 changed files with 22 additions and 6 deletions
+15 -3
View File
@@ -53,7 +53,11 @@ DEFAULTS = {
"agent_file": "agents/stack-support.agent.md",
"runbook_file": "docs/stack-support-runbook.md",
"claude_bin": "/home/paul/.local/bin/claude",
"claude_model": None, # None = claude default
# Pin a standard 200K-window model. Leaving this None uses the account
# default, which may be a 1M-context ([1m]) model; once a cycle's context
# crosses 200K that escalates to the 1M tier and fails on subscription
# plans with "Usage credits are required for long context requests" (429).
"claude_model": "claude-opus-4-8",
"claude_extra_args": [],
"agent_timeout_seconds": 1800,
"kuma_volume": "uptime-kuma-data",
@@ -242,10 +246,18 @@ def matrix_poll_admin(cfg, state):
if not room:
return messages
for ev in room.get("timeline", {}).get("events", []):
if ev.get("type") != "m.room.message":
continue
if ev.get("sender") != admin:
continue
# This bot is stdlib-only and cannot do E2E encryption. If the room is
# encrypted, the admin's replies arrive as undecryptable m.room.encrypted
# events — warn loudly rather than silently ignoring the operator. The
# room should be created unencrypted (see register-matrix-bot.sh).
if ev.get("type") == "m.room.encrypted":
log("WARN: received an ENCRYPTED message from the admin — this bot "
"cannot decrypt it. The maintenance room must be unencrypted.")
continue
if ev.get("type") != "m.room.message":
continue
content = ev.get("content", {})
if content.get("msgtype") == "m.text":
messages.append(content.get("body", "").strip())