Files
isphere-ai-bridge/docs/source-discovery/2026-07-10-msglib-readonly-schema-extraction.md
2026-07-10 02:36:42 +08:00

6.0 KiB

MsgLib.db copied read-only schema extraction

Date: 2026-07-10

Question

Can copied MsgLib.db files be opened read-only with the wrapper password recovered in C25, and which schema fields should drive the next business read implementation?

Evidence checked

Ignored C26 artifacts:

  • runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c26-schema-probe-x86/
  • runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c26-msglib-schema-probe-x86.json

Probe method:

  • referenced the bundled System.Data.SQLite.dll from the extracted iSphere client files;
  • opened copied MsgLib.db files only;
  • used the C25 recovered password 123;
  • forced read-only mode in the SQLite connection string;
  • queried only sqlite_master, PRAGMA table_info(...), and safe target-table row counts;
  • did not dump message bodies, contact values, file paths, or raw rows.

Runtime finding

  • A 64-bit probe failed at CLR/SQLite mixed-mode loading.
  • A 32-bit .NET Framework probe succeeded.
  • Successful provider: System.Data.SQLite, version observed through the opened DB runtime as SQLite 3.6.23.1.

This means the production path should not assume Go can open this DB directly. The practical route is a dedicated x86 .NET read-only sidecar/helper that Go MCP calls through a bounded JSON contract.

Open result

All three copied MsgLib.db candidates opened successfully with Password=123 in read-only mode.

Copied DB Open result Table count Notable safe counts
DB A, about 12.2 MB ok 13 tblMsgGroupPersonMsg=2884, tblPersonMsg=2132, tblRecent=52, TD_SystemMessageRecord=469
DB B, about 2.84 MB ok 23 tblMsgGroupPersonMsg=1048, tblPersonMsg=1209, tblRecent=80, tblChatLevel=105, TD_WorkGroupAuth=2, TD_SystemMessageRecord=314
DB C, about 2.78 MB ok 13 tblMsgGroupPersonMsg=796, tblPersonMsg=1932, tblRecent=51, TD_SystemMessageRecord=228

The counts above are schema-validation counts only. No row values were extracted into committed docs.

Confirmed business schema map

Contacts and display names

Validated tables/columns:

  • TD_Roster: JId, Domain, Nick, Ask, Subscription, Show, Status, GroupName.
  • TD_CustomEffigy: PersonJid, PersonName, PersonSex, HeadImageSize, LocalPath, ServerUpdateTime.
  • tblRecent: Id, PersonId, PersonName, ActionTime, FType.
  • tblChatLevel: present in the richer DB and already known from C25 model fields as PersonId, PersonName.
  • tblPersonMsg: SndPerson, SndPersonId, RecvPerson, RecvPersonId, ObjPerson, ObjPersonId, plus message metadata fields.

Recommended contact display-name priority for a future read source:

  1. TD_Roster.Nick by TD_Roster.JId when present.
  2. TD_CustomEffigy.PersonName by PersonJid when present.
  3. tblRecent.PersonName by PersonId for recent conversations.
  4. tblPersonMsg sender/receiver/object display fields as fallback.
  5. JID-derived fallback when DB display fields are absent.

Groups and member names

Validated tables/columns:

  • tblMsgGroupPersonMsg: MsgGroupId, MsgGroupName, SessionTitle, SessionPersonId, SessionPersonName, GroupType, plus message metadata fields.
  • TD_WorkGroupAuth: SessionID, SessionStatus, SessionType, ApplyInfo, GroupJID, GroupName, SendPersonSex, ApplyDateTime; richer DB also has ChildGroupJid.
  • tblRecent: stores group recent entries through triggers using PersonId = MsgGroupId, PersonName = MsgGroupName, and FType = GroupType.

Recommended group display/member priority:

  1. tblMsgGroupPersonMsg.MsgGroupName by MsgGroupId.
  2. tblRecent.PersonName by PersonId where FType indicates group/discussion.
  3. TD_WorkGroupAuth.GroupName by GroupJID for work-group authorization records.
  4. tblMsgGroupPersonMsg.SessionPersonId/SessionPersonName for member-name enrichment.
  5. JID-derived fallback when DB display fields are absent.

Receive messages

Validated tables/columns:

  • tblPersonMsg: one-to-one message table, including ids, sender/receiver/object identities, text/body/content/version/read fields, timestamps, and receipt state.
  • tblMsgGroupPersonMsg: group/discussion message table, including ids, sender identities, group ids/names, session title/member fields, message body/content/version/read fields, and timestamps.
  • TD_SystemMessageRecord: system/auth message metadata.

C27 should not read message bodies yet. The next code loop should first add a schema/display-name sidecar and only later add DB-backed message listing with strict limit/redaction controls.

File metadata

Validated tables/columns:

  • TD_ReceiveFileRecord: ReceiveMsgGuid, FileName, FileSize, FilePath, SourceID, SourceName, FileType, SendPersonJid, SendPersonName, SendTime.
  • TD_SendFileRecord: SendMsgGuid, FileName, FileSize, FilePath, SourceID, SourceName, FileType, ReceivePersonJid, ReceivePersonName, ReceiveTime.

File download remains blocked until cache/download mapping is separately validated.

Decision

C26 validates the DB path:

MsgLib.db can be opened from copied evidence with the bundled 32-bit System.Data.SQLite.dll, Password=123, and read-only mode.

The project can now move from log-only read support toward DB-backed contact/group display-name enrichment. Because the working provider path is 32-bit .NET, the next implementation should be a bounded x86 .NET sidecar/helper rather than direct Go SQLite access.

Next slice

Loop C27 should implement the first production-shaped DB bridge as a narrow helper/sidecar contract, not as broad message extraction:

  1. Build a committed contract for a read-only MsgLib.db schema/display-name sidecar.
  2. Start with safe operations such as msglib_self_check and msglib_list_display_sources or equivalent.
  3. Return only table availability, column availability, and display-name candidate maps with strict limits.
  4. Keep message-body reads, file downloads, sends, writes, and DB mutation out of scope.