# What Is the Context Compatibility Layer and Why Is It Necessary?

> Understand the context compatibility layer, a runtime abstraction that unifies session manager APIs for consistent conversation context access across Pi, OMP, and Claude Code runtimes.

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

---

**The context compatibility layer is a runtime abstraction module in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) that normalizes different session manager APIs across Pi, OMP, and Claude Code runtimes to provide uniform access to conversation context.**

The `i-have-adhd` extension must maintain consistent behavior across multiple AI assistant execution environments. Without this layer, the plugin would require platform-specific code branches for every runtime, creating maintenance overhead and fragile dependencies on unstable internal APIs.

## Why Multiple Runtimes Need a Compatibility Layer

Different AI assistant runtimes expose conversation history through incompatible interfaces. **OMP** provides `sessionManager.buildSessionContext()`, which returns an object containing a `messages` array, while the **Pi** runtime uses `sessionManager.buildContextEntries()` to return an array of "entries" directly. Older or custom runtimes may not expose either method, or may implement variations with different return shapes.

This fragmentation creates a fundamental problem: the extension cannot reliably determine what the model currently "knows" without inspecting runtime-specific internals. A direct call to `buildSessionContext()` on Pi would throw an error, while expecting `buildContextEntries()` on OMP would return undefined.

## How the Context Compatibility Layer Works

The layer exposes two primary utilities that shield the rest of the codebase from runtime differences.

### Normalizing Context Access with `contextMessages`

The `contextMessages(sessionManager)` function (lines 12‑39 of [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts)) probes the provided session manager to detect which API variant exists. It calls the appropriate method—whether `buildSessionContext()` or `buildContextEntries()`—and normalizes the result to a plain `ContextMessageMarker[]` array. If the runtime throws an exception or returns an unexpected shape, the function catches the error and safely returns an empty array.

This normalization ensures that downstream logic always receives a consistent data structure regardless of the underlying runtime implementation.

### Detecting Active Rules with `latestMarkerIsActive`

The `latestMarkerIsActive(messages, activeType, disabledType)` function (lines 41‑61) analyzes the normalized message array to determine the current state of the ADHD ruleset. It scans for custom markers (identified by `role: "custom"` or `type: "custom_message"`) and compares the most recent marker's type against the active identifier (`"i-have-adhd-rules"`) and disabled identifier (`"i-have-adhd-disabled"`).

The function returns `true` only if the latest relevant marker matches the active type, allowing the extension to determine whether the rules are currently injected into the model's context without knowing how the runtime stores those markers internally.

## Fail-Open Design for Cross-Platform Stability

Both utilities implement a **fail-open** strategy that catches all errors and returns empty results rather than propagating exceptions. If a runtime updates its API or a method is temporarily unavailable, the extension continues to function rather than crashing during initialization.

This defensive design is essential for a plugin that must survive future runtime updates and operate across platforms with divergent release cycles. The safety guarantees are validated in [`scripts/check_context_compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/scripts/check_context_compat.ts) (lines 15‑34), which tests the compatibility functions against mock implementations of both OMP and Pi managers.

## Implementation Example

The following pattern appears in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 101‑108) to conditionally inject or remove the ADHD ruleset based on current context state:

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

const RULES = "i-have-adhd-rules";
const DISABLED = "i-have-adhd-disabled";

// Retrieve normalized messages from any runtime
const msgs = contextMessages(sessionManager);

// Check if ADHD rules are currently present
const rulesActive = latestMarkerIsActive(msgs, RULES, DISABLED);

if (rulesActive) {
  console.log("ADHD rules are present in the model context.");
} else {
  console.log("ADHD rules have been removed or disabled.");
}

```

## Summary

- The `contextMessages` function in [`extensions/context-compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/context-compat.ts) abstracts differences between Pi's `buildContextEntries()` and OMP's `buildSessionContext()`, returning a normalized `ContextMessageMarker[]`.
- The `latestMarkerIsActive` function determines whether `"i-have-adhd-rules"` or `"i-have-adhd-disabled"` markers are currently active in the conversation context.
- Fail-open error handling ensures the extension starts successfully even when runtime APIs change or are unavailable.
- This architecture allows the `i-have-adhd` extension to maintain consistent behavior across all supported platforms without runtime-specific code branches.

## Frequently Asked Questions

### Which runtimes does the context compatibility layer support?

The layer explicitly handles **OMP**, **Pi**, and **Claude Code** runtimes. For older or custom runtimes that lack the expected session manager methods, it gracefully degrades by returning empty arrays, ensuring the extension remains functional even on unsupported platforms.

### What happens if the session manager API changes in a future runtime update?

The fail-open design catches all exceptions and returns empty arrays when APIs are missing or changed. This prevents the extension from crashing during initialization while allowing it to continue operating in a degraded state until the compatibility layer is updated.

### How does the layer determine if ADHD rules are currently active?

The `latestMarkerIsActive` function scans the normalized message array for markers with `role: "custom"` or `type: "custom_message"`. It returns `true` only if the most recent marker of relevance has the type `"i-have-adhd-rules"` rather than `"i-have-adhd-disabled"`, accurately reflecting whether the ruleset is presently injected into the model's context window.

### Where is the context compatibility layer used in the codebase?

The layer is imported and utilized in [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) (lines 101‑108) to synchronize the ruleset state with the model context, and it is unit-tested in [`scripts/check_context_compat.ts`](https://github.com/ayghri/i-have-adhd/blob/main/scripts/check_context_compat.ts) (lines 15‑34) against mock session managers simulating both OMP and Pi behaviors.