# Understanding the i-have-adhd-rules Custom Message Type in the i-have-adhd Extension

> Discover the purpose of the i-have-adhd-rules custom message type in the i-have-adhd browser extension. Learn how it injects ADHD-specific rules for improved AI interaction.

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

---

**The `i-have-adhd-rules` string acts as a hidden context marker that injects ADHD-specific prompting rules into the model's conversation history and tracks whether those rules remain active across session lifecycles.**

The `ayghri/i-have-adhd` repository provides a Pi Coding Agent extension that modifies AI responses for ADHD-friendly formatting. The custom message type `i-have-adhd-rules` serves as the core mechanism for managing these behavioral rules within the model's context window, ensuring the instructions persist across conversation turns without cluttering the user interface.

## What is i-have-adhd-rules?

The string `i-have-adhd-rules` is exposed as the constant `RULES_MESSAGE_TYPE` in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts). This identifier marks hidden messages that contain the complete ADHD rule set read from [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md). Unlike regular user messages, these custom messages have `display: false`, making them invisible in the chat interface while remaining visible to the model.

## How the Extension Uses i-have-adhd-rules

### Injecting Rules into Context

When ADHD mode is enabled, the extension sends a hidden message with `customType` set to `RULES_MESSAGE_TYPE`. This occurs once per session rather than on every turn, preventing token waste while ensuring the model receives the instructions.

```typescript
pi.sendMessage(
  {
    customType: RULES_MESSAGE_TYPE,        // ← i-have-adhd-rules
    content: `${RULES_HEADER}\n\n${rules}`,
    display: false,
  },
  { triggerTurn: false },
);

```

*(see lines 22‑30 of [i-have-adhd.ts](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts#L22-L30))*

The `triggerTurn: false` option prevents the message from triggering a model response, keeping the injection silent while the `display: false` property hides it from the user interface.

### Detecting Active Rules

The helper function `latestMarkerIsActive` in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) scans context messages to determine whether the ADHD rules remain active. It compares timestamps between the rules marker (`i-have-adhd-rules`) and the disabling marker (`i-have-adhd-disabled`).

```typescript
export function latestMarkerIsActive(
  messages,
  activeType,   // ← i-have-adhd-rules
  disabledType, // ← i-have-adhd-disabled
)

```

*(see lines 41‑58 of [context-compat.ts](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts#L41-L58))*

If the most recent marker is `i-have-adhd-rules`, the extension knows the rule set remains in the model's context. If `i-have-adhd-disabled` appears later, the rules have been superseded.

### Synchronizing State Across Sessions

On every session event (`session_start`, `session_tree`, `session_compact`), the extension calls `syncContext` to maintain consistency.

1. **If ADHD mode is on** and no `i-have-adhd-rules` marker exists, the extension injects the rules message.
2. **If ADHD mode is off** but a stale rules marker remains, the extension sends an `i-have-adhd-disabled` message to nullify the previous injection.

This synchronization ensures the model only sees ADHD formatting instructions when explicitly enabled, and cleanly removes them when disabled.

## Implementation Details and Code Examples

### Manually Sending Rules Messages

Developers can replicate the extension's behavior using the Pi Coding Agent API:

```typescript
import { pi } from "@earendil-works/pi-coding-agent";

const RULES_MESSAGE_TYPE = "i-have-adhd-rules";
const RULES_HEADER = 'ADHD MODE ACTIVE. The ruleset below applies …';
const rules = `...contents of SKILL.md...`;

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

```

### Checking Rule Status Programmatically

To verify whether ADHD rules currently affect the model's context:

```typescript
import { contextMessages, latestMarkerIsActive } from "./context-compat";

const messages = contextMessages(sessionManager);
const rulesActive = latestMarkerIsActive(
  messages,
  "i-have-adhd-rules",
  "i-have-adhd-disabled"
);

if (rulesActive) {
  console.log("ADHD rules are currently in the model's context.");
}

```

### Toggling via Command

The `/i-have-adhd` command handler uses these markers to toggle the mode:

```typescript
pi.registerCommand("i-have-adhd", {
  description: "Toggle ADHD-friendly output for this session",
  handler: async (args, ctx) => {
    const arg = args.trim().toLowerCase();
    if (arg === "on")   setEnabled(true, ctx);
    else if (arg === "off") setEnabled(false, ctx);
    else                      setEnabled(!enabled, ctx); // toggle
  },
});

```

## Summary

- **Identifier constant**: `RULES_MESSAGE_TYPE` in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) defines the string `i-have-adhd-rules`.
- **Context injection**: Hidden messages with this type insert [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) contents into the model's context without displaying in the UI.
- **State detection**: The `latestMarkerIsActive` function in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) tracks whether rules remain active by comparing timestamps with `i-have-adhd-disabled` markers.
- **Lifecycle management**: The extension synchronizes these markers across session events, injecting rules when ADHD mode activates and removing them when deactivated.
- **Testing coverage**: Unit tests in [`scripts/check_pi_extension.py`](https://github.com/ayghri/i-have-adhd/blob/main/scripts/check_pi_extension.py) verify that exactly one `i-have-adhd-rules` entry exists when the feature is enabled.

## Frequently Asked Questions

### What content does the i-have-adhd-rules message type contain?

The message contains the complete rule set defined in [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md), prefixed by `RULES_HEADER`. This typically includes formatting instructions and behavioral constraints that modify how the model structures responses for ADHD accessibility, such as using concise paragraphs, bullet points, and clear hierarchical organization.

### How does the extension prevent duplicate rule injection?

The `syncContext` function checks for existing `i-have-adhd-rules` markers before sending new ones. By scanning the conversation history using `latestMarkerIsActive`, the extension ensures it only injects the rules once per session when ADHD mode is enabled, avoiding token waste and context pollution.

### What happens when ADHD mode is disabled?

When a user disables ADHD mode, the extension sends a compensating message with `customType: "i-have-adhd-disabled"`. This marker supersedes any previous `i-have-adhd-rules` message in the context history, effectively canceling the instructions without requiring a full context reset.

### Where is the i-have-adhd-rules constant defined?

The constant is defined as `RULES_MESSAGE_TYPE` in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) at line 22. The extension exports this string value for use across the codebase, ensuring consistent typing when checking message types in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) and other modules.