Repository navigation
Remove Container Concept - Use Root Node Detection Instead #531
Description
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:
container_node_id/containerId- Field that was removed in SurrealDB Schema Refactor: Graph-Native Architecture #511- "Container node" - Root node that holds children
update_container_from_markdown- MCP tool name_containerId- Transient field used in API (from Bug: Placeholder node loses focus immediately after typing, preventing text input #528 fix)
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_idreferences - ❌
_containerIdtransient field (use_parentIdonly, 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 APIsStep 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_idreferences removed -
_containerIdtransient 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 operationspackages/core/src/operations/mod.rs- Container validationpackages/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
- SurrealDB Schema Refactor: Graph-Native Architecture #511: Graph-native architecture (removed container_node_id field)
- Remove parent_id/container_node_id from Node API - Complete Graph Migration #514: Removed parent_id/container_id from Node API
- Bug: Placeholder node loses focus immediately after typing, preventing text input #528: Uses
_containerIdtransient field (should be removed) - Audit and Fix: Complete Parent Relationship Migration for Graph-Native Architecture #530: Parent relationship migration audit
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
malibio commentedon Nov 17, 2025
Combining with #530 into a single comprehensive issue