Record public facade boundary
This commit is contained in:
61
docs/adr/0006-public-facade.md
Normal file
61
docs/adr/0006-public-facade.md
Normal 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.
|
||||
Reference in New Issue
Block a user