How Cognitive Frames Are Defined and Used in ADHD: A Complete Technical Guide
Cognitive frames in ADHD are TypeScript objects that inject "vantage-point" system prompts into divergent LLM reasoning branches, forcing the model to explore solutions from 15+ distinct perspectives such as hardware engineer, 10-year-old, or adversarial hacker.
This deep dive examines how the ADHD repository (Attention-Driven Heuristic Design) implements cognitive frames as a core mechanism for breaking LLM convergent bias. You'll learn the exact data structures, selection algorithms, and engine integration patterns that enable multi-perspective ideation.
What Are Cognitive Frames in ADHD?
At their foundation, cognitive frames are lightweight instruction objects that recontextualize the same problem through radically different lenses. Rather than relying on a single chain-of-thought, ADHD spawns parallel reasoning branches—each "possessed" by a frame-specific persona.
The architecture serves one purpose: escape local optima in LLM reasoning by manufacturing perspectives the base model would not naturally inhabit.
Frame Definition: The TypeScript Interface
The canonical frame structure lives in [src/frames.ts](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts), declared at line 5:
export type Frame = {
id: string;
label: string;
prompt: string;
tags: ("code" | "design" | "general" | "wild")[];
};
| Property | Purpose |
|---|---|
| id | Machine-readable unique key for logging and reference |
| label | Human-readable persona name (e.g., "Hardware engineer", "10-year-old") |
| prompt | System-prompt fragment injected into the divergent branch |
| tags | Categorical filter for bias-guided selection |
The Built-in Frame Library
The repository ships with 15 pre-crafted frames in the FRAMES array. These cover technical, creative, naive, adversarial, and domain-specific vantage points. Examples include:
hardware-engineer— thinks in constraints, cost, and physicsregulator-auditor— compliance and safety-first perspective10-year-old— naive clarity, no assumptionsadversarial-hacker— threat modeling and exploit discoverybiologist— organic, evolutionary, systems-level thinking
Each frame's prompt field contains explicit instructions like "You are a hardware engineer obsessed with unit economics and thermal constraints. Generate ideas as this persona would."
Frame Selection Algorithm
The selectFrames(n, codeMode) function (lines 36-47) controls which frames activate per run:
// Simplified conceptual flow
function selectFrames(n: number, codeMode: boolean): Frame[] {
// 1. Filter by codeMode if enabled (prioritizes "code" and "design" tags)
// 2. Guarantee at least one "wild" tag inclusion for true divergence
// 3. Shuffle and return n frames
}
Key behaviors:
- Bias injection:
codeMode=trueweights technical frames higher - Wild-card requirement: Every selection includes at least one
wild-tagged frame to prevent over-optimization - Deterministic shuffling: Reproducible while maintaining variety across runs
This selector is re-exported from [src/index.ts](https://github.com/UditAkhourii/adhd/blob/main/src/index.ts) as part of the public API.
Engine Integration: Frames in Action
The orchestration layer in [src/engine.ts](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts) consumes frames to drive divergent generation.
Import and Setup
Line 18 imports the frame machinery:
import { selectFrames, Frame } from "./frames.js";
Runtime Selection
At line 349, the engine acquires active frames based on configuration:
const frames = selectFrames(framesPerRun, codeMode);
Per-Frame Execution Loop
For each selected frame, the engine:
- Constructs branch-specific system prompt: Merges frame
promptwith problem context - Spawns isolated LLM call: No cross-branch contamination
- Captures raw generation: Timestamped and tagged with frame
id
async function divergentCall(frame: Frame, problem: string) {
const systemPrompt = `${frame.prompt}\n\nProblem: ${problem}`;
return await LLM.generate({
system: systemPrompt,
temperature: 0.9 // elevated for exploration
});
}
Critic Phase: Frame-Agnostic Evaluation
After divergence, a separate critic pass operates on frame outputs. This phase:
- Scores ideas on novelty, feasibility, and alignment
- Clusters semantically similar proposals
- Prunes "trap" solutions (locally attractive, globally poor)
- Deepens surviving branches with refinement prompts
Critically, critic logic is frame-agnostic—it evaluates what was generated, not who generated it. This separation of concerns (divergent framing vs. convergent judgment) prevents frame bias from corrupting quality assessment.
Practical Code Examples
Creating and Registering a Custom Frame
import { Frame, FRAMES } from "./frames.js";
const quantumFrame: Frame = {
id: "quantum-thinking",
label: "Quantum-style thinker",
prompt: `You perceive problems as superpositions of possibility.
Generate 3 solutions that would work in parallel universes,
then collapse to the single most feasible variant in ours.`,
tags: ["design", "wild"]
};
// Runtime registration
FRAMES.push(quantumFrame);
Programmatic Frame Selection
import { selectFrames } from "./frames.js";
// Technical run: 4 frames, code-biased
const techFrames = selectFrames(4, true);
console.log(techFrames.map(f => `${f.label} [${f.tags.join(", ")}]`));
// Output: [ 'Hardware engineer [code]', 'Regulator/auditor [general]',
// 'Adversarial hacker [code, wild]', 'Biologist [design, wild]' ]
Engine-Level Integration Pattern
// Simplified excerpt from engine.ts execution loop
async function runDivergentPhase(problem: string, config: RunConfig) {
const frames = selectFrames(config.framesPerRun, config.codeMode);
const branchResults = await Promise.all(
frames.map(async frame => ({
frameId: frame.id,
output: await divergentCall(frame, problem),
metadata: { timestamp: Date.now(), tags: frame.tags }
}))
);
return branchResults; // Passed to critic phase
}
Key Files Reference
| File | Responsibility |
|---|---|
[src/frames.ts](https://github.com/UditAkhourii/adhd/blob/main/src/frames.ts) |
Frame type definition, FRAMES library, selectFrames() algorithm |
[src/index.ts](https://github.com/UditAkhourii/adhd/blob/main/src/index.ts) |
Public API re-exports for consumer modules |
[src/engine.ts](https://github.com/UditAkhourii/adhd/blob/main/src/engine.ts) |
Divergent execution orchestration, frame-to-LLM mapping |
documentation/frames.md |
Human-readable frame catalog and authoring guidelines |
Summary
- Cognitive frames are typed objects with
id,label,prompt, andtagsthat define reasoning personas - The 15 built-in frames span technical, naive, adversarial, and creative domains
- Selection algorithm enforces
wildtag inclusion and optionalcodeModebiasing - Engine integration maps each frame to an isolated LLM call with persona-prefixed system prompt
- Critic phase evaluates outputs without frame awareness, ensuring quality judgments remain unbiased
Frequently Asked Questions
How do I add a custom cognitive frame to ADHD?
Define a Frame-typed object and push it to the FRAMES array at runtime, or modify src/frames.ts directly for permanent inclusion. Ensure your prompt explicitly instructs the persona's perspective, and tag appropriately with code, design, general, or wild for proper selection routing.
Why does selectFrames() require at least one "wild" frame?
The wild-tag guarantee prevents codeMode or heavy filtering from collapsing diversity into safe, conventional perspectives. Wild frames (10-year-old, biologist, adversarial hacker) introduce cognitive friction that breaks LLM echo chambers and surfaces non-obvious solutions.
Can frames modify each other's outputs during generation?
No. Each frame executes in complete isolation with no cross-branch communication until the critic phase. This architectural constraint preserves the purity of each perspective and prevents premature convergence during ideation.
What's the performance cost of running multiple frames?
Cost scales linearly with framesPerRun—each frame equals one full LLM call. The repository provides no native parallelization throttling; implement your own semaphore if hitting rate limits. Trade-off: more frames = broader exploration + higher latency and token spend.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →