Skip to content

Configuration

Gates setting

The app stores gate settings under the key ninebrains.gates.

FieldRangeDefault
testingRigor0–105
securityRigor0–105
evidenceRetentionDays1–365030

Change both rigor values with the sliders in Settings → Gates. The evidence retention has no control; the Gates page shows the current value. Verification gates explains what each rigor level attaches.

Per-project gate preferences

Each project can hold these values, all set in Settings → Gates → Tests after picking the project. Rigor override sets testingRigor and securityRigor together to one level from 0 to 10; Use app default clears both.

FieldMeaning
testingRigorOverrides the app’s testing rigor for this project. Empty means use the app setting
securityRigorOverrides the app’s security rigor for this project. Empty means use the app setting
testCommandThe command the tests gate runs, up to 500 characters. Only you set it, never a job or a file in the worktree

With no testCommand, the tests gate reports a setup problem and the job is blocked. See Verification gates.

Tests gate options

The tests gate reads two per-project options. Both default to off, including for projects set up before they existed. Turn them on with the Allow network and Allow unsandboxed switches in Settings → Gates → Tests. Only you can change them: no job, lane or Brain session can. They apply only when the gate runs in one of that project’s lane worktrees.

OptionWhen on
testsGate.allowNetworkThe test command may reach any network address, not only localhost
testsGate.allowUnsandboxedThe test command may run without an OS sandbox, on Windows or on Linux without bubblewrap. This is an accepted risk: the command then runs as you with full access

Environment variables

Ninebrains reads these from the environment it was started with. On macOS, an app opened from the Dock or Finder does not see variables set in your shell. Start it from a terminal to pass them.

For users

VariableEffect
NINEBRAINS_SECRET_<NAME>Supplies the pack secret or setting <NAME>, for example NINEBRAINS_SECRET_GOOGLE_ACCESS_TOKEN. Used when the app’s secret store has no value for it. An empty value counts as unset
NINEBRAINS_SECRET_AEO_MCP_BASE_URLThe SEO pack’s server address. Default https://aeo.advancelabs.dev/api/mcp. Must be https, or http on localhost. There is no plain AEO_MCP_BASE_URL variable; the pack reads it as a secret. See Packs
CLAUDE_CONFIG_DIRThe Claude Code config directory lanes use, and where Claude hooks are installed. Default ~/.claude. See Accounts
CODEX_HOMEThe Codex config directory lanes use, and where Codex hooks are installed. Default ~/.codex
EMDASH_USER_DATA_DIRReplaces the whole app data folder: databases, logs and settings
EMDASH_WORKSPACE_SERVER_ARTIFACTS_URLWhere remote (SSH) projects download the workspace server. The default points at Ninebrains releases, which do not carry it yet
TELEMETRY_ENABLEDSet to false, 0 or no to turn telemetry off. No telemetry endpoint is built in, so nothing is sent either way
EMDASH_DB_FILEReplaces the app database path
EMDASH_LOG_FILEReplaces the log file path
EMDASH_LOG_LEVELThe log level. Falls back to LOG_LEVEL

Set by the app

These are set by Ninebrains for the processes it starts. You read them; you do not set them.

VariableWhereValue
EMDASH_PORTEvery task and lane terminal, and project scriptsA port from 50000 to 59990, in steps of 10, derived from a hash of the worktree path. Start your dev server on it
EMDASH_TASK_ID, EMDASH_TASK_NAME, EMDASH_TASK_PATH, EMDASH_ROOT_PATH, EMDASH_DEFAULT_BRANCHThe same placesThe task and its worktree
NINEBRAINS_BRAIN_URL, NINEBRAINS_TOKEN, NINEBRAINS_LANE_IDOnly the Brain’s MCP server process for a laneHow that server reaches the app

The app’s own EMDASH_* variables are removed from the environment agents get.

For builds and development

VariableWhenEffect
NINEBRAINS_GITHUB_OAUTH_CLIENT_IDBuild timeBakes in a GitHub OAuth app ID, which turns on device-flow sign-in. Empty by default. Setting it on an installed app does nothing
FLAG_<NAME>Dev builds onlyForces feature flag <name> on (true or 1) or off. Ignored in packaged builds. No feature in this build reads a flag
EMDASH_SKIP_ELECTRON_REBUILD=1Install timeSkips rebuilding native modules for Electron

Some switches are fixed when the app is built, with no variable to change them: auto-update, the hosted account, the telemetry settings card and user packs are all off.

File locations

The app data folder is:

OSBuilt appDev build (pnpm run dev)
macOS~/Library/Application Support/ninebrains~/Library/Application Support/ninebrains-dev
Linux~/.config/ninebrains~/.config/ninebrains-dev
Windows%APPDATA%\ninebrains%APPDATA%\ninebrains-dev

EMDASH_USER_DATA_DIR replaces it. Inside it:

PathWhat
emdash4.dbThe app database (the name is kept from Emdash)
ninebrains-brain.dbThe Brain database: jobs, edges, mailbox, runs. Mode 0600
logs/emdash.logLogs, 5 MB per file, 5 files kept
ninebrains/Ninebrains’ own files. Mode 0700, and denied to every lane’s sandbox
ninebrains/lanes/<launchId>/One folder per running lane launch: mcp.json, and for Claude settings.json, both mode 0600. Deleted when the lane stops, and swept when the app starts
ninebrains/runs/<runId>.jsonlUnattended run transcripts, redacted, mode 0600
ninebrains/evidence/<jobId>/<attempt>/Gate evidence and the verdict for each attempt. Kept for 30 days

Outside the data folder, see Files outside the data folder.

.emdash.json

A project can keep shared settings in .emdash.json at the repository root. The file name is kept from Emdash. Ninebrains writes it only when you choose to share a project’s settings.

{
"preservePatterns": [".env.local"],
"shellSetup": "source .venv/bin/activate",
"scripts": {
"prepare": "",
"setup": "pnpm install",
"run": "PORT=$EMDASH_PORT pnpm dev",
"teardown": ""
}
}
KeyMeaning
preservePatternsGitignored files to copy into each new worktree, such as local env files
shellSetupA shell line run before each of the project’s scripts, terminals and agent sessions starts
scripts.prepare, scripts.setup, scripts.run, scripts.teardownThe project’s lifecycle scripts

Other keys are ignored. A file that does not parse is treated as empty.

The auto-run switches and project environment variables are not part of the file. They are per-machine settings in the project’s Settings tab. By default, setup runs automatically in a new task and run does not.