# C26 — Harness input binding: role names bind archive columns **Guarantee.** A strategy blueprint declares WHICH data it consumes as the NAMES of its root input roles: a role whose name is in the **closed column vocabulary** — `open`, `high`, `low`, `close`, `spread`, `volume`, plus `price` as the backward-compatible alias of `close` — binds by default to that column of the campaign cell's (or run invocation's) instrument. A campaign document may **override** the name default per role via the additive `data.bindings` block (`role name → column name`; serde `default` + skip-if-empty, so binding-less documents keep their content ids) — the 6b rebind seam: the blueprint's content identity never changes. Resolution (`aura-runner`'s `binding` module, `resolve_binding`) produces ONE ordered plan consumed by BOTH halves of the old weld: the columns are opened (`aura_ingest::open_columns`, the generalization of `open_ohlc`/#92) and the wrapped root roles declared (`aura-runner::member`'s `wrap_r`) in the **same canonical order** — `M1Field` declaration order (open, high, low, close, spread, volume), filtered to the consumed set — which is the [C4](c04-cycle-granularity.md) merge tie-break order, so role *i* receives source *i* by construction. A close column is always part of the plan (shared when the strategy consumes `close`/`price`, else opened for the broker/executor pair alone). The vocabulary is **Blockly-litmus-clean** ([C25](c25-role-model.md)): role-name slots draw from a closed enum, the bindings block is typed `role → column` with no free-form holes, and validation is two-tier — values against the column vocabulary in the intrinsic tier (`validate_campaign`, `aura-research`), keys against the strategies' `input_roles()` in the resolver tier (`validate_campaign_refs`, `aura-registry`). **Forbids.** Guessing a column for an unknown role name (refuse with the vocabulary + the override remedy, never default); opening columns in any order other than the canonical declaration order (the [C4](c04-cycle-granularity.md) tie-break contract); free-form or logic-bearing binding values (the [C17](c17-authoring-surface.md)/[C25](c25-role-model.md) line — a binding value is a typed column reference, nothing else); fabricating synthetic OHLC when a multi-column strategy meets synthetic data (the walk generates a close series only — refuse with the `--real` remedy). **Why.** The single-price weld — `wrap_r`'s hard-wired `price`←close and the six `M1Field::Close`-only open sites — made every strategy monocular regardless of what its blueprint declared. Binding by role name keeps the blueprint the single source of its own data needs ([C24](c24-blueprint-data.md): topology-as-data carries its input contract), lets a campaign re-aim a strategy without touching its content id ([C18](c18-registry.md) identity), and pins opening and declaring to one shared, canonically-ordered plan so the two halves cannot drift ([C1](c01-determinism.md)/[C4](c04-cycle-granularity.md) determinism). ## Current state `resolve_binding` lives in `aura-runner`'s `binding` module (`crates/aura-runner/src/binding.rs`), moved out of the shell with #295; it takes the strategy name, its `input_roles()`, and the campaign override map and returns one `ResolvedBinding` plan. Column opening is `aura_ingest::open_columns` (`crates/aura-ingest`; the `M1Field` enum fixes the declaration order open/high/low/close/spread/volume); role declaration is `wrap_r` in `aura-runner::member`. Both validation tiers are realized: `validate_campaign` (`crates/aura-research`) checks binding values against the column vocabulary; `validate_campaign_refs` (`crates/aura-registry`) checks binding keys against the strategy's declared roles. **Extension point (deferred).** When recorded non-price sources land (the #71 Source seam), the binding VALUE-space grows additively from archive columns to recorded-stream references — a root role like `sentiment` becomes bindable to a recorded stream then, and until then refuses with the vocabulary-naming message. The role-name key-space and the campaign `bindings` carrier are unchanged by that growth. ## See also - [C4](c04-cycle-granularity.md) — the merge tie-break order that is the canonical open/declare order - [C24](c24-blueprint-data.md) — topology-as-data carrying its own input contract - [C18](c18-registry.md) — the content-id identity a rebind must not touch - [C25](c25-role-model.md) — the Blockly litmus the vocabulary satisfies; the 6b rebind seam - [C1](c01-determinism.md) — the determinism the shared plan protects - [C27](c27-declared-taps.md) — the output-side twin (`taps` to `input_roles`)