The workspace filesystem

Sudo does not drive a catalogue of per-surface tools. He is handed the workspace as a directory tree and works on it with ordinary commands. That is why he needs no new tool when the product grows a new kind of surface: a new export folder is a new folder.

The mounts

/
├── workspace/   the configuration, exactly as the definitions export writes it   [writable]
├── reference/   a generated example workspace, one well-formed file per surface  [read-only]
├── docs/        one page per code-execution scope, plus the schema helper         [read-only]
├── sdk/         the C# surface your workspace code is written against             [read-only]
├── proc/        live runtime state, regenerated on every read                     [read-only]
├── session/     the assistant's own to-do list                                    [read-only]
├── stage/       the files you uploaded to the Stage area, as text                 [read-only]
└── tmp/         scratch, discarded with the session                              [writable]

Only two of them accept writes, and only a write under /workspace is a change to your workspace. That is what makes diff and commit answerable by comparing one directory against the live configuration.

Directories are synthesised from the file names rather than stored. The export is a flat list of paths, and a tree kept beside it could disagree with it, so one list is the source of truth for ls, find, grep -r and the diff alike.

/workspace — the configuration

The same layout as the workspace-definitions export zip, the WebDAV mount and the git-tracked configuration repository. Everything you configure by hand in the admin pages has a file here:

Path Surface Format
code/endpoints/ Custom endpoints .cs
code/chat-ai-tools/ AI tools .cs
code/agents/ Agents .cs
code/skills/ Skills .md
code/ai-assistants/ AI assistants .cs
code/ai-prompt-templates/ Prompt templates .cs
code/ai-providers/ Custom-code AI providers .cs
code/scheduled-tasks/ Custom-code scheduled tasks .cs
code/data-connector-tasks/ In-workspace data connectors .cs
code/migration-tasks/ Migrations .cs
code/indexes/code/ Code indexes .cs
code/indexes/search/ Search code indexes .cs
code/entity-post-processing/ Entity post-processing .cs
config/schemas/nodes/ Node schemas .json
config/schemas/edges.json Edge schemas .json
config/schemas/nodes/styles/ Node styles .json
config/schemas/nodes/rendererers/ Node renderers .json
config/indexes/others/ Other index settings .json
config/chat-policies/ Chat policies .json
config/secrets/ Secret declarations (names only, never values) .json
config/packages/ Installed NuGet package declarations .json
config/search.json Search settings .json
config/interface.json Interface settings .json
config/file-indexing.json File-indexing settings .json
config/chat-policy-enforcement.json Chat-policy enforcement settings .json
config/general.json General workspace settings .json
nlp/spotters/, nlp/patterns/, nlp/pipelines/, nlp/linking/ NLP configuration .json

A file whose path the classifier cannot name is a file commit would silently drop, so build refuses it rather than passing it through.

Editing a file changes nothing until you approve it

Writes under /workspace land in the session's own overlay on top of the live configuration. The workspace is untouched until you approve a commit.

/reference — a worked example of every surface

A generated example workspace, built from the same content classes the real exporter uses, with one well-formed file per kind of surface. It is what Sudo reads when he is unsure what a file of a given kind looks like, instead of guessing from memory, and it is regenerated with the product, so it cannot drift out of date the way a hand-written template would.

/docs — the code-execution scopes

One page per code-execution scope: what an endpoint's scope exposes, what an AI tool's does, what a data connector's does, plus the generated graph-schema helper for your workspace's own node and edge types. The type command serves the same pages for a single type.

/sdk — the C# surface your code is written against

The types and methods that custom endpoints, AI tools, connectors, indexes, scheduled tasks and custom front ends are written against, as files grouped by area (Query/, Endpoints/, Connector/, Search/, AITools/, FrontEndComponents/, …) with an index.tsv to grep.

It is a partial extract by design: signatures and documentation, with method bodies rendered as { ... } and non-surface members left out. The point is to let Sudo get a call right, not to ship the product's source into a chat.

/proc — what the workspace is doing now

Every file here is generated when it is read, in the shape /proc has on Linux:

File Contents
nodetypes, edgetypes node and edge types with counts, key field and field count (TSV)
exceptions the 100 most recent recorded exceptions (JSON)
metrics endpoint and AI-tool call metrics (JSON)
audit recent configuration commits, who changed what and when (JSON)
connectors data connectors and their last run (JSON)
indexes indexes and their status (JSON)
embeddings embedding models and settings (JSON)
scheduled-tasks schedules and last outcome (JSON)
migrations migration tasks, status and progress (JSON)
access-groups access groups (JSON)
logs the tail of the server's own log, newest last (text)
runs/ one folder per thing this session ran: status, log, output, error

Because it regenerates on every read, the same cat run a minute later shows how far a still-running task has got, and jq works on it directly:

jq '.[] | select(.type == "System.NullReferenceException") | .message' /proc/exceptions
awk -F'\t' '$2 > 1000' /proc/nodetypes

Nothing under /proc is configuration and nothing here can be edited or committed.

/stage — the files you handed him

Files uploaded to the private Stage area, served as their text rather than their bytes: a PDF's bytes are no use to a shell, and the indexed text is what answering a question about the upload actually needs. A file nothing has indexed yet reads as a note pointing at the extract command, rather than as an empty file that looks like an empty document.

That is what makes "here is a CSV, build me a connector and a schema for it" a request he can start from.

/session — his own plan

todo.md, rendered from the list the tasks command maintains. It is generated and never parsed, and the mount refuses writes, so tasks is the only way to change it. A plan that could also be half-edited with sed would have two sources of truth and no way to tell which one is current.

The list outlives the conversation, which is what makes a multi-step change survive a session that is picked up again the next day.

/tmp — scratch

Writable, and thrown away with the session. Nothing here is ever part of a commit.

© 2026 Curiosity. All rights reserved.