How ADHD Detects and Prunes Traps (Broken Ideas) Using LLM Scoring
ADHD identifies broken ideas by prompting the LLM to flag hidden costs during scoring, then automatically excludes flagged "traps" from the shortlist while preserving them for user review.
The ADHD framework (Adaptive Divergent-Hybrid Decision-making) treats traps as ideas that appear attractive on the surface but conceal critical flaws—scalability limits, false economies, or unsustainable tradeoffs. This article explains how the UditAkhourii/adhd repository implements systematic trap detection and pruning through three coordinated pipeline stages.
Scoring Stage: LLM-Powered Trap Detection
Trap detection begins in engine.ts with a carefully engineered system prompt.
The SCORE_SYSTEM Prompt
Lines 82-86 define SCORE_SYSTEM, which instructs the LLM to return an optional trap field:
trap (optional): if the idea looks attractive but has a hidden cost ...
name it as a specific, actionable heads-up
This prompt structure ensures the model actively searches for disguised problems rather than glossing over them.
Score Parsing with Zod Validation
The scoreIdeas function (lines 14-27) processes LLM responses using Zod schema validation. Each returned JSON object populates a Score type that may include:
interface Score {
novelty: number;
viability: number;
fit: number;
strength: string;
trap?: string; // Optional trap description
}
Example LLM output:
{
"id": "websocket-central",
"novelty": 4,
"viability": 6,
"fit": 7,
"strength": "simple implementation",
"trap": "breaks after ~10k concurrent users"
}
Filtering Stage: Automatic Trap Exclusion
Once all ideas are scored, the engine performs semantic partitioning in lines 80-86 of engine.ts.
The Separation Logic
// Extract trapped ideas
const traps = allIdeas.filter((i) => i.score?.trap);
// Build ranked list excluding traps
const ranked = allIdeas.filter((i) => i.score && !i.score.trap);
// Final shortlist contains no traps
const shortlist = ranked.slice(0, topK);
This filtering guarantees that:
- Downstream processing (focus/deepen passes) only operates on viable candidates
- No trap accidentally reaches the final recommendation set
- All trapped ideas are preserved in a separate array for transparency
Why Separate Rather Than Delete?
ADHD preserves traps rather than discarding them because:
- User awareness: Teams can learn from rejected patterns
- Auditability: The decision trail includes why an idea failed
- Iterative refinement: A trap in one context may be solvable in another
Presentation Stage: Dedicated Trap Rendering
The render.ts module handles user-facing output through the renderText function (lines 60-66).
Terminal Output Structure
Traps appear under a distinct visual section:
// Simplified from render.ts lines 60-66
if (traps.length > 0) {
lines.push(`\nTraps (watch-outs, not verdicts)${"-".repeat(20)}`);
for (const t of traps) {
lines.push(` ${index++}. ${t.text}`);
lines.push(` ⚠️ ${t.score?.trap}`);
}
}
This presentation convention uses "watch-outs, not verdicts" language to signal that traps are heuristic flags, not absolute rejections.
Complete Working Example
The following runnable TypeScript demonstrates trap detection in practice:
import { run } from "./engine.js";
async function demo() {
const result = await run({
problem: "Create a realtime collaborative text editor",
framesPerRun: 4,
ideasPerFrame: 5,
topK: 3,
});
console.log("=== Trapped Ideas ===");
for (const trap of result.traps) {
console.log(`💡 ${trap.text}`);
console.log(` 👉 ${trap.score?.trap}`);
}
console.log("\n=== Shortlist (trap-free) ===");
for (const i of result.shortlist) {
console.log(`✔ ${i.text} (N${i.score?.novelty} V${i.score?.viability})`);
}
}
demo();
Sample output:
=== Trapped Ideas ===
💡 Use a central WebSocket server for all edits
👉 breaks after ~10k concurrent users
=== Shortlist (trap-free) ===
✔ Peer-to-peer CRDT sync (N9 V7)
✔ Operational transformation with selective persistence (N8 V8)
Implementation Files Reference
| File | Purpose | Key Location |
|---|---|---|
src/engine.ts |
Core orchestration: scoring, trap filtering, shortlist creation | Lines 14-27, 80-86 |
src/types.ts |
TypeScript definitions for Score with optional trap field |
Score interface |
src/render.ts |
Terminal output formatting with dedicated traps section | Lines 60-66 |
tests/llm.test.ts |
Unit tests verifying trap field parsing | Test suite |
Summary
- Detection: The
SCORE_SYSTEMprompt inengine.tsexplicitly solicits trap descriptions from the LLM - Storage: Traps populate the optional
Score.trapstring field, validated by Zod - Pruning: The filtering logic separates trapped ideas before shortlist construction (lines 80-86)
- Transparency:
render.tsdisplays traps distinctly, preserving visibility without polluting recommendations - Safety: Downstream "focus" and "deepen" passes operate exclusively on trap-free candidates
Frequently Asked Questions
What qualifies as a "trap" in ADHD?
A trap is any idea with a hidden cost that undermines its apparent value. Common patterns include scaling bottlenecks, legal risks, maintenance burdens, or false economies. The LLM identifies these during scoring based on the problem context and the explicit trap prompt instruction.
Can a trapped idea ever reach the final shortlist?
No. The filtering logic in engine.ts (line 83) builds ranked exclusively from ideas where !i.score.trap is true. The shortlist array is sliced from this pre-filtered list, making trap inclusion architecturally impossible without code modification.
How does ADHD handle ambiguous trap classifications?
When the LLM returns a trap value, ADHD treats it as definitive for exclusion purposes. However, the "watch-outs, not verdicts" framing in render.ts reminds users that these are heuristic flags from language model inference. Teams can manually review traps via the result.traps array and override decisions outside the automated pipeline.
Is trap detection configurable or disableable?
The current implementation in UditAkhourii/adhd has hardcoded trap detection as part of the core scoring protocol. The SCORE_SYSTEM prompt (lines 82-86) always requests trap analysis. To disable trap detection, you would need to modify the prompt and remove the filtering logic in the scoreIdeas flow.
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 →