# /etc/udev/rules.d/98-halogen-npu-access.rules # # Why the NPU node is world-writable: `frank-dragoon` runs rootless podman under a # unit with `User=dank`, and the container's user namespace maps exactly one uid and # one gid (dank). `/dev/accel/accel0` is `root:render 0660`, so inside the container # the node reads `nobody:nogroup` and the engine dies with its own diagnosis: # # halogen npu: /dev/accel/accel0 is here, but this process cannot open it # (crw-rw---- nobody:nogroup). # # `--group-add keep-groups` is the vendor's advice and it does NOT work in this # shape: measured 2026-10-19 from the host as a `dank` shell that was already in # `render`, with and without the flag, the node still read `nobody:nogroup` and the # open was refused — an unmapped gid cannot be granted to a process inside a # namespace that does not map it. Same conclusion `99-comfyui-gpu-access.rules` # reached for `/dev/kfd` from the systemd-user-spawn direction: the mode is the only # spawn-context-independent door short of running the stack rootful. # # Blast radius: any process in this host's single uid domain (every rootless # container here shares it) can submit to the XDNA2 NPU. The NPU holds no user data # and no privileged context — the same trade already accepted for the GPU compute # nodes beside it. Installed by `deploy-remote.sh` when the NPU lane is armed and left # in place afterwards — the mode costs nothing while the lane is idle. `serve-frank-dragoon.sh` # refuses to arm the lane on a node that is not other-accessible, so a host that lost this # file fails loudly at boot instead of crash-looping. KERNEL=="accel[0-9]*", SUBSYSTEM=="accel", MODE="0666"