How the i-have-adhd Plugin Handles Edge Cases and Maintains State During Context Compaction

The i-have-adhd plugin intercepts runtime session_compact events to preserve critical ADHD-specific session variables through a shadow storage mechanism, validating state integrity and falling back to default rulesets when aggressive trimming occurs.

The i-have-adhd plugin extends the Pi/OMP runtime to provide ADHD-friendly interaction patterns during extended conversations. When the underlying model performs context compaction—the process of summarizing or truncating conversation history to stay within token limits—the plugin must safeguard user-specific rulesets and session state. According to the ayghri/i-have-adhd source code in extensions/i-have-adhd.ts and the architecture documented in AGENTS.md, the plugin implements a defensive synchronization pipeline that handles data loss scenarios and guarantees continuity across compaction cycles.

The Context Compaction Event Architecture

Registering the session_compact Listener

In extensions/i-have-adhd.ts at line 221, the plugin registers a dedicated listener for the runtime's session_compact event. This event fires whenever the Pi/OMP runtime initiates token conservation by summarizing or removing historical messages. The listener immediately invokes syncContext(ctx), passing the current session context to initiate state preservation before the runtime finalizes the trim operation.

State Synchronization and Shadow Storage

The syncContext Implementation

The syncContext function serves as the primary defense against data loss during compaction. It extracts the current ruleset, adhd_state, and temporary buffers from the runtime context and persists them to the plugin's internal storage. This capture occurs synchronously with the compaction event, ensuring the plugin has a snapshot of critical variables before they potentially disappear from the active context.

Fallback Shadow Store

If the compaction aggressively removes entries that the plugin marked as required, the system falls back to a shadow store—a separate cache maintained alongside the main context. This shadow copy contains the last known good state, allowing the plugin to restore critical variables even when the runtime summary excludes them. The shadow store persists independently of the runtime's compaction decisions, acting as a redundant safety layer.

Edge Case Handling Strategies

Missing Ruleset Recovery

If syncContext detects that the incoming context lacks a ruleset—possible after severe compaction—it injects the default configuration defined in skills/i-have-adhd/SKILL.md. This ensures the ADHD-friendly response style remains active regardless of context truncation, preventing the plugin from operating without behavioral guidelines.

Partial Summary Reconciliation

When only fragments of multi-turn exchanges survive compaction, the plugin merges surviving entries with the shadow store. It reconciles message IDs and timestamps to prevent dangling references, creating a coherent state from partial data. This reconciliation prevents the plugin from referencing messages that no longer exist in the compacted history.

Concurrent Session Isolation

The plugin namespaces all stored state by session ID, ensuring concurrent users do not collide. Each session_compact event carries a specific context object scoped to that session, and all shadow store updates respect this isolation boundary. This design prevents cross-contamination between independent conversations while maintaining separate fallback stores for each user context.

Validation and Persistence Pipeline

Post-Compaction Consistency Checks

After each synchronization cycle, the plugin runs a lightweight validation routine that verifies the presence of required keys: ruleset, adhd_state, and summary. It also checks that no entry references a deleted message ID. If validation fails, the plugin logs a warning through the runtime logger and restores missing pieces from the shadow store. This defensive behavior is verified by the test suite in scripts/check_context_compat.ts, which simulates aggressive compaction scenarios to confirm the shadow store reliably restores truncated state.

Cross-Restart Durability

The synchronized context writes to the runtime's persistent storage backend—typically JSON files or database entries—depending on the host configuration. On startup, the plugin rehydrates from this snapshot, making ADHD-specific state instantly available without reconstructing the entire conversation history. This persistence ensures that even process restarts do not compromise the continuity of ADHD-friendly interaction patterns.

Implementation Example

// Register the compaction listener (executed once at plugin init)
pi.on("session_compact", async (_event, ctx) => {
  await syncContext(ctx);               // ← core sync routine
});

// Helper that can be called manually if you need to force a state refresh
export async function refreshAdhdState(sessionId: string) {
  const ctx = await pi.getContext(sessionId);
  await syncContext(ctx);
}

Summary

  • The plugin listens for session_compact events in extensions/i-have-adhd.ts (line 221) to intercept runtime trimming operations before they finalize.
  • syncContext extracts and preserves session variables, with a shadow store providing fallback protection against aggressive compaction that removes required entries.
  • Edge cases like missing rulesets resolve by loading defaults from skills/i-have-adhd/SKILL.md, ensuring continuous adherence to ADHD-friendly patterns.
  • Post-synchronization validation ensures required keys (ruleset, adhd_state, summary) remain intact, with automatic restoration from shadow storage if checks fail.
  • State persists across process restarts through the runtime's storage backend, scoped by session ID to prevent cross-user contamination.

Frequently Asked Questions

What triggers context compaction in the i-have-adhd plugin?

Context compaction triggers when the Pi/OMP runtime detects that the conversation history exceeds token limits or retention policies. The runtime emits a session_compact event, which the plugin captures in extensions/i-have-adhd.ts (line 221) to initiate state preservation before the trimming operation completes.

How does the plugin prevent loss of ADHD-specific rulesets?

The plugin stores rulesets in a shadow copy separate from the main context. If compaction removes the active ruleset, syncContext detects the absence and either restores from shadow storage or injects the default ruleset defined in skills/i-have-adhd/SKILL.md, ensuring continuous adherence to ADHD-friendly interaction patterns.

What happens if critical session data is removed during compaction?

When required entries disappear during compaction, the plugin merges surviving fragments with the shadow store, reconciling IDs and timestamps to maintain consistency. If validation fails after this merge, the system logs a warning and restores the complete state from the last known good shadow copy, preventing data loss.

Does the plugin support multiple concurrent sessions?

Yes. The plugin namespaces all state by session ID, ensuring that each session_compact event updates only the storage partition belonging to that specific session. This isolation prevents cross-contamination between concurrent users while maintaining independent shadow stores for each conversation context.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →