feat: add Matrix appservice bot, platform-agnostic core, and Kubernetes deployment #1
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/matrix-appservice"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds native Matrix appservice integration to Steward, refactors the conversation pipeline to be platform-agnostic, and adds Kubernetes deployment scaffolding mirroring the pr_reviewer pattern.
Changes
steward/bot/matrix.py): mautrix-python appservice that receives Synapse transactions and replies via the client-server API.steward/bot/core.py):ConversationService+ThreadKeyowning the LLM call, history, knowledge-base search, and thread-memory keying, shared by Telegram and Matrix.ConversationService.chat_id:thread_idmigration.matrixsection (homeserver, tokens, room/user allowlists).kube/manifests + Gitea Actions workflow (.gitea/workflows/build_push.yml) mirroring pr_reviewer.matrix/steward_appservice.yaml.Verification
kubectl apply --dry-run=clientNotes
mautrix>=0.21.0(matrix-nio is unmaintained and has no appservice framework).PR received — starting review, sit tight 🫡
PR Review Results
Consolidated Review Report: Matrix Integration & Core Refactor
1. Executive Summary
This Pull Request represents a major architectural pivot, transitioning the bot from a Telegram-specific implementation to a hexagonal, platform-agnostic architecture. The introduction of a centralized
ConversationServiceis a significant engineering win, decoupling the core LLM logic from the transport layers (Telegram/Matrix).However, while the software design is excellent, the operational and security scaffolding is currently insufficient for a production deployment. The review identifies critical gaps in Kubernetes security context, secret management, and resource boundary definitions. Furthermore, because the review was conducted on architectural patterns and metadata, specific verification of the
ThreadKeyimplementation is required to prevent cross-platform data leakage.2. Prioritized Issue List
🔴 Critical
kube/steward_deployment.yamland CI pipelines.securityContextin K8s manifests; the bot may be running asroot, increasing the blast radius of a potential RCE.ThreadKeygeneration lacks strict delimitation.🟠 High
ConversationServicefreezing both Telegram and Matrix bots simultaneously.requestsandlimitsin Kubernetes, risking Node-level OOM events.🟡 Medium
livenessProbeandreadinessProbe; K8s cannot detect if the internal async event loop has hung.latesttags in Gitea Actions instead of Git SHAs or SemVer.🔵 Low
SIGTERMhandling to close connections cleanly.3. Domain-Specific Recommendations
💻 Code & Architecture
core.pyandConversationServiceto ensure zero blocking calls. Useasyncio.to_threadfor any CPU-bound parsing.platform::user_id::thread_id) to ensure absolute collision resistance.config.pyto a provider-based object structure (e.g.,Config.matrix,Config.telegram).🛡️ Security
steward_deployment.yamlwith:secretKeyRefpointing to K8s Secrets or an external Vault.ConversationServicelevel to prevent "Denial of Wallet" attacks on the LLM API.platformanduser_idtags for forensic analysis.🏗️ Infrastructure
resources.limitsandresources.requestsin the deployment manifest to ensure cluster stability./healthzendpoint (viaaiohttporFastAPI) and link it to K8s liveness/readiness probes.NetworkPolicyrestricting egress traffic only to known API endpoints (Matrix, Telegram, LLM provider).4. Positive Aspects of the PR
chat_id\rightarrowthread_idmigration demonstrates attention to data persistence.5. Overall Assessment & Recommendation
Final Rating: ⚠️ SIGNIFICANT CHANGES NEEDED
Justification:
While the code refactor is "Approved" from a design perspective, the infrastructure and security implementation is "Needs Changes." The current state of the K8s manifests and the lack of visible secret management constitute a high risk for production deployment. The transition to a centralized service also creates a high-value target that requires stricter validation and isolation than what is currently documented.
Required Action Items for Merge:
securityContext(non-root) andsecretKeyRefin K8s manifests.resourceslimits andliveness/readinessprobes.ThreadKeyandmatrix.pyto verify collision resistance and input validation.Response to review + fixes applied
Thanks for the thorough review. I have addressed the actionable items and pushed the fixes to the branch. Here is the disposition of each finding:
✅ Fixed
securityContexttokube/steward_deployment.yaml:runAsNonRoot: true,runAsUser/Group: 1000,allowPrivilegeEscalation: false, drop all capabilities.${{ gitea.sha }}) in addition tolatest, and pins the deployed image to the SHA viakubectl set imagefor idempotent rollbacks.🔍 Already handled (no change needed)
envFrom: secretRef: steward-envand the workflow uses${{ secrets.* }}/${{ vars.* }}placeholders only.AppServiceverifies thehs_tokenon every incoming transaction automatically; unauthorized requests returnM_FORBIDDEN.main.pyinstalls SIGINT/SIGTERM handlers and shuts down both the Telegram updater and Matrix appservice cleanly.Settings.matrix,Settings.telegram, etc.), not flat.resources.requests/limitswere already present in the manifest.platformfield already delimits keys (telegram:100:55vsmatrix:room:...), so cross-platform collision is impossible. The__str__uses:separators and platform is always the first component.📝 Noted for follow-up (out of scope for this PR)
ThreadMemoryStoredoes synchronous file I/O in async handlers. This is a pre-existing pattern; a follow-up could move it toasyncio.to_thread./healthzendpoint + liveness/readiness probes would be valuable; deferred to a follow-up.Please re-review the updated branch. Thanks!
pr_reviewer: Consolidated Review (manual trigger)
Unified Code Review Synthesis Report: Steward Bot Matrix Integration
1. Executive Summary
This PR represents a major architectural evolution for the Steward bot, transitioning it to a platform-agnostic core to support both Telegram and Matrix. While the structural refactor is well-conceived and significantly improves the maintainability of the business logic, the current implementation contains critical failures in the deployment pipeline and severe memory management issues that make it unsuitable for production in its current state.
The most alarming finding is a "nuke and pave" CI/CD strategy that deletes the entire Kubernetes namespace on every push, effectively nullifying the purpose of the Persistent Volume Claim (PVC) and causing total data loss upon every deployment. Additionally, a high-severity memory leak in the core conversation logic poses a significant stability risk.
2. Prioritized Issue List
🔴 Critical (Must be fixed before merge)
stewardnamespace on every push (kubectl delete namespace steward). This wipes all secrets and the PVC containing the knowledge base._historiesdictionary inConversationServicegrows indefinitely for every uniqueThreadKey, leading to inevitable OOM (Out-of-Memory) crashes.🟠 High (Should be fixed before merge)
Path.write_text) inThreadMemoryStorewill block the event loop, causing latency spikes for all users during KB flushes.--from-literalin CI, risking leakage in logs and process memory.🟡 Medium (Address shortly after merge)
NodePortand0.0.0.0binding exposes the Matrix endpoint to the broader network without strict NetworkPolicies.🔵 Low (General improvements)
Settingsclass is bloated with legacy properties.:latestin manifests complicates rollbacks and stability.3. Domain-Specific Recommendations
💻 Code Quality
_historiesdict with a TTL (Time-To-Live) cache or an LRU cache. For production scale, migrate active session history to Redis.jsonandPathcalls withaiofilesor wrap blocking calls inasyncio.to_thread()._FLUSH_SYSTEM_PROMPTand_TAGS_SYSTEM_PROMPTexclusively tocore.pyto ensure consistency across Telegram and Matrix.try...exceptblock inStewardMatrixBot._on_eventto prevent silent failures and provide user feedback on errors.🛡️ Security
### KB START ###) and explicitly instruct the LLM to treat the content as data, not instructions.thread_memory.jsonfile or migrate to an encrypted database.NetworkPolicyto restrict traffic to the bot's port (8000) so only the Matrix Homeserver can communicate with it.:latesttag.⚙️ Infrastructure
kubectl delete namespacewithkubectl apply -f. Move toward a declarative model using Helm or Kustomize.--from-literal. Use SealedSecrets or an external secret provider (Vault/AWS SM).NodePortwith anIngresscontroller to enable proper TLS termination and DNS management.livenessProbeandreadinessProbeto the Deployment to ensure the Matrix HTTP server is healthy before routing traffic.4. Positive Aspects of the PR
ConversationServiceis a major win for the project's scalability and maintainability.ThreadKeyelegantly solves the problem of identifying conversations across disparate platforms.SecurityContext(non-root) shows good baseline awareness of container best practices.5. Overall Assessment & Recommendation
Overall Rating: 🔴 SIGNIFICANT CHANGES NEEDED
Justification:
While the code's structural design is excellent, the operational implementation is dangerous. The combination of a destructive deployment pipeline (which deletes user data on every update) and a critical memory leak creates a high risk of data loss and production instability. These two issues, combined with the potential for indirect prompt injection, must be resolved before this PR can be approved.
Action Plan for Developer:
kubectl applyinstead ofdelete namespace._histories.Response to pr_reviewer findings
Thanks for the thorough review. I have addressed the critical and high-severity items and pushed the fixes to the branch (commit
f79214b).✅ Fixed
kubectl delete namespace steward. The workflow now useskubectl apply(via--dry-run=client -o yaml | kubectl apply -f -) for the namespace and secrets, so the PVC and conversation memory survive every deployment.ConversationService._historiesis now an LRU cache bounded to 1000 active threads (_MAX_ACTIVE_THREADS), evicting least-recently-used scopes.### KB START ###/### KB END ###delimiters with an explicit instruction to treat the content as data, not instructions.StewardMatrixBot._on_eventnow wraps processing intry/exceptand logs failures instead of dropping them._FLUSH_SYSTEM_PROMPT/_TAGS_SYSTEM_PROMPTfromtelegram.py; they now live only incore.py.🔍 Already handled / by design
ThreadMemoryStoredoes synchronous file I/O. This is a pre-existing pattern; a follow-up can move it toasyncio.to_thread. Noted.latestimage tag — the workflow now tags with the git SHA and pins the deployed image viakubectl set image. The manifest keepslatestas a fallback for the initial apply.📝 Deferred (follow-up PRs)
livenessProbe/readinessProbe)asyncio.to_threadfor blocking I/OPlease re-review. Thanks!
Checkout
From your project repository, check out a new branch and test the changes.