Record public facade boundary

This commit is contained in:
2026-09-12 15:56:11 +00:00
parent eb7de8e40a
commit f81def9365
7 changed files with 202 additions and 10 deletions

View File

@@ -0,0 +1,61 @@
# ADR 0006: Keep the public facade root-owned
## Status
Accepted. This records a design decision, not implementation completion.
## Date
2026-09-12
## Context
The root `configkit` package currently combines the supported consumer API with
the loading, decoding, inspection, and rendering machinery. That makes ordinary
consumer navigation harder and risks exposing implementation details through
future public declarations. Moving files alone would not preserve the identity,
method sets, callbacks, ownership rules, or reflection-sensitive behavior of
the root's public types.
## Decision
Keep `configkit` as the sole supported consumer import path and keep all public
named types defined there. When lifecycle machinery is extracted, it will live
in a cohesive `internal/engine`; the root facade may hold private engine state
and forward deliberately selected methods. The dependency direction is root to
engine and its supporting internal packages. Internal production packages do
not import the root package.
The facade will use root-owned wrappers and explicit private conversions. It
will not use public aliases to engine types, anonymous embedding that promotes
engine methods, public engine types in signatures or fields, or public bridge
methods. Existing document and YAML boundaries remain intact.
The migration may use a temporary internal candidate facade while the unchanged
root remains the only production entry point. That duplication is a bounded
relocation mechanism, not a second supported package, feature path, or runtime
selection mechanism. The final cutover removes the temporary candidate and old
root implementation together.
The [architecture policy](../policy/architecture.md#public-api-and-dependency-direction)
owns the binding boundary. The [public-facade roadmap](../roadmap/public.md)
owns the intended end state and its implementation plan owns progress.
## Alternatives considered
- Alias root types to engine types: reduces forwarding, but makes the engine's
exported method set and type ownership part of the consumer API.
- Keep all machinery in the root package: avoids migration work, but leaves the
public boundary difficult to navigate and easy to expand accidentally.
- Introduce a generic adapter or registration framework: could reduce some
handwritten conversions, but adds machinery and obscures the ownership rules
this boundary needs to preserve.
## Consequences
The refactor carries explicit forwarding and conversion work, especially for
callbacks, detached records, source ownership, frozen inspection, and the
exact-type secret bridge. Public compatibility must be verified by behavior and
external-package evidence rather than inferred from package names. Internal
exports remain implementation surfaces, and the completed architecture will
have one engine and one root facade.