refactor(desktop): share the dev userData profile across worktrees - #3359
refactor(desktop): share the dev userData profile across worktrees#3359Astro-Han wants to merge 1 commit into
Conversation
The macOS TCC dev build redirected userData to
`~/Library/Application Support/Maka Dev-<worktreeHash>`, derived from the
same WORKTREE_ID used for the TCC bundle identifier. That per-worktree
data root was collateral of the TCC grant and diverged from every other
dev entry point:
- `npm run cli:dev` resolves to the `Maka Dev` profile
- plain `npm run dev` (via app.setName("Maka Dev")) resolves to `Maka Dev`
- only the TCC dev build (MAKA_DEV_TCC=1) wrote to `Maka Dev-<hash>`
So enabling MAKA_DEV_TCC silently switched the developer's database, and
the TCC dev host could not join the same runtime host as the repository
CLI. Dev/release data isolation is provided by the `Maka Dev` profile
(distinct from release `Maka`), not by the per-worktree hash: the hash
must stay only on DEV_BUNDLE_ID, where macOS TCC keys its grants.
Pointing the TCC dev bootstrap at the shared `Maka Dev` profile makes dev
data layout mirror release data layout: single runtime host per profile,
second-instance focuses the existing window, and the repository CLI and
dev Desktop attach to the same host.
Because the profile is burned into the generated bootstrap at build time,
the chosen root is added to the runtime cache marker so existing
worktrees rebuild instead of silently keeping the old hashed root.
Generated-by: Maka (design via Codex and Claude consult)
hqhq1025
left a comment
There was a problem hiding this comment.
Reviewed the current revision across the TCC bootstrap, the plain Desktop and repository CLI profile contracts, and runtime cache invalidation. The shared Maka Dev data root now matches the other development entry points while the worktree-scoped bundle identity remains unchanged; the previous marker is invalidated by the new burned-in path. The script syntax and focused marker/bootstrap assertions passed, and the required CI check is green.
Codex-assisted review performed under the maintainer-approved review workflow.
jackwener
left a comment
There was a problem hiding this comment.
Automated Codex review — blocking finding on exact head c17e155f47d8ff5cae02cb20a41f5a9f91950b01.
P2: the shared profile invalidates the launcher's worktree-local stale-owner recovery. resolveMacosDevelopmentLaunch() still calls ensureNoRunningDevelopmentApp(), but that function probes and kills only this worktree's DEV_EXECUTABLE. After this PR, a TCC app from worktree A and a launch from worktree B use the same Maka Dev single-instance lock while having different executable paths. If A is still running—or was orphaned after its terminal/Vite process died—B cannot see or stop it. B's Electron instance is absorbed by A's lock and exits, while B's monitor only watches B's path and eventually reports never-started. This is the same stale-window failure the ownership step's comment says it prevents, now moved to the cross-worktree case.
The README partly exposes the mismatch: it says another worktree's app survives and holds the shared lock, then says a launch reclaims an app left by a hard-killed session. The latter is no longer true across worktrees.
Before merge, make launch ownership profile-scoped as well as userData profile-scoped (or fail immediately with an explicit current-owner contract), and add a two-worktree regression that proves a stale owner cannot absorb the new launch. Keep DEV_BUNDLE_ID worktree-scoped for TCC as this PR already does.
Required conclusions:
- Optimal for the actual problem: not yet; the data-root correction is sound, but ownership follows the old isolation boundary.
- Production code to delete: none identified.
- Tests to delete/replace: none; current marker smoke coverage misses the cross-worktree lock behavior.
- Deeper refactor: no; align the existing stale-owner recovery with the new shared-profile boundary.
- Ready to merge: no, despite green
testand a current-head committer approval. - Residual risk/gaps: stale/other-worktree app absorption and 30-second false
never-startedfailure.
This is a developer-workflow behavior change; the existing independent human review remains necessary under CONTRIBUTING.md after the blocker is resolved.
Summary
The macOS TCC dev build redirected
userDatato~/Library/Application Support/Maka Dev-<worktreeHash>, derived from the sameWORKTREE_IDused for the TCC bundle identifier. That per-worktree data root was collateral of the TCC grant and diverged from every other dev entry point:npm run cli:devresolves to theMaka Devprofilenpm run dev(viaapp.setName("Maka Dev")) resolves toMaka DevMAKA_DEV_TCC=1) wrote toMaka Dev-<hash>So enabling
MAKA_DEV_TCCsilently switched the developer's database, and the TCC development host could not join the same runtime host as the repository CLI. Dev/release data isolation comes from theMaka Devprofile (distinct from releaseMaka), not from the per-worktree hash — the hash must stay only onDEV_BUNDLE_ID, where macOS TCC keys its grants.This change points the TCC dev bootstrap at the shared
Maka Devprofile so dev data layout mirrors release data layout: one runtime host per profile, second-instance focuses the existing window, and the repository CLI and dev Desktop attach to the same host. Because the profile is burned into the generated bootstrap, the chosen root is added to the runtime cache marker so existing worktrees rebuild instead of silently keeping the old hashed root.Verification
apps/desktoponly:DEV_USER_DATA_DIRconstant,createRuntimeMarkercache input, and the README profile paragraph.DEV_BUNDLE_ID(TCC) is untouched.node: the bootstrap default is now the sharedMaka Devpath (no worktree hash), an old pre-change marker is correctly judged stale (forces a rebuild so existing worktrees pick up the change), and a current marker is judged current (no needless rebuild churn)..mjsbuild script + README) are outside the biome-managed surface, so format/lint does not apply.Behavior change
Dev data root becomes shared across worktrees, matching release semantics: only one non-E2E dev Desktop instance runs per profile; a second launch focuses the existing window.
--user-data-dir=remains the escape hatch for isolation. ExistingMaka Dev-<hash>dirs are left as-is (no auto-migration — multiple roots cannot be safely merged).Review focus
userDataDiradded tocreateRuntimeMarker;isDevelopmentRuntimeCurrentcompares every field, so existing cachedMaka Dev.appbundles rebuild. Note this triggers a one-time macOS Accessibility/Screen Recording re-grant (existing bare-cdhash tradeoff).AI use
Tool(s) and scope: Design was developed with read-only Codex and Claude consult (both independently reached the same approach and flagged the cache-invalidation pitfall); main-thread verified all load-bearing claims against source. Generated-by trailer attached to the commit.
Checklist
Does this PR entail a change in behavior?