Skip to content

Remove Container Concept - Use Root Node Detection Instead #531

Closed as not planned

Description

@malibio

Remove Container Concept - Use Root Node Detection Instead

Problem

The codebase still uses "container" terminology and containerId/container_node_id concepts from the old field-based architecture. In the graph-native architecture (#511), this concept is obsolete - a "container" is simply a root node (node with no parent), detected via graph queries.

Current Container Usage

Terminology found in codebase:

What "container" actually means:

  • Root node in a tree (no parent)
  • Detected by: !EXISTS(<-has_child<-node) (no incoming edges)
  • Examples: Date nodes, document roots

Why It's Confusing

Old architecture (field-based):

{
    parent_id: "some-parent",
    container_node_id: "root-node",  // Denormalized field for scoping
}

New architecture (graph-native):

{
    // No fields needed!
    // Parent: Query via <-has_child<-node
    // Root: Detected via !EXISTS(<-has_child<-node)
}

The term "container" is misleading because:

  • ❌ Implies a special node type (it's not - any node can be a root)
  • ❌ Suggests a separate concept from "parent" (it's just the tree root)
  • ❌ Perpetuates old field-based thinking

Proposed Solution

Replace "Container" with Clear Terminology

Use:

  • "Root node" - Node with no parent (!EXISTS(<-has_child<-node))
  • "Parent node" - Immediate parent in tree
  • "Ancestor node" - Any node up the tree
  • "Tree root" - Top-level node in a hierarchy

Remove:

  • ❌ "Container node"
  • ❌ containerId / container_node_id references
  • ❌ _containerId transient field (use _parentId only, or better approach)

Implementation

Step 1: Audit All Container References

Search for:

grep -rn "container\|Container" packages/ --include="*.rs" --include="*.ts" --include="*.svelte"

Categorize each reference:

  • Category A: Can be replaced with "root node"
  • Category B: Actually means "parent node"
  • Category C: Domain-specific (keep if truly needed)

Step 2: Update Terminology

Backend (Rust):

// BEFORE
fn get_container_node(container_id: &str) -> Result<Node>
fn is_container_node(node: &Node) -> bool
update_container_from_markdown(container_id, markdown)

// AFTER
fn get_root_node(root_id: &str) -> Result<Node>
fn is_root_node(node_id: &str) -> Result<bool>  // Uses graph query
update_tree_from_markdown(root_id, markdown)

Frontend (TypeScript):

// BEFORE
interface Node {
    containerId?: string;  // ❌ Remove
}
_containerId?: string;  // ❌ Remove transient field

// AFTER
// No container fields at all!
// Parent relationship via _parentId only (if needed temporarily)
// Or better: use dedicated hierarchy APIs

Step 3: Replace Scoping Queries

Old way (using container_id for scoping):

SELECT * FROM nodes WHERE container_node_id = $id;

New way (using graph traversal):

-- Get all descendants of root
SELECT ->has_child->node.{..} FROM node:⟨$root_id⟩;

-- Get all nodes in current tree (for mention autocomplete)
LET $root = (
    SELECT <-has_child<-node.{..} FROM node:⟨$current⟩
    WHERE !EXISTS(<-has_child<-node)
    LIMIT 1
);
SELECT ->has_child->node.{..} FROM $root;

Step 4: Update MCP Tool Names

MCP tools to rename:

// BEFORE
"update_container_from_markdown"
"get_container_node"

// AFTER
"update_tree_from_markdown"
"get_root_node"

Maintain backward compatibility (optional):

// Keep old names as aliases temporarily
"update_container_from_markdown" => handle_update_tree_from_markdown,  // Deprecated
"update_tree_from_markdown" => handle_update_tree_from_markdown,

Step 5: Update Documentation and Comments

Files to update:

  • All architecture docs mentioning "container nodes"
  • Code comments explaining container concept
  • API documentation
  • Error messages using "container" terminology

Acceptance Criteria

Terminology Cleanup

  • All "container node" references replaced with "root node"
  • containerId / container_node_id references removed
  • _containerId transient field removed
  • Function/variable names updated (get_container → get_root)
  • MCP tool names updated or aliased

Functional

  • Root node detection uses graph queries (!EXISTS(<-has_child<-node))
  • Tree scoping uses graph traversal (not container_id field)
  • Mention autocomplete scoping works with graph queries
  • All existing functionality works (no regressions)

Documentation

  • Architecture docs updated (no "container" concept)
  • Code comments updated
  • API docs use consistent terminology
  • Error messages updated

Testing

  • All tests updated to use new terminology
  • Root node detection tests
  • Tree traversal tests
  • No broken references to old "container" concept

Impact Analysis

Files likely affected (based on grep):

  • packages/core/src/mcp/handlers/markdown.rs - Container markdown operations
  • packages/core/src/operations/mod.rs - Container validation
  • packages/desktop-app/src/lib/services/*.ts - Container references
  • Documentation files

Breaking changes:

  • MCP API: update_container_from_markdown → update_tree_from_markdown
  • Internal APIs: Various function renames

Mitigation:

  • Add deprecation warnings for old MCP tool names
  • Maintain aliases for 1-2 releases
  • Update all internal callers

Why This Matters

Clarity: "Container" is ambiguous - does it mean parent? root? scope?
Graph semantics: In graph databases, we think in terms of roots, ancestors, descendants
Consistency: Aligns terminology with graph-native architecture
Future-proofing: Reduces confusion for new developers

Related Issues

Estimated Effort

  • Audit: 2-3 hours (find all container references)
  • Rename/refactor: 4-6 hours (update code and tests)
  • Testing: 2-3 hours (verify no regressions)
  • Documentation: 1-2 hours (update docs and comments)
  • Total: 9-14 hours (1-2 days)

Priority

Medium - Cleanup/tech debt, not blocking core functionality, but important for code clarity and maintainability.

Activity

  1. malibio commented on Nov 17, 2025

    @malibio
    CollaboratorAuthor

    Combining with #530 into a single comprehensive issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions