Split out of #56, which scoped this in only if the app-settings read/write half turned out to be solid. It was not — three of its six actions had UI that could not work and three had none — so the migration correctly waited. PR #102 fixes that half, which makes this the next step rather than a speculative one.
Why per-machine settings are the right home
/help/app-settings frames per-machine settings as exactly this case: a value that is meaningful on one machine only. The Document Sync Agent's sync-folder path is the textbook example — it is a local filesystem path, and syncing it to another Mac would point that Mac at a folder that may not exist.
Today the agent keeps its configuration in UserDefaults, which means:
- it does not survive a clean reinstall
- a second Mac has to be configured from scratch with no indication that is expected
- the Devices pane can show you a machine and tell you nothing about what that machine is actually doing
What moves
The agent's state, roughly: enabled/disabled, the sync folder path (as a security-scoped bookmark, not a plain string — a sandboxed app cannot reopen a user-chosen folder from a path alone), last-sync timestamp, and whatever conflict policy it holds.
The parts that need care
Bookmarks are machine-local by definition. A security-scoped bookmark resolved on another Mac is meaningless. So the stored shape should be the bookmark plus a human-readable path for display, and the receiving machine should treat a foreign bookmark as "not configured here" rather than attempting to resolve it.
Migration must be one-way and idempotent. Read UserDefaults, write the per-machine document, keep reading UserDefaults as a fallback until a successful write is confirmed. A migration that runs on every launch and overwrites a newer server value with a stale local one is worse than no migration.
The writes are compare-and-set. PR #102 established that the app-settings family requires baseVersion and answers 409 with the current document on a stale write. The agent runs in the background, so it is the most likely thing in the app to lose that race — it needs a re-base-and-retry, not a failure toast.
Do not put it in shared settings. Shared is seeded to a new machine on first sign-in; a sync-folder path arriving pre-filled from a different Mac is the specific failure this whole feature exists to avoid.
Acceptance
- The agent reads its configuration from per-machine app settings, falling back to
UserDefaults only until the first successful write.
- A folder chosen on one Mac does not appear as configured on another.
- A
409 on the agent's own write re-bases and retries rather than surfacing.
- The Devices pane can show whether a given machine has the agent configured.
- BDD quartet, including the boundary where
UserDefaults is empty (a fresh install) and the one where both sources have a value.
Split out of #56, which scoped this in only if the app-settings read/write half turned out to be solid. It was not — three of its six actions had UI that could not work and three had none — so the migration correctly waited. PR #102 fixes that half, which makes this the next step rather than a speculative one.
Why per-machine settings are the right home
/help/app-settingsframes per-machine settings as exactly this case: a value that is meaningful on one machine only. The Document Sync Agent's sync-folder path is the textbook example — it is a local filesystem path, and syncing it to another Mac would point that Mac at a folder that may not exist.Today the agent keeps its configuration in
UserDefaults, which means:What moves
The agent's state, roughly: enabled/disabled, the sync folder path (as a security-scoped bookmark, not a plain string — a sandboxed app cannot reopen a user-chosen folder from a path alone), last-sync timestamp, and whatever conflict policy it holds.
The parts that need care
Bookmarks are machine-local by definition. A security-scoped bookmark resolved on another Mac is meaningless. So the stored shape should be the bookmark plus a human-readable path for display, and the receiving machine should treat a foreign bookmark as "not configured here" rather than attempting to resolve it.
Migration must be one-way and idempotent. Read
UserDefaults, write the per-machine document, keep readingUserDefaultsas a fallback until a successful write is confirmed. A migration that runs on every launch and overwrites a newer server value with a stale local one is worse than no migration.The writes are compare-and-set. PR #102 established that the app-settings family requires
baseVersionand answers409with the current document on a stale write. The agent runs in the background, so it is the most likely thing in the app to lose that race — it needs a re-base-and-retry, not a failure toast.Do not put it in shared settings. Shared is seeded to a new machine on first sign-in; a sync-folder path arriving pre-filled from a different Mac is the specific failure this whole feature exists to avoid.
Acceptance
UserDefaultsonly until the first successful write.409on the agent's own write re-bases and retries rather than surfacing.UserDefaultsis empty (a fresh install) and the one where both sources have a value.