--- id: CMP-9 family: RT-CMP level: extended profiles: [runtime] posture: normative-target added: "1.0" changed: "1.0" source: https://flowdrop.io/spec/rules/rt-cmp/cmp-9 specification: FlowDrop Workflow Specification 1.0-draft licence: CC BY 4.0 --- # CMP-9 — Tool names are unique per consumer, checked at compile time *RT-CMP (Part II) · level: extended · profiles: runtime · added in 1.0* ## The rule > **Normative.** This is the rule. > > 1. For each node that consumes tools, the names of the tools wired to it must be unique across the flattened set of leaf tools it will see. > > 2. A collision refuses compilation. > > 3. Passthrough tools are exempt from this check and are checked at the consumer instead. ## What it means Two things about the check are easy to guess wrong. First, it is not scoped to the tools wired straight onto a node: the flattened set includes every tool reachable through any number of passthrough hops, so a collision two hops away is refused exactly as one on a direct wire would be, and a passthrough node's own name plays no part in it — only the leaf tools it forwards count, checked where they finally land. Second, the check is scoped to one node's own view, not to the workflow as a whole: the same name landing on two different nodes is not a collision at all. ## Example Two tools, reached by an agent through a passthrough box, whose labels look different but resolve to the same name: ```json title="Two tools reaching one node through a box" verdict="refused" { "nodes": [ { "id": "tool_a", "type": "http_request", "data": { "label": "Web Search" } }, { "id": "tool_b", "type": "http_request", "data": { "label": "web-search" } }, { "id": "box_1", "type": "toolbox", "data": { "label": "My Tools" } } ], "edges": [ { "source": "tool_a", "target": "box_1", "data": { "edgeType": "tool_availability" } }, { "source": "tool_b", "target": "box_1", "data": { "edgeType": "tool_availability" } }, { "source": "box_1", "target": "agent_1", "data": { "edgeType": "tool_availability" } } ] } ``` The same pair of labels causes no trouble at all once they sit on two different nodes instead of one: ```json title="The same tool name at two different consumers" verdict="accepted" { "nodes": [ { "id": "tool_a", "type": "http_request", "data": { "label": "Search" } }, { "id": "tool_b", "type": "http_request", "data": { "label": "Search" } } ], "edges": [ { "source": "tool_a", "target": "agent_1", "data": { "edgeType": "tool_availability" } }, { "source": "tool_b", "target": "agent_2", "data": { "edgeType": "tool_availability" } } ] } ``` ## Related rules - Names: CMP-10 - Referenced by: CMP-1, CMP-10 --- Rule identifiers are permanent and are never renumbered. This specification carries no implementation status: each implementation publishes its own standing against these rules. Licensed CC BY 4.0.