Make consumer documentation easier to follow

This commit is contained in:
2026-11-01 19:04:48 +00:00
parent e74c26a4b3
commit 6db441893d
12 changed files with 1065 additions and 399 deletions

134
README.md
View File

@@ -1,56 +1,14 @@
# ConfigKit
An opinionated Go library for applications that use YAML configuration files.
ConfigKit loads YAML into your application's Go configuration type, combines the
inputs you choose, and lets you inspect where the final values came from. You
supply the types, defaults, and application rules; ConfigKit handles loading,
combination, strict decoding, and inspection.
Linux is release-validated; macOS support is best-effort. See the
[platform support policy](docs/policy/release.md#platform-support) for details.
[platform support policy](docs/policy/release.md#platform-support).
ConfigKit's simple `Load` accepts one strict YAML source (or explicit
defaults-only input). `LoadLayered` additionally combines explicit lower-priority
source groups with an independently selected main input. Sources can be host
files, native `fs.FS` files, labeled bytes or readers, or snapshotted mappings.
Enabled explicit imports compose strictly within their group; precedence
between groups combines mappings recursively. Both entry points return a complete,
validated configuration with detached metadata and safe diagnostics. Successful
results and load errors also provide passive `Source(id)` lookups alongside source
enumeration.
Applications may perform audited defaulting and normalization through a resolver,
then report domain errors and warnings through read-only semantic validation. Secret
tags and a path predicate drive deterministic redacted effective YAML. Typed secret
references resolve environment names before validation, and explicit
secrets-directory bootstrap is available as a separate startup operation. Explicit
CLI override records apply after inheritance and typed decoding, before application
resolution. Value explanation is available through
detached structured records and deterministic redacted output. Built-in
`extends` relationships let a mapping inherit from a named sibling during the
same load, retaining explicit presence and source/derivation history. The root
`Diff` API compares frozen effective values from two successful same-type loads;
the [configuration contract](docs/config.md#effective-configuration-diffs) and
[consumer guide](docs/consumers/README.md#effective-configuration-diffs) describe
its safe changed-region records and maintained workflows.
Sources can also be explicitly placed as sequence items. Configuration
declarations and application registrations can give selected sequences scalar
identities and choose how they combine across precedence and inheritance.
Strict peers combine distinct records, while higher-priority collections can
replace, append, or upsert whole records. See the
[sequence contract](docs/config.md#strict-document-composition),
[maintained catalog examples](docs/consumers/README.md#identified-prompt-sequences),
and [ADR 0017](docs/adr/0017-collection-sequence-policy.md).
Imports are also explicit: a source may name files, search declared directories,
or select files with path globs. Applications can set load-wide import defaults
while keeping declaration-specific exceptions. Files are acquired in authored
declaration order; dependency-ready composition uses a shared stable scheduler.
ConfigKit does not search conventional application paths implicitly. See the
[import contract](docs/config.md#explicit-imports), [consumer examples](docs/consumers/README.md),
and [ADR 0015](docs/adr/0015-shared-dependency-ready-ordering.md) and
[ADR 0016](docs/adr/0016-independent-import-controls.md).
Main-file discovery is explicit too: applications choose and order `Search`
descriptions and pass `SearchConfig` to the existing load APIs. See the
[discovery contract](docs/config.md#configuration-discovery), [consumer guide](docs/consumers/README.md#explicit-main-file-discovery),
and [ADR 0019](docs/adr/0019-explicit-configuration-discovery.md).
## Load a configuration file
```go
import "go.maximumdirect.net/configkit"
@@ -72,48 +30,54 @@ func ReadConfig(path string) (Config, error) {
Existing consumers should follow the
[module-path migration guidance](docs/consumers/README.md#vanity-module-path-migration).
## Add the features you need
Start with one file. Optional features use the same loading and inspection model:
- [Choose inputs](docs/consumers/README.md#choosing-a-loading-entry-point): read
files, an application-owned `fs.FS`, bytes, a reader, or a Go mapping. Use
explicit search descriptions when the application should look in several places.
- [Supply lower-priority settings](docs/consumers/README.md#native-filesystem-and-layered-input):
use `LoadLayered` for bundled defaults that application configuration can override.
- [Combine configuration](docs/config.md#explicit-imports): add declared imports,
select one overlay, or pass values explicitly set by your CLI parser.
- [Reuse settings](docs/config.md#sibling-inheritance): let one named entry inherit
from a sibling. [Identified lists](docs/config.md#strict-document-composition)
also support record inheritance and replace, append, or upsert operations.
- [Apply application rules](docs/config.md#recorded-application-resolution): derive
or normalize values in a resolver, then check the final configuration in a validator.
- [Handle credentials](docs/config.md#typed-secret-references): use environment-name
references and choose which configuration fields to hide in inspection output.
- [Inspect a load](docs/config.md#layered-metadata): examine sources, presence,
history, safe YAML output, or [changes between two loads](docs/config.md#effective-configuration-diffs).
The [consumer guide](docs/consumers/README.md) walks through these tasks and links
to maintained examples. The [configuration reference](docs/config.md) defines the
exact YAML, combination, and lifecycle rules.
## Design philosophy
ConfigKit favors one coherent, predictable configuration model over flexibility
for reproducing each consumer's conventions. Its goal is to let applications
load once, inspect where final values came from, and distinguish explicit values
from omissions with minimal configuration bookkeeping. Applications retain their
domain rules and execution responsibilities.
ConfigKit favors consistent, predictable rules across applications. A load returns
the final configuration and metadata that distinguish supplied values such as
`false` and `0` from omissions. Applications keep their domain rules and runtime
initialization.
Loading is synchronous and complete on return. Applications normally load once
near startup and then use the final configuration and metadata; ConfigKit stays
inactive until explicitly called again. Applications may initiate additional
loads as needed. See the [loading lifecycle](docs/config.md#completion-and-resource-lifetime)
for completion and ownership details.
Within one layer, independent contributions combine strictly: conflicting
values are errors. Across layers, higher-priority settings can replace
lower-priority settings, while mappings combine by key. Identified lists have
their declared combination rules. See the [worked combination
examples](docs/config.md#strict-document-composition) for the details and
exceptions.
Within a configuration tier, independent contributions compose strictly: shared
mappings combine, while overlapping non-mapping definitions are errors. Between
precedence tiers, mappings combine recursively, retaining omitted lower-priority
children; other values replace lower-priority values. The main document and its
imports form one strictly composed tier. Explicit underlay groups sit below it
and above typed defaults; a selected overlay applies before inheritance, while
explicit CLI overrides apply after decoding and before application resolution.
The [configuration contract](docs/config.md#strict-document-composition) owns
the detailed combination rules and input-specific constraints. Declared or
registered collections combine distinct identified records within strict tiers
and use their selected operation at precedence boundaries; other sequences keep
their strict-conflict and whole-value-replacement behavior.
Loading finishes before the call returns. ConfigKit then stays inactive until you
call it again; inspection uses the saved result. See
[completion and resource lifetime](docs/config.md#completion-and-resource-lifetime).
The [architecture goals](docs/policy/architecture.md#success-criteria) explain
these priorities and how genuine new needs can justify extending the shared
model. The [future feature list](docs/roadmap/future.md) preserves candidates for
consideration in future releases.
The [configuration contract](docs/config.md) describes implemented behavior,
including [input destinations](docs/config.md#input-destinations). The
[consumer adoption guide](docs/consumers/README.md) provides maintained simple,
layered, mounted-collection, and identified-prompt examples alongside the
migration shapes. Input placement decisions are recorded in
[ADR 0011](docs/adr/0011-input-destinations.md) and sequence placement and
composition in [ADR 0014](docs/adr/0014-sequence-placement-and-composition.md).
See the [development guide](docs/development.md) for repository orientation and
the [release procedure](docs/release.md) for maintainer-only candidate and
publication steps.
The [architecture goals](docs/policy/architecture.md#success-criteria) and
[ADRs](docs/adr) explain design decisions, including shared import and inheritance
ordering. [Future work](docs/roadmap/future.md) lists possible extensions.
Contributors can start with the [development guide](docs/development.md);
release maintainers use the [release procedure](docs/release.md).
ConfigKit code is licensed under the [LGPL v3.0 or later](COPYRIGHT).