Skip to content

Configuration

Settings live in the database config table and are edited from the Config surface in the TUI or GUI, or with PATCH /api/config. Secrets are separate: credentials are stored encrypted (see Credentials).

KeyPurpose
github_repoowner/name the agent manages.
pickup_labelsComma-separated labels an issue must carry to be picked up. Empty means every issue.
pr_merge_methodPreferred gh pr merge method: squash (default) or rebase.
GitHub App settingsApp id / installation when authenticating as a bot (see the GitHub App guide).

steelframe:needs_human always skips pickup, even when a pickup label is also present: a parked task stays parked until a human responds.

KeyValuesDefault
coding_runtimepi (legacy claude, grok, codex, opencode and aliases resolve to pi)pi
coding_runtime_binaryPath or name of the Pi CLI binary (ignored for a legacy coding_runtime unless it names pi)pi on PATH
coding_runtime_modelsteelframe/<id> runs the local OpenAI-compatible endpoint; <provider>/<id> passes through to Pi’s provider catalogsteelframe/qwen3.8
coding_runtime_base_urlLocal OpenAI-compatible base URL for steelframe/* modelshttp://127.0.0.1:8080/v1
coding_runtime_contextAdvertised context tokens for steelframe/* models (Pi contextWindow)65536
coding_runtime_outputAdvertised max output tokens for steelframe/* models (Pi maxTokens)16384

Workers and one-shot decisions spawn Pi through the runtime facade; workflows never spawn a CLI directly. Workers set an isolated PI_CODING_AGENT_DIR in their sandbox so host Pi config cannot override these limits. A catalog model authenticates from the model_<provider> credential, host Pi auth (pi auth login --provider <id>), or the provider’s ambient env var; with none it fails closed before the spawn.

Clef and Clairic share one cloudflare_ai credential: the Cloudflare account ID in the URL field and a Workers AI API token in the secret field. See Conversation classification.

KeyDefaultPurpose
cloudflare_account_idcredential URLFallback account ID when the credential has none.
clef_modelclefDecision model (clef or clef-flash).
clairic_modelclairicExtraction model.

The bot is off without a discord_bot credential (or STEELFRAME_DISCORD_BOT_TOKEN). See Discord.

KeyDefaultPurpose
discord_bot_enabled10 keeps the gateway off.
discord_allowed_channelsemptyComma-separated channel/thread IDs.
discord_allowed_usersemptyComma-separated Discord user IDs.
discord_conversation_channelsemptyChannel IDs where Clef decides whether each human message is for the bot (requires Message Content + cloudflare_ai).
discord_intake_reaction📥Reaction that files an Intake.
discord_allow_dms01 answers direct messages.
KeyValuesPurpose
delivery_profilelive (default) or sourceRun the staging/production path, or merge when green.
external_urlURLBase URL used in links the agent writes.
KeyDefaultEffect
dispatch_min_available_mb1024Do not spawn a worker below this MemAvailable. 0 disables.
db_memory_limitautoDuckDB memory_limit. auto gives it 35% of physical RAM (max 1.5 GB, min 256 MB); off restores DuckDB’s own default (80% of RAM, written back to the running instance); or a size with a unit (768MB, 1GiB — a bare number counts as bytes).
queue_stall_minutes120Alarm (audit + Discord) when a run has waited for capacity this long: a stuck queue is named instead of waiting silently. 0 disables the alarm.
max_compile_slots1Flock around cargo/cargo-clippy. 0 disables.
max_parallel_tasks3Engine limit on concurrent task runs. Read at agent startup, so a change applies on restart. 0 or invalid falls back to 3.
repo_max_in_flight0Cap on running task runs for the repo, enforced at pickup and WaitingForWorker. 0 disables.
dispatch_overlapserializeHow tasks whose triage touches intersect dispatch: serialize admits one member of an overlap group at a time; order runs implementation in parallel and records the group and creation-order position for the landing queue. Enforced at pickup and WaitingForWorker.
overlap_unknownignoreWhat an empty touches prediction means: ignore treats the task as non-overlapping (more parallelism); serialize puts it in a per-repo unknown group that runs alone.
repo_merge_strategysteelframe_landingHow PRs land: steelframe_landing serializes them through the per-repo landing queue (rebase → verify → merge, in order); github_merge_queue enables auto-merge and lets GitHub’s merge queue serialize instead, exactly as before phase 3.
landing_max_attempts3Landing-queue work episodes (a rebase worker, a failing-checks poll, a merge conflict or error) per PR before the row fails and the task parks with steelframe:needs_human.
github_rate_floor500github_sync skips pickup and external PR reviews for a cycle when remaining core API requests are below this. 0 disables.
worker_model_stall_timeout_secs600Stop a tracked Pi worker after this many seconds without model-turn progress; 0 disables. Positive values are clamped to 30–86,400 seconds. Tool execution and compaction are excluded; the existing overall worker timeout still applies.
worker_memory_maxautoPer-worker cgroup cap: auto, an explicit size like 8G, or off.
memory_recycle_mbautoRecycle the agent process when its RSS crosses this size while idle (no workers, no task runs): auto sizes it at 60% of the cgroup’s memory.max with a 2.5G floor, an explicit size like 6G is floored the same way, and off/0 disables. The watchdog checks every 5 minutes, posts a ♻️ Discord note, and exits; systemd Restart=always brings the agent back with an empty heap.
auto_update_minutes5Release-channel poll interval. 0 disables.
update_channelstablestable reads latest.json; beta opts into prereleases from beta.json. STEELFRAME_UPDATE_CHANNEL overrides the config.
host_exposure_minutes60Host posture scan interval. Flags services listening on 0.0.0.0/:: that are not in the allowlist and not the agent itself. 0 disables.
host_exposure_allow_ports22,80,443Public TCP ports the agent host is expected to serve. Anything else on a wildcard address alerts and is reported to Discord once per change.

System units that use worker_memory_max need Delegate=yes; a user unit must leave its service cgroup before memory limits can be attached.

Docker-published ports bypass ufw: docker-proxy inserts its DNAT rules before ufw’s, so -p 5432:5432 is reachable from the network even when ufw status shows only SSH. Publish dev services on loopback (-p 127.0.0.1:5432:5432) or add the port to host_exposure_allow_ports when it is intentional. The scan runs on the agent host — ephemeral sandboxes skip it. See Host exposure.

Workers run as local host processes by default. Set sandbox_provider=e2b to run them inside E2B-compatible remote sandboxes — the provider keys are sandbox_endpoint, sandbox_template, sandbox_work_dir, sandbox_idle_timeout_secs, sandbox_cpu, sandbox_memory_mb, sandbox_max_concurrency, and sandbox_reap_minutes. The API key is the sandbox credential, not a config key. See Sandbox providers.

The GUI paints the selected project’s logo and theme colors. Both are optional: an unset key falls back to the shipped Steelframe mark or palette.

KeyValuesDefault
brand_logodata:image/<type>;base64,… for the uploaded logo (PNG, JPEG, WebP, GIF, or SVG, at most 512 KiB)unset — Steelframe mark
brand_accentHex color for primary actions, active navigation, and focus#e8ff3a
brand_backgroundHex color for the window, lists, and inputs#030806
brand_surfaceHex color for the sidebar, panels, popovers, and table headers#07140e
brand_elevatedHex color for hover, selected rows, and raised buttons#0f3a22
brand_textHex color for body text#d7e3d4
brand_mutedHex color for metadata and secondary labels#7d8e80

Set them from Config → Settings → Branding in the GUI. They are API-only because the TUI cannot paint a logo or a custom palette. Hairlines, selection, and overlay shades derive from the accent and background with fixed alpha, so a custom palette keeps the shipped relationships.

KeyValuesDefault
mcp_enabledtrue/1 on, false/0 offunset = off

Turns on the operator MCP surface at /mcp. Edit it from Config → Settings. STEELFRAME_MCP in the environment wins: 1/true on, 0/false off. See MCP.

Singleton workflows run on intervals (for example harness_converge_minutes, default 15). Each interval is a config key; inspect the Config surface for the current set.

Some settings are environment, not config: bind address/port, database URL, and the master key. See Install and Auth.

Operator access (auth_allowed_users, auth_github_org) is managed from Config → Users and GET/PUT /api/access, not PATCH /api/config.