Configuration
Stoneforge uses a layered configuration system. Settings can be defined in a config file, environment variables, or CLI flags, with a clear precedence order.
Precedence
Configuration is resolved in this order (highest wins):
- CLI flags —
--actor,--db, etc. - Environment variables —
STONEFORGE_* - Config file —
.stoneforge/config.yaml - Built-in defaults
Config file
The .stoneforge/config.yaml file is created by sf init and controls project-level settings.
actor: default-agent
base_branch: master # optional, auto-detected from git if omitted
database: stoneforge.db
demo_mode: false # set to true for free opencode/minimax-m2.5-free provider
sync: auto_export: true export_debounce: 300000 # 5 minutes in ms elements_file: elements.jsonl dependencies_file: dependencies.jsonl
playbooks: paths: - .stoneforge/playbooks - ~/.stoneforge/playbooks
tombstone: ttl: 2592000000 # 30 days in ms min_ttl: 604800000 # 7 days in ms
identity: mode: soft time_tolerance: 300000 # 5 minutes in ms
plugins: packages: []All options
General
| Parameter | Type | Default | Description |
|---|---|---|---|
actor | string | — | Default actor name for operations. Can be an entity name or ID. |
baseBranch | string | — | Base branch for merge targets (e.g., master or main). Auto-detected from git if omitted. |
database | string | stoneforge.db | SQLite database filename, relative to .stoneforge/. |
demo_mode | boolean | false | Enable demo mode. When true, all agents use the free opencode/minimax-m2.5-free provider. Set automatically by sf init --demo or the dashboard settings toggle. See the Demo Mode guide for details. |
Sync
| Parameter | Type | Default | Description |
|---|---|---|---|
sync.auto_export | boolean | true | Automatically export mutations to JSONL files. |
sync.export_debounce | number | 300000 | Debounce interval in ms for batching exports (5 minutes). |
sync.elements_file | string | elements.jsonl | JSONL filename for exported elements. |
sync.dependencies_file | string | dependencies.jsonl | JSONL filename for exported dependencies. |
Identity
| Parameter | Type | Default | Description |
|---|---|---|---|
identity.mode | string | soft | Identity verification mode: soft (name-based), cryptographic (Ed25519 signatures), or hybrid (accepts both). |
identity.time_tolerance | number | 300000 | Time tolerance in ms for signature expiry in cryptographic mode (5 minutes). |
Playbooks
| Parameter | Type | Default | Description |
|---|---|---|---|
playbooks.paths | string[] | [".stoneforge/playbooks", "~/.stoneforge/playbooks"] | Search paths for playbook definitions. |
Tombstone
| Parameter | Type | Default | Description |
|---|---|---|---|
tombstone.ttl | number | 2592000000 | Time-to-live in ms for soft-deleted records before permanent removal (30 days). |
tombstone.min_ttl | number | 604800000 | Minimum TTL in ms for tombstones (7 days). |
Plugins
| Parameter | Type | Default | Description |
|---|---|---|---|
plugins.packages | string[] | [] | NPM package names that export CLI plugins. First-party packages like @stoneforge/smithy are auto-discovered. |
External sync settings
External sync is managed via runtime settings and CLI commands rather than config.yaml. Use sf external-sync config to view and modify.
External Sync
| Parameter | Type | Default | Description |
|---|---|---|---|
externalSync.enabled | boolean | false | Enable external sync with third-party tools. |
externalSync.pollInterval | number | 60000 | Background sync polling interval in ms (clamped to 10s–30min). |
externalSync.conflictStrategy | string | last_write_wins | Conflict resolution strategy: last_write_wins, local_wins, remote_wins, or manual. |
externalSync.defaultDirection | string | bidirectional | Default sync direction: push, pull, or bidirectional. |
externalSync.autoLink | boolean | false | Auto-create external issues when new tasks are created. |
externalSync.autoLinkProvider | string | — | Provider for task auto-linking (e.g., github, linear). |
externalSync.autoLinkDocumentProvider | string | — | Provider for document auto-linking (e.g., notion, folder). |
Provider tokens and projects
Per-provider authentication and project settings are stored as runtime settings:
# Set provider credentialssf external-sync config set-token github ghp_xxxxxxxxxxxxsf external-sync config set-token linear lin_api_xxxxxxxxxxxxsf external-sync config set-token notion ntn_xxxxxxxxxxxx
# Set default project (repo, team, database, or folder path)sf external-sync config set-project github org/reposf external-sync config set-project folder ./docsRuntime settings
In addition to config.yaml, Stoneforge has runtime settings managed by the SettingsService. These are stored in SQLite and managed via the dashboard or API — they don’t appear in config.yaml.
| Setting | Description | Managed in |
|---|---|---|
| Default provider | Pre-selected provider for new agents | Settings > Workspace > Agent Defaults |
| Default models | Per-provider default model ID | Settings > Workspace > Agent Defaults |
| Executable paths | Custom paths to provider CLI binaries | Settings > Workspace > Agent Defaults |
| Fallback chain | Ordered list of provider executables for rate limit fallback | Settings > Workspace > Agent Defaults |
| External sync providers | API tokens and default projects for sync providers | sf external-sync config |
| Sync cursors | Per-provider cursors tracking last sync position | Managed automatically |
Environment variables
| Variable | Config path | Example |
|---|---|---|
STONEFORGE_ACTOR | actor | agent-1 |
STONEFORGE_BASE_BRANCH | baseBranch | main |
STONEFORGE_DB | database | stoneforge.db |
STONEFORGE_SYNC_AUTO_EXPORT | sync.autoExport | true |
STONEFORGE_IDENTITY_MODE | identity.mode | cryptographic |
STONEFORGE_JSON | — | true (JSON output mode) |
STONEFORGE_VERBOSE | — | true (verbose/debug mode) |
STONEFORGE_CONFIG | — | /path/to/config.yaml |
STONEFORGE_SIGN_KEY | — | Base64 PKCS8 private key |
STONEFORGE_SIGN_KEY_FILE | — | Path to private key file |
Duration strings
Time values in config support human-readable duration strings:
parseDuration('30s'); // 30000 (30 seconds)parseDuration('5m'); // 300000 (5 minutes)parseDuration('1h'); // 3600000 (1 hour)parseDuration('7d'); // 604800000 (7 days)parseDuration('100ms'); // 100 (100 milliseconds)Supported units: ms, s, m, h, d.
CLI commands
# Show all configurationsf config show
# Show a specific valuesf config show actorsf config show sync.autoExport
# Set a value (updates config file)sf config set actor my-agentsf config set sync.autoExport falsesf config set identity.mode cryptographic
# Remove a value (falls back to default)sf config unset actor
# Open config in your editorsf config editProgrammatic access
Loading configuration
import { loadConfig, getConfig, reloadConfig } from '@stoneforge/quarry';
// Load with all sources (file + env + defaults)const config = loadConfig();
// Load with optionsconst config = loadConfig({ configPath: '/custom/config.yaml', cliOverrides: { actor: 'cli-agent' }, skipEnv: false, skipFile: false,});
// Get cached config (loads if not cached)const config = getConfig();
// Force reloadconst config = reloadConfig();Reading values
import { getValue, getValueWithSource, getValueSource } from '@stoneforge/quarry';
// Get a valueconst actor = getValue('actor');const autoExport = getValue('sync.autoExport');const mode = getValue('identity.mode');
// Get value with its sourceconst { value, source } = getValueWithSource('actor');// source: 'default' | 'file' | 'environment' | 'cli'Available config paths:
actor, baseBranch, database,sync.autoExport, sync.exportDebounce, sync.elementsFile, sync.dependenciesFile,playbooks.paths,tombstone.ttl, tombstone.minTtl,identity.mode, identity.timeTolerance,plugins.packagesWriting values
import { setValue, unsetValue, saveConfig } from '@stoneforge/quarry';
// Set value (updates config file)setValue('actor', 'new-agent');setValue('sync.autoExport', false);
// Remove value (falls back to default)unsetValue('actor');
// Save entire config objectsaveConfig(config, '/path/to/config.yaml');Source tracking
Track where each configuration value came from:
import { getTrackedConfig } from '@stoneforge/quarry';
const tracked = getTrackedConfig();
tracked.actor;// { value: 'agent-1', source: 'cli' }
tracked.sync.autoExport;// { value: true, source: 'default' }Config file utilities
import { getConfigPath, configFileExists, discoverConfigFile,} from '@stoneforge/quarry';
const path = getConfigPath();const exists = configFileExists();const discovery = discoverConfigFile(undefined, '/project');// { exists: boolean, path?: string, stoneforgeDir?: string }Validation
import { validateConfiguration, validatePartialConfiguration,} from '@stoneforge/quarry';
// Full validation (throws on error)validateConfiguration(config);
// Partial validation (for merging)validatePartialConfiguration(partialConfig);Defaults
import { DEFAULT_CONFIG, getDefaultConfig } from '@stoneforge/quarry';
// Static referenceDEFAULT_CONFIG.sync.autoExport; // true
// Fresh copyconst defaults = getDefaultConfig();