# How the i-have-adhd Persistence Mechanism Works Across Conversation Turns

> Discover how i-have-adhd's persistence mechanism maintains ADHD-friendly formatting across conversation turns by storing toggle state in session manager and optionally using a hidden flag file.

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

---

**The i-have-adhd extension maintains ADHD-friendly formatting rules across multiple conversation turns by storing toggle state in the runtime's session manager and optionally using a hidden flag file for permanent activation.**

The i-have-adhd repository provides a Pi-based extension that ensures system prompts remain formatted for ADHD accessibility throughout extended coding sessions. Unlike ephemeral command toggles, this persistence mechanism survives session branches, resumes, and new conversation turns without requiring repeated user activation.

## Storing State in the Session Manager

The extension leverages the Pi runtime's session manager to maintain the `enabled` boolean across turns. When a user toggles the mode via `/i-have-adhd`, `on`, `off`, or stop phrases like "stop adhd mode", the extension writes a custom entry to the session manager using `pi.appendEntry`.

The entry `i-have-adhd-state` contains `{ enabled: true|false }` and is stored persistently for the session duration. On every new turn, the extension retrieves this value through `getSavedState` to determine whether the ruleset should remain active. This approach ensures that once enabled, the mode persists implicitly without re-injection on every message.

*Source:* [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 66-78)

## Permanent Activation with the Flag File

For users requiring ADHD mode by default across all future sessions, the extension checks for a hidden file named **`.i-have-adhd-always`** in the agent directory returned by `getAgentDir()`. Presence of this file forces `enabled` to `true` immediately upon session initialization, bypassing the need to manually toggle the mode each time.

This file-based persistence operates independently of the session manager, serving as a permanent configuration flag that survives process restarts and new workspace openings.

*Source:* [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 48-51)

## Restoring State on Session Events

The extension registers event listeners for `session_start` and `session_tree` to handle branching and resumption scenarios. Each time a session is created or a branch is resumed, the `restoreState` function executes automatically.

This function reads the saved session entry (if present) or falls back to the flag file default, then updates the UI status to reflect the current state. By hooking into these lifecycle events, the extension guarantees that ADHD mode remains active even when switching between conversation branches or reloading previous contexts.

*Source:* [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 19-22)

## Synchronizing Rules with Context

The core persistence logic resides in the `syncContext` helper, which manages the actual injection and removal of the ruleset. The function checks `rulesAreInContext` to determine if the `i-have-adhd-rules` message exists in the model's current context window.

- **If enabled is true** and the rules are missing, `syncContext` sends a hidden custom message containing the rules header plus the full Markdown rules from [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md).
- **If enabled is false** but a rules message remains present, the function sends a hidden "disabled" notice to cancel the prior injection, effectively removing the formatting constraints.

This synchronization ensures the context contains exactly one instance of the ruleset when active and zero instances when inactive, preventing duplication or stale instructions across turns.

*Source:* [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 18-43)

## Cross-Turn Persistence Behavior

Because the state entry lives in the session manager, every subsequent turn automatically inherits the same `enabled` value without requiring re-injection of the rules. The rules are only re-added to the context during three specific events: when a new session starts, when a branch is resumed, or when the user explicitly toggles the mode.

This design minimizes context window usage by avoiding repetitive system prompt updates while maintaining consistent formatting constraints throughout the conversation lifecycle.

## Shell Hook Implementation

For runtimes utilizing hook scripts rather than the Pi extension API, the repository provides [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) (and a Node.js equivalent). These hooks perform the same `.i-have-adhd-always` flag file check at session startup, printing a persistent notice and injecting the rules via stdout to mirror the extension's behavior in shell-based environments.

## Practical Implementation Examples

Toggle the mode programmatically within a Pi session:

```typescript
// Toggle the mode from a chat turn
await pi.runCommand("i-have-adhd");          // toggles on/off
await pi.runCommand("i-have-adhd on");       // forces enable
await pi.runCommand("i-have-adhd off");      // forces disable

// Using the stop phrases inside normal chat input
await pi.sendMessage({ text: "stop adhd mode" });
// → the model replies with the confirmation "ADHD mode disabled."

// Making the mode always‑on for every new session
import { join } from "node:path";
import { getAgentDir } from "@earendil-works/pi-coding-agent";

const flagPath = join(getAgentDir(), ".i-have-adhd-always");
await writeFile(flagPath, "");   // create empty flag file

```

Create the persistent flag using bash:

```bash

# Bash example: creating the always‑on flag

$ mkdir -p ~/.claude   # or whatever getAgentDir() resolves to

$ touch ~/.claude/.i-have-adhd-always

# The next Pi or Claude Code session will automatically inject the rules.

```

## Summary

- The i-have-adhd persistence mechanism uses `pi.appendEntry` to store state in the Pi session manager under the key `i-have-adhd-state`, surviving across individual chat turns.
- A hidden `.i-have-adhd-always` flag file in the agent directory enables permanent default activation across all future sessions.
- Event listeners for `session_start` and `session_tree` trigger `restoreState` to maintain consistency when branching or resuming conversations.
- The `syncContext` function manages ruleset injection by checking `rulesAreInContext` and updating the model context only when necessary.
- Hook scripts in [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) provide equivalent persistence for non-Pi runtimes by checking the same flag file.

## Frequently Asked Questions

### How does the extension remember my preference between individual chat messages?

The extension stores a boolean flag inside the Pi runtime's session manager using `pi.appendEntry` under the entry name `i-have-adhd-state`. Because this storage persists for the entire session duration, subsequent turns retrieve the same value via `getSavedState` without requiring the user to reactivate the mode or re-inject the ruleset.

### What is the .i-have-adhd-always file and where is it located?

The `.i-have-adhd-always` file is a hidden empty file that forces ADHD mode to default to enabled for every new session. It resides in the directory returned by `getAgentDir()`, typically the agent's configuration folder. When present, the extension automatically enables the mode during `session_start` before processing any user input.

### How do I temporarily disable ADHD mode without deleting the flag file?

You can temporarily disable the mode by sending the command `/i-have-adhd off` or typing the stop phrase "stop adhd mode" or "normal mode" in chat. This updates the session manager state to `{ enabled: false }` and triggers `syncContext` to remove the rules from the current context. The flag file remains untouched, so future new sessions will still default to enabled.

### Which runtime events trigger the state restoration process?

The extension listens for `session_start` (new sessions) and `session_tree` (branch creation or resumption) events. When either fires, the `restoreState` function executes to read the saved entry or check the `.i-have-adhd-always` flag file, ensuring the correct mode status applies immediately to the new conversation context.