Config PR Assessment and Roadmap
Contextβ
This document captures the assessment of the current config PR (feat(config): add config, config-yaml, config-json, config-hocon modules) and the roadmap discussion for making the config system best-in-class.
The core direction is strong:
- typed configuration decoding from
Schema - provenance tracking
- unified config + flags + rollout model
- DI integration via
Config.wire[...] - synchronous, zero-dependency core
But the PR is not yet best-in-class. The biggest gaps are documentation coherence, operational/source breadth, secret handling completeness, and introspection UX.
Assessment Summaryβ
Current strengthsβ
-
Provenance is a real differentiator
ConfigSourceandFlagSourcecarry source identity.- resolved values retain provenance.
- composition preserves origin.
- this is genuinely better than many mainstream config libraries.
-
DI integration is unusually strong
Config.wire[A]andConfig.wire[A](prefix)keep config decoding inside the dependency graph.- this is framework-grade design rather than just βsettings loadingβ.
-
Config + flags + rollout in one model
- this is strategically smart and potentially differentiating.
-
Format adapters normalize into one model
- YAML / JSON / HOCON all end up as
ConfigSource, which keeps the rest of the system simple.
- YAML / JSON / HOCON all end up as
Current weaknessesβ
-
Public docs and API story are not fully coherent
- stale
Optiondocs where impl usesMaybe - stale
Schema.derivedcompanion examples where Scala 3derivesis preferred - generated README blocked by unrelated website-plugin failure
- stale
-
Source ecosystem is still narrow
- no first-class secrets directory source
- no
_FILEsupport - no secret-manager integrations
- no clear profile/environment model
-
Secret handling is directionally correct but incomplete
Secretas string-only wrapper is good- redaction exists, but full reporting/audit safety must be verified everywhere
-
Diagnostics are structured but not yet elite
- errors are accumulated
- but βwhy did this value win?β / operator-facing explainability is still immature
-
Merge / precedence model is still basic
- simple fallback composition works
- richer advanced composition semantics are still missing
-
Validation and operational governance are still shallow
- strong decode
- weaker config-specific semantic validation, migration, deprecation, profile-aware rules
Ecosystem Comparisonβ
JVM / Spring Bootβ
Spring Boot is ahead on:
- property source ecosystem breadth
- metadata generation
- operational introspection (
env,configprops, origin tracking) - mature profile model
This PR is ahead on:
- conceptual purity
- tighter config/flags/rollout unification
- stronger framework-substrate potential
Rust / Figmentβ
Figment is the closest conceptual peer.
Figment is ahead on:
- provider abstraction maturity
- profile support
- provider ecosystem
- provenance polish
This PR is ahead on:
- DI integration
- flag/rollout unification
Go / koanfβ
koanf is ahead on:
- provider breadth
- composable source ecosystem
- merge flexibility
This PR is ahead on:
- typed decode from schemas
- provenance richness
- DI integration
Python / pydantic-settings + dynaconfβ
Pydantic settings is ahead on:
- startup UX
- strong validation ergonomics
- nested env conventions
- secrets dir support
Dynaconf is ahead on:
- layered source breadth
- environment/profile support
- secrets/provider integration
This PR is ahead on:
- provenance quality
- DI alignment
- config/flags/rollout unification
TypeScript / t3-env / envalid / convictβ
These are ahead on:
- startup validation ergonomics
- low-friction adoption
- concise developer experience
This PR is ahead on:
- hierarchical typed decode
- provenance
- multi-format config normalization
- DI integration
Roadmapβ
1. Must merge nowβ
These are quality-bar issues for this PR itself.
A. Fix public coherenceβ
- update
docs/reference/config.mdtoMaybeinstead ofOption - update
Config.scalaScaladoc examples to Scala 3derives Schema, Unscoped - ensure all high-level examples use:
Config.wire[...]Resource.use(...)- Scala 3 style
- either:
- fix
generateReadme, or - explicitly mark README generation as blocked by unrelated website-plugin failure in PR notes
- fix
B. Tighten the config storyβ
Document the canonical golden path:
Wire(source)
Config.wire[FooConfig]("foo")
Resource.from[App](...)
appResource.use(_.run())
C. Tighten secret guaranteesβ
Before merge, verify:
- all human-facing config rendering redacts
Secret - provenance never leaks secret raw values in default reporting
- error formatting does not accidentally print secrets
2. Next 3 PRsβ
PR 1 β Source ecosystem + secrets ergonomicsβ
Add:
ConfigSource.fromEnv(...)ConfigSource.fromSystemProperties(...)as a clearly canonical public pathConfigSource.fromSecretsDir(...)_FILEconvention support
PR 2 β Diagnostics and explainabilityβ
Add:
- richer config load reports
- βwhy did this value win?β APIs
- structured diagnostic output
- provenance rendering designed for operators
PR 3 β Profiles / environments / layered config modelβ
Add:
- named environments/profiles
- explicit precedence helpers
- layered composition utilities
3. 1.0 checklistβ
For a true 1.0-quality config system:
Coreβ
- typed decode from
Schema Maybe-based source API- provenance for every resolved value
- config + flags + rollout unified
- DI-first wiring
- ergonomic
Resource.use(...)
Sourcesβ
- map
- env
- system properties
- YAML
- JSON
- HOCON
- secrets dir
_FILE- custom source extension point
Secretsβ
- string-only
Secret - default redaction everywhere
- no accidental secret exposure in reports
- nested secret support
- secret manager adapter strategy
Diagnosticsβ
- accumulated errors
- explain/report API
- effective-value provenance
- machine-readable diagnostics
- human-readable startup report
Framework readinessβ
- profile/environment model
- clear precedence semantics
- deprecation/migration support for renamed keys
- test-friendly override model
- future hook points for framework introspection
Strategic Recommendationβ
The product should be positioned as:
typed configuration with provenance, rollout, and DI integration
not merely as another config library.
The best path is to make the strongest differentiators impossible to miss:
- typed config that explains itself
- config that belongs inside the DI/runtime model
- one unified system for config, flags, and rollout
Priority Orderβ
Highest priorityβ
- docs coherence
- secrets-dir +
_FILE - diagnostics / explainability
Medium priorityβ
- profiles / environments
- custom source/provider story
- deprecation / alias migration support
Laterβ
- secret manager integrations
- reload/watch model
- metadata/schema export
- framework actuator/introspection layer