Finalize ConfigKit design and implementation plan
This commit is contained in:
@@ -2,29 +2,119 @@
|
||||
|
||||
**Base Policy Version:** 1.0
|
||||
|
||||
**Last Updated**: 2026-09-06
|
||||
**Last Updated:** 2026-09-06
|
||||
|
||||
## Base Policy Template
|
||||
## Purpose and applicability
|
||||
|
||||
This document is the base template for the canonical architecture policy,. Repositories that implement this policy should:
|
||||
ConfigKit is an opinionated Go library for consistent YAML configuration loading
|
||||
and resolution across consuming applications. This policy governs contributions
|
||||
now; it does not claim that the target features are implemented. The
|
||||
[component overview](../internal/overview.md) owns implementation inventory and
|
||||
[initial roadmap](../roadmap/initial.md) owns unimplemented target behavior.
|
||||
|
||||
1. Revise this document to include an architectural policy tailored to the implementing repository, including a description of the repository's purpose, overall intended system shape, and any architectural and/or engineering invariants that must be maintained during future development;
|
||||
2. Ensure that any supporting documents referenced in the architecture policy are present on the filesystem, even if the initial content is simply `TODO`;
|
||||
3. Update the `Last Updated` field to the current date; and
|
||||
4. Remove this heading (`Base Policy Template`) and the associated text.
|
||||
## Success criteria
|
||||
|
||||
As compared to other base policy documents, the Architecture Policy is the document that should be most heavily customized and tailored to the intended architecture of a particular application.
|
||||
1. **Reduce application infrastructure:** Can applications delete substantial
|
||||
configuration infrastructure while retaining clear ownership of their domain
|
||||
rules?
|
||||
2. **Unify configuration conventions:** Do consumers adopt one consistent
|
||||
configuration model, with only the flexibility needed to express genuine
|
||||
application requirements?
|
||||
|
||||
## Purpose
|
||||
Both criteria must hold. ConfigKit should not preserve divergent consumer
|
||||
conventions merely for compatibility, nor impose restrictions that prevent useful
|
||||
domain information from being expressed. Prefer a canonical representation using
|
||||
existing primitives before adding another mechanism. Extend the model when a
|
||||
concrete requirement cannot be accommodated cleanly, not simply because a
|
||||
consumer already implements a different convention.
|
||||
|
||||
This policy defines the purpose of this repository and the architectural principles that contributors
|
||||
must follow during development.
|
||||
Use both criteria to evaluate public API changes and consumer adoption. Shared
|
||||
loading, presence tracking, source attribution, and diagnostic plumbing should
|
||||
move out of applications; application types, defaults, normalization, and semantic
|
||||
validation should remain recognizable application code. Replacing that plumbing
|
||||
with equally repetitive callback bookkeeping does not meet the first criterion.
|
||||
Offering alternate parsing, precedence, or composition conventions through escape
|
||||
hatches does not meet the second.
|
||||
|
||||
TODO: Complete this document.
|
||||
Consumer migrations are expected and may intentionally change configuration
|
||||
syntax. Existing consumer code supplies implementation foundations and evidence
|
||||
of needs; it does not define ConfigKit's compatibility obligations. Once ConfigKit
|
||||
publishes its own contracts, changes to those contracts remain governed by the
|
||||
[release policy](release.md).
|
||||
|
||||
Non-limiting examples of topics that may be addressed by an architectural policy include:
|
||||
- Adherence to a hexagonal architecture, including whether external integrations/APIs must be encapsulated within internal adapters (strongly recommended)
|
||||
- Whether a library is intended to provide a highly flexible API that supports a variety of downstream consumers, or a strongly opinionated API that is intended to enforce consistency across downstream consumers
|
||||
- Whether an application should support a full DAG, or alternatively a strongly ordered sequence of discrete stages
|
||||
- Whether the application should use specific external libraries to provide key functionality (e.g., FeedKit, ConfigKit, PromptKit)
|
||||
- Any explicit architectural non-goals
|
||||
Require representative simple and complex consumer examples to substantiate API
|
||||
designs. Proposed extensions must identify the domain requirement, explain why
|
||||
existing primitives cannot accommodate it cleanly, and show how the extension
|
||||
preserves a coherent model. Application-specific interpretation and validation
|
||||
remain appropriate. Reuse Narratio's applicable infrastructure under these
|
||||
boundaries, and keep simple consumers independent of optional composition
|
||||
features. The [consumer API design](../roadmap/initial.md#consumer-api-design)
|
||||
describes the proposed surface; this policy does not claim it is implemented.
|
||||
|
||||
## Responsibility boundaries
|
||||
|
||||
ConfigKit owns configuration input processing and the coordination of decoding,
|
||||
resolution, validation, and inspection. Applications own their configuration
|
||||
types, field meanings, defaults, normalization, semantic validation, and schema
|
||||
version policy. Applications also own main-file search conventions, CLI wiring,
|
||||
remote acquisition, runtime initialization, and resource checks.
|
||||
|
||||
Library code must not depend on consuming applications or initialize their
|
||||
runtime resources. It must not perform implicit network access, discover
|
||||
application-specific paths, or change process-global state to load configuration.
|
||||
Remote data can enter through application-supplied input without introducing a
|
||||
network provider into the library.
|
||||
|
||||
## Public API and dependency direction
|
||||
|
||||
Keep one small, coherent public surface for the supported lifecycle. Simple
|
||||
single-document consumers must not need import, profile, or provider machinery.
|
||||
Do not expose parser-specific nodes, errors, or extension hooks through the
|
||||
public API. Parser integration belongs behind a private boundary, as recorded
|
||||
in [ADR 0002](../adr/0002-own-yaml-semantics.md).
|
||||
|
||||
Separate input access, document processing, composition, decoding, metadata, and
|
||||
rendering responsibilities without prescribing an interface or package for each.
|
||||
Dependencies must preserve those boundaries; package splits and abstractions
|
||||
must earn their complexity. Do not impose a full application or hexagonal
|
||||
framework on this library.
|
||||
|
||||
## Configuration integrity
|
||||
|
||||
Composition and intentional overlay are distinct operations. Composition must
|
||||
not silently become last-wins override through file ordering. The decision and
|
||||
alternatives are recorded in [ADR 0001](../adr/0001-separate-composition-and-overlay.md).
|
||||
|
||||
ConfigKit must define supported YAML semantics explicitly rather than inherit
|
||||
parser defaults. Processing order and diagnostics must be deterministic for the
|
||||
same inputs and options. Invalid input must not produce a successful usable
|
||||
configuration. Do not run application hooks on invalid typed configuration.
|
||||
|
||||
Preserve presence and source information through processing. Ordinary Go zero
|
||||
values must not be used to infer whether input was absent. Final configuration,
|
||||
metadata, and effective inspection must agree, including application resolution
|
||||
changes; see [ADR 0003](../adr/0003-preserve-presence-and-resolution-history.md).
|
||||
Detailed syntax and operation tables belong to the target roadmap until their
|
||||
current configuration contract is implemented.
|
||||
|
||||
## Ownership and confidentiality
|
||||
|
||||
Returned configuration and metadata must not share mutable state across loads.
|
||||
ConfigKit must not mutate a result after returning it. Ordinary exported Go
|
||||
values are not language-enforced immutable objects; document caller ownership
|
||||
and the lifetime of captured metadata without promising otherwise.
|
||||
|
||||
Secrets must be considered throughout error handling and inspection. Library
|
||||
renderers must apply secret classification, and parser errors must not be
|
||||
forwarded blindly when they can include raw input. Do not log configuration
|
||||
implicitly. Applications remain responsible for classifying their secrets and
|
||||
for safe messages supplied by their hooks.
|
||||
|
||||
## Scope boundaries
|
||||
|
||||
Do not introduce automatic directory discovery, network providers, arbitrary
|
||||
merge strategies, additional configuration languages, or application runtime
|
||||
management without concrete consumer evidence and an explicit design decision.
|
||||
The roadmap owns the complete deferred-feature inventory. Significant boundary
|
||||
changes require an ADR and corresponding policy/contract updates; implementation
|
||||
convenience alone is not a reason to broaden the public API.
|
||||
|
||||
Reference in New Issue
Block a user