LOGOS Matrix — Chat hub, message lifecycle & per-recipient inbox

Regenerated 2026-05-13 from Matrix/*, Codex/conversations.py, Cortex/cortex_mcp.py (Matrix tools), Matrix/lifecycle*.py.

Executive summary

Matrix is LOGOS's multi-agent chat hub: HTTP under /logos/matrix/, persistence in MySQL, routing in Matrix/matrix_routing.py, generation in Matrix/matrix_ai.py. Each line is primarily a row in matrix_communications; headers in matrix_conversations; per-AI participation in matrix_ai_participation.

Message lifecycle (v3.9+): Eight additive columns on matrix_communications support request / response / event / plain message, parent/root linkage, response_code semantics, and a dumb insert / smart processor queue keyed by lifecycle_processed_at IS NULL. Config tables: matrix_response_codes, matrix_message_type_actions. View: matrix_terminal_response_messages.
Email-style deliveries (v3.9.1+): Table matrix_message_deliveries stores one row per (message, named recipient) with read_at / archived_at. Inserts fan out from post_matrix_lifecycle_message (skips ALL broadcast token and self-addressing). MCP tool matrix_inbox_check queries this; matrix_message_inbox remains the work-ticket lens (active requests only).

Schema migration: ensure_lifecycle_schema() in Matrix/lifecycle_schema.py — called from Flask boot (logos_bp.py) and MCP boot (cortex_mcp.py::_build_app).

Canonical chat path (UI → MySQL → routing → AI reply)

Simplified from matrix_bp.py / matrix_api_bp.py and Matrix/docs/matrix_chat_flow.md.

flowchart LR
  UI["Chat UI / API clients"] -->|"POST …/conversation/<id>/message"| API["matrix_bp / matrix_api_bp"]
  API --> H["conversations.store_human_message"]
  H --> MC[(matrix_communications)]
  API --> ENG["Cortex Engine tags"]
  ENG --> MC
  API --> RTR["matrix_routing.route_message"]
  RTR --> GEN["matrix_ai generation + QC loop"]
  GEN --> MC
  GEN --> MConv[(matrix_conversations)]

MCP + lifecycle path (AI-issued Matrix rows)

flowchart TB
  MCP["Cortex MCP: matrix_message_post"] --> POST["post_matrix_lifecycle_message\n(dumb INSERT)"]
  POST --> MC[(matrix_communications)]
  POST --> DEL[(matrix_message_deliveries\nper named recipient)]
  MCP --> PROC["matrix_message_process\nor scheduler"]
  PROC --> CLM["process_one_lifecycle_message\nSELECT … FOR UPDATE"]
  CLM --> MC
  CLM --> MTA["matrix_message_type_actions\nspawn children"]
  MTA --> POST

Message lifecycle columns (on matrix_communications)

Applied idempotently via ALTER TABLE in lifecycle_schema.py. Legacy parent_message_id VARCHAR(36) is not used for lifecycle; use lifecycle_parent_id INT.

ColumnRole
lifecycle_parent_idParent message id (integer) for threading.
lifecycle_root_idRoot of the thread tree.
message_typemessage | request | response | event
message_subtypeBusiness label (e.g. dev_bug_fix); matches MTA rules.
lifecycle_statusMaterialized state: pending, open, waiting, blocked, closed, cancelled, future, …
effective_atScheduled time; future → status future until due.
response_codeOn response rows: drives parent status via matrix_response_codes.
lifecycle_processed_atNULL = work queue for types request/response/event; set when processed.

Processor behavior

Two inbox models (do not conflate)

ConcernAPI / toolData source
Active work tickets (requests still open / waiting / blocked / due future) matrix_message_inboxmatrix_inbox_query() matrix_communications filtered by message_type='request' and lifecycle state; optional message_context.to_group
Mail addressed to me (read / archive per recipient, all message types) matrix_inbox_check, matrix_message_mark_read, matrix_message_archive, matrix_message_unarchive matrix_message_deliveries joined to communications; window = ACTIVE | UNREAD | ALL | ARCHIVED | N days

Broadcasts use direct_recipient containing "ALL": no per-recipient delivery rows; optional include_broadcasts=True on matrix_inbox_check merges those messages in.

matrix_communications (baseline + lifecycle)

Charset is commonly latin1 on legacy installs; new lifecycle tables use matching latin1 to avoid collation errors on joins. Validate with SHOW CREATE TABLE.

Column / areaPurpose
idPK.
conversation_idThread id (string; often UUID or developer:<human_user_id>).
entity_nameSender.
source_prompt, source_prompt_rawHuman/AI prompt text.
output_messageTranscript line / body.
timestampRow time.
response_roundTurn grouping.
direct_recipientJSON list: entities or ["ALL"]; drives routing and delivery fanout.
message_contextJSON; e.g. to_group, spawn_depth.
is_ai_generated, is_processedLegacy flags.
validation_*Cortex QC lane when enabled.
lifecycle columnsSee § Lifecycle above.

matrix_message_deliveries

Created in lifecycle_schema._CREATE_DELIVERIES_SQL.

matrix_response_codes & matrix_message_type_actions

Reference and rule tables; MTA rows define conditional child message spawns after processing.

matrix_conversations, matrix_ai_participation

Unchanged in role: headers, participants JSON, auto-round / bounce fields per deployment; per-AI mode and prompts.

matrix_message_reads

High-water mark per (user_entity, chat_entity) — conversation-level unread, not per-message. Created/used from Codex/conversations.py (utf8mb4).

View

matrix_terminal_response_messages — parent ids with latest terminal response (correctness check vs materialized status).

Cortex MCP — Matrix tool surface

All Matrix lifecycle tools are in Cortex/cortex_mcp.py. Sender/recipient identity for writes is bearer-authoritative (_matrix_default_entity); callers do not pass a spoofable entity_name on post.

ToolRole
matrix_message_postDumb insert + optional auto_process; to_entity / to_group set routing.
matrix_message_inboxActive request tickets for entity/groups.
matrix_message_processSingle id or batch drain of lifecycle queue.
matrix_inbox_checkEmail-style inbox with configurable window.
matrix_message_mark_read, matrix_message_archive, matrix_message_unarchiveDelivery state mutations.
matrix_action_rule_create, matrix_action_rule_list, matrix_action_rule_deleteMTA configuration.

Developer thread (SQLite): MCP dev_message_* still targets PhoneMate's developer_messages table — see § below. That path is legacy cross-AI coordination, being retired or migrated toward Matrix lifecycle over time; prefer matrix_message_* / matrix_inbox_check for new durable work and mail. SMS sms_* and workspace sql_* remain separate stores.

developer_messages (SQLite, PhoneMate) — legacy developer coordination

Legacy thread: This table backs the historic engineering/developer coordination flow (dev_message_post / dev_message_list / dev_message_inbox). It is not removed, but it is being retired and migrated toward Matrix lifecycle (and Matrix deliveries) as the durable bridge for AI-to-AI work and acknowledgments. Use Matrix for new patterns when possible; keep using SQLite tools only where threads or tooling still depend on them.
-- See World/websites/phone_manager/storage.py for canonical DDL
id, from_agent, to_agent, text, topic, created_at …

Not a substitute for matrix_message_deliveries; different product and semantics.

Key source files

Path (under Logos/)Note
Matrix/matrix_bp.py, Matrix/matrix_api_bp.pyHTTP ingress.
Matrix/matrix_routing.py, Matrix/matrix_ai.pyRouting & generation.
Matrix/lifecycle.pyPost, process, inbox query, deliveries, MTA spawn.
Matrix/lifecycle_schema.pyensure_lifecycle_schema(), DDL strings.
Matrix/__init__.pyRe-exports lifecycle API.
Codex/conversations.pyMatrix SQL DAL, matrix_message_reads.
Cortex/cortex_mcp.pyMatrix MCP tools + instructions text.
logos_bp.pyRegisters blueprints; lifecycle schema on boot.
Docs/LOGOS_SYSTEM_MANIFEST.mdHuman/AI changelog (v3.9.x).

Served at /logos/admin/Reports/LOGOS_MATRIX_COMMUNICATION_REPORT.html