Repository navigation
fix(devices): stop wrapper-launched tailnet watchers; skip alias-only network tests on macOS - #3329
Conversation
…nly tests on macOS Core tests failed only on a Mac with Tailscale installed: - watchTailnet spawned `tailscale debug watch-ipn`; when `tailscale` on PATH is a /bin/sh wrapper without exec, child.kill() stopped only the wrapper, the real watcher kept the stdout pipe open, 'close' never fired and plugin dispose hung (hook timeouts in plugin.test.ts, dm-turn.test.ts). Spawn the watcher in its own process group, signal the group, and drop stdout once the child has exited. - Real-bridge tailnet tests bind 127.0.0.x addresses that macOS lacks without lo0 aliases (EADDRNOTAVAIL -> network-listener-unavailable). Probe the addresses and skip with a hint instead of failing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lpx6qjn5hiharccxWBTehc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lpx6qjn5hiharccxWBTehc
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Owned process lifecycle packages/core/src/devices/bot-tailnet-watch.ts, packages/core/test/bot-tailnet-watch.test.ts, changes/3329-tailnet-watch-wrapper.md |
The watcher starts an owned process and stops its process group on non-Windows platforms. Failure and shutdown use the same stop helper. A test checks that disposing a watcher also stops a child launched through a shell wrapper. English and Chinese release notes describe the change. |
Loopback-dependent integration tests
| Layer / File(s) | Summary |
|---|---|
Loopback alias availability check packages/core/test/loopback-aliases.ts |
The helper attempts to bind each supplied address, closes successful listeners, warns about unavailable addresses, and returns whether all addresses are available. |
Gate network tests on available aliases packages/core/test/bot-network-continuity.test.ts, packages/core/test/bot-tailnet-bridge.test.ts, packages/core/test/network-lifecycle.test.ts, packages/core/test/network-withdrawal.test.ts |
The network tests check the loopback addresses they require and skip when any are unavailable. Their existing test scenarios and assertions remain in place. |
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Possibly related PRs
- BotHarness/DeepSeekBot#3262: Adds the original tailnet watcher and network tests updated in this pull request.
- BotHarness/DeepSeekBot#472: Removes Core source comments under the source policy; this pull request also includes source-comment cleanup in the Core tailnet watcher.
Merge Risk: 
Minimal · up to 5d2c1
-
No merge-blocking risk is identified from the reviewed changes.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Description check
-
Explanation
The description includes the required Why, Special things to note, verification results, CI test plan, and Change outline sections. It explains the causes, implementation, risks, test coverage, and remaining macOS verification gap.
-
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 5 functions across 7 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lpx6qjn5hiharccxWBTehc
…t zombies as stopped Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lpx6qjn5hiharccxWBTehc
Requested by Vain · project thread
Why the change
The full Core suite fails locally on a Mac with Tailscale (30 failures) while CI and Linux are green; one of the two causes is a real Host shutdown hang.
Issue / Discussion: found while validating #1950; no tracking issue.
Special things to note
bot-tailnet-watch.ts); the rest is test-only. Review focus: process-group kill (process.kill(-pid)) and its fallback for injected children; Windows behavior is unchanged (nodetached, plainchild.kill()).main(Node 24.21.0, 8 CPUs, Tailscale running,tailscaleon PATH = 2-line/bin/shwrapper withoutexec): 30 failed in the full run, 27 serially, all explained by the two causes below. Running Hosts / UDP 43288 were ruled out (removingtailscalefrom PATH cleared cause B with those Hosts still up).stops a wrapper-launched watcher and the process it started when disposedtimes out (10 s) without the fix and passes with it (Linux).vitest run packages/core/teston Linux: 433 files / 4087 tests passed.oxfmt --check,oxlint,tsc --noEmitclean.packages/core/test/loopback-aliases.tshelper sits in an existing test directory.Change outline
A. Real bug: tailnet watcher dispose hangs behind a shell wrapper (plugin.test.ts ×7–9, dm-turn.test.ts ×3, bot-group-review-rounds ×1 under load; all
Hook timed out in 10000msinctx.fiber.dispose())The same hang applies to a real Host with this wrapper on PATH (shutdown / plugin reload), not just tests.
B. Environment: tests bind 127.0.0.x that macOS lacks (17 tests in bot-tailnet-bridge, bot-network-continuity, network-withdrawal, network-lifecycle;
network-listener-unavailable/EADDRNOTAVAIL)The bridge identifies peers by source address, so these tests need distinct loopback IPs; Linux CI keeps running them. On macOS they skip with a console hint (
sudo ifconfig lo0 alias 127.0.0.Nto run them locally).A bilingual
changes/fragment for the shutdown fix follows in the next commit (it needs this PR's number).Generated by Claude Code
Summary by CodeRabbit