--- model: claude-opus-4-6 service: claude session: (ad-hoc, not tracked via conf.toml) timestamp: 2026-04-13T19:21:16Z git_ref: f851f28 scope: code substantive: true --- ## Prompt User provided a detailed implementation plan for a new `test_tpt_bind_addrs.py` test suite covering `open_root_actor(tpt_bind_addrs=...)` — the three runtime code paths in `_root.py:385-450`: 1. Non-registrar, no explicit bind -> random addrs 2. Registrar, no explicit bind -> registry_addrs 3. Explicit bind given -> `wrap_address()` + merge Plan specified 6 test functions (~10 parametrized variants), predicted a type-mixing bug at line 446, and asked for an in-flight fix if confirmed. ## Response summary Created `tests/discovery/test_tpt_bind_addrs.py` with 9 collected test variants across 6 functions: - `test_registrar_root_tpt_bind_addrs` (3 variants: `bind-eq-reg`, `bind-subset-reg`, `bind-disjoint-reg`) - `test_non_registrar_root_tpt_bind_addrs` (2 variants: `bind-same-bindspace`, `bind-disjoint`) - `test_non_registrar_default_random_bind` (baseline, no explicit bind) - `test_tpt_bind_addrs_as_maddr_str` (multiaddr string input) - `test_registrar_merge_binds_union` (registrar + disjoint bind -> union) - `test_open_nursery_forwards_tpt_bind_addrs` (`open_nursery(**kwargs)` forwarding) Confirmed and fixed the predicted bug at `_root.py:446`: the registrar merge path mixed `Address` objects (`tpt_bind_addrs`) with raw tuples (`uw_reg_addrs`) inside `set()`, preventing deduplication and causing double-bind `OSError`. Fix: wrap `uw_reg_addrs` before the set union: ```python # before (broken) tpt_bind_addrs = list(set( tpt_bind_addrs + uw_reg_addrs )) # after (fixed) tpt_bind_addrs = list(set( tpt_bind_addrs + [wrap_address(a) for a in uw_reg_addrs] )) ``` All 9 tests pass after the fix. ## Files changed - `tests/discovery/test_tpt_bind_addrs.py` (new) - `tractor/_root.py:446` (bug fix, 1 line) ## Human edits N/A — pending review.