--- model: claude-fable-5 service: claude timestamp: 2026-07-02T15:50:06Z git_ref: 65bf9df5 diff_cmd: git diff main..wkt/uds_macos_473 --- # Raw output — GH #473 UDS-on-macOS root-cause session NOTE: code output is diff-referenced (not copied) per prompt-io diff-ref mode; all generated code is on branch `wkt/uds_macos_473` relative to `main` (65bf9df5). ## Diagnostic narrative (verbatim) Root-cause work proceeded by linux-side simulation since no macOS host is available: 1. Pulled the actual macOS CI failure log from PR #460 run 28343878933 (job 84115107992): the failure is a bare `assert 1 == 0` on `proc.returncode` with NO stderr surfaced — the harness only re-raised when the LAST stderr line contained 'Error'. 2. Reproduced the stderr-swallow mechanism on linux: any `tractor` root-actor crash ends stderr with the strict-EG collapse note `( ^^^ this exc was collapsed from a group ^^^ )` which never matches 'Error' — so EVERY possible crash was swallowed. (Verified by sabotaging the runtime dir via an over-long `XDG_RUNTIME_DIR` → `OSError: AF_UNIX path too long` → rc=1 + swallowed.) 3. Found + proved a macOS-only addr-corruption bug in `MsgpackUDSStream.get_stream_addrs()`: the `(str(), str())` match-arm unconditionally took `peername`, but on no-autobind platforms (macOS lacks linux's `SO_PASSCRED`-triggered autobind) the accept side's `getpeername()` is `''` → `Path('')` garbage laddr/raddr on EVERY accepted UDS conn. Simulated on linux by nulling `SO_PASSCRED` (no autobind → same `''` shape): pre-fix the example printed `listener sock file: .`; post-fix it prints the real registry sockpath. Non-fatal on linux-sim (rc=0), so possibly not the final macOS crasher — the diagnostic patch guarantees the next macOS CI run reveals any remaining layer. 4. Falsified the missing-parent-dir theory: `get_rt_dir()` already `mkdir(parents=True, exist_ok=True)`s at import (and macOS TCP CI passes), so `~/Library/Caches/TemporaryItems` absence cannot be the crasher. Hardened `start_listener()`'s bindspace mkdir anyway (custom `filedir` case + racing actors). ## Generated changes (diff pointers) > `git diff main..wkt/uds_macos_473 -- tests/test_docs_examples.py` - always raise with FULL subproc stderr (+stdout) on any non-zero example exit; keep legacy last-line 'Error' check for zero-rc cases; drop the macOS+CI skip of `uds_transport_actor_tree.py` (GH #473 next-step). > `git diff main..wkt/uds_macos_473 -- tractor/ipc/_uds.py` - `get_stream_addrs()`: document the autobind semantics (bytes = linux abstract-ns autobind artifact), add no-autobind `(str, str)` arm picking the non-empty name (`peername` connect-side, `sockname` accept-side) with an empty-pair `ValueError` guard. - `start_listener()`: `bs.mkdir(parents=True, exist_ok=True)`. > `git diff main..wkt/uds_macos_473 -- .github/workflows/ci.yml` - remove the `macos-latest`+`uds` matrix exclude so UDS-on-macOS is exercised by CI (GH #473 next-step). > `git diff main..wkt/uds_macos_473 -- examples/uds_transport_actor_tree.py` - docs nit: peer-pid mechanism is `SO_PEERCRED` on linux, `LOCAL_PEERPID` on macOS. ## Verification (verbatim summary) - macOS-shape sim (no autobind) + fix: example rc=0 with correct listener sockpath. - native linux post-fix: example rc=0, autobind arms unchanged. - sabotage smoke-test: diagnostic patch surfaces the full EG traceback incl. collapse-note line. - `pytest tests/ipc/ tests/test_2way.py tests/discovery/ --tpt-proto uds`: 61 passed, 1 `TooSlowError` flake (test_simple_rpc) that passes solo in 2.2s — attributed to a concurrent full-suite run (other session) loading the host. - full `tests/test_docs_examples.py` run pending at raw-file write time (queued behind the concurrent session's suite).