Skip to content

fix: config env overrides - lenient env source, seeded defaults, CLI flag precedence (#92) - #103

Merged
jsam merged 3 commits into
mainfrom
fix/config-env-overrides
Aug 20, 2026
Merged

jsam merged 3 commits into
mainfrom
fix/config-env-overrides

Conversation

@jsam

@jsam jsam commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Fixes the config problems from #92, plus a third layer found while reproducing it:

  1. Documented env vars crashed --config startup. INPUTLAYER_BOOTSTRAP_API_KEY / INPUTLAYER_ADMIN_PASSWORD / INPUTLAYER_API_KEY are read via std::env, not config fields, but figment rejected them as unknown keys. The env source is now filtered to the known top-level sections (storage/optimization/logging/http); TOML file parsing stays strict.
  2. The no-config-file path ignored env entirely (Config::default() used directly). load() and from_file() now seed Serialized::defaults first: env overrides always apply, and a partial config file only needs the fields it changes (which also defuses most of the stale-template problem).
  3. --host/--port clap defaults clobbered file and env values unconditionally (server.rs). They are now Options applied only when explicitly passed. Precedence: CLI > env > file > built-in defaults.

Tested

  • Three new figment::Jail tests (non-config env vars ignored; env applies with no config file; env beats file).
  • Full lib suite: 2630 passed.
  • Live: INPUTLAYER_HTTP__PORT=8082 with both bootstrap env vars set boots and binds 8082 (previously: crash in --config mode, silent ignore otherwise).

Remaining from #92 (not in this PR)

The shipped config.toml template still references removed fields ([http.auth] enabled, etc.). Seeded defaults make partial/stale files much less likely to hard-fail, but the template itself still deserves a refresh pass.

Merge order

Independent - no conflicts with #98/#100/#101/#102; mergeable any time.

Refs #92

…flag precedence (#92)

Three related fixes for the config problems in #92:

1. Documented non-config env vars (INPUTLAYER_BOOTSTRAP_API_KEY,
   INPUTLAYER_ADMIN_PASSWORD, INPUTLAYER_API_KEY) crashed --config
   startup because figment rejected unknown keys from the env source.
   The env source now passes through only the known top-level sections
   (storage/optimization/logging/http); TOML parsing stays strict.

2. The no-config-file path used Config::default() directly, so
   INPUTLAYER_* overrides did nothing. load() and from_file() now seed
   Serialized::defaults first, so env overrides always apply and a
   partial config file only needs the fields it changes.

3. The server's clap defaults for --host/--port clobbered file and env
   values unconditionally. They are now Options applied only when
   explicitly passed: CLI > env > file > defaults.

Verified live: INPUTLAYER_HTTP__PORT=8082 with the bootstrap env vars
set boots and binds 8082. Three new figment::Jail tests; full lib suite
2630 passed.
@jsam jsam changed the title fix: config env overrides — lenient env source, seeded defaults, CLI flag precedence (#92) fix: config env overrides - lenient env source, seeded defaults, CLI flag precedence (#92) Aug 19, 2026
jsam added 2 commits August 20, 2026 09:50
With seeded defaults, a missing file silently produced a default config;
tests/config_tests.rs rightly asserts an explicit --config path that
does not exist is an error. Now checked explicitly. Full test suite run
this time (33 binaries), not just --lib.
…loud load errors

Adversarial review of this PR found the defaults seed broke configs
using the documented storage aliases and silently flipped defaults:

1. The seed emits canonical field names, so a config using
   default_database / auto_create_databases (both documented, both in
   the shipped template) failed as a serde duplicate field. A provider
   wrapper now renames aliases to canonical names before figment
   merges - aliases work in files AND env vars (they never worked via
   env before).
2. The seed was Config::default(), whose hand-written values diverge
   from the field-level serde defaults that governed omitted keys
   (enable_join_planning false->true against its own 'disabled by
   default' comment, max_result_rows 0->100000 silently truncating
   results, gui.enabled). The seed is now built through serde with
   explicit empty sections, so field-level defaults are authoritative
   everywhere.
3. server.rs swallowed real load() errors as 'Using default
   configuration', running on pure defaults after e.g. one bad env
   value. Configuration errors now print and exit non-zero.
4. The shipped config.toml template referenced the removed
   [http.auth] enabled field; a new test asserts the template parses.

New tests: aliases via file and env, seed-matches-field-defaults,
shipped-template-parses. Full suite: 33 binaries green.
@jsam
jsam merged commit 727885c into main Aug 20, 2026
11 checks passed
@jsam
jsam deleted the fix/config-env-overrides branch August 20, 2026 12:29
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