Fix uds addr corruption + exercise macOS CI#480
Open
goodboy wants to merge 4 commits into
Open
Conversation
The docs-example harness only re-raises captured subproc stderr when the LAST line contains 'Error', but a `tractor` root-actor crash always ends stderr with the strict-EG collapse note `( ^^^ this exc was collapsed from a group ^^^ )` — so every possible crash is swallowed down to a bare `assert 1 == 0`, exactly what the macOS CI leg shows for the UDS example in GH #473. - raise with the FULL stderr (+stdout) whenever the example subproc exits non-zero, regardless of stderr shape. - keep the legacy last-line 'Error' check for zero-rc runs which still emit error-ish output. First task-bullet of GH #473. Prompt-IO: ai/prompt-io/claude/20260702T155006Z_65bf9df5_prompt_io.md (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
`MsgpackUDSStream.get_stream_addrs()` matches the
`(peername, sockname)` pair by type to find the listener's
fs-path, but the `(str, str)` arm unconditionally takes
`peername`: on platforms without linux's
`SO_PASSCRED`-triggered autobind (macOS!) the accept side's
`getpeername()` is `''`, so every accepted conn gets garbage
`Path('')` laddr/raddr structs.
Proven on linux by disabling `SO_PASSCRED` (no autobind ->
same `''` shape as darwin): the `uds_transport_actor_tree.py`
example reports `listener sock file: .` pre-fix and the real
registry sockpath post-fix.
- pick the non-empty name in the `(str, str)` arm: `peername`
on the connect side, `sockname` on the accept side; raise
`ValueError` on an (unexpected) empty pair.
- document the linux-autobind origin of the `bytes` arms
which the original impl noted as "unclear".
- `start_listener()`: create the bindspace dir with
`parents=True, exist_ok=True` (nested custom `filedir`s +
racing actors).
- example docstring: peer-pid comes via `SO_PEERCRED` on
linux but `LOCAL_PEERPID` on macOS.
May not be the (only) macOS crasher for GH #473 — it is
non-fatal on the linux sim — but with stderr surfacing now
in place the next macOS CI run pins any remaining layer.
Prompt-IO: ai/prompt-io/claude/20260702T155006Z_65bf9df5_prompt_io.md
(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
UDS-on-macOS is otherwise un-exercised: the matrix explicitly excludes the `macos-latest` + `uds` combo, so the `uds_transport_actor_tree.py` example (skipped on macOS CI since PR #460) is the only thing that ever touches that path. - drop the matrix `exclude` so the full suite runs with `--tpt-proto=uds` on `macos-latest`. - un-skip the example on macOS+CI; with example-stderr surfacing in place a still-red run now yields the full traceback GH #473 asks for instead of a bare returncode assert. Task-bullets 3 + 4 of GH #473. Prompt-IO: ai/prompt-io/claude/20260702T155006Z_65bf9df5_prompt_io.md (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
Provenance entry (+ unedited raw output) for the root-cause session behind the prior three patches, per the NLNet generative-AI policy tracked under `ai/prompt-io/`. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
There was a problem hiding this comment.
Pull request overview
This PR aims to root-cause and harden Unix Domain Socket (UDS) transport behavior on macOS (and surface failures better in CI), including enabling the macOS+UDS CI leg and removing the previous docs-example skip.
Changes:
- Harden UDS listener bindspace directory creation (
parents=True,exist_ok=True) and fixget_stream_addrs()for “no-autobind” platforms (macOS) so emptypeername/socknamedoesn’t producePath(''). - Improve docs-example test diagnostics by surfacing stdout/stderr on non-zero exits, and un-skip the UDS transport example on macOS CI.
- Enable UDS coverage on macOS in the GitHub Actions CI matrix; update UDS example docs to note platform-specific peer PID mechanisms.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tractor/ipc/_uds.py | Makes UDS bindspace creation more robust and fixes address selection logic on macOS/no-autobind platforms. |
| tests/test_docs_examples.py | Changes the example-run harness to surface subprocess output and removes the macOS CI skip for the UDS example. |
| examples/uds_transport_actor_tree.py | Updates example documentation to reflect Linux vs macOS peer PID mechanisms. |
| .github/workflows/ci.yml | Enables macOS+UDS test coverage by removing the exclude from the CI matrix. |
| ai/prompt-io/claude/20260702T155006Z_65bf9df5_prompt_io*.md | Adds prompt-IO logs documenting the investigation and changes for GH #473. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
168
to
171
| try: | ||
| if not proc.poll(): | ||
| _, err = proc.communicate(timeout=timeout) | ||
| out, err = proc.communicate(timeout=timeout) | ||
|
|
Comment on lines
172
to
176
| @@ -190,9 +176,34 @@ def test_example( | |||
| proc.kill() | |||
| proc.kill() | ||
| err = e.stderr | ||
|
|
||
| errmsg: str = err.decode() if err else '' |
| # `assert 1 == 0` in CI logs.. see GH #473. | ||
| rc: int|None = proc.returncode | ||
| if rc: | ||
| outmsg: str = out.decode() if out else '' |
Comment on lines
+193
to
+203
| if rc: | ||
| outmsg: str = out.decode() if out else '' | ||
| raise Exception( | ||
| f'Example script exited with rc={rc} !?\n' | ||
| f'\n' | ||
| f'stdout:\n' | ||
| f'{outmsg}\n' | ||
| f'\n' | ||
| f'stderr:\n' | ||
| f'{errmsg}\n' | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix
udsaddr corruption + exercise macOS CIMotivation
The new
examples/uds_transport_actor_tree.py(PR #460) reliablyfails on macOS CI but the docs-example harness swallows the
traceback: it only re-raises captured stderr when the LAST line
contains 'Error', and a
tractorroot-actor crash always ends withthe strict-EG collapse note
( ^^^ this exc was collapsed from a group ^^^ )— so every possible crash reduces to a bareassert 1 == 0in the CI logs. Worse, UDS-on-macOS is otherwise entirelyun-exercised: the test matrix explicitly excludes the
macos-latestudscombo, so the (skipped) example was the only thing that evertouched that path.
This branch lands the diagnosis plan from GH #473: surface the real
stderr, fix the one macOS UDS bug provable from linux, and turn on
the missing CI coverage so the next macOS run either goes green or
pins any remaining crasher layer with a full traceback.
Summary of changes
tests.test_docs_examples: always raise with the FULL subprocstderr (+stdout) whenever an example exits non-zero, regardless of
stderr shape; un-skip the
udsexample on macOS+CI.tractor.ipc._uds: fix accept-side addr corruption on no-autobindplatforms (macOS!) — the
(str, str)match arm inMsgpackUDSStream.get_stream_addrs()tookgetpeername()unconditionally, which is
''on the accept side without linux'sSO_PASSCRED-triggered autobind, corrupting every accepted conn'sladdr/raddr to
Path(''). Proven + verified via a linux sim(nulling
SO_PASSCRED).mkdir()w/parents=True, exist_ok=True(nested customfiledirs + racing actors)..github/workflows/ci.yml: drop the matrixexcludeso the fullsuite runs with
--tpt-proto=udsonmacos-latest.ai/prompt-io/: session provenance log per the NLNet generative-AIpolicy.
TODOs before landing
macos-latest+udsCI job and theun-skipped example: the addr fix is non-fatal on the linux sim so
it may not be the (only) macOS crasher — if the leg is still red,
the now-surfaced traceback pins the remaining layer (which is
itself the GH Root-cause UDS-on-macOS —
uds_transport_actor_treeexample fails on CI #473 deliverable).Future follow up
Tracked in GH #473 — its remaining checkboxes get checked off
with commit ref-links as part of landing this.
(this pr content was generated in some part by
claude-code)