ADR-components-001
BaseCanvasNode as universal base class (Block/Node unification)
Context
The project has 6 separate base classes (BaseTool, BaseNodeSet, BaseSkill, BaseAgent, BasePolicy, BaseCanvasNode) with different interfaces. Tools, Skills, Policies are invisible on the canvas — separate concepts that can't be wired visually. Adding a new capability requires knowing which base class to use and which registration path to follow. The frontend requires 3 manual file edits per new node type because port information isn't shared from backend to frontend.
Decision
Make BaseCanvasNode the universal base class. BaseTool, BaseSkill, BasePolicy, BaseAgent all inherit from it. BaseEnv stays separate (it's the substrate, not a node). Key design choices: (1) Every node has kind ("block"|"composite"|"control"), description, icon, children (GraphDefinition|None), config_schema, input_ports, output_ports, initialize(), shutdown(). (2) Block = atomic function with execute(). Composite = contains children graph. Control = structural mechanics (IterIn, PortIn, etc.). (3) BaseTool keeps its execute(args) signature via execute_as_node() adapter — zero changes to 18+ existing tools. (4) GenericBlockRenderer on frontend auto-renders any block from backend port schemas — no custom .tsx needed. (5) Dynamic sidebar catalog generated from GET /api/navigate/inner-nodes. For groups of related tools, authors subclass BaseNodeSet instead — a nodeset bundles tools under shared lifecycle.
Alternatives
(a) Keep separate base classes, add a shared interface. (b) Full signature unification (break all existing tools).
Rationale
"Everything is a node" eliminates the classification problem — researchers don't need to know "is this a Tool or a Node?" One base class means one extension point, one registration path, one rendering system. The execute_as_node() adapter preserves backward compatibility with all existing tool implementations. GenericBlockRenderer closes the frontend extensibility gap: adding a capability becomes 1 Python file (auto-discovered, auto-rendered) instead of 4 files across frontend and backend.
Affected docs
concepts/base-canvas-node.md, architecture.md, glossary.md, roadmap.md, capabilities/customizable-node-system.md