feat(desktop): name the dev-profile lock holder in conflict messages - #3953
feat(desktop): name the dev-profile lock holder in conflict messages#3953rbalachandar wants to merge 2 commits into
Conversation
Closes the observability half of the shared 'Maka Dev' profile launch race (apache#3539). When a launch loses the single-instance lock, the loser surfaces named the conflict only generically. Resolve the holder from Chromium's own SingletonLock record (a <hostname>-<pid> symlink target in the user-data dir), never from the process table: the symlink alone is not evidence — it survives SIGKILL — so a holder is reported only while its PID is still alive (kill(pid, 0), EPERM counts as alive), and a hostname mismatch is reported as another machine for shared homes. - packages/core/dev-single-instance-owner: parse + liveness + describe, undefined on any inconsistency so every caller degrades to the existing generic wording. - All three loser surfaces name the holder: the main-process loser dialog, the absorbed outcome in dev.mjs / start-dev-app.mjs, and the plain-loser stderr in dev-app-runtime.mjs. An explicit --user-data-dir wins over the shared default, matching launch behavior. The message is hedged ("appears to be"), which also covers the inherent PID-reuse race. The race's atomic-reservation half stays open.
|
I reviewed this PR at exact head Standards: NO-GO — 1×P1 + 1×P2 + 2×P3
Other checks: branch/title conform, Spec: NO-GO — 3×P2 + 1×P3
No missing macOS loser surface was sustained; atomic reservation/handshake remains intentionally outside this naming scope. Other checks: core 665/665 PASS, launcher 25/25 PASS, format 1690 PASS, changed-file Biome PASS; What I did not check: full local Desktop suite beyond the checks noted. Gate: exact head has P1/P2/P3 findings in both axes and a failing required
|
Summary
Refs #3539 (follow-up to #3359's shared 'Maka Dev' profile owner gate). When a launch loses the single-instance lock, all three loser surfaces — the main-process loser dialog, the absorbed outcome in
dev.mjs/start-dev-app.mjs, and the plain-loser stderr indev-app-runtime.mjs— named the conflict only generically.This resolves the holder from Chromium's own
SingletonLockrecord (a<hostname>-<pid>symlink target in the user-data dir), never from the process table:kill(pid, 0), withEPERMcounted as alive).undefined, and every caller falls back to the existing generic wording.--user-data-dirwins over the shared default, matching launch behavior.New
packages/core/dev-single-instance-owner(parse + liveness probe + describe), exported via the package map and lazy-loaded by the launcher scripts.This covers the "surface the actual owner" half of the issue's post-spawn handshake option; the atomic-reservation half remains open.
Verification
npm run build— passpackages/coresuite: 665/665apps/desktopsuite (dist/main+dev-app-runtimescripts): 1577/1577 stable run;dev-app-runtime.test.mjs25/25 including the five new conflict-detail testsnpm run lint,npm run format:check,npm run typecheck— pass (exit 0)AI use
Select exactly one:
Tool(s) and scope: Claude Code — implementation review, rebase onto current main, verification runs; human contributor of record reviewed and owns the change.
Checklist
Does this PR entail a change in behavior?