# How the session_compact Event Handles Rules Re-Injection in i-have-adhd

> Discover how the session_compact event re-injects ADHD rulesets in i-have-adhd. Learn about automatic context scans and Pi runtime compaction for seamless rule management.

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

---

**The `session_compact` event in i-have-adhd triggers an automatic context scan that re-injects the ADHD ruleset if the Pi runtime's compaction process removes it from the conversation history.**

The `i-have-adhd` extension for the Pi platform ensures that ADHD coaching rules remain visible to the model throughout an entire session. When the Pi runtime performs a **session compact**—summarizing or discarding old messages to manage context window size—the extension must verify that the rules have not been stripped out. According to the `ayghri/i-have-adhd` source code, this is handled by a dedicated hook listener that synchronizes the context after every compaction.

## Registering the session_compact Listener

The extension registers a listener for the `session_compact` hook in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts). When the Pi runtime compacts the session, the listener receives the current `ExtensionContext` and immediately calls `syncContext` to reconcile the ruleset state.

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

```

(See [[`i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/i-have-adhd.ts) line 121-122](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts#L121-L122).)

## Checking Whether the Rules Are Still in Context

The `syncContext` function delegates the presence check to `rulesAreInContext`, defined at line 90 of [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts). This helper calls `latestMarkerIsActive` from [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) to determine whether the latest relevant marker in the conversation history is active or inactive.

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

```

(See [[`i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/i-have-adhd.ts) line 90-96](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts#L90-L96).)

The `latestMarkerIsActive` utility, implemented at line 41 of [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts), iterates over all context messages and toggles a boolean each time it encounters the active marker (`"i-have-adhd-rules"`) or the disabled marker (`"i-have-adhd-disabled"`). It returns the effective state after processing the full message list.

(See [[`context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/context-compat.ts) line 41-60](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts#L41-L60).)

## Re-Injecting the Ruleset After Compaction

If ADHD mode is enabled and `rulesAreInContext` returns `false`—meaning the compact operation removed the rules marker—`syncContext` sends a new custom message containing the full ruleset.

```ts
pi.sendMessage(
  {
    customType: RULES_MESSAGE_TYPE,
    content: `${RULES_HEADER}\n\n${rules}`,
    display: false,
  },
  { triggerTurn: false },
);

```

(See [[`i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/i-have-adhd.ts) line 21-30](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts#L21-L30).)

Conversely, if ADHD mode is disabled but a stale rules marker remains in context, the extension sends a disabled notice to neutralize the old instruction.

(See [[`i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/i-have-adhd.ts) line 33-42](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts#L33-L42).)

## Practical Example: Simulating a Session Compact

The following sequence demonstrates how the extension behaves during a typical interaction.

First, enable ADHD mode to inject the initial rules marker:

```ts
await pi.runCommand("i-have-adhd");

```

After several turns, the Pi runtime may compact the session and drop older messages:

```ts
await pi.emit("session_compact");

```

The extension's listener automatically runs `syncContext`. Because the compaction removed the original rules marker, the extension re-injects the rules silently:

```ts
{
  customType: "i-have-adhd-rules",
  content: "ADHD MODE ACTIVE. …\n\n<full ruleset>",
  display: false
}

```

If the user later disables ADHD mode, the extension sends a disabled marker. A subsequent compact would trigger the same synchronization logic to ensure the disabled state remains authoritative.

```ts
await pi.runCommand("i-have-adhd off");

```

## Summary

- The `session_compact` hook in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) registers a listener that calls `syncContext` after every compaction.
- `rulesAreInContext` uses `latestMarkerIsActive` from [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) to determine whether the `"i-have-adhd-rules"` or `"i-have-adhd-disabled"` marker is currently effective.
- If the rules are missing while ADHD mode is enabled, the extension re-injects the full ruleset via `pi.sendMessage` with `customType: RULES_MESSAGE_TYPE`.
- If ADHD mode is disabled but a stale marker persists, the extension emits a disabled notice to clear the old state.
- This mechanism guarantees that the ADHD ruleset remains consistent throughout the conversation regardless of runtime context window management.

## Frequently Asked Questions

### What triggers the rules re-injection in i-have-adhd?

The Pi runtime emits a `session_compact` event whenever it summarizes or prunes old messages to free up context window space. The extension listens for this event in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) and automatically invokes `syncContext` to verify and restore the ruleset if necessary.

### How does the extension know whether the rules are still present after compaction?

The `syncContext` function calls `rulesAreInContext`, which relies on `latestMarkerIsActive` from [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts). This helper scans the entire message history for `"i-have-adhd-rules"` and `"i-have-adhd-disabled"` markers and returns the latest effective state.

### What happens if ADHD mode is turned off but the rules marker survives compaction?

If `rulesAreInContext` detects a lingering active marker while ADHD mode is disabled, `syncContext` sends a disabled notice message. This ensures the model does not continue following the ADHD ruleset after the user has turned the feature off.

### Does the re-injected rules message appear in the user interface?

No. The re-injected message is sent with `display: false`, so it remains invisible to the user. The `triggerTurn: false` option also prevents the message from prompting a new model turn, keeping the interaction seamless.