Skip to the content.

Data directory

Stageflow keeps the SQLite run store, run workspaces, Host Pi agent files, and related state under one durable root. Override it with STAGEFLOW_HOME. When unset, the default is ~/.stageflow.

The operator auth file is <credential-root>/agent/auth.json. STAGEFLOW_CREDENTIAL_HOME sets that root to a directory. When it is unset, the root is the host user's ~/.stageflow. A job-local data directory is its own operator when STAGEFLOW_CREDENTIAL_HOME is set to that directory. Docker and the release and publish workflows set the override. scripts/start-ui-local.sh leaves it unset, so that server shares the machine operator store. When an existing login lives under a non-default data directory, set STAGEFLOW_CREDENTIAL_HOME to that directory.

The Host is machine-global. Catalog roots are seeded examples plus registered absolute project folders stored in the durable SQLite store (not only past-run history). sf ui registers the directory it was started in. sf mcp does not. Local sf run registers its resolved project folder before start. Remote MCP/HTTP may only use already-registered or seeded roots. See MCP — catalog roots and CLI — sf run.

Per-project settings stay at <git-root>/.stageflow/settings.json. They are not the run store.

See also CLI reference — Storage locations and Providers.

Layout

Path under $STAGEFLOW_HOME Keep / disposable Notes
state.db (+ -wal, -shm) keep Run store (SQLite, WAL mode), including the durable projects registry and the agent tables (agent): agent_definitions, agent_revisions, agent_sessions (eval conversations are rows here with source = 'eval', hidden from agent lists and removed with their eval run), agent_messages, agent_turns, agent_spans, agent_eval_scores, agent_approvals, agent_executed_payloads, agent_outbound_sends, agent_inbound_events, agent_deliveries, agent_schedules, and the eval tables (eval_runs, eval_cases, eval_results, eval_grades, eval_result_reviews, eval_result_tags and their support tables). Agent YAML stays in the project; only history is here
settings.json keep Global settings (credential source, concurrency, …)
agent/auth.json keep Operator auth file when this directory is the credential root
connections.yaml keep Host-level communication channel connections (provider settings, env:/store: secret references; never a secret value). A project-root connections.yaml or STAGEFLOW_CONNECTIONS_FILE can replace it. Not included in sf backup.
memories/<id>/ keep One memory the host keeps. memory.yaml stays version 1 (id, version, description). body.md is the cover page. Cards live beside it: the file name is a hash of the key, and the key is stored in the card. One previous cover (.body.md.prev) and one previous card copy may sit in the same folder. Replacing the cover does not delete cards. Created in the console, then attached by memory id from a pipeline or an agent. Pipelines and agents store that id only. There is no project copy. Not included in sf backup.
channel-secrets.json keep Secrets typed into the console Connections page, mode 0600. Lives in the credential root (this directory when it is the credential root). Plaintext, same trust level as agent/auth.json. Not included in sf backup.
.stageflow/channel-sends.json keep Per-workspace send ledger for channel messages (hashes and outcomes, never message text). Keeps an uncertain send from being repeated after a restart. Records older than 30 days are pruned.
agent/ keep Host Pi agent directory (PI_CODING_AGENT_DIR for the Host process). OAuth tokens for MCP servers you signed in to live in agent/mcp-oauth-encrypted (AES-256-GCM)
agents/pi-sessions/ keep Pi session files for agent conversations (one per agent session; history and costs are in state.db)
agent/mcp-cache.json disposable Tool lists cached from the last successful MCP connect or Check
mcp/.mcp.json keep MCP servers added in Settings → Project MCP, merged over the project .mcp.json. Holds ${NAME} references, never token values. Not included in sf backup; see MCP servers. Mode 0600, written atomically. A corrupt file is reported, never overwritten
secrets/mcp-secrets.json keep Write-only store for the values behind those ${NAME} references (directory 0700, file 0600, plaintext at the same trust level as channel-secrets.json)
secrets/mcp-oauth.key keep Host key for the encrypted OAuth store (0600); PI_MCP_ADAPTER_OAUTH_FILE_KEY overrides it
runs/ disposable Per-run workspaces, stage attempts, artifacts
eval-engine/ disposable The eval engine installed by sf eval engine install: eval-engine/<promptfoo-version>/ (about 1.2 GB, pinned version 0.124.0). Re-installable. The Docker image bakes it in. See Evals
eval-runs/ disposable Work directory of an eval run in progress (eval-runs/<evalRunId>/: generated engine config, results, logs). Removed when the run ends unless STAGEFLOW_EVALS_KEEP_WORKDIR=1. Eval results themselves are in state.db
a2a-artifacts/ disposable A2A artifact bytes
repos/ disposable Shared bare-clone cache (repos/<host>/<owner>/<repo>.git); Host-owned, used for repository-bound runs
worktrees/ disposable Per-run checkouts (worktrees/<runId>); Host-owned, created on repository-bound start. When a run reaches succeeded, Stageflow may reclaim the worktree (keeping run_branch); the checkout_root column can still be recorded after the directory is gone. Failed/cancelled runs keep their worktrees until retention SLIM.
cache/ disposable Reserved name; this release creates cache/jiti when the jiti MCP fallback runs
tmp/ disposable Soft-default when TMPDIR / TMP / TEMP are unset or whitespace-empty at Host boot (assertTmpdirUsable creates $STAGEFLOW_HOME/tmp then asserts writability)
backups/ disposable sf backup archives (default output)
restore-pending/ disposable Staged API restore archives + marker
service.log disposable Detached Host autostart log (stays at the root)
workshop/builds/ keep Untitled Workshop drafts. One {id}.json per build (the draft package). Always under $STAGEFLOW_HOME.
workshop/sessions/ keep Workshop Author chat sessions (History / New): per-id directory with session.json (title, timestamps, transcript, piSessionId, optional activeBuildId) and optional pi-session.jsonl. The session points at a build; it does not embed the draft. Always under $STAGEFLOW_HOME.
workshop/autosave/ disposable Older Workshop WIP slots (draft package + chat messages). The studio uses builds. For git catalog projects this usually lives under <git-root>/.stageflow/workshop/autosave/; otherwise under $STAGEFLOW_HOME/workshop/autosave/.

Workshop: builds and sessions

workshop/builds/ workshop/sessions/
Purpose The untitled draft Durable Author chat (History / New)
Contents Draft package JSON Transcript + title/timestamps + piSessionId + optional activeBuildId
Draft? Yes No — activeBuildId names the build
Root Always $STAGEFLOW_HOME Always $STAGEFLOW_HOME

History reopens the session and the build in activeBuildId. New starts a fresh session. Saved catalog YAML lives in the project (by default workshop/<pipeline-id>/), not in this directory. See Workshop Author.

For the operator keep-table and why cp state.db is unsafe, see Docker and self-hosting.

Stage workers do not use $STAGEFLOW_HOME/agent/ as their Pi agent directory. Each stage attempt binds PI_CODING_AGENT_DIR to a per-attempt directory under that run's workspace (runs/<runId>/stages/<stageId>/attempts/<n>/.pi-agent).

models.json sits beside the operator auth file. The Cursor key file is <credential-root>/agent/cursor-api-key. A usable agent/auth.json in a data directory is the store only when that directory is the credential root.

Temp dir: Host boot still requires a writable temp directory. If TMPDIR / TMP / TEMP are unset or whitespace-empty, Stageflow soft-defaults to $STAGEFLOW_HOME/tmp (creates it), then asserts writability. An explicit unwritable TMPDIR still fails with tmpdir_unusable.

Stage agents' Pi read, write, and edit tools deny paths whose real path is inside the durable root and outside that run's workspace (stageflow_path_denied). On repository- or path-bound runs, checkoutRoot (the Host worktree or checkout path) is allowlisted for those file tools so the agent can edit the bound tree; other durable-root paths (state.db, agent/, sibling worktrees) stay denied. That is defence in depth, not a sandbox — bash is not path-restricted.

Container image user and volumes

The published image runs as 10001:10001 (stageflow). Named volumes are the default mount for the durable root. The process never recursively changes ownership of the data root on boot — if the volume is not writable by that uid/gid, startup fails with a message that includes the live uid and a chown hint.

Version support