How Oda stores workspaces
This page describes how DataMind Oda keeps its list of workspaces on the computer, how a chat joins
one, and what hiding, pinning or removing never touch. It is for people who build, ship or debug Oda
itself. For the user-facing view, see Workspaces, files and permissions;
the steps to add, rename or remove a workspace are in Add, rename or delete a workspace.
The workspace list
Oda keeps an ordered, persistent list of its workspaces: one entry per folder, with the chats that
ran in it.
- The list survives restarts. It is part of Oda's own application data, not of the folders it points
at; the folders are only referenced.
- The display order is its own record and is authoritative. A new workspace leads the list; a caller
that creates one can place it at the end instead (
position: 'end').
- Each workspace has a title and an identity. The title defaults to the folder's final path segment;
a filesystem root keeps its own spelling. Titles may repeat.
- Renaming changes the title only. The identity is a generated id, never the path: paths get
normalised, so the id is the stable anchor.
Which folders can become a workspace
- A folder must be fully qualified: a filesystem root such as
C:\ or \\server\share, or an
ordinary directory.
- Refused, without creating anything: relative paths (
., \work), bare and drive-relative forms
(C:, C:work), paths that do not exist, and files. The messages read
Workspace path is not fully qualified: '<path>' and
cannot create a workspace at '<canonical>': path is not a directory.
- Creating a workspace for a folder that already has one returns the existing workspace, unchanged;
it is not retitled. The check runs on the folder's real path, so a symbolic-link alias returns the
same workspace too.
- The stored path is canonical: trailing separators,
.. and symbolic links are resolved once, at
creation, and the path is never rewritten afterwards, even when the directory disappears.
- Oda reports the folder's status:
ok when it is there, missing-dir when it is gone.
How chats join a workspace
- A chat joins the workspace of the folder it runs in. The folder recorded in the chat is matched
against the workspace's canonical path; a chat belongs to one workspace at most.
- A chat is attached only after that check. A chat with no recorded folder, one whose folder no
longer resolves, and one whose folder is a file cannot attach and remains under Ungrouped in
the sidebar.
- Each workspace keeps its chats in a manual order: a new chat attaches at the top, and running
activity never reorders them.
- When Oda starts with chats already on the computer but no stored list yet, it rebuilds the
grouping from the chats' stored headers: one workspace per folder, in the order the folders first
appear. It reads headers only, never message content, and it runs only while the list has never
been initialised.
- The automatic first-use workspace is created only when there is nothing at all to group: no stored
workspaces and no chat history, archived chats and chats without a recorded folder included. An
empty-looking sidebar is not enough, and once the workspace exists it is remembered, so deleting
it does not make Oda create another one.
Archiving and pinning a chat
- Archiving hides a chat from the grouping; the user-facing side is in
Your chats in the sidebar. The chat, its history and its place in
the workspace stay intact, and unarchiving returns it to that place, or to Ungrouped when it
belongs to none.
- Archiving a chat with work still running is refused, and the answer lists what runs: its own turn,
a running helper, a background job, or an active reminder. The message reads
cannot archive session '<id>': the session is active (<kinds>). The check covers every chat that
shares the same conversation row, not only the one being hidden.
- The stop-and-archive path used by the interface writes the archive first, then asks the running
pieces to stop, the same way your own stop actions do. A stop that fails is logged and never
undoes the archive.
- Pinning needs a known, unarchived chat, and pinned chats surface ahead of unpinned ones, most
recently pinned first. Archiving clears the pin in the same write, and unarchiving does not bring
the pin back; pinning an archived chat is refused:
cannot pin session '<id>': the session is archived.
- Archiving an id that matches no live or stored chat is refused:
cannot archive session '<id>': live sessions and session persistence hold no such session.
Removing a workspace
- Removing a workspace deletes its entry in the list only. The folder and its files are never
touched, and no chat history is ever deleted; the chats become ungrouped.
- Adding the same folder again starts a fresh workspace: a new identity, with none of the old chats
attached. The old chats stay in history, ungrouped.
- Removing a workspace that is not on the list does nothing and is not an error.
What is stored
Oda's workspace registry holds two kinds of record:
- One per workspace: the canonical path, the title, the chats in their manual order, and creation
and update times.
- One for the list itself: the display order, the pinned and archived chat sets (most recently
pinned first), the automatic first-use workspace when one was created, and a marker for a change
in progress.
Change safety
- Writes are serialised, one at a time. A change that touches two records writes the in-progress
marker first, so a start after a crash completes or rolls the change back instead of leaving it
half applied. A removal that already committed still reports success even if its cleanup step
fails.
- At start-up the stored state is checked, and inconsistencies are not guessed at: a folder claimed
by two workspaces, a chat accounted by two, or an order that repeats or misses a workspace stops
the start with a message naming the problem.
- Reading the list answers from memory; it performs no storage reads.
Questions, answered
Where is the workspace list kept?
In Oda's own application data on this computer, not inside the folders it points at. The app loads
it at start, and it survives restarts; the folders themselves are only referenced.
Can a workspace point at a drive root or a network share?
Yes. A filesystem root counts as fully qualified, so C:\ and a share such as \\server\share are
accepted, as is any ordinary directory. What is refused: relative and drive-relative forms, paths
that do not exist, and files.
What happens when I add a folder that already has a workspace?
You get the existing workspace, unchanged: it is not retitled and nothing is duplicated. The check
runs on the folder's real path, so adding an alias that resolves to the same folder also returns the
same workspace.
What happens when the folder behind a workspace is deleted or moved?
The stored path is never rewritten, and Oda does not guess a new location. The folder's status reads
missing-dir, and chats whose folder cannot be validated stay under Ungrouped.
Does unarchiving bring back a chat's pin?
No. Archiving clears the pin in the same write, and unarchiving does not restore it. Pin the chat
again to surface it ahead of unpinned chats.
Can one chat belong to two workspaces?
No. A chat belongs to one workspace at most, and a chat whose folder cannot be validated belongs to
none.
Does the workspace list reach the model?
No. The list is invisible to models and adds no prompt or request cost.
What happens if the stored list is inconsistent?
Oda refuses to guess. At start-up, an inconsistency such as a folder claimed by two workspaces, a
chat accounted by two, or an order that repeats or misses a workspace stops the start with a message
naming the problem, instead of dropping data silently.