# Phase 15: WiFi/DDP Fallback and Transport Selection - Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-04-19
**Phase:** 15-wifi-ddp-fallback-and-transport-selection
**Areas discussed:** Transport selection logic, DDP target config, VID/PID auto-detect behavior, `status` command output format

---

## Gray Area Selection

| Option | Description | Selected |
|--------|-------------|----------|
| Transport selection logic | VRSettings pin-one vs auto-fallback; LedController ownership | ✓ |
| DDP target config | IP vs hostname vs mDNS discovery; port; conn semantics | ✓ |
| VID/PID auto-detect behavior | SetupDi scan; manual override interaction; multi-device | ✓ |
| `status` command output format | Key=value vs multi-line vs JSON; field set | ✓ |

---

## Transport selection logic

### Q1: Transport selection model — how does driver pick USB vs DDP?

| Option | Description | Selected |
|--------|-------------|----------|
| VRSettings enum, strict | `usb | ddp | auto`. Strict explicit values; `auto` = USB-first then DDP. | ✓ |
| VRSettings enum, no auto | `usb | ddp` only. No fallback. Simpler state machine. | |
| Always USB, DDP silent fallback | Hardcoded priority; no VRSettings knob (violates TRNS-03). | |

### Q2: Runtime transport switching

| Option | Description | Selected |
|--------|-------------|----------|
| Restart required (init-time only) | Read VRSettings once at driver load. | ✓ |
| VRSettings hot-reload only | Poll key change, swap transport live. | |
| Pipe command + VRSettings hot-reload | Most flexible; expands pipe surface. | |

### Q3: Unreachable transport fail state

| Option | Description | Selected |
|--------|-------------|----------|
| Degraded disabled (same as Phase 14 D-15) | Log INFO, mark disabled, `ERR backglow disabled` on pipe. | ✓ |
| Degraded + periodic retry only | No hotplug; periodic background retry every N seconds. | |

### Q4: Auto-fallback trigger

| Option | Description | Selected |
|--------|-------------|----------|
| At startup only | USB Open fail → try DDP once, then stay on DDP. | ✓ |
| Startup + mid-session USB drop | Migrate to DDP on N reconnect failures. | |
| N/A (no `auto` mode) | Only relevant if auto mode rejected in Q1. | |

---

## DDP target config

### Q1: DDP target host

| Option | Description | Selected |
|--------|-------------|----------|
| VRSettings IP string | `backglow.ddp_host` = raw IPv4. | ✓ |
| VRSettings hostname or IP | DNS/mDNS resolved. | |
| mDNS scan + VRSettings override | Zero-config auto-discovery. | |

### Q2: DDP port

| Option | Description | Selected |
|--------|-------------|----------|
| Fixed 4048 (WLED default) | Hardcoded per TRNS-02. | ✓ |
| VRSettings `backglow.ddp_port`, default 4048 | Override knob. | |

### Q3: DDP connection semantics

| Option | Description | Selected |
|--------|-------------|----------|
| Host reachable at startup = connected | Open() = socket bind + one probe + fire-and-forget. | ✓ |
| Periodic heartbeat | Writer thread pings WLED JSON periodically. | |
| Never disconnected, no probe | Once socket bound, always connected. | |

### Q4: LED count for DDP

| Option | Description | Selected |
|--------|-------------|----------|
| Fixed 10 (kBackglowMaxLeds) | Lock to LedController surface. | |
| Query WLED via JSON at Open() | `/json/info` yields strip length. | ✓ |

**Notes:** Combined with Q3, the single `GET /json/info` at Open() serves as both the reachability probe and the LED count query.

---

## VID/PID auto-detect behavior

### Q1: COM port resolution order when transport = USB

| Option | Description | Selected |
|--------|-------------|----------|
| Manual override wins, scan fills blank | com_port set → use it; blank → scan. | |
| Scan always, VRSettings ignored unless no match | Auto first, config fallback. | |
| Scan always, VRSettings removed | Deprecate com_port key. | |
| **Other (user free text)** | **Manual override wins, fallback to scan if manual port cnx fails** | ✓ |

**User notes:** Manual override wins, fallback to scan if manual port cnx fails.

**Interpretation:** `backglow.com_port` is tried first when set; if `Open()` fails on that port, driver falls through to VID/PID scan. If key is blank, scan directly.

### Q2: Multi-device disambiguation

| Option | Description | Selected |
|--------|-------------|----------|
| First match wins + log WARN | Lowest COM number; list candidates. | ✓ |
| Probe each with 'v' until WLED responds | Adalight version probe per candidate. | |
| Fail = degraded, require explicit override | Refuse to pick; user intervention required. | |

### Q3: Scan trigger

| Option | Description | Selected |
|--------|-------------|----------|
| Init + DBT_DEVICEARRIVAL hotplug | Re-scan on arrival notification if disabled. | ✓ |
| Init only | One-shot at driver load. | |

### Q4: TPM2 stub fate

| Option | Description | Selected |
|--------|-------------|----------|
| Keep stub as-is (D-08a) | No Phase 15 work on TPM2. | ✓ |
| Delete stub | Remove unused weight. | |
| Promote to functional implementation | Expand scope. | |

---

## `status` command output format

### Q1: Output format

| Option | Description | Selected |
|--------|-------------|----------|
| Single-line key=value | `OK transport=usb conn=open port=COM5 ...` | |
| Multi-line human-readable | Aligned columns, newline-separated. | ✓ |
| JSON | Machine-friendly structured. | |

**User selected preview:**
```
transport: usb
conn:      open
port:      COM5
bri:       50
ceiling:   50
color:     FF8000
leds:      10
```

### Q2: Fields in `status` (multi-select)

| Option | Description | Selected |
|--------|-------------|----------|
| transport + conn state | Core DIAG-01. | ✓ |
| port/host identifier | `port=COM5` or `host=192.168.1.42`. | ✓ |
| brightness + ceiling | Clamping headroom. | ✓ |
| current color | Last-sent uniform or `mixed`. | |

### Q3: `color` field when frame is per-LED

| Option | Description | Selected |
|--------|-------------|----------|
| Show `mixed` literal | Clear signal. | |
| Show first LED's color | Misleading. | |
| Show all 10 hex values | Verbose. | |
| Omit color field entirely | Drop tracking burden. | ✓ |

### Q4: Error context in `status`

| Option | Description | Selected |
|--------|-------------|----------|
| Add `err=<code>` when disabled/reconnecting | Debugging aid. | ✓ |
| No error context | Keep minimal. | |

---

## Claude's Discretion

Items the user explicitly or implicitly left to Claude's judgement during planning:
- Default value of `backglow.transport`
- DDP probe timeout
- Exact ordering/formatting of `status` fields
- HTTP client choice for `/json/info` probe (WinHTTP / WinINet / raw socket)
- DDP payload chunking approach
- `com_port_scan` helper placement
- VRSettings key naming exact spelling
- `15-SMOKE.md` scaffolding

## Deferred Ideas

- mDNS/Bonjour WLED discovery
- DDP heartbeat / periodic reachability probe
- Runtime transport switching (pipe command or VRSettings hot-reload)
- Mid-session USB→DDP failover
- VRSettings `backglow.ddp_port` knob
- `color` field in `status`
- TPM2 functional implementation
- Per-transport brightness ceiling
- Reviewed todos (unrelated): input/system click probing; v2.0 IPD slider

---

*Discussion log generated by `/gsd-discuss-phase` on 2026-04-19.*
