### Fixed: `VeraConfig` refuses a `render_width` no view can be rendered at

`render_width` is the per-view pixel width every camera frame is resized to before it reaches the WAN/DFoT planner - the same quantity as the recorders' `width`/`height` and `HybridCompositor.default_width`, for which `positive_whole_number_error` already exists as the shared media domain, and whose own docstring names "the media knobs that count frames or pixels" as one of the two families it serves. `render_width` was not one of its callers. It was declared `int | None`, defaulted per embodiment, and then read twice under a truthiness coalesce with an `int()` at each site, so no value was refused: `0` and `False` were discarded and the per-embodiment default silently applied in their place, `True` rendered a 1x1 view and `2.7` a 2x2 view - both under a success result, so the mistake presented as a policy that does not solve rather than as an error - and `-1`, `"abc"`, `nan`, `inf` and `[128]` escaped as a `ValueError`, `OverflowError` or `TypeError` out of `int()` or `np.linspace` naming neither the field nor the class. Those escapes arrived per frame from `_extract_frame`, which `get_actions` calls *after* `_ensure_started` has launched the WAN server subprocess and completed the handshake, so a width that was wrong at construction cost a model load - up to `server_ready_timeout`, 600s by default - before anything reported it.

`render_width` now shares `positive_whole_number_error`, applied at the config funnel beside the two port guards and for the argument already recorded above them: refusing before any client or runner is built leaves nothing half-configured behind. `None` still means "apply `VERA_RENDER_WIDTH` else the per-embodiment default", the same opt-out the neighbouring pixel-count callers give it. Three consequences worth naming. The environment override is now read with `is not None`, matching `vis_port` six lines above rather than the `or` this line carried, so `VERA_RENDER_WIDTH=0` is refused instead of being replaced by 128. The effective width is normalized to a plain `int` - the obligation the shared domain documents for its callers, since it admits any real scalar with an integral value while `Image.resize` and the `view_widths` payload need a true `int` - so `128.0` is stored as `128` and a `np.int64` no longer outlives the boundary. And a numeric string such as `"128"` is now refused where `int("128")` used to accept it, which is the convergence on the shared domain rather than a side effect. Both read sites drop the now-dead `int()` and coalesce; the second one's `context_rgb.shape[2] // n_views` fallback turned out to be a redundant second definition of the same case rather than a divergence, because the frames had already been resized to the first one's value, and a test now pins `sum(view_widths) == context_rgb.shape[2]` so nothing has to be inferred from that coincidence again. No resource ceiling is added: the domain documents that as the consumer's per-backend decision, and an outsized width stays accepted and pinned as out of scope.
