Skip to content

Post-compartment cleanup synchronously reads all session parts, blocking OpenCode for 4.8–6.7 seconds #437

Description

@null-axiom

Environment

  • @cortexkit/opencode-magic-context 0.41.4
  • OpenCode Desktop 1.18.30, custom branch with additional performance diagnostics
  • macOS, Electron's Node sidecar
  • Large, long-lived sessions

Problem

After compartment publication, Magic Context's drop-queue cleanup reads every stored part in the session through synchronous SQLite. On large sessions, individual reads block the shared OpenCode sidecar for several seconds.

Observed symptoms include delayed session loading, output delivery, and Stop acknowledgment. These operations share the blocked backend; the evidence does not establish that this query explains every historical slowdown.

Measured evidence

Records from September 11, 2026; timestamps are EDT and identify record emission, not query start:

Timestamp SQLite call duration Returned rows
15:26:32.271 4,811.7 ms 101,919
15:27:44.091 6,702.1 ms 143,946

Both records identify the same SQL fingerprint and Magic Context call chain:

a96296ae25dd024a5600dbd5c8fd1edd8e09a47a1ac7b45e71127a853681f422

A separate live sidecar stack sample at 15:25:07 found 88 of 90 main-thread samples inside node::sqlite::StatementSync::All, including disk reads. That sample corroborates synchronous database blocking but does not independently identify the query.

Exact query

Installed bundle dist/index-0y2mcg5y.js:8470–8472:

SELECT message_id, data, time_updated
FROM part
WHERE session_id = ?
ORDER BY time_created ASC, id ASC

The query has no message-boundary restriction or page limit.

Caller chain

compartment publication
  → queueDropsForCompartmentalizedMessages
  → getRawSessionTagKeysThrough
  → readRawSessionMessages
  → readRawSessionMessagesFromSource
  → readRawSessionMessagesFromDb
  → synchronous full-session part query

Installed-bundle locations in dist/index-0y2mcg5y.js:

  • queueDropsForCompartmentalizedMessages: 30673–30699
  • getRawSessionTagKeysThrough: 9973–9974
  • Raw reader/source: 9794–9804, 9954–9960
  • Full-session part query: 8470–8479
  • Publication callers: 37311, 37604, 37811

The recorded stack includes index-0y2mcg5y.js:8472:137 and :9960:40. The database wrapper in index-raatkvw5.js opens OpenCode's database read-only.

Both incremental Historian and recomp publication paths reach this cleanup. The incident logs do not distinguish which publication path triggered each read.

Expected behavior

Cleanup should avoid synchronously materializing the entire session's part history merely to determine tag ownership through a compartment boundary.

An existing paged reader appears relevant:

  • Message pagination: 8495–8515
  • Parts restricted to selected message IDs: 8518–8522
  • Exposed as readRawSessionMessages.readPage: 9829

A possible correction is boundary-limited traversal with bounded hydration batches and event-loop yielding. Tool-invocation ownership must remain correct across page boundaries. Simply adding a row limit to the current query could omit required ownership information. This proposed correction has not been implemented or benchmarked.

Suggested regression coverage

  • Identical tag/drop ownership to the existing reader, including tool calls spanning pages.
  • No reading beyond the required message boundary.
  • Bounded parts hydration on large sessions.
  • Backend responsiveness during cleanup, not merely eventual query completion.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions