Dynamic ports carry no exposure state and are not addressable from outside
Exposure is a property of a port the processor declares. A dynamic port is not declared, so there is nothing to hide and nothing to strip, and for the same reason nothing an outside caller can name.
The rule
- A dynamic port has no exposure: it is always wireable, its value is never stripped from a node's output, and edge validation raises no exposure objection against it.
- For the same reason a dynamic port is not addressable at the workflow boundary: a launch-input manifest entry naming one is refused, because the port is not declared by the node's processor.
What it means
A dynamic port carries none of the machinery an ordinary port carries: no default exposure, no per-instance override, nothing edge validation can weigh a wire against. The missing machinery does not fall on the cautious side — it is not treated as hidden. A dynamic port is always wireable, and a value produced under its name reaches the node's output exactly as produced, because there is no schema entry to strip it against.
The same absence cuts the other way at the workflow's outside edge. A launch-input manifest entry only succeeds against a port the node's processor actually declares, and a dynamic port is never declared by the processor. Naming one in the manifest is refused for that reason — the freedom a dynamic port enjoys inside a run does not extend to being something an outside caller can build a launch on.
Example
A node type hides one of its declared outputs. Alongside it, the node also produces a value under a name the type never declared at all:
{"result": "ok", "dynamic_field": "kept", "ssn": "secret"}{"result": "ok", "dynamic_field": "kept"}ssn, a declared output the node type does not expose, is the one key
removed. dynamic_field, declared nowhere, has no schema entry to be removed
against, so it passes through untouched.