--- id: RT-TOOL-3 family: RT-TOOL level: extended profiles: [runtime] posture: normative-target added: "1.0" changed: "1.0" source: https://flowdrop.io/spec/rules/rt-tool/rt-tool-3 specification: FlowDrop Workflow Specification 1.0-draft licence: CC BY 4.0 --- # RT-TOOL-3 — Artifacts leave a tool call on their own port, apart from the model's prose *RT-TOOL (Part II) · level: extended · profiles: runtime · added in 1.0* ## The rule > **Normative.** This is the rule. > > 1. A node that invokes tools surfaces every call's artifacts on a dedicated `tool_artifacts` output port, as a list of exactly `{type, payload, tool_call_id}` entries built key by key, so a tool can neither override the real `tool_call_id` nor smuggle keys of its own through. > > 2. That port is not exposed by default. > > 3. The prose fed back to the model is built from a result's `data` alone and never from its artifacts. > > 4. Delivery of a run's artifacts must not depend on whether the author exposed the port. ## What it means The prose the model reads back is built from `data` alone — an artifact never leaks into it, even as a stray mention of a URL or a name that also appears in the artifact's payload. The two travel on entirely separate paths: prose in the tool message, artifacts on `tool_artifacts`, paired to the call that produced them by `tool_call_id` so a node invoking several tools at once can still tell whose artifact is whose. That port carries the artifacts whether or not the author exposed it — delivery does not wait on an exposure decision that governs only what a person sees in an editor. ## Example One tool call returns a result whose `data` is a short confirmation string and whose artifact is a link the confirmation never mentions. ```json title="What the tool result carries" verdict="produced" { "data": { "result": "Created node 5 (draft)." }, "artifacts": [{ "type": "link", "payload": { "url": "https://example.com/node/5" } }] } ``` ```json title="What lands on the node's tool_artifacts port" verdict="surfaced" [{ "type": "link", "payload": { "url": "https://example.com/node/5" }, "tool_call_id": "c1" }] ``` The prose fed back to the model stays `"Created node 5 (draft)."` — nothing about the link appears in it. ## Related rules - Names: RT-TOOL-2, RT-TOOL-4 - Referenced by: RT-TOOL-2, RT-TOOL-4 --- 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.