marque-config
Layered configuration loading for Marque.
marque-config resolves a single, validated Config from up to four sources
and hard-fails fast on misuse. The engine never reads files itself — it
takes the resolved Config as a constructor argument.
Role in Marque
.marque.toml ─┐
.marque.local.toml ─┼─→ marque-config ─→ Config ─→ marque-engine
env vars ─┘ (validates, merges)
CLI flags ─────────────┘ (caller-applied)
Precedence
Highest wins:
CLI flags > env vars > .marque.local.toml > .marque.toml
load(start_dir) walks upward from start_dir and stops at the first
.marque.toml, .git/, or filesystem root. load_with_explicit_config(path)
short-circuits the walk and uses path directly.
Usage
use load;
let cwd = current_dir?;
let config = load?;
println!;
# Ok::
Config files
.marque.toml — committed, project/org policy:
[]
= "ISM-v2022-DEC"
[]
= "fix" # portion-mark-in-banner; off | info | warn | error | fix
= "warn" # missing-usa-trigraph
= "warn" # equivalent — rule names are accepted as aliases
[]
= "SECRET"
.marque.local.toml — gitignored, per-user identity. Never commit:
[]
= "TEST-12345"
= "EO 13526"
= "1.4(c)" # optional
= "Multiple Sources" # optional
Rule keys: IDs or names
The [rules] section accepts either the canonical rule ID (E001) or
the rule name (portion-mark-in-banner) as the key. Both forms resolve to
the same rule at engine construction time. Using the name form makes configs
more self-documenting; the ID form is shorter and stable across renames.
Writing both forms with different severities for the same rule is rejected at engine construction time — one form would have silently won the HashMap iteration race and the other would have been dropped. Writing both forms with the same severity is accepted silently.
Hard-fail validators
The loader (or engine constructor) refuses to produce a Config / Engine
(exit code in parens) when:
.marque.tomlcontains a[user]section — identity must live only in.marque.local.tomlor env vars (FR-010, exit65).[capco] versiondoes not match the compiledmarque_ism::SCHEMA_VERSION(FR-011, exit65).confidence_thresholdis outside[0.0, 1.0](exit65).- A rule severity string is not one of
off,info,warn,error,fix(exit65). - The config file cannot be read (exit
74). - A
[rules]key is not a registered rule ID or name — the engine emitsEngineConstructionError::UnknownRuleOverridewith a best-effort "did you mean…" suggestion (exit65). - A
[rules]section specifies the same rule two different ways with conflicting severities — the engine emitsEngineConstructionError::ConflictingRuleOverride(exit65).
ConfigError::exit_code() and EngineConstructionError::exit_code()
return the appropriate code for the CLI.
Public types
| Type | Role |
|---|---|
Config |
The resolved, merged configuration. |
UserConfig |
Classifier identity (from .marque.local.toml or env). |
RuleConfig |
Per-rule severity overrides. |
CapcoConfig |
Schema version pin. |
ConfigError |
Validation failures, with exit_code() mapping. |
License
Marque License 1.0 (LicenseRef-MarqueLicense-1.0). See LICENSE.md.