How ADHD Detects and Flags Traps in Generated Ideas
ADHD detects traps using a two-stage diverge-critic architecture where the LLM identifies hidden-cost risks during the scoring pass, storing them in a dedicated trap field that the engine surfaces separately from shortlisted ideas.
The open-source idea generation engine ADHD (UditAkhourii/adhd) helps engineers avoid seductive but unviable designs by explicitly detecting and flagging "traps" during the evaluation phase. This capability relies on a structured scoring schema and targeted prompting that forces the LLM to articulate hidden costs. Understanding how ADHD detects and flags traps reveals how the system prioritizes shippable solutions over prototypes that fail at scale.
The Diverge-Critic Architecture
ADHD operates on a two-stage pipeline: first, it diverges to generate candidate ideas, then it employs a critic pass to score them. Trap detection occurs exclusively during the critic (scoring) pass, where the LLM evaluates each idea for hidden risks that appear attractive but carry unanticipated costs. This separation ensures that generation remains creative while evaluation remains skeptical.
Schema Design for Trap Capture
The ScoreRowSchema Definition
In src/engine.ts, the scoring schema explicitly reserves space for trap identification. The ScoreRowSchema defined at lines 35-40 includes an optional trap string field that the LLM may populate with a one-line reason why an idea looks appealing but is risky. This schema structure ensures that every scored idea has the capacity to carry a warning without breaking the type contract.
The System Prompt Instruction
The system prompt used for the critic pass, defined as SCORE_SYSTEM in src/engine.ts at lines 82-86, explicitly instructs the model to add a "trap" entry for any idea that "looks attractive but has a hidden cost." This prompt engineering ensures the LLM consistently considers failure modes during evaluation rather than focusing solely on novelty.
Extracting and Filtering Trapped Ideas
After the LLM returns the JSON array of scores, the scoreIdeas function (lines 22-27 in src/engine.ts) parses each row and stores the trap value on the Score object if present. The engine then builds the final output by separating concerns:
- Shortlisted ideas compete for the final selection based on weighted scores
- Traps are filtered into a separate list by checking where
score.trapis defined (lines 80-82 insrc/engine.ts)
This filtering explicitly excludes trapped ideas from the shortlist, ensuring that only viable candidates appear in the final recommendations while preserving the warnings for developer review.
Viability Weighting as Trap Prevention
The scoring algorithm weights viability higher than other factors to prevent traps from achieving high scores in the first place. In src/engine.ts at lines 16-18, the scoreIdeas implementation assigns viability a coefficient of 0.4 because, as the source code comments, "a brilliant unshippable idea is a trap." This mathematical prioritization ensures that novel but impractical concepts score lower than boring but buildable alternatives, while the explicit trap field still surfaces the specific risk for transparency.
Working with Traps in Practice
The trap field declared in src/types.ts on the Score and Idea types allows the rendering logic in src/render.ts to display warnings via dim(t.score?.trap). You can access trapped ideas programmatically through the engine's output:
import { run } from "./engine.js";
const result = await run({
problem: "Design a highly-available caching layer for a microservice",
topK: 3,
});
// `result.traps` holds all ideas that the critic marked as traps
for (const t of result.traps) {
console.log(`⚠️ Trap: ${t.text}`);
console.log(` Reason: ${t.score?.trap}`);
}
// Example output:
// ⚠️ Trap: "Cache everything in memory for ultra-low latency"
// Reason: solid for a prototype, breaks past 10k concurrent users
Summary
- Two-stage architecture: Trap detection occurs during the critic pass, not generation.
- Schema support:
ScoreRowSchemainsrc/engine.ts(lines 35-40) defines the optionaltrapstring field. - Prompt engineering:
SCORE_SYSTEMexplicitly requests trap identification for attractive but costly ideas. - Separation logic: Lines 80-82 in
src/engine.tsfilter trapped ideas intoresult.traps, excluding them from the shortlist. - Preventive weighting: Viability carries a 0.4 coefficient to mathematically de-prioritize unshippable ideas.
Frequently Asked Questions
What qualifies as a "trap" in ADHD?
A trap is an idea that appears attractive on the surface but contains a hidden cost or scalability limitation that makes it risky to implement. The system specifically flags concepts that work for prototypes but fail under production load, such as caching strategies that break at high concurrency.
How does the scoring schema accommodate trap detection?
The ScoreRowSchema defined in src/engine.ts includes an optional trap property of type string. This schema allows the LLM to return a one-line explanation of the risk without requiring every idea to have a trap, creating a flexible type system where warnings exist only when relevant.
Why does ADHD separate traps from the shortlist?
The engine filters trapped ideas into a dedicated traps array (lines 80-82 in src/engine.ts) and explicitly excludes them from the shortlisted candidates. This separation ensures that the final selection pool contains only viable options while preserving trap warnings as actionable feedback for developers to review separately.
How does viability weighting help prevent traps?
The scoring algorithm in scoreIdeas assigns viability a weight of 0.4, higher than other criteria, because the source code recognizes that "a brilliant unshippable idea is a trap." This mathematical prioritization ensures that ideas with high novelty but low practicality receive lower overall scores, reducing the chance they appear in final recommendations.
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 →