genesis config
Config helpers for non-interactive edits in genesis.json: get/set/unset/file/schema/validate
values by path and print the active config file. Run without a subcommand to
open the configure wizard (same as genesis configure).
Root options:
--section <section>: repeatable guided-setup section filter when you rungenesis configwithout a subcommand
Supported guided sections:
workspacemodelwebgatewaydaemonchannelspluginsskillshealth
Examples
genesis config file
genesis config --section model
genesis config --section gateway --section daemon
genesis config schema
genesis config get browser.executablePath
genesis config set browser.executablePath "/usr/bin/google-chrome"
genesis config set browser.profiles.work.executablePath "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
genesis config set agents.defaults.heartbeat.every "2h"
genesis config set agents.list[0].tools.exec.node "node-id-or-name"
genesis config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json --merge
genesis config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN
genesis config set secrets.providers.vaultfile --provider-source file --provider-path /etc/genesis/secrets.json --provider-mode json
genesis config unset plugins.entries.brave.config.webSearch.apiKey
genesis config set channels.discord.token --ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN --dry-run
genesis config validate
genesis config validate --json
config schema
Print the generated JSON schema for genesis.json to stdout as JSON.
What it includes:
- The current root config schema, plus a root
$schemastring field for editor tooling - Field
titleanddescriptiondocs metadata used by the Control UI - Nested object, wildcard (
*), and array-item ([]) nodes inherit the sametitle/descriptionmetadata when matching field documentation exists anyOf/oneOf/allOfbranches inherit the same docs metadata too when matching field documentation exists- Best-effort live plugin + channel schema metadata when runtime manifests can be loaded
- A clean fallback schema even when the current config is invalid
Related runtime RPC:
config.schema.lookupreturns one normalized config path with a shallow schema node (title,description,type,enum,const, common bounds), matched UI hint metadata, and immediate child summaries. Use it for path-scoped drill-down in Control UI or custom clients.
genesis config schema
Pipe it into a file when you want to inspect or validate it with other tools:
genesis config schema > genesis.schema.json
Paths
Paths use dot or bracket notation:
genesis config get agents.defaults.workspace
genesis config get agents.list[0].id
Use the agent list index to target a specific agent:
genesis config get agents.list
genesis config set agents.list[1].tools.exec.node "node-id-or-name"
Values
Values are parsed as JSON5 when possible; otherwise they are treated as strings.
Use --strict-json to require JSON5 parsing. --json remains supported as a legacy alias.
genesis config set agents.defaults.heartbeat.every "0m"
genesis config set gateway.port 19001 --strict-json
genesis config set channels.whatsapp.groups '["*"]' --strict-json
config get <path> --json prints the raw value as JSON instead of terminal-formatted text.
Object assignment replaces the target path by default. Protected map/list paths
that commonly hold user-added entries, such as agents.defaults.models,
models.providers, models.providers.<id>.models, plugins.entries, and
auth.profiles, refuse replacements that would remove existing entries unless
you pass --replace.
Use --merge when adding entries to those maps:
genesis config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json --merge
genesis config set models.providers.ollama.models '[{"id":"llama3.2","name":"Llama 3.2"}]' --strict-json --merge
Use --replace only when you intentionally want the provided value to become
the complete target value.
config set modes
genesis config set supports four assignment styles:
- Value mode:
genesis config set <path> <value> - SecretRef builder mode:
genesis config set channels.discord.token \
--ref-provider default \
--ref-source env \
--ref-id DISCORD_BOT_TOKEN
- Provider builder mode (
secrets.providers.<alias>path only):
genesis config set secrets.providers.vault \
--provider-source exec \
--provider-command /usr/local/bin/genesis-vault \
--provider-arg read \
--provider-arg openai/api-key \
--provider-timeout-ms 5000
- Batch mode (
--batch-jsonor--batch-file):
genesis config set --batch-json '[
{
"path": "secrets.providers.default",
"provider": { "source": "env" }
},
{
"path": "channels.discord.token",
"ref": { "source": "env", "provider": "default", "id": "DISCORD_BOT_TOKEN" }
}
]'
genesis config set --batch-file ./config-set.batch.json --dry-run
Policy note:
- SecretRef assignments are rejected on unsupported runtime-mutable surfaces (for example
hooks.token,commands.ownerDisplaySecret, Discord thread-binding webhook tokens, and WhatsApp creds JSON). See SecretRef Credential Surface.
Batch parsing always uses the batch payload (--batch-json/--batch-file) as the source of truth.
--strict-json / --json do not change batch parsing behavior.
JSON path/value mode remains supported for both SecretRefs and providers:
genesis config set channels.discord.token \
'{"source":"env","provider":"default","id":"DISCORD_BOT_TOKEN"}' \
--strict-json
genesis config set secrets.providers.vaultfile \
'{"source":"file","path":"/etc/genesis/secrets.json","mode":"json"}' \
--strict-json
Provider builder flags
Provider builder targets must use secrets.providers.<alias> as the path.
Common flags:
--provider-source <env|file|exec>--provider-timeout-ms <ms>(file,exec)
Env provider (--provider-source env):
--provider-allowlist <ENV_VAR>(repeatable)
File provider (--provider-source file):
--provider-path <path>(required)--provider-mode <singleValue|json>--provider-max-bytes <bytes>--provider-allow-insecure-path
Exec provider (--provider-source exec):
--provider-command <path>(required)--provider-arg <arg>(repeatable)--provider-no-output-timeout-ms <ms>--provider-max-output-bytes <bytes>--provider-json-only--provider-env <KEY=VALUE>(repeatable)--provider-pass-env <ENV_VAR>(repeatable)--provider-trusted-dir <path>(repeatable)--provider-allow-insecure-path--provider-allow-symlink-command
Hardened exec provider example:
genesis config set secrets.providers.vault \
--provider-source exec \
--provider-command /usr/local/bin/genesis-vault \
--provider-arg read \
--provider-arg openai/api-key \
--provider-json-only \
--provider-pass-env VAULT_TOKEN \
--provider-trusted-dir /usr/local/bin \
--provider-timeout-ms 5000
Dry run
Use --dry-run to validate changes without writing genesis.json.
genesis config set channels.discord.token \
--ref-provider default \
--ref-source env \
--ref-id DISCORD_BOT_TOKEN \
--dry-run
genesis config set channels.discord.token \
--ref-provider default \
--ref-source env \
--ref-id DISCORD_BOT_TOKEN \
--dry-run \
--json
genesis config set channels.discord.token \
--ref-provider vault \
--ref-source exec \
--ref-id discord/token \
--dry-run \
--allow-exec
Dry-run behavior:
- Builder mode: runs SecretRef resolvability checks for changed refs/providers.
- JSON mode (
--strict-json,--json, or batch mode): runs schema validation plus SecretRef resolvability checks. - Policy validation also runs for known unsupported SecretRef target surfaces.
- Policy checks evaluate the full post-change config, so parent-object writes (for example setting
hooksas an object) cannot bypass unsupported-surface validation. - Exec SecretRef checks are skipped by default during dry-run to avoid command side effects.
- Use
--allow-execwith--dry-runto opt in to exec SecretRef checks (this may execute provider commands). --allow-execis dry-run only and errors if used without--dry-run.
--dry-run --json prints a machine-readable report:
ok: whether dry-run passedoperations: number of assignments evaluatedchecks: whether schema/resolvability checks ranchecks.resolvabilityComplete: whether resolvability checks ran to completion (false when exec refs are skipped)refsChecked: number of refs actually resolved during dry-runskippedExecRefs: number of exec refs skipped because--allow-execwas not seterrors: structured schema/resolvability failures whenok=false
JSON output shape
{
ok: boolean,
operations: number,
configPath: string,
inputModes: ["value" | "json" | "builder", ...],
checks: {
schema: boolean,
resolvability: boolean,
resolvabilityComplete: boolean,
},
refsChecked: number,
skippedExecRefs: number,
errors?: [
{
kind: "schema" | "resolvability",
message: string,
ref?: string, // present for resolvability errors
},
],
}
Success example:
{
"ok": true,
"operations": 1,
"configPath": "~/.genesis/genesis.json",
"inputModes": ["builder"],
"checks": {
"schema": false,
"resolvability": true,
"resolvabilityComplete": true
},
"refsChecked": 1,
"skippedExecRefs": 0
}
Failure example:
{
"ok": false,
"operations": 1,
"configPath": "~/.genesis/genesis.json",
"inputModes": ["builder"],
"checks": {
"schema": false,
"resolvability": true,
"resolvabilityComplete": true
},
"refsChecked": 1,
"skippedExecRefs": 0,
"errors": [
{
"kind": "resolvability",
"message": "Error: Environment variable \"MISSING_TEST_SECRET\" is not set.",
"ref": "env:default:MISSING_TEST_SECRET"
}
]
}
If dry-run fails:
config schema validation failed: your post-change config shape is invalid; fix path/value or provider/ref object shape.Config policy validation failed: unsupported SecretRef usage: move that credential back to plaintext/string input and keep SecretRefs on supported surfaces only.SecretRef assignment(s) could not be resolved: referenced provider/ref currently cannot resolve (missing env var, invalid file pointer, exec provider failure, or provider/source mismatch).Dry run note: skipped <n> exec SecretRef resolvability check(s): dry-run skipped exec refs; rerun with--allow-execif you need exec resolvability validation.- For batch mode, fix failing entries and rerun
--dry-runbefore writing.
Write safety
genesis config set and other Genesis-owned config writers validate the full
post-change config before committing it to disk. If the new payload fails schema
validation or looks like a destructive clobber, the active config is left alone
and the rejected payload is saved beside it as genesis.json.rejected.*.
The active config path must be a regular file. Symlinked genesis.json
layouts are unsupported for writes; use GENESIS_CONFIG_PATH to point directly
at the real file instead.
Prefer CLI writes for small edits:
genesis config set gateway.reload.mode hybrid --dry-run
genesis config set gateway.reload.mode hybrid
genesis config validate
If a write is rejected, inspect the saved payload and fix the full config shape:
CONFIG="$(genesis config file)"
ls -lt "$CONFIG".rejected.* 2>/dev/null | head
genesis config validate
Direct editor writes are still allowed, but the running Gateway treats them as untrusted until they validate. Invalid direct edits can be restored from the last-known-good backup during startup or hot reload. See Gateway troubleshooting.
Whole-file recovery is reserved for globally broken config, such as parse
errors, root-level schema failures, legacy migration failures, or mixed plugin
and root failures. If validation fails only under plugins.entries.<id>...,
Genesis keeps the active genesis.json in place and reports the plugin-local
issue instead of restoring .last-good. This prevents plugin schema changes or
minHostVersion skew from rolling back unrelated user settings such as models,
providers, auth profiles, channels, gateway exposure, tools, memory, browser, or
cron config.
Subcommands
config file: Print the active config file path (resolved fromGENESIS_CONFIG_PATHor default location). The path should name a regular file, not a symlink.
Restart the gateway after edits.
Validate
Validate the current config against the active schema without starting the gateway.
genesis config validate
genesis config validate --json
After genesis config validate is passing, you can use the local TUI to have
an embedded agent compare the active config against the docs while you validate
each change from the same terminal:
If validation is already failing, start with genesis configure or
genesis doctor --fix. genesis chat does not bypass the invalid-config
guard.
genesis chat
Then inside the TUI:
!genesis config file
!genesis docs gateway auth token secretref
!genesis config validate
!genesis doctor
Typical repair loop:
- Ask the agent to compare your current config with the relevant docs page and suggest the smallest fix.
- Apply targeted edits with
genesis config setorgenesis configure. - Rerun
genesis config validateafter each change. - If validation passes but the runtime is still unhealthy, run
genesis doctororgenesis doctor --fixfor migration and repair help.