A workflow may not expose a port hidden on its node
Hidden means hidden in both directions. R7 stops an edge reaching a hidden port; R10 stops the workflow's public surface reaching one.
The rule
- A workflow exposure entry must name a port that is exposed on the target node instance, resolved through the same chain as R7.c: the instance's
config.ports[].exposedwhere it sets one, otherwise the node type'sexposedByDefault. - An entry naming a hidden port is refused with
R10_EXPOSURE_HIDDEN_PORT, and the error names the workflow port, the node and the node's port. - A port the node type's metadata does not declare is out of scope, mirroring R7.d.
- R10 and R7 are disjoint by construction (R7 judges edges, R10 judges exposure entries), so one hidden port never earns one exposure entry two reports.
What it means
An exposure entry is judged against the port's exposure as it stands after the instance override is applied, not against the node type's own default in isolation. A port the node type hides by default is not permanently out of reach: an instance that turns it back on legalises every exposure entry naming it, exactly as R7.c resolves the same chain for edges. The reverse also holds — an instance can hide a port the node type exposes by default — so neither the type's default nor the presence of an exposure entry, on its own, says whether the entry is refused.
Example
A node type declares its error output hidden by default, and the workflow
exposes it anyway:
{ "name": "err", "node_id": "s", "port": "error" }The same entry, once the node instance turns that output back on:
{ "ports": { "outputs": [{ "id": "error", "exposed": true }] } }Why
Recorded under OPEN-2.