NVIDIA / NVIDIA/Personal-AI-Router

[Bug]: macOS M4 cannot obtain Local Network permission (no prompt, missing NSLocalNetworkUsageDescription) — cross-host discovery and EC-peer routing fail

Ouverte
#3 5 commentaires 0 réactions 1 personne assignée Voir sur GitHub

@Noah-Tervalon-Nvidia y travaille déjà.

Depuis le 11/9/2026.

Langage dominant
Go
Étoiles
1.4k
Forks
250
Merge moyen
23 h 27 min
PR mergées (30 j)
1

Description

PAIR version

v0.1.1 (both nodes), from the official release assets:

  • Linux amd64 .deb (devbox, x86_64)
  • macOS arm64 .dmg (Apple M4)
Host OS (exact)
  • macOS node: macOS 27.0 (build 26A5388g), Apple M4, 16 GB
  • Linux node: Omarchy 4.0.2 (/etc/os-release: ID=omarchy, VERSION_ID=4.0.2), x86_64, NVIDIA RTX 2000 Ada (8 GB)
Summary

macOS M4 node cannot obtain Local Network permission, so cross-host discovery and EC-peer registration fail. The shipped macOS bundle lacks NSLocalNetworkUsageDescription, and no permission prompt ever appears on this macOS version.

Verified (2026-09-04): plist keys alone are insufficient on macOS 27.0

We rebuilt PAIR from source applying the exact config fix from the (now-closed)
PR #12: added NSLocalNetworkUsageDescription and
NSBonjourServices: ["_nvpair-node._tcp"] to mac.extendInfo in
electron-builder.config.ts, built all modular Go binaries for darwin/arm64,
and produced a fresh .app whose Info.plist verifiably contains both keys.
Launched under the original com.nvidia.nvpair identity:

  • No Local Network consent prompt appears.
  • mDNS multicast still fails identically: sendto: no route to host on en0.
  • Unified logs show the LocalNetwork subsystem finding the bundle by PID/UUID
    each attempt, but no prompt and no explicit verdict.

Conclusion: the two plist keys are necessary but not sufficient. Leading
hypothesis: PAIR's scanner sends raw UDP multicast via Go's net package,
which does not traverse the API path (Bonjour/DNSService) that macOS TCC Local
Network enforcement associates with the declared NSBonjourServices — so no
consent is ever solicited. A fix likely needs the discovery layer to use the
system Bonjour API, not just the plist declaration.

What works (verified)
  • Single-node routing on the Linux node: model pull + chat through PAIR's proxy (11434) with Jobs telemetry (devbox→devbox).
  • Cluster membership via manual Add-node-by-IP: both nodes appear as member in members.json with the same clusterId.
  • TCP connectivity between nodes after opening firewall ports.
  • Privileged firewall helper (com.nvidia.nvpair.helper) loads from the signed bundle once approved in Login Items.
What fails (observed)
  1. Mac node-scanner mDNS multicast blocked. Log repeats every ~5 s:

    [nvpair-node-scanner] WARN mdns send: query did not leave any interface
    service=_nvpair-node._tcp failed=2 errors="en0 write: write udp4
    192.168.1.42:...->224.0.0.251:5353: sendto: no route to host"
    

    A direct Python UDP multicast from Terminal to 224.0.0.251:5353 succeeds on the same host — so the block is app-specific.

  2. No Local Network permission prompt ever appears on macOS for com.nvidia.nvpair, and the app never appears under System Settings → Privacy & Security → Local Network. NSLocalNetworkUsageDescription is absent from the shipped Info.plist (only legacy NSAllowsLocalNetworking is present). macOS will not show the consent prompt or list the app without that key.

  3. Patched-copy test: inconclusive. Added NSLocalNetworkUsageDescription, re-signed (ad-hoc, then Apple Development identity), reset TCC (tccutil reset All com.nvidia.nvpair), launched from Finder/LaunchServices — still no prompt, multicast still denied. Caveat: this copy was made by editing only the outer Info.plist/CFBundleIdentifier; nested Mach-O binaries retained the original team/signing identity. This test did not establish a fresh TCC identity, so it cannot determine whether the key alone fixes prompting.

  4. Cross-node engine-control fails. Both nodes log node X is not a discovered ec peer (engine-manager remote.go). Manual node admission creates cluster membership but does not populate the EC peer directory, which is fed only from discovery relay snapshots.

  5. Cross-node model routing fails. Devbox PAIR proxy returns no available node advertises the requested model for a Mac-only model; Mac proxy likewise for a devbox-only model. Manual-node model probing appears limited to plaintext engine endpoints, which PAIR's proxy rejects for remote peers (loopback-only, mTLS ingress required).

Expected behavior
  • macOS node should be able to receive Local Network permission (prompt appears; app listed in Privacy → Local Network), enabling mDNS discovery of _nvpair-node._tcp.
  • With mDNS working, discovery snapshots should populate the EC peer directory so cross-node engine status and routing work, as they do for same-LAN Linux nodes.
Suggested fix (actionable)
  • Add NSLocalNetworkUsageDescription to the macOS Info.plist and
    _nvpair-node._tcp under NSBonjourServices in mac.extendInfo
    (electron-builder.config.ts) — done in the closed PR #12 and verified in a
    source rebuild, but this alone does not restore the prompt.
  • Migrate the discovery layer's mDNS from raw Go net UDP sockets to the
    system Bonjour API (DNSServiceBrowse/DNSServiceRegister), which is the
    path macOS TCC associates with the declared Bonjour service and uses to
    solicit Local Network consent.
  • Verify the notarized build's first-use prompt on a clean macOS install.
Environment notes
  • tccutil reset for LocalNetwork service names returns RC 70 on this macOS version ("unsupported service"); tccutil reset All com.nvidia.nvpair succeeds.
  • Tailscale on/off both tested — not the cause.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.