Atlas Configuration Reference
This article lists every setting Timebase Atlas reads, where each one lives, what it defaults to, and whether a change needs a restart.
Overview#
This article lists every setting Timebase Atlas reads, where each one lives, what it defaults to, and whether a change needs a restart. Use it when you are installing Atlas, moving it to a new host, pointing it at a different Timebase Pulse, or trying to work out why an edit you made had no effect.
Atlas is a single component: one container (or one Windows service) serving both the browser interface and the API from the same process. There is no separate user interface process and no separate settings file for one.
Almost everything you will change lives in one file, settings.config, in the Atlas Settings folder. Atlas writes that file for you on first start. A handful of values (the folder paths themselves, and the environment name) can only be supplied as environment variables or command-line arguments, because Atlas has to know where to look before it can read any file.
Where settings come from, and which one wins#
Atlas loads its configuration from six places. Later entries in this list override earlier ones for the same key.
The file carries a version.
settings.configopens with"version": "1.0.0", and Atlas migrates an older file forward when it starts. See Configuration file versions and upgrades.
| Order | Source | Notes |
|---|---|---|
| 1 (weakest) | appsettings.json |
Ships inside the installation. Do not edit; your change is replaced on upgrade |
| 2 | appsettings.{Environment}.json |
For example appsettings.Docker.json. Also ships inside the installation |
| 3 | settings.config |
The operator's file, in the Settings folder |
| 4 | Environment variables | Set in docker-compose.yml or the host environment |
| 5 (strongest) | Command-line arguments | Always the final word |
Important: an environment variable takes precedence over the settings file. Where a key is set both in
settings.configand as an environment variable indocker-compose.yml, the environment variable is the one in effect, and a command-line argument outranks both. A value in the file holds only where nothing outranks it, so when a change in the file seems ignored, look for a matchingenvironment:entry first.
settings.Docker.config is not a file in the volume and not a layer. It is an overlay embedded in the image, applied once: the first time Atlas starts into an empty volume it composes settings.config from its template patched with that overlay, which sets Pulse:Host to pulse. After that only settings.config exists and is read, so edit it there, or set Pulse__Host as an environment variable, which outranks the file.
The exception: the Settings folder itself#
The Settings path cannot come from settings.config, because Atlas has to resolve that path before it can find the file. It is read from appsettings.json, an environment variable, or the command line only.
The Data, Logs and Certificates paths are resolved later, over the complete stack, so a value for one of those in settings.config would beat the environment variable in the normal way.
How the files are created#
On first start Atlas writes settings.config into the Settings folder from a copy embedded in the program, then writes the matching settings.{Environment}.config overlay if one is embedded for that environment. Both are loaded with file watching switched on, so Atlas notices an edit immediately, but only one section actually acts on it without a restart (see Which changes need a restart).
If Atlas cannot create those files it prints a fatal error naming the path it could not initialise and stops.
Ports and addresses#
| Purpose | Port | Where it is set |
|---|---|---|
| HTTP | 4551 |
Kestrel:Endpoints:Http:Url in settings.config |
| HTTPS | 4552 |
Kestrel:Endpoints:Https:Url in settings.config |
Atlas redirects every plain HTTP request to HTTPS, so both ports must be published for the interface to be reachable. The Compose file in Start Here for Docker publishes both.
4552 is not optional in practice. Browsers only allow microphone access over HTTPS or on localhost, so the dictation button in the assistant cannot work without it.
Everything Atlas serves is on the same two ports. There is no second port and no second process.
| Path | What it is |
|---|---|
/ |
The Atlas browser interface |
/api/v1/... |
The API for programmatic clients. Needs a Pulse bearer token |
/api/help |
The built-in API reference (Swagger), served in every environment |
/api/v1.json, /api/i3x.json |
The API descriptions behind /api/help |
/i3x/v1/... |
The i3X interoperability surface |
/mcp |
The assistant tool endpoint |
/hubs/connector |
Where Timebase Connector connects |
/hubs/v1/branches/{branch}/domains/{domain}/subscribe |
Live values and type descriptions for subscribers |
/hubs/logs |
The live log tail the interface shows |
/app/... |
Internal glue for the browser interface. Not an integration surface |
If you are writing firewall or reverse-proxy rules, all of the above must reach the same host and port.
Environment variables#
Only the folder paths and the environment name are usefully set as environment variables. Everything else belongs in settings.config.
| Variable | Default | Effect | Takes effect |
|---|---|---|---|
ASPNETCORE_ENVIRONMENT |
Production (the Docker image sets Docker) |
Chooses which appsettings.{Environment}.json and settings.{Environment}.config are loaded |
Restart |
Config |
C:\ProgramData\Flow Software\Timebase\Atlas\Config |
The Git-backed store: domains, libraries and branches, plus views, assistant agents and skills, and draft-session working copies | Restart |
Data |
C:\ProgramData\Flow Software\Timebase\Atlas\Data |
Machine-owned state: the assistant's chat sessions, threads and script exports, and the licensing state file. Safe to delete while Atlas is stopped: you lose chat history, never configuration | Restart |
Settings |
C:\ProgramData\Flow Software\Timebase\Atlas\Settings |
Where settings.config is written and read |
Restart |
Logs |
C:\ProgramData\Flow Software\Timebase\Atlas\Logs |
Where daily log files are written | Restart |
Certificates |
C:\ProgramData\Flow Software\Timebase\Atlas\Certificates |
Where the generated certificate timebase-generated.pfx and its password file are kept |
Restart |
The platform Compose file in Start Here for Docker sets Config=/atlas/config, Settings=/atlas/settings, Logs=/atlas/logs, Certificates=/atlas/certificates and Data=/atlas/data, all inside the named volume atlas.
if Atlas cannot create the Certificates folder it prints a fatal error naming the certificates path and stops.
always keep the Config folder on a persistent volume. It holds every domain model, library, branch and commit.
Environment variables Atlas does not read#
Two of these turn up often enough to be worth naming, because setting them looks like it should work:
| Variable | What to do instead |
|---|---|
ANTHROPIC_API_KEY |
Atlas never calls a model provider directly. Register the provider and its key in Pulse - see Configuring Gage LLM providers and models. |
ASPNETCORE_URLS |
Atlas takes its listening addresses from Kestrel:Endpoints in settings.config, which wins. Change the ports there. |
Kestrel (the web server)#
Section Kestrel in settings.config.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Kestrel:Endpoints:Http:Url |
text | http://0.0.0.0:4551 |
The plain HTTP address and port. 0.0.0.0 means all network interfaces |
Restart |
Kestrel:Endpoints:Https:Url |
text | https://0.0.0.0:4552 |
The HTTPS address and port | Restart |
Kestrel:Endpoints:Https:Certificate:Path |
text | "" (empty) |
Path to your own certificate file. Empty means Atlas manages a certificate for you (see Certificates) | Restart |
Kestrel:Endpoints:Https:Certificate:Password |
text | not set | Password for the certificate named above. A secret; see Secrets | Restart |
Kestrel:Endpoints:Https:Certificate:PasswordPath |
text | not set | Path to a file holding the certificate password. When unset, Atlas uses a file beside the certificate | Restart |
if you change the HTTP or HTTPS port, update the ports: mapping in docker-compose.yml to match. Publish 4552 as 4552: the HTTPS redirect carries the port Atlas itself is listening on, so remapping the host side sends browsers to a port that does not answer.
Request limits#
Section Kestrel:Limits. Every key here is optional. A key you do not set keeps the web server's own default, with the one exception noted below.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Kestrel:Limits:MaxRequestBodySize |
number (bytes) | unlimited | Largest request Atlas accepts. Atlas defaults to unlimited rather than the usual 30 MB, so that Timebase Connector can stream large payloads. 0 also means unlimited |
Restart |
Kestrel:Limits:MaxConcurrentConnections |
number | web server default | Cap on open connections | Restart |
Kestrel:Limits:MaxConcurrentUpgradedConnections |
number | web server default | Cap on upgraded (WebSocket) connections | Restart |
Kestrel:Limits:KeepAliveTimeoutSeconds |
number | web server default | How long an idle connection is held open | Restart |
Kestrel:Limits:RequestHeadersTimeoutSeconds |
number | web server default | How long Atlas waits for request headers | Restart |
Kestrel:Limits:MaxRequestHeaderCount |
number | web server default | Largest number of headers on one request | Restart |
Kestrel:Limits:MaxRequestHeadersTotalSizeKB |
number (KB) | web server default | Largest total header size | Restart |
Kestrel:Limits:MaxRequestLineSize |
number (bytes) | web server default | Largest request line | Restart |
Kestrel:Limits:Http2MaxStreamsPerConnection |
number | web server default | HTTP/2 stream cap | Restart |
Kestrel:Limits:Http2InitialConnectionWindowSize |
number | web server default | HTTP/2 connection window | Restart |
Kestrel:Limits:Http2InitialStreamWindowSize |
number | web server default | HTTP/2 stream window | Restart |
Kestrel:Limits:MinRequestBodyDataRateBytesPerSecond |
number | web server default | Slowest acceptable upload rate. 0 switches the check off |
Restart |
Kestrel:Limits:MinRequestBodyDataRateGracePeriodSeconds |
number | 5 |
Grace period for the rate above | Restart |
Kestrel:Limits:MinResponseDataRateBytesPerSecond |
number | web server default | Slowest acceptable download rate. 0 switches the check off |
Restart |
Kestrel:Limits:MinResponseDataRateGracePeriodSeconds |
number | 5 |
Grace period for the rate above | Restart |
setting Kestrel:Limits:MaxRequestBodySize to a positive number can break Connector ingestion. A large payload is rejected at the network level before Atlas can report a useful error.
Authentication#
Section Pulse:Auth in settings.config. Pulse is the Timebase component that checks credentials.
Atlas's OAuth client lives inside the Pulse section, alongside the address of the Pulse it authenticates against. There is no separate identity-provider address to keep in step with it.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Auth:Enabled |
true/false | true as shipped |
Switches Pulse sign-in on. With it off, the interface opens without signing in and the assistant is not offered at all | Restart |
Pulse:Host |
text | localhost (Docker overlay sets pulse) |
Hostname of your Pulse instance | Restart |
Pulse:Port |
number | 4542 |
Pulse's HTTPS port | Restart |
Pulse:UseTls |
true/false | true |
Whether to reach Pulse over HTTPS | Restart |
Pulse:Auth:ClientId |
text | Atlas |
The name of Atlas's OAuth client in Pulse. It is also the audience a calling client's token must carry | Restart |
Pulse:Auth:ClientSecret |
text | "" (empty) |
The secret for that client. A secret; see Secrets | Restart |
the built-in fallback for Pulse:Auth:Enabled is false, but the settings.config Atlas writes on first start sets it to true. A default installation is therefore protected, and every API call without a Pulse bearer token is rejected.
with Pulse:Auth:Enabled set to true, leaving Pulse:Host or Pulse:Port blank stops Atlas from starting, with the message Pulse Host and Port is required when authentication is enabled.
for a programmatic client to call /api/v1/..., its Pulse registration must list Atlas (the value of Pulse:Auth:ClientId) among its audiences. A token issued without that audience is rejected.
Warning: the shipped empty
Pulse:Auth:ClientSecretdoes not work, and this is the most common first-run failure. Pulse seeds anAtlasclient for you on its first start, so you do not need to create one. But it generates that client's secret as a random GUID, and Pulse compares secrets exactly - an empty string never matches. A default Atlas paired with a fresh Pulse therefore fails to obtain a token, and the assistant and licensing stay unavailable until you either read the generated secret out of Pulse or rotate it to a value you choose, and put that value here.In Docker or compose this is an ordering problem: the secret does not exist until Pulse has started. Start Pulse first, set the secret, then start Atlas. Atlas does not recover on its own once it has failed, so restart it after the secret is in place. See Registering Timebase apps as OAuth clients in Pulse (
pulse-oauth-clients.md).
Pulse connection#
Section Pulse in settings.config. One block, three consumers: licensing, certificates, and the assistant. Changing Pulse:Host moves all three at once.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Host |
text | localhost (Docker overlay sets pulse) |
Hostname of your Pulse instance | Restart |
Pulse:Port |
number | 4542 |
Pulse's port | Restart |
Pulse:UseTls |
true/false | true |
Whether to reach Pulse over HTTPS | Restart |
Pulse:Cert:Enabled |
true/false | true |
Lets Atlas manage its own certificate and sync one from Pulse. Set to false to supply your own |
Restart |
Certificates#
When Pulse:Cert:Enabled is true and an HTTPS endpoint is configured, Atlas checks for a valid certificate before the web server starts and generates a self-signed one if it needs to. The generated file is timebase-generated.pfx in the Certificates folder. Once Pulse is reachable, Atlas also syncs the Pulse certificate authority so browsers stop warning.
Setting Pulse:Cert:Enabled to false turns the whole mechanism off, including the hot reload, so you must then supply Kestrel:Endpoints:Https:Certificate:Path yourself.
Licensing#
Atlas acquires its licence through Pulse, using the same Pulse:Host / Pulse:Port / Pulse:UseTls values and the existing Pulse:Auth:ClientId client. There is no separate licensing setting to fill in.
Licensing does not gate any API call. It is read-only visibility, shown in the interface. You do not need a licence to call the API.
Atlas does not read Portal:Host, Portal:Port or Portal:UseTls, so setting them in Atlas has no effect. Atlas reaches Portal only through Pulse.
The assistant#
Atlas's assistant runs on models served by your Pulse instance through Gage. Atlas never declares a model, a provider, an endpoint or an API key of its own. The model catalogue comes from Pulse.
Everything in this section switches the assistant on and points it at Pulse. The providers, API keys and model handles themselves are configured in Pulse, and none of the settings below will produce a working assistant on their own. See Configuring Gage LLM providers and models (
pulse-gage-providers.md), and note that Gage ships hard token quotas by default rather than unlimited access.
Gage#
Section Pulse:Gage in settings.config.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Gage:Enabled |
true/false | true |
Switches the assistant on. Off means it is simply not offered, with no partial mode and no call to Pulse | Restart |
Pulse:Gage:Agents |
name-to-text map | {} (empty) |
Per-agent model override. Maps an agent name to a Pulse model handle in the form providerId/logicalModelId, or to the word default. Names are matched without regard to capitalisation. An agent not listed here uses its own declared model, then the installation's default model, marked in Pulse |
Restart |
Pulse:Gage:ThinkingEnabled |
true/false | true when unset |
Whether extended thinking is requested. Set to false to switch it off |
Restart |
Pulse:Gage:ThinkingBudgetTokens |
number | 16000 when unset |
How much extended thinking to allow. Only applies when the key above is not false |
Restart |
the assistant needs Pulse:Auth:Enabled to be true. The Gage path requires a caller it can identify and meter, so with authentication off the assistant reports itself as not ready. There is no anonymous assistant mode.
Everything else the assistant needs is derived from settings you have already made: the Pulse address from Pulse:Host / Pulse:Port / Pulse:UseTls, and the credentials from Pulse:Auth:ClientId and Pulse:Auth:ClientSecret.
Assistant guardrails#
Section Pulse:Gage:Guardrails. Shipped commented out in settings.config; the defaults below apply whether or not you uncomment it.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Gage:Guardrails:Enabled |
true/false | true |
Confines the assistant's shell and file tools to the calling chat session's own workspace folder. The data folder and the rest of the machine are out of bounds | Next tool call |
Pulse:Gage:Guardrails:AdditionalAllowedRoots |
list of paths | [] (empty) |
Extra folders the assistant may read, write and run in, for example a shared import folder | Next tool call |
this is a security control. Turning it off restores unconfined behaviour for the assistant's shell and file tools.
a blank or empty entry in AdditionalAllowedRoots stops Atlas from starting, with the message Pulse:Gage:Guardrails:AdditionalAllowedRoots contains a null or blank entry..
Dictation#
Section Pulse:Gage:Dictation. Speech-to-text runs on the Atlas server; audio never leaves your infrastructure. The small.en model is built into the Docker image and into the Windows installation, so dictation works with no extra setup.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Gage:Dictation:Enabled |
true/false | true |
Switches dictation off outright when set to false |
Restart |
Pulse:Gage:Dictation:ModelPath |
text | /app/models/ggml-small.en-q5_1.bin in Docker, models/ggml-small.en-q5_1.bin otherwise |
The speech model file. Any GGML-format Whisper model works. A relative path is measured from the Atlas installation folder, never from the working folder | Restart |
Pulse:Gage:Dictation:ThreadCount |
number | the smaller of 8 and the machine's processor count |
Processor threads per transcription. Lower it on a host doing other heavy work | Restart |
Pulse:Gage:Dictation:MaxAudioDurationSeconds |
number | 120 |
Longest clip accepted | Restart |
Pulse:Gage:Dictation:MaxAudioDurationSlackSeconds |
number | 10 |
Tolerance added to the limit above | Restart |
Pulse:Gage:Dictation:MaxUploadBytes |
number (bytes) | 26214400 (25 MB) |
Largest audio upload accepted | Restart |
Pulse:Gage:Dictation:BiasPrompt |
text | a built-in prompt | Vocabulary hint that nudges recognition towards Timebase terms | Restart |
Pulse:Gage:Dictation:MaxConcurrentTranscriptions |
number | 2 |
How many transcriptions run at once | Restart |
Pulse:Gage:Dictation:QueueTimeoutSeconds |
number | 30 |
How long a queued transcription waits before giving up | Restart |
browsers only allow microphone access over HTTPS or on localhost. The dictation button is unusable on a production install reached over plain HTTP, no matter how this section is configured.
Each of the numeric keys above stops Atlas from starting when set to a nonsensical value, with a message naming the key, for example Pulse:Gage:Dictation:ThreadCount must be a positive integer..
Assistant resilience#
Section Pulse:Gage:Resilience. Advanced; leave these alone unless you are diagnosing a specific problem.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Pulse:Gage:Resilience:HeartbeatIntervalSeconds |
number | 15 |
How often a running conversation sends a keepalive | Restart |
Pulse:Gage:Resilience:ToolCallTimeoutSeconds |
number | 60 |
How long one assistant tool call may run | Restart |
Pulse:Gage:Resilience:RunIdleWatchdogIntervalSeconds |
number | 300 |
How often an idle run is checked | Restart |
Pulse:Gage:Resilience:McpReconnectBackoffSeconds |
number | 5 |
How long to wait before retrying a dropped tool-server connection | Restart |
0 switches a knob off. A value outside the range 0.001 to 86400 seconds stops Atlas from starting.
Live values#
Section LiveProjection in settings.config.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
LiveProjection:AllowedLatencyMs |
number (milliseconds) | 2000 |
How long Atlas waits for a lagging data source before it publishes a live row without that value. Smaller means fresher rows and less tolerance for a slow source | Restart |
This is the global fallback. A connector may declare its own tolerance per binding path when it accepts a subscription, and that value wins over this one.
a value outside 0 to 86400000 stops Atlas from starting, with the message LiveProjection:AllowedLatencyMs must be in [0, 86400000] milliseconds..
Startup behaviour#
Section Compilation in settings.config. Not present in the shipped file; add it if you need to change the default.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Compilation:AutoRecompileOnStartup |
true/false | true |
Recompiles every domain that was compiled before the last restart, in the background, as soon as Atlas comes up. false leaves domains uncompiled until somebody compiles them |
Restart |
Atlas remembers which domains were compiled in compiled-worlds.json in the Config folder. This setting is what explains the burst of processor activity shortly after a restart, and why domains are queryable straight away without a manual recompile. A domain that reads live data from a connector is the exception: it waits for its connector to report in.
Draft sessions#
Section Atlas:DraftSessions in settings.config. Not present in the shipped file.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Atlas:DraftSessions:Enabled |
true/false | true |
Keeps work that failed validation in a private draft belonging to the person who saved it, rather than putting it on the branch | Restart |
Atlas:DraftSessions:IdleTimeout |
duration | 7.00:00:00 (7 days) |
How long an untouched draft is kept before it is reclaimed | Restart |
Atlas:DraftSessions:SweepInterval |
duration | 01:00:00 (1 hour) |
How often Atlas looks for drafts to reclaim | Restart |
with this on, a save that fails validation returns success but the branch does not move. The only signal is a response header. If somebody reports "I saved it and compiled it and nothing changed", this is the first thing to check. Setting Enabled to false restores the earlier behaviour exactly and is the documented recovery lever.
a zero or negative IdleTimeout or SweepInterval stops Atlas from starting, with a message naming the key, for example Atlas:DraftSessions:IdleTimeout must be positive (was 00:00:00)..
Git#
Section Git in settings.config. Not present in the shipped file.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Git:DefaultBranch |
text | not set | Names the branch Atlas treats as the default, for example trunk. Used only if a branch with that name exists; otherwise Atlas prefers main, then master, then whichever branch the repository was created on |
Restart |
A repository Atlas creates for you is initialised on main.
The i3X surface#
Section I3x in settings.config. Not present in the shipped file. Only relevant if another system reads Atlas over the i3X interoperability standard.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
I3x:Branch |
text | main |
The branch i3X clients read | Restart |
I3x:Domain |
text | not set | Restricts i3X to a single domain. Leave unset to expose every domain and every visible library on the branch | Restart |
I3x:MaxCompositionDepth |
number | 64 |
How many levels deep a rollup request may descend before Atlas truncates the answer | Restart |
I3x:MaxHistoryValues |
number | 10000 |
The most entries one object's /objects/history result may hold. A longer range is cut there, keeping the earliest, and the response is 206 so the client can continue from the last timestamp. Zero or less means the default |
Restart |
I3x:SubscriptionTtlSeconds |
number | 300 |
How long an i3X subscription survives without activity | Restart |
I3x:SubscriptionMaxPendingBatches |
number | 1000 |
How many sync batches a subscription may hold unacknowledged. Past this the oldest batch is dropped and the next /sync answers 206. Zero or less means the default |
Restart |
I3x:ServerName |
text | not read | The i3X /info endpoint returns a fixed name |
n/a |
I3x:Domain names a domain, not a branch. Leave it unset unless you are serving a specific domain over i3X.
Logging#
Section Serilog in settings.config.
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
Serilog:MinimumLevel:Default |
text | Warning |
Minimum level for everything. Accepted values: Verbose, Debug, Information, Warning, Error, Fatal |
Restart |
Serilog:MinimumLevel:Override:Timebase.Atlas |
text | Information |
Minimum level for Atlas's own messages. Set to Debug while troubleshooting |
Restart |
Serilog:MinimumLevel:Override:Microsoft |
text | not set (inherits Default) |
Minimum level for web-framework messages. Add this key yourself if you need to raise framework logging to Information while troubleshooting HTTP or live-value connections |
Restart |
Log messages go to three places at once: the console, the live log view in the browser interface, and daily files in the Logs folder. Files roll every day and the last seven are kept.
Serilog:MinimumLevel:Override:Microsoft is a key you add, not one you edit. It is not in the shipped file, so you will not find it there.
Other settings#
| Key | Type | Default | Effect | Takes effect |
|---|---|---|---|---|
FunctionLibraries |
name-to-path map | {} (empty) |
Extra .NET assemblies your calculation functions may call. Each entry maps a name to the full path of a .dll file, which must exist on the Atlas server |
Restart |
DetailedErrors |
true/false | true as shipped |
A standard ASP.NET Core framework setting. The host acts on it, not Atlas | Restart |
FunctionLibraries lives in appsettings.json as an empty block and can be set in settings.config like any other key. Verified and appsettings.json. Leave it empty unless your functions need an external library.
Example:
{
"FunctionLibraries": {
"MyMathLib": "/atlas/data/libs/MyMathLibrary.dll"
}
}
Secrets#
Two values in the configuration are sensitive.
| Key | What it is | How to supply it |
|---|---|---|
Pulse:Auth:ClientSecret |
The secret for Atlas's OAuth client in Pulse | Put it in settings.config and restrict the file's permissions, or pass it as a command-line argument |
Kestrel:Endpoints:Https:Certificate:Password |
The password for a certificate you supply yourself | Prefer Kestrel:Endpoints:Https:Certificate:PasswordPath, pointing at a permission-restricted file |
a Pulse__Auth__ClientSecret environment variable in the Compose file outranks the empty Pulse:Auth:ClientSecret the shipped settings.config carries, so it does take effect - but it also leaves the secret in the Compose file and in docker inspect output. Prefer the component's setup form, which writes the secret into settings.config in the volume, or fill it in there by hand.
The Certificates folder holds the private key for the certificate Atlas generates, in timebase-generated.pfx, plus its password file. On Windows the password file is encrypted for the local machine; on Linux it is written with owner-only permissions. Restrict access to that folder.
What is in the Config and Data folders#
You can stop Atlas, delete the Data folder and restart without losing any configuration, because everything you author lives under Config.
Config is the Git-backed store (the Config key; /atlas/config in Docker).
| Item | What it holds | In Git? |
|---|---|---|
domains/<domain>/ontology.jsonld |
The domain's type definitions | Yes |
domains/<domain>/instances/*.map.json |
The domain's instance maps | Yes |
libraries/*.jsonld |
Shared libraries | Yes |
views/<domain>.views.json |
Saved views, one file per domain | No |
.git/ |
The repository holding the history of everything above | n/a |
compiled-worlds.json |
Which (branch, domain) pairs were compiled, so a restart can recover them |
No |
draft-sessions.json |
The index of open draft sessions | No |
.worktrees/ |
Working copies for open draft sessions | No |
agents/ |
Assistant agents you have defined | No |
skills/ |
Assistant skills you have defined | No |
Data holds machine-owned state only (the Data key; /atlas/data in Docker).
| Item | What it holds | What you lose if you delete it |
|---|---|---|
Agent/sessions/, Agent/threads/, Agent/exports/ |
The assistant's chat sessions and uploads, chat transcripts, and script output | Chat history and uploads |
atlas.state |
The instance serial used for licensing, plus related licensing state files | The licensing serial is minted again |
Deleting Data loses chat history and uploads and mints the licensing serial again. It does not affect compilation: the boot recompile reads compiled-worlds.json from Config, so domains come back by themselves after a restart whether or not Data was wiped.
In 2.0.0 sessions/, threads/ and exports/ sat under Config. From the next release they live under Agent/ in Data, and the first start after upgrading moves them there, once; a folder is left where it is if the destination already exists.
the domain file is ontology.jsonld. If you have notes showing schema.jsonld, they are out of date. A domain folder counts as a domain if it holds at least one .jsonld file anywhere inside it.
your assistant agents and skills are held outside the repository, so a Git backup does not cover them. Back up the whole Config folder, and the Data folder as well, rather than the model history alone.
atlas-core is system-owned. On every start Atlas compares it with the copy inside the installation and restores the shipped version if they differ, which keeps the framework vocabulary consistent across upgrades. Put your own types in a library of your own. Libraries you copied in during commissioning, such as atlas-common and isa95-equipment, are yours and are never rewritten.
Model changes are committed to the repository, but a save that fails validation goes to a private draft instead and does not advance the branch. See Draft sessions.
Which changes need a restart#
Only one section acts on an edit without a restart: Pulse:Gage:Guardrails, which takes effect on the assistant's very next tool call.
Every other section listed in this article is read once when Atlas starts. Atlas watches the settings files and reloads the values into memory, but the components that use them keep the values they were given at startup. Restart Atlas after any other change.
Troubleshooting#
| Symptom | Likely cause | What to do |
|---|---|---|
You set a value in settings.config and nothing changed |
An environment variable in docker-compose.yml, or a command-line argument, sets the same key and outranks the file. There is no error message |
Remove or change the matching environment: entry, then restart |
You changed Pulse:Host or Pulse:Port in settings.config and Atlas still uses the old address |
The Compose file sets Pulse__Host or Pulse__Port as an environment variable, which outranks the file, or Atlas was not restarted |
Change or remove the environment entry, then restart. There is no settings.Docker.config to edit: the Docker overlay was composed into settings.config on the first start |
| Every API call is rejected, or a programmatic client receives an HTML sign-in page instead of the JSON it expected | Pulse:Auth:Enabled is true by default, so callers must present a Pulse bearer token |
Register the calling client in Pulse with Atlas among its audiences and send a bearer token. Do not rely on a response arriving; check that the response type is JSON before parsing it |
Atlas will not start: IdP Host and Port is required when authentication is enabled |
Pulse:Auth:Enabled is on but Pulse:Host or Pulse:Port is blank |
Fill both in, or point Atlas at a reachable Pulse instance |
Atlas will not start: LiveProjection:AllowedLatencyMs must be in [0, 86400000] milliseconds. |
A typo in that value, commonly ticks pasted where milliseconds were meant | Set it to a millisecond value inside the range. 2000 is the shipped default |
Atlas will not start: Atlas:DraftSessions:IdleTimeout must be positive |
A zero or negative duration in that section | Use a positive duration such as 7.00:00:00, or remove the section to take the default |
| Atlas will not start: a fatal configuration error at startup | Atlas cannot write settings.config into the Settings folder |
Check the folder exists, is writable by the account Atlas runs as, and that the volume is mounted |
| Atlas will not start: a fatal certificates-path error at startup | Atlas cannot create the Certificates folder | Same checks as the row above, for the Certificates path |
| The assistant is unavailable or shows a setup message | Pulse:Auth:Enabled is off, Pulse:Gage:Enabled is off, Pulse is unreachable, no model is published in Pulse, or Atlas cannot get a token because Pulse:Auth:ClientSecret is still empty |
Work through the setup steps the assistant lists. Atlas has no model API key of its own, and setting ANTHROPIC_API_KEY will not help. Check the client secret first; it is the most common cause on a new install |
Atlas cannot authenticate against Pulse: InvalidClientSecret |
The seeded Atlas client in Pulse has a randomly generated GUID secret and Atlas still ships Pulse:Auth:ClientSecret: "". An empty string never matches |
Read the generated secret out of Pulse or rotate it to a value you choose, put it in Pulse:Auth:ClientSecret, and restart Atlas. See pulse-oauth-clients.md |
| The assistant reports a quota or limit rather than answering | Gage ships hard token budgets per client and per user, and blocks once they are exceeded | Not an Atlas setting. Review the Gage policies in Pulse; see pulse-gage-providers.md |
| The dictation microphone button has no effect, or is not shown | The browser was opened over plain HTTP on a machine other than the server | Reach Atlas over HTTPS on port 4552. Publish that port in docker-compose.yml if you have not already |
http://<host>:4551 reports that the site cannot be reached, and the address bar has jumped to https://<host>:4552 |
Atlas redirects HTTP to HTTPS, and the shipped Compose file does not publish 4552 |
Add - "4552:4552" to the ports list and restart. Publish it as 4552, not remapped |
Port 4551 is already in use |
Another program holds it | Remap the host side, for example "14551:4551", or change Kestrel:Endpoints:Http:Url |
| A save reports success but the model on the branch has not changed | The save had outstanding violations and is held in your private draft session | Check the validation report for the domain, clear the violations, and publish the draft. Set Atlas:DraftSessions:Enabled to false to write straight to the branch instead |
Your edits to atlas-core are restored after a restart |
That library is system-owned and refreshed from the installation on every start | Create your own library and put your additions there |
| Log files are growing too fast | The log level is too low | Set Serilog:MinimumLevel:Default to Warning and Serilog:MinimumLevel:Override:Timebase.Atlas to Information, then restart |
| The processor is busy for a while after every restart | Atlas recompiles every previously compiled domain in the background, so it is queryable without you doing anything | Set Compilation:AutoRecompileOnStartup to false to compile on demand instead, in which case domains become queryable when you compile them |
| Connect ingestion reports an error on large payloads | A Kestrel:Limits:MaxRequestBodySize cap is set |
Remove it, or set it to 0. Atlas runs with no body-size cap by default |
| Domain configuration is lost after a container restart | The Config folder is not on a persistent volume | Mount a named volume or a host folder at the Config path before starting again. Data already lost cannot be recovered |