Skip to content

Add a global config at ~/.config/forge.toml - #23

Merged
bkearns merged 2 commits into
mainfrom
feat/global-config-path
Aug 17, 2026
Merged

Add a global config at ~/.config/forge.toml#23
bkearns merged 2 commits into
mainfrom
feat/global-config-path

Conversation

@bkearns

@bkearns bkearns commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Every layer that could set the task board's CQL host was tied to where forge is run from: an explicit argument, FORGE_CQL_HOST, or a .forge/config.toml found by walking up from the working directory. There was no way to configure a machine.

That is a real gap for an installer. The Ferrosa workbench provisions a database on a non-default port and could only reach forge by asking the user to export a variable, or by dropping a file into every repo they own. Anything else met

Error: connect to CQL ... Connection refused

against a database that was running the whole time.

The layer

~/.config/forge.toml, between the project file and the built-in default:

source
1 explicit --cql-host / cql_host argument
2 FORGE_CQL_HOST
3 nearest .forge/config.toml, walking up from the cwd
4 ~/.config/forge.toml
5 127.0.0.1:9042

A project config still wins, so a repo pins its own board and a machine-wide setting only applies where nothing more specific does.

debug_stop gets the same treatment. It shares the file and the schema, and honouring the global config for one key while ignoring it for the other would be the more surprising design.

Why that path

It matches the rest of the system rather than inventing a location — forge already reads ~/.config/ferrosa-memory.toml for its memory client, so its own settings sit beside it, with the same schema as the project file:

# ~/.config/forge.toml
cql_host = "127.0.0.1:47017"

One shape, two locations. A separate schema for the global file would mean two formats to document and keep in step.

Verification

Unit coverage for the precedence rule at every layer, blank-value fall-through, the resolved path landing at ~/.config/forge.toml, and both keys parsing from one body.

Beyond that, checked with the release binary against a live database from a directory with no project config and no exported variable:

before: Error: connect to CQL
after:  []

Precedence confirmed in both directions — a project config pointing at a dead port still beats a working global one, and FORGE_CQL_HOST still beats that.

Full workspace suite green (1304), build clean.

Note for review

dirs is added to forge-tasks, workspace-pinned like every other crate that uses it. The Cargo.lock change is the single corresponding line.

Every layer that could set the task board's CQL host was tied to WHERE
forge is run from: an explicit argument, an environment variable, or a
.forge/config.toml found by walking up from the working directory. There
was no way to configure a machine.

That is a real gap for an installer. The Ferrosa workbench provisions a
database on a non-default port, and could only reach forge by asking the
user to export a variable or by dropping a file into every repo they
own. Anything else met

    Error: connect to CQL ... Connection refused

against a database that was running the whole time.

The new layer sits between the project file and the built-in default, so
a repo still pins its own board and a machine-wide setting only applies
where nothing more specific does. debug_stop gets the same treatment,
since it shares the file and schema -- honouring the global config for
one key and ignoring it for the other would be the more surprising
design.

The path matches the rest of the system rather than inventing a
location: forge already reads ~/.config/ferrosa-memory.toml for its
memory client, so its own settings sit beside it, with the same schema
as the project file.

Verified with the release binary against a live database, from a
directory with no project config:

    before: Error: connect to CQL
    after:  []

and precedence confirmed both ways -- a project config pointing at a
dead port still wins over a working global one, and the environment
variable still wins over that.
CI's Format & Lint gate caught four sites in the new code. Committed
separately from the change itself so the review diff stays about the
config layer.
@bkearns
bkearns added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit ce08bf9 Aug 17, 2026
5 checks passed
@bkearns bkearns mentioned this pull request Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant