Comfy-Org / Comfy-Org/Comfy-Desktop
fix(telemetry): Linux device IDs fall back to per-launch random, fragmenting all person-level telemetry
- Dominant language
- TypeScript
- Stars
- 458
- Forks
- 59
- Avg merge
- 22h 18m
- Merged PRs (30d)
- 45
Description
## Summary
On Linux, non-root installs get a **new random `distinct_id` on every launch**, with no aliasing to stitch sessions together. This fragments *all* person-level analytics for Linux users — retention, per-user funnels, cohorts, and any `person.properties` breakdown — because each launch looks like a brand-new person.
This was discovered while verifying GPU telemetry: a Linux dual-RTX-4090 machine emitted a perfect `comfy.desktop.person.set` `$set` with the right `comfyui_gpu_model` / `comfyui_gpu_count` etc., yet `person.properties.comfyui_gpu_model` was null. The event data itself was flawless — the person identity was the problem (`id_class: random_fallback`).
## Root cause
`deriveMachineId()` (`src/main/lib/deviceId.ts`) derives the device id from `si.system().uuid`, which on Linux reads `/sys/class/dmi/id/product_uuid` — **root-only**. A normal Electron process can't read it, so it falls through to `randomUUID()` flagged `random_fallback`.
Then in `initDeviceId()`:
- the random UUID is generated **fresh every launch**, so the computed `newId` never matches the persisted `existing` in `device-id.txt`;
- because the existing value is a 64-char hash (not a legacy UUID), it takes the "update silently, **no alias**" branch and overwrites the file.
Net effect: **new `distinct_id` every Linux launch, no alias stitching.**
```
Windows / macOS Linux (non-root)
si.system().uuid = stable SMBIOS /sys/.../product_uuid = root-only -> fail
-> machine_derived (stable) -> random_fallback (new uuid each launch)
-> same distinct_id across runs -> new distinct_id every run, NO alias
-> person props accumulate -> every launch = throwaway person
```
## Impact
- All Linux person-level metrics are unreliable: person properties never accumulate, retention/per-user funnels are inflated, cohort breakdowns on `person.properties` undercount Linux.
- GPU/driver/model person props (`comfyui_*`) specifically appear missing for Linux users even though the underlying events are correct.
- **Event-level data is unaffected** — `accelerator_detected`, `system_info`, `model_usage`, etc. carry the real values as event properties; only person-profile stitching is broken.
## Proposed fix
Add a non-root Linux fallback **before** the random UUID in `deriveMachineId()`:
1. Try `si.system().uuid` (current behavior; works when readable).
2. **New:** on Linux, read `/etc/machine-id`, then `/var/lib/dbus/machine-id` — both world-readable (`0444`), stable per-install. Use as a `machine_derived`-quality id.
3. Only if all of the above fail, use `randomUUID()` + `random_fallback`.
This gives Linux users a stable id and fixes the per-launch fragmentation.
### Caveats / considerations
- Containers, snap, and flatpak may namespace or vary `/etc/machine-id`; still strictly better than per-launch random, and can be flagged with a distinct `id_class` (e.g. `linux_machine_id`) so dashboards can tell the source.
- Consider whether to alias historical `random_fallback` ids forward on first stable boot (likely not worth it — they're already fragmented; just stop the bleeding going forward).
- Keep the existing UUID-shape/placeholder rejection logic.
## Acceptance criteria
- [ ] Linux non-root installs produce a stable `distinct_id` across launches
- [ ] `id_class` distinguishes the source (`machine_derived` vs `linux_machine_id` vs `random_fallback`)
- [ ] Unit tests for: SMBIOS available, SMBIOS unreadable + `/etc/machine-id` present, both absent -> random
- [ ] PostHog verification: `random_fallback` rate on Linux drops sharply in the next release
## Notes
Found during telemetry verification for the GPU/driver/array work (PR #1177). No code in that PR is affected — this is a pre-existing identity issue surfaced by checking person-level GPU props on a Linux machine.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in src/main/lib/deviceId.ts by reading deriveMachineId() and initDeviceId(), then inspect the existing device-ID unit tests. Verify the SMBIOS, Linux machine-ID, and random fallback paths, including their id_class values. Done means non-root Linux IDs remain stable across launches and the tests cover the stated fallback cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, linux, typescript
- Domain
- desktop, observability-sre, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100