--- id: R4.d family: GR-VAL level: core profiles: [storage-api] posture: normative-target added: "1.0" changed: "1.0" source: https://flowdrop.io/spec/rules/gr-val/r4-d specification: FlowDrop Workflow Specification 1.0-draft licence: CC BY 4.0 --- # R4.d — An exposure entry must name a port the node declares *GR-VAL (Part I) · level: core · profiles: storage-api · added in 1.0* ## The rule > **Normative.** This is the rule. > > 1. A workflow exposure entry's `port` must be declared by the named node: as an input parameter for an entry on the input side, as an output for one on the output side. > > 2. An entry naming an undeclared port is refused at `schema.{side}.{index}`. > > 3. Where the node's executor cannot be resolved the port cannot be checked, so this check and R10 are skipped for that entry rather than guessed at; the skip is narrower than the entry, and R4.a's name format and R4.b's uniqueness (both decided from the entry alone) are still reported. ## What it means The skip this rule allows is narrower than it sounds. Losing the ability to resolve a node's declared ports only silences this one check and R10; it does not silence R4.a's name-format check or R4.b's uniqueness check, both of which are decided from the entry's own fields and need nothing from the node. An entry can therefore fail on its name at the same time its port check is skipped for want of a resolvable node — one refusal, not a cascade of guesses about a port that was never checked. ## Example An exposure entry naming an unresolvable node, with a name that also fails the format check: ```json title="An exposure entry on a node whose executor can't be resolved" verdict="checked" { "name": "Bad Name", "node_id": "n1", "port": "no_such_port" } ``` ```json title="The two errors reported for that entry" verdict="reported" ["R1_PLUGIN_MISSING", "R4_NAME_FORMAT"] ``` `R4_PORT_MISSING` does not appear: with no resolvable executor there is no port list to check the entry's `port` against, so this check stays silent while the name-format complaint still reaches the caller. ## Related rules - Names: R4.a, R4.b, R10 - Referenced by: R4.c, R10 --- 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.