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:
- Logs degraded mode and continues with
compartmentEndMessageId: null.
- Performs no splice, so
skippedVisibleMessages stays zero.
- 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
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:
The boundary message exists in opencode.db but is excluded from the messages array passed to the plugin hook, because OpenCode's
filterCompactedstops at a newer compaction marker. The injection code (inject-compartments.ts:446-456) then:compartmentEndMessageId: null.skippedVisibleMessagesstays zero.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