# Share a directory with humans

> The private session directory, the fixed workspace root that humans and agents share, the private root rule, and the shared pack cache.

Canonical URL: https://www.slivingdoc.dev/docs/guides/shared-directory/ · Version: 0.1 · Updated: 2026-09-21

Full site index: https://www.slivingdoc.dev/llms.txt

By default an MCP server keeps its notebook to itself. That is the right
setting for a fleet of agents and the wrong one for a person who wants to
open the files. This guide covers the switch between the two, and the
caching decision that follows it.

## The default: a private session directory

`serve` with neither root configured takes a per-process session
directory and puts both roots inside it:

```text
<tmp>/slivingdoc-<random>/notebook    the workspace root
<tmp>/slivingdoc-<random>/private     the private root
```

Nothing has to be configured or coordinated: every server gets its own
notebook directory and its own private state, so concurrent agents never
contend for one operation lock. The tools then need no `path`, and both
the server instructions and every tool result name the directory.

The whole session directory is removed at shutdown. Nothing of value is
in it — the durable notebook is the bucket. A process killed outright
leaves the directory for the operating system to reap; no later process
reuses it.

## The switch: a fixed workspace root

Configuring either root turns the default off, and neither root is
removed at shutdown:

```text
export SLIVINGDOC_BUCKET=my-notes
slivingdoc serve --workspace-root /srv/notes
```

Use that when humans and agents share one directory, or when you want the
notebook to survive a server restart on disk. In an MCP host
configuration it is two more arguments:

```json
{
  "mcpServers": {
    "slivingdoc": {
      "command": "npx",
      "args": ["-y", "slivingdoc", "serve", "--workspace-root", "/srv/notes"],
      "env": {
        "SLIVINGDOC_BUCKET": "my-notes",
        "AWS_PROFILE": "notes"
      }
    }
  }
}
```

`--workspace-root` is the root below which request paths may live, and it
is also the notebook directory an omitted path resolves to. With it set,
`path` can address any directory below it.

`pull` and `commit` never take a session directory. They default to the
working directory, which you can still open after the process exits.

## Working in the shared directory

The host and the server share the visible directory. Agents and people
edit files there with whatever tools they already have, and the server
scans them at each call. There is no protocol between calls:

- A person edits `/srv/notes/today.md` in an editor. The next
  `notes_commit` for that path publishes the change, and so does
  `slivingdoc commit /srv/notes -m "..."` run by hand.
- An agent commits. The person's next `slivingdoc pull /srv/notes` brings
  the change down.
- Both edit different lines of one file. The merge takes both.
- Both edit the same lines. The commit returns
  [a conflict](/docs/guides/conflicts/) with markers in the file, instead
  of losing either side.

Files must be valid UTF-8 text without the NUL character. Empty files are
valid, and bytes and line endings are preserved. Symbolic links, devices,
sockets, and named pipes are rejected.

> **Note:** Sharing needs `--workspace-root`. A session directory is
> private to the server process, and it is deleted when that process
> stops.

## The private root

The private root holds the internal Git repository, the state record, and
the operation locks. It is not the notebook, and nothing edits it by
hand.

```text
slivingdoc serve \
  --workspace-root /srv/notes --private-root /var/lib/slivingdoc/private
```

> **Warning:** The private root must not sit at or below the workspace
> root, and the two must never be the same directory. Startup refuses
> otherwise. Both roots become absolute before startup.

When only `--workspace-root` is set, the private root falls back to the
user cache directory rather than to the workspace; the rule above is
about what you may configure, not about a default you can trip over.

## The shared pack cache

By default every workspace keeps its own cache of downloaded pack bytes
inside its private state. Several agents on one machine therefore each
download the same packs, and an ephemeral session throws its cache away
at shutdown. `--shared-pack-cache` moves that cache to one durable
directory per notebook:

```text
<user-cache-dir>/slivingdoc/pack-cache/<bucket>-<prefix>-<digest>/
```

Every server addressing the same endpoint, bucket, and prefix computes
the same directory from its own configuration, so agents share downloads
with no coordination: the first cold pull populates the directory, and
later pulls by any agent read from it. Entries are keyed by SHA-256 and
re-verified against the authoritative manifest on every read, so a
corrupt or foreign entry is discarded and downloaded again, never
trusted.

Only pack bytes are shared. Each workspace keeps its own private
repository, baseline, and locks.

> **Note:** Writing into the cache is best-effort. A read-only or full
> cache directory logs a warning and the operation continues, which is
> what makes a pre-populated read-only cache — baked into a container
> image, for example — work as it is.

The directory names make manual cleanup easy: remove a notebook's
directory when you are done with it, and the next pull downloads again.

## Next

- [Restrict agents with path policies](/docs/guides/path-policies/) —
  which parts of a shared notebook one process may change.
- [Resolve conflicts](/docs/guides/conflicts/) — what happens when two
  writers change the same lines.
- [Configuration](/docs/reference/configuration/) — the three flags on
  this page beside every other setting.
