# ECP-0067: Control Transport Resolution And NixOS Control Wiring

Status: Implemented

## Decision

Add two pieces on top of ECP-0066:

1. `ec-node control-resolve`:
- resolve a `stream_id` from iroh-gossip control announcements,
- enforce freshness (`updated_unix_ms` + TTL / max age),
- choose transport by policy (`direct-first`, `relay-first`, direct-only, relay-only),
- emit machine-readable JSON for automation.

2. Extend the `services.every-channel.ec-node` NixOS module with `control.*` options that map directly to `wt-publish --control-announce` flags.

## Motivation

We already announce relay/direct transport availability, but consumers and deployment automation still need ad-hoc logic to pick a path. `control-resolve` makes this deterministic and scriptable.

For ops, control announcements should be configured as immutable host state in Nix, not hand-managed CLI flags on each machine.

## Scope

In scope:
- New `control-resolve` command in `ec-node`.
- Freshness + transport-preference policy in resolver.
- NixOS module options for control announce enable/ttl/interval/discovery/identity/peers.

Out of scope:
- Browser-native iroh direct transport.
- End-to-end automatic failover execution (resolve + launch subscribe) in one command.
- Cryptographic policy hardening beyond current control-topic trust model.

## Alternatives considered

- Keep transport selection in ad hoc shell logic. Rejected because policy behavior becomes inconsistent across operators.
- Wire control flags per host manually. Rejected because it is error-prone and not declarative.

## Rollout / Reversibility

- Additive only: existing relay and direct publish/subscribe paths remain unchanged.
- If needed, disable by not using `control-resolve` and leaving `services.every-channel.ec-node.control.enable = false`.
