8.3 KiB
8.3 KiB
MsgLib.db message-table source precheck
Date: 2026-07-10
Question
Can copied MsgLib.db message tables become a future DB-backed source for isphere_receive_messages, and what is the safest next implementation slice?
Evidence used
Committed evidence:
docs/source-discovery/2026-07-10-msglib-readonly-schema-extraction.mddocs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.mddocs/msglib-read-sidecar-contract.md
Ignored local evidence consulted in this loop:
- C26 schema-only x86 JSON under
runs/offline-evidence-intake/.../metadata/.
Scope of this loop:
- Read table names, column names, schema SQL, and row counts only.
- Do not read or print message row values.
- Do not read or print message bodies, file paths, contact/group values, or raw rows.
- Do not add code that exposes DB message rows yet.
Candidate DB tables
| Table | Safe evidence | Candidate role | C35 decision |
|---|---|---|---|
tblPersonMsg |
Present in all opened copied DBs; count-only evidence shows thousands of rows in inspected copies | direct/person-to-person messages | strong candidate for future DB-backed direct messages |
tblMsgGroupPersonMsg |
Present in all opened copied DBs; count-only evidence shows hundreds/thousands of rows in inspected copies | group/discussion messages | strong candidate for future DB-backed group messages |
TD_SystemMessageRecord |
Present with count-only evidence | system/auth/notification messages | secondary candidate after direct/group message flow |
TD_GroupReceiptMessage |
Present in richer schema | per-person group receipt state by MsgGuid/PersonID |
useful join candidate for receipt enrichment |
TD_ReceiveFileRecord |
Present with message-guid and file metadata columns | received-file metadata linked by message guid | useful for attachment metadata, but FilePath must not be exposed by default |
TD_SendFileRecord |
Present with message-guid and file metadata columns | sent-file metadata linked by message guid | later outbound/file-source evidence only |
tblRecent |
Maintained by triggers from person/group message inserts | recent conversation index | useful for conversation ordering/display, not primary message body source |
Field mapping hypothesis
Direct messages: tblPersonMsg
| MCP receive field | Candidate DB column | Confidence | Notes |
|---|---|---|---|
message_id / id |
Id |
high | primary key in schema |
conversation_type |
constant direct |
high | table is direct/person message source |
conversation_id |
ObjPersonId, fallback normalized `SndPersonId |
RecvPersonId` | medium |
sender_id |
SndPersonId |
high | schema names sender identity explicitly |
sender_name |
SndPerson or optional display-entity map |
high | value exposure should follow existing display-name policy |
receiver_id |
RecvPersonId |
high | schema names receiver identity explicitly |
text / content_text |
MsgText or MessageBody |
medium | body columns exist, but C35 does not read values; future body read needs strict limit/audit contract |
content_type |
MsgType |
medium | values not inspected in C35 |
timestamp / created_at |
ActionTime |
high | direct message timestamp column |
read |
MsgReadState |
medium | boolean-like column; semantics need row-level validation |
receipt_id / receipt state |
IsReceipt, MsgReceiptState, ReceiptTime, MsgRecaptionState |
low/medium | schema supports state but not the same as PacketReader receipt id |
subject |
none | low | direct DB table does not expose PacketReader <subject> equivalent in schema |
attachments |
join TD_ReceiveFileRecord.ReceiveMsgGuid = tblPersonMsg.Id |
medium | FilePath is sensitive and should remain hidden unless a separate download/cache contract exists |
Group messages: tblMsgGroupPersonMsg
| MCP receive field | Candidate DB column | Confidence | Notes |
|---|---|---|---|
message_id / id |
Id |
high | primary key in schema |
conversation_type |
constant group |
high | table is group/discussion message source |
conversation_id |
MsgGroupId |
high | group id column and recent trigger key |
conversation.display_name |
MsgGroupName or SessionTitle, plus optional display-entity map |
high | use existing MsgLib display source priority where possible |
sender_id |
SndPersonId |
high | schema names sender identity explicitly |
sender_name |
SndPerson or optional display-entity map |
high | value exposure should follow existing display-name policy |
receiver_id |
MsgGroupId |
medium | group id is the receive target in MCP contract terms |
text / content_text |
MsgText or MessageBody |
medium | body columns exist, but C35 does not read values; future body read needs strict limit/audit contract |
content_type |
MsgType, possibly GroupType for conversation class |
medium | values not inspected in C35 |
timestamp / created_at |
MsgTime |
high | group message timestamp column |
read |
MsgReadState |
medium | boolean-like column; semantics need row-level validation |
receipt_id / receipt state |
IsReceipt, MsgReceiptState, MsgRecaptionState; optional join TD_GroupReceiptMessage.MsgGuid |
low/medium | DB state exists but PacketReader receipt id equivalence is unproven |
subject |
none | low | group DB table does not expose PacketReader <subject> equivalent in schema |
attachments |
join TD_ReceiveFileRecord.ReceiveMsgGuid = tblMsgGroupPersonMsg.Id |
medium | hide FilePath; list only safe file metadata until cache/download mapping exists |
System messages: TD_SystemMessageRecord
| MCP receive field | Candidate DB column | Confidence | Notes |
|---|---|---|---|
message_id / id |
MsgGuid |
high | primary key in schema |
conversation_type |
constant system |
medium | source is system/auth record table |
sender_id / sender_name |
SendPersonJid / SendPersonName |
medium | values not inspected in C35 |
text / content_text |
MsgText |
medium | body-like column exists; future body read requires a strict contract |
subject |
MsgTitle |
medium | title-like field exists |
timestamp |
MsgTime |
high | system message timestamp column |
read |
MsgReadState |
medium | bit-like field exists |
Important gaps
MsgTextandMessageBodyare body columns. C35 confirms only that they exist, not whether their values are safe, decoded, complete, or aligned with PacketReader bodies.MsgLib.dbmay not contain every received message. Earlier SaveToDB evidence noted some messages may not be stored to the small DB, so DB-backed receive should not replace PacketReader as the only source until reconciliation is tested.subjectis strong in PacketReader XML but not clearly represented intblPersonMsg/tblMsgGroupPersonMsgschema.- Receipt semantics are not identical yet. DB columns show receipt/read state, but C35 does not prove the PacketReader receipt id mapping.
- Attachment metadata can likely join through
TD_ReceiveFileRecord, butFilePathis sensitive and should remain hidden by default. - Row ordering and incremental pagination need an explicit timestamp/id strategy before DB-backed listing is exposed.
Decision
MsgLib.db is a strong future source for DB-backed isphere_receive_messages, but it should not jump directly to body-returning message listing.
Recommended next implementation slice:
- Add a metadata-only sidecar operation for message-source readiness, for example
message_sources. - Return table availability, required/present columns, count-only summaries, and the committed field-map shape.
- Wire a Go wrapper and verification script for this metadata-only operation.
- Keep message body values, raw rows, local file paths, and DB row dumps out of scope until the metadata operation is verified.
Proposed C36 acceptance gate
- Default sidecar smoke still passes with
self_checkonly. - Evidence-backed sidecar smoke prints only
message_source_count, table names, required/present columns, and row counts. - No
MsgText,MessageBody,FilePath, entity values, raw rows, sends, downloads, hooks, injection, or DB writes. - Capability matrix records whether C37 may safely design a bounded DB-backed receive source.