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

> Learn how the i-have-adhd plugin ensures session data integrity during context compaction. Discover its shadow storage and fallback mechanisms for edge cases.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: deep-dive
- Published: 2026-08-19

---

**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`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) and the architecture documented in [`AGENTS.md`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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

```typescript
// 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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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.