Where the register lives
A workspace is one client's register, held in one SQLite file on this Mac. Switching workspaces opens a different file. Nothing is shared between them, and nothing is copied.
- For
- Switch between client registers, each held in its own SQLite file on this Mac.
- Will not
- Only one workspace can be open at a time. You cannot delete the last remaining workspace or the one currently open; switch away first.
- Writes
- Creating, renaming and deleting workspaces changes the workspaces.json index and database files; the page does not say these actions are attributed or audited.
- On iPhone
- A paired iPhone reads only the workspace the Mac currently has open, and a demo workspace never syncs so the phone will not see sample data.
One workspace, one file
The unit is the file, not a filter. Two clients are two databases, and the app can only have one open at a time.
Every workspace is a .sqlite file in the app’s store directory, alongside a workspaces.json index that lists them. The index holds a name, a file name, a creation date and, for the sample, a flag. That is the whole of it: there is no shared schema, no tenant column, and no query that can reach across two workspaces, because there is no connection that spans them.
The first workspace is called Primary and points at starkive.sqlite. If you have been running Manifest since before workspaces existed, that is the database you already had: the app adopts it as the first entry in the index rather than migrating it anywhere, so nothing is lost on the upgrade.
New workspaces are named workspace-<uuid>.sqlite. The name you give one is a label in the index; the file name is generated and does not change when you rename.
Switching
Switching tears down the open environment and builds a new one against the other file. It is not a filter being applied to the same data.
Choosing a workspace closes the current environment and opens the other one. The app remembers which you were in, so the next launch returns you to it.
The outgoing environment stops its server first
Each environment runs its own LAN server for the paired phone, on port 7277. The outgoing one is stopped before the new one is opened, not after, so the port is free when the successor asks for it.
The new environment is built against the other file
A fresh environment, a fresh database connection, a fresh server. The schema is created and migrated if the file is new.
Your write standing is applied before it is handed back
If the account is read-only, the new environment is born read-only. It is never briefly writable between construction and the next update pass.
The order in step one is the whole point. Opening the new server while the old one still held the port failed with Address already in use, and the old server went on answering, still bound to the workspace you had just left. The phone kept reading the previous register with a timestamp saying it had synced a minute ago. Both devices were telling the truth about different registers, which is worse than an error.
Creating, renaming, deleting
Three operations, and one of them refuses more often than you would expect.
Create takes a name. An empty or whitespace-only name becomes New Workspace rather than being rejected. The file is created and migrated as part of the same operation, and the app switches to it.
Rename changes the label in the index. The file name is left alone, so nothing that refers to the workspace by file is disturbed. An empty name is ignored rather than applied.
Delete removes the database file and its -wal and -shm companions. It refuses in two cases: you cannot delete the last remaining workspace, and you cannot delete the one currently open. Switch away first.
Deleting a workspace also deletes its paired-device state directory. Those tokens are live bearer credentials, and leaving them behind means the next workspace to be given that file name would inherit them. The register is not the only thing a workspace owns.
The sample workspace
A workspace called Demo: Northwind Trading, which behaves differently from yours in three specific ways.
- It never syncs. Its assets are invented, and pushing them into a real organisation would put fiction in front of an auditor, indistinguishable once there from the fleet.
- It has its own operator. The current user is Tom Becker, IT Operations, who is already seeded as a user in Northwind Trading Co. Everywhere else, the current user defaults to your macOS account name.
- It can be rebuilt. Load demo opens the existing sample if there is one. Rebuild demo leaves it if you are in it, deletes it, and creates and seeds a pristine one.
The second point is the one worth reading twice. The sample is shown to other people: in a sales call, in a screenshot, in this documentation. If it used your macOS account name, that name would sit inside invented data and leave the building every time the demo did.
What the phone sees
A paired iPhone reads the workspace the Mac currently has open, and only that one.
The LAN server is per environment, so it is per workspace. When you switch on the Mac, the server the phone was talking to is stopped and a new one is started against the new file. The phone follows, because there is nothing else for it to talk to.
This is also why the switch order in the section above matters so much. The failure it prevents is not a crash or an error message: it is the phone quietly continuing to show the register you navigated away from, with a fresh sync timestamp, while the Mac shows a different one. Nothing on either screen says anything is wrong.
A demo workspace never syncs, so a paired phone will not see the sample data. That is deliberate, and it is the same reason the demo has its own operator.
Read-only, and which workspace it applies to
Your write standing is a property of the account, not of the workspace, and it is held above the environment rather than inside it.
When the trial has ended and nothing has been bought, the register goes read-only. It stays readable and exportable on both platforms, and reportable on the Mac. Only writing stops. What each plan costs is on the plans page.
That standing is held by the coordinator, not pushed onto whichever environment happens to be open. Every switch, every new workspace and every demo load builds a whole new environment, and a new environment is born writable. Correcting it afterwards leaves a window between construction and the next update pass, and the window is not theoretical: Load demo seeds the environment on the very next line, so a read-only operator pressing it wrote a whole workspace past the gate. The same window reopened the LAN server to a paired phone.
Setting the standing applies it to the live environment. Every successor is built with it already applied, so an environment cannot exist in the wrong standing even for one statement.
When there is no window
App Intents and Spotlight answer questions from a process where no coordinator has been built.
“Hey Siri, how many laptops do I have” can arrive cold, before the app has a window. The answer has to come from the workspace you are actually in, which means resolving the current workspace from disk rather than from a live coordinator.
The app reads workspaces.json and the saved workspace identifier, and opens the file that names. It does not open starkive.sqlite by default, which is the workspace the multi-workspace model happens to have adopted rather than the one you are in. Getting that wrong meant a consultant working in client B’s workspace got client A’s numbers back from Siri and out of Spotlight, which is one tenant’s data surfacing inside another’s by the most public route the app has.
This resolution reads UserDefaults.standard, which is correct only while the intents run in the app’s own process. If they are ever moved into an app extension, that becomes the extension’s own domain, the lookup falls back to Primary, and the leak above comes back looking exactly like the fix. An extension target would need an app group and a suite name.