wavefnd / wavefnd/Wave

Resolve native macOS stdout-capture regressions on both architectures

Open
#633 0 comments 0 reactions 0 assignees View on GitHub
bug ci
Dominant language
Rust
Stars
53
Forks
16
Avg merge
4h 22m
Merged PRs (30d)
46

Description

Observed at PR #631 head `d811e0c2accc8997eecb5071f8752f88e9fb44e4`. [Failing CI job](https://github.com/wavefnd/Wave/actions/runs/34737095086/job/103670349676).

Both native macOS jobs fail the same two tests in `tools.test_std_io_runtime`:
- `test_capture_has_no_inherited_pipe_reader_and_no_parent_leak`: fixture exits 12.
- `test_capture_writer_observes_consumer_closure`: fixture exits 11.

`capture.wave` exit 12 combines child exit status, byte count and payload checks. `capture_close.wave` exit 11 combines wait failure and non-normal child termination. Logs contain no child status or payload, so they do not establish a leaked reader, exec failure, or SIGPIPE root cause.

Reproduce on each native host with the repository std installed:
```sh
cargo test --locked --test std_io_regressions --jobs 2 -- --nocapture
```

Trace fork return conventions, descriptor remapping/closure, script execution and child wait status. Compare a minimal executable child with the generated Python shebang child to distinguish runtime defects from fixture assumptions. Retain the closed-standard-descriptor and early-consumer-closure checks.

Acceptance:
- Both capture scenarios pass repeatedly on native amd64 and arm64 macOS.
- A missing child reader is demonstrated by descriptor inspection and bounded producer termination.
- Preserve child status and capture contents when a check fails.
- No libc binding workaround and no platform skip to hide failure.

Follow-up to #559 after its child-reader cleanup; related to broader Darwin provider audit #434. The two failures are intentionally grouped until evidence establishes different root causes.

Source references:
- [tests/fixtures/io/capture.wave](https://github.com/wavefnd/Wave/blob/d811e0c2accc8997eecb5071f8752f88e9fb44e4/tests/fixtures/io/capture.wave)
- [tests/fixtures/io/capture_close.wave](https://github.com/wavefnd/Wave/blob/d811e0c2accc8997eecb5071f8752f88e9fb44e4/tests/fixtures/io/capture_close.wave)
- [tools/test_std_io_runtime.py](https://github.com/wavefnd/Wave/blob/d811e0c2accc8997eecb5071f8752f88e9fb44e4/tools/test_std_io_runtime.py)
- [std/process/spawn.wave](https://github.com/wavefnd/Wave/blob/d811e0c2accc8997eecb5071f8752f88e9fb44e4/std/process/spawn.wave)

Both affected jobs: [amd64](https://github.com/wavefnd/Wave/actions/runs/34737095086/job/103670349659), [arm64](https://github.com/wavefnd/Wave/actions/runs/34737095086/job/103670349676).

Contributor guide

Open the contributing guide

Research direction

Run cargo test --locked --test std_io_regressions --jobs 2 -- --nocapture on native amd64 and arm64 macOS. Read tools/test_std_io_runtime.py, the capture.wave and capture_close.wave fixtures, and std/process/spawn.wave; trace fork returns, descriptor remapping and closure, script execution, and child wait status. Done means both scenarios pass repeatedly, with descriptor inspection and bounded producer termination demonstrating the missing-reader behavior while preserving child status and captured contents on failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
operating-systems, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.