FlowDrop Workflow Specification 1.0-draft

Artifacts leave a tool call on their own port, apart from the model's prose

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.

What the tool result carriesproduced
{
  "data": { "result": "Created node 5 (draft)." },
  "artifacts": [{ "type": "link", "payload": { "url": "https://example.com/node/5" } }]
}
What lands on the node's tool_artifacts portsurfaced
[{ "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.

Rule identifiers are permanent and are never renumbered. Each implementation publishes its own standing against these rules; this specification does not.spec 1.0-draft · RT-TOOL-3 · changed in spec 1.0