# How the i-have-adhd Extension Detects and Re-injects Rules After Context Compaction

> Discover how the i-have-adhd extension detects and re-injects rules after context compaction using marker-based detection to ensure a seamless user experience.

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

---

**The i-have-adhd extension uses marker-based detection in the session message tree to verify rule presence and automatically re-injects the ADHD-friendly ruleset whenever Pi's context compaction removes it from the active conversation.**

The i-have-adhd extension ensures that specialized ADHD-friendly conversation rules persist across Pi's context window management. When the platform compacts long sessions by summarizing earlier turns, the extension must detect whether the ruleset has been dropped and restore it to maintain consistent model behavior according to the ayghri/i-have-adhd source code.

## How Context Compaction Affects Extension Rules

Pi manages long conversations through **context compaction**, a process that summarizes or truncates earlier message history to stay within token limits. During this process, system messages and extension-injected content can be removed from the active context. The i-have-adhd extension solves this by implementing a two-phase recovery system that detects missing rules and re-injects them immediately after compaction events.

## Detecting Rule Presence in the Message Tree

The extension determines whether the ADHD ruleset is still active by scanning the session's message tree for specific marker types. This detection happens through specialized utility functions that check the chronological order of injected markers.

### The rulesAreInContext Function

In [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 90‑96), the `rulesAreInContext` function serves as the primary detection mechanism:

```typescript
function rulesAreInContext(ctx: ExtensionContext): boolean {
  return latestMarkerIsActive(
    contextMessages(ctx.sessionManager),
    RULES_MESSAGE_TYPE,
    DISABLED_MESSAGE_TYPE,
  );
}

```

This function returns **true** only when the ruleset is currently active in the conversation context. It delegates the actual validation logic to `latestMarkerIsActive` while passing the current session messages and the two relevant marker types.

### Checking Marker Order with latestMarkerIsActive

The detection logic resides in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts). The `latestMarkerIsActive` function scans the session's message tree and compares the positions of `RULES_MESSAGE_TYPE` and `DISABLED_MESSAGE_TYPE` markers. It returns **true** only if the most recent marker of type `RULES_MESSAGE_TYPE` appears **after** any `DISABLED_MESSAGE_TYPE` marker in the conversation history.

This chronological check ensures that the extension correctly identifies whether the rules are currently enabled or have been superseded by a disable command, even after the conversation has been compacted.

## Re-injecting Rules After Session Compaction

When Pi compacts the session, the extension automatically triggers a recovery sequence to restore the correct conversation state. This ensures the model always receives the appropriate ADHD-friendly instructions regardless of context window changes.

### Listening for the session_compact Event

The extension registers an event listener in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 221‑222) that monitors for compaction events:

```typescript
pi.on("session_compact", async (_event, ctx) => syncContext(ctx));

```

This listener calls `syncContext` immediately after every compaction, creating a hook where the extension can verify and restore its injected content before the conversation continues.

### The syncContext Recovery Logic

The `syncContext` function implements conditional recovery based on the current ADHD mode state and the results of `rulesAreInContext`:

- **When ADHD mode is enabled**: If `rulesAreInContext` returns false (indicating the rules were removed during compaction), the extension sends a new message containing the ruleset via `pi.sendMessage` with the `RULES_MESSAGE_TYPE` marker.

- **When ADHD mode is disabled**: If the function detects that a stale ruleset remains in the context (rules present but should be disabled), it injects a "disabled" notice using `DISABLED_MESSAGE_TYPE` to effectively cancel the old instructions.

This bidirectional synchronization ensures the conversation context always matches the user's current settings, regardless of how aggressively Pi compacts the message history.

## Implementation Details

The actual ruleset content is stored in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md), which the extension reads and injects into the conversation when needed. The marker-based approach allows the extension to maintain state across context changes without requiring persistent storage of the full conversation history.

## Summary

- The extension detects rule presence using `rulesAreInContext`, which calls `latestMarkerIsActive` from [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts)
- Detection validates that the most recent `RULES_MESSAGE_TYPE` marker appears after any `DISABLED_MESSAGE_TYPE` marker
- A listener for the `session_compact` event triggers automatic recovery via `syncContext`
- The system re-injects rules when ADHD mode is enabled but rules are missing, or injects disable notices when stale rules remain
- All logic is implemented in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) with utility support from [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts)

## Frequently Asked Questions

### What triggers the i-have-adhd extension to re-inject rules?

The `session_compact` event triggers the re-injection process. When Pi compacts the conversation to manage token limits, the extension's listener calls `syncContext`, which checks `rulesAreInContext` and re-injects the rules if they are missing. This happens automatically without user intervention.

### How does the extension know if rules are still active in the context?

The extension calls `rulesAreInContext`, which uses `latestMarkerIsActive` to scan the message tree in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts). It returns true only if the most recent `RULES_MESSAGE_TYPE` marker appears after any `DISABLED_MESSAGE_TYPE` marker, confirming the ruleset is currently active and not superseded by a disable command.

### What happens if ADHD mode is disabled but old rules remain in the context?

If `syncContext` detects that ADHD mode is disabled but `rulesAreInContext` still finds active rules (stale state), the extension injects a `DISABLED_MESSAGE_TYPE` message. This marker cancels the previous ruleset, ensuring the model does not continue following ADHD-specific instructions when the feature is turned off.

### Where is the actual ruleset content stored before injection?

The ruleset content lives in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) according to the repository structure. When the extension needs to re-inject rules, it sends the contents of this file into the conversation as a message marked with `RULES_MESSAGE_TYPE`, allowing the model to receive the full ADHD-friendly instructions.