Skip to content

Degraded mode in inject-compartments has no recovery path when boundary is outside the visible window #264

Description

@SK-DEV-AI

Short description

When the compartment boundary message is not in the visible message window, inject-compartments enters degraded mode, skips the splice, and queues zero drops. There is no re-anchor path: the state repeats on every transform pass until the boundary becomes visible again, which can take days.

What happened?

Observed in a forked session (see the companion issue about fork-orphaned markers). Log line, repeated on every transform pass:

compartment injection entering degraded mode: boundary msg_fb0cab953001SLJx4ZG6LA7jiO not in visible messages

The boundary message exists in opencode.db but is excluded from the messages array passed to the plugin hook, because OpenCode's filterCompacted stops at a newer compaction marker. The injection code (inject-compartments.ts:446-456) then:

  1. Logs degraded mode and continues with compartmentEndMessageId: null.
  2. Performs no splice, so skippedVisibleMessages stays zero.
  3. Caches the null boundary, so the next pass hits the "cache in degraded mode (null boundary), forcing rebuild" branch and repeats the same failed lookup.

The drop queue (compartment-runner-drop-queue.ts) only drops tags observed in the visible window, so zero drops get queued. The session sat at 96.3% context usage with a 200K window; the emergency tiered drop reclaimed 649 of 104,534 tokens.

The assumption that does not hold

The comment in inject-compartments.ts assumes the missing boundary means "covered messages were already trimmed by OpenCode (compaction, old history not sent)". That holds when OpenCode itself compacted the history. It does not hold when a compaction marker newer than the boundary cuts the window: the boundary is then below the cut, the covered range is not fully summarized, and the trim that should shrink context never happens.

Expected behavior

When the boundary is not in the visible window, the code should re-anchor instead of no-op: fall back to the newest compaction marker present in the visible window (or the visible window start) as the trim boundary, or surface the state instead of silently repeating the failed lookup. Either way, degraded mode should not persist indefinitely with no recovery path and no user-visible signal beyond a log line.

Environment

  • Plugin version: 0.33.0
  • OpenCode: 1.18.10
  • Platform: Linux
  • Client: OpenCode TUI

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions