Understanding the depth and parentId Fields in the ADHD Idea Type

The depth field tracks how many levels an idea sits below the root of a divergence tree, while parentId references the immediate ancestor idea that spawned it, together enabling hierarchical traversal and branching logic.

The ADHD (AI-driven Divergence-Heavy Design) tool models brainstorming as a tree of related concepts, where each node is an Idea type defined in src/types.ts. The depth and parentId fields serve as the structural backbone of this hierarchy, allowing the system to trace lineage, render visual trees, and prioritize which branches to expand.

What the depth Field Represents

The depth property is a numeric indicator that measures an idea's vertical position within the divergence hierarchy.

  • Value 0 marks a root divergence—the first-level split from the original problem statement with no ancestors.
  • Values 1, 2, … indicate ideas that have been deepened one or more levels, representing sub-ideas generated from earlier concepts.

This field serves multiple critical functions in the ADHD engine:

  1. Prioritization – The system uses depth to identify and expand the most promising branches when running divergence heuristics.
  2. Visualization – Rendering engines rely on depth values to create indented lists or tree diagrams that show conceptual nesting.
  3. Scoring context – Deeper ideas often reflect more refined or novel angles, allowing the scorers in src/engine.ts to weight abstraction levels appropriately.

According to the ADHD source code in src/types.ts, the property is declared with the explicit comment 0 = root divergence, 1+ = deepened【source】.

What the parentId Field Represents

The parentId field stores the id of the immediate predecessor from which the current idea was derived.

  • Definition – It contains the UUID string referencing the parent Idea that spawned this node during the divergence process.
  • Optionality – This field is deliberately omitted for root ideas (where depth = 0) because they have no ancestral node.
  • Traversal – By following parentId references, the engine can reconstruct full ancestry chains for back-tracking and explanation generation.

The parentId definition appears alongside depth in src/types.ts【source】, forming a lightweight pointer system that avoids storing full object references.

How depth and parentId Model the Divergence Tree

Together, these two fields create a standard tree structure without circular references:

Depth parentId Meaning
0 omitted Root idea (no parent)
1 root's UUID First-level child of the root
2 depth-1 idea's UUID Grandchild (sub-idea of a depth-1 idea)
n ancestor's UUID Further nesting follows the same pattern

When the engine executes a run via engine.run(...), it instantiates new Idea objects by assigning unique id values, computing depth based on the current recursion level, and recording the parentId of the spawning node. Later stages—including scoring, clustering, and deepening—navigate this graph efficiently using these hierarchical markers.

Working with Hierarchy in Code

Creating a Root Idea

Root ideas initialize the divergence process with depth: 0 and no parentId:

import { v4 as uuidv4 } from "uuid";

const rootIdea = {
  id: uuidv4(),
  frameId: "frame-1",
  text: "Enable voice-controlled navigation",
  depth: 0,          // root divergence
  // parentId omitted intentionally
};

Adding a Deepened Child Idea

Child ideas increment the depth and reference their parent's identifier:

const childIdea = {
  id: uuidv4(),
  frameId: "frame-2",
  text: "Integrate with speech-to-text API",
  depth: 1,               // one level deeper than the root
  parentId: rootIdea.id,  // reference to its parent
};

Traversing the Ancestry Chain

To reconstruct the lineage of any idea, map ids to objects and follow the parentId pointers:

function getAncestors(ideaId: string, ideas: Idea[]): Idea[] {
  const map = new Map(ideas.map(i => [i.id, i]));
  const lineage: Idea[] = [];
  let cur = map.get(ideaId);
  
  while (cur?.parentId) {
    const parent = map.get(cur.parentId);
    if (!parent) break;
    lineage.unshift(parent);
    cur = parent;
  }
  return lineage;
}

Rendering a Visual Tree

The src/render.ts utilities group children by their parentId to produce indented output:

function renderTree(ideas: Idea[]) {
  const byParent = new Map<string | undefined, Idea[]>();
  
  ideas.forEach(i => {
    const key = i.parentId ?? "root";
    if (!byParent.has(key)) byParent.set(key, []);
    byParent.get(key)!.push(i);
  });

  function render(nodeId: string | undefined, indent = 0) {
    const children = byParent.get(nodeId) ?? [];
    children.forEach(c => {
      console.log(" ".repeat(indent * 2) + "- " + c.text);
      render(c.id, indent + 1);
    });
  }

  render(undefined); // start at roots
}

Key Files Implementing These Fields

File Purpose
src/types.ts Declares the Idea interface including depth and parentId definitions
src/engine.ts Orchestrates idea generation and manages branching logic using these fields
src/render.ts Contains tree visualization utilities that parse the hierarchy
tests/llm.test.ts Validates idea creation and hierarchy behavior in the test suite

Summary

  • depth indicates vertical position in the divergence tree, where 0 represents root ideas and higher integers represent successive layers of refinement.
  • parentId stores the UUID of the immediate ancestor, omitted only for root nodes to maintain acyclic structure.
  • Together they enable efficient traversal, visual rendering, and intelligent branching in the ADHD brainstorming engine.
  • The implementation resides primarily in src/types.ts with consumption across src/engine.ts and src/render.ts.

Frequently Asked Questions

What happens if parentId references a non-existent idea?

The traversal logic in src/engine.ts and utility functions like getAncestors include null checks that break the chain if a parent lookup fails, preventing runtime errors while potentially logging warnings about orphaned nodes.

Can an idea have multiple parentId values?

No, the parentId field is singular by design. ADHD models strict hierarchical trees rather than directed acyclic graphs (DAGs), ensuring each idea has exactly one lineage path back to a root divergence.

Why is parentId optional in the TypeScript type?

The field is typed as optional (parentId?: string) specifically to accommodate root ideas at depth: 0, which logically have no parent. This design choice enforces referential integrity where only non-root nodes carry ancestral pointers.

How does the engine prevent infinite loops when deepening ideas?

The divergence process in src/engine.ts enforces depth limits and tracks visited id values during recursion. Since parentId references always point to shallower depths (lower numbers), the structure inherently prevents cycles by moving toward the root.

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 →