How i-have-ADHD Restates State on Every Turn to Minimize Cognitive Load

The i-have-ADHD extension uses a persistent session entry to track mode status and automatically re-injects ADHD-friendly rules whenever they drop from context, eliminating the need for users to remember or repeat their preference.

The ayghri/i-have-adhd repository implements a state-restating mechanism designed specifically for users with ADHD who may struggle to track whether assistive features are active. Rather than burdening the user with monitoring mode status, the system handles state persistence and rule reinjection automatically through Pi's session manager architecture.

State Storage: The Persistent Flag

When a user enables ADHD-friendly mode, the extension creates a durable session entry that survives across turns and compaction operations.

In extensions/i-have-adhd.ts at line 75, the setEnabled function calls:

pi.appendEntry("i-have-adhd-state", { enabled: true });

This creates a custom entry of type i-have-adhd-state with a boolean enabled flag. Unlike transient context, session entries persist even when the conversation tree is compacted, ensuring the preference survives long-running sessions.

State Retrieval on Every Turn

The extension checks the stored flag at critical session lifecycle points—specifically session_start and session_tree events—via the restoreState function.

From lines 81-95 in extensions/i-have-adhd.ts, the code walks the session branch:

const branch = ctx.sessionManager.getBranch();
for (const entry of branch) {
  if (entry.type === "i-have-adhd-state") {
    state.enabled = entry.data.enabled;
  }
}

This loop finds the most recent state entry and extracts the current enabled value, giving the extension authoritative knowledge of user preference regardless of intervening conversation turns.

Detecting Missing Rules with Rule Presence Check

Knowing the preference is only half the solution. The extension must also determine whether the rule set remains in the active context or was evicted during compaction.

The rulesAreInContext function (lines 105-110) leverages latestMarkerIsActive from extensions/context-compat.ts:

function rulesAreInContext(ctx: Context): boolean {
  return latestMarkerIsActive(ctx, "i-have-adhd-rules");
}

This utility checks if the most recent i-have-adhd-rules marker is still active and hasn't been superseded by a disabled marker. The marker-based approach handles edge cases where rules might be partially present but invalidated by later context changes.

Automatic Restatement via syncContext

The core restatement logic lives in syncContext, triggered on session_compact events after every turn. Lines 134-148 implement the conditional reinjection:

async function syncContext(ctx: Context, state: State) {
  if (state.enabled && !rulesAreInContext(ctx)) {
    // Rules were dropped by compaction—re-inject invisibly
    await pi.sendMessage({
      customType: "i-have-adhd-rules",
      content: RULES,
      display: false,  // Hidden from user view
      triggerTurn: false  // Doesn't advance conversation turn
    });
  }
}

Key characteristics of this restatement:

  • Invisible execution: display: false ensures the user never sees duplicate rule injections
  • Non-intrusive: triggerTurn: false prevents the hidden message from advancing the conversation state
  • Idempotent: Repeated calls with rules already present safely no-op via the rulesAreInContext guard

Clean Disabling with State Transition

When the user signals deactivation through any phrase in STOP_PHRASES (such as "stop adhd mode"), the extension performs a coordinated shutdown at lines 221-232:

if (state.enabled && STOP_PHRASES.has(input)) {
  await setEnabled(false, ctx);  // Flips flag, appends disabled entry
  await pi.sendMessage({
    customType: "i-have-adhd-disabled",
    content: "ADHD-friendly mode disabled.",
    display: true
  });
}

The disabled state entry prevents future rule reinjection, while the visible confirmation gives the user clear feedback. Subsequent syncContext calls see enabled: false and skip all rule handling.

Complete State Lifecycle Flow

The restatement mechanism follows this deterministic sequence on every user turn:

  1. Restore: restoreState reads the latest i-have-adhd-state entry from the session branch
  2. Validate: rulesAreInContext checks if rule markers remain active
  3. Reinstate: syncContext injects hidden rules if enabled but missing
  4. Process: User input handled with guaranteed rule presence
  5. Persist: Any state changes appended as new session entries

This design ensures causal consistency—the model always operates with the correct rule context without requiring user intervention.

State vs. Context: Architectural Distinction

The extension exploits Pi's dual storage model:

Storage Type Persistence Use Case in i-have-ADHD
Session entries Survive compaction Boolean enabled flag
Context/markers Evicted during compaction Full rule content

Separating the lightweight state (one boolean) from heavyweight content (full rule set) minimizes storage pressure while enabling reliable recovery. The state entry acts as a checkpoint, while markers track ephemeral context presence.

Summary

  • Persistent boolean flag: Stored in i-have-adhd-state session entries, surviving compaction and cross-turn navigation
  • Automatic rule reinjection: syncContext detects missing rules via latestMarkerIsActive and re-injects via hidden messages
  • Invisible operation: Restatement uses display: false and triggerTurn: false to avoid user distraction
  • Explicit disable: STOP_PHRASES trigger clean shutdown with state entry and user confirmation
  • Zero user burden: No requirement to remember mode status or repeat preferences

Frequently Asked Questions

What triggers the state restatement in i-have-ADHD?

The syncContext function runs on every session_compact event, which fires after each turn. It checks whether enabled is true and whether rules remain in context via rulesAreInContext. If enabled but rules are missing, it re-injects them automatically.

Does the user see when rules are restated?

No. The restatement uses display: false in the pi.sendMessage call, making the injection completely invisible. The user experiences seamless rule adherence without visual clutter or repetition.

How does the extension handle session compaction?

Session compaction can evict context entries including rule markers, but it preserves session entries. The i-have-adhd-state entry survives, allowing restoreState to recover the preference. syncContext then detects missing rules and restates them before the model processes new input.

Where is the actual rule content defined?

The human-readable rule set lives in skills/i-have-adhd/SKILL.md. This file's content is loaded into the RULES constant and injected whenever syncContext determines restatement is necessary.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →