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.
|
||||
@@ -30,6 +30,7 @@ Accepted decisions:
|
||||
- [Preserve presence and record application resolution](adr/0003-preserve-presence-and-resolution-history.md)
|
||||
- [Secret references and explicit bootstrap](adr/0004-secret-references-and-explicit-bootstrap.md)
|
||||
- [Explicit overrides and safe explanation](adr/0005-explicit-overrides-and-safe-explanation.md)
|
||||
- [Keep the public facade root-owned](adr/0006-public-facade.md)
|
||||
|
||||
For cross-cutting changes, follow every applicable row. Completed implementation
|
||||
and remediation plans are preserved in Git history at `cb5b435`; use current
|
||||
@@ -47,9 +48,10 @@ records are preserved in Git history at `244104f`. The
|
||||
[configuration contract](config.md#application-schema-versions) owns current behavior.
|
||||
|
||||
The completed [source-origins during resolution record](roadmap/source-origins-during-resolution.md)
|
||||
links to the current contract and evidence. Its staged implementation handoffs remain
|
||||
in [implementation.md](roadmap/implementation.md) until release preparation retires
|
||||
completed roadmap material.
|
||||
links to the current contract and evidence. Its completed implementation handoffs
|
||||
are preserved at `28e7fc5:docs/roadmap/implementation.md`; inspect them with
|
||||
`git show 28e7fc5:docs/roadmap/implementation.md` until release preparation
|
||||
retires the completed roadmap material.
|
||||
|
||||
## Baseline validation
|
||||
|
||||
|
||||
@@ -76,6 +76,18 @@ 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).
|
||||
|
||||
The root `configkit` package is the sole supported consumer import path. Public
|
||||
named types stay root-owned and may hold private delegated implementation state;
|
||||
their exported signatures, fields, and method sets must not expose internal
|
||||
types or acquire internal methods through anonymous embedding. Root production
|
||||
code may depend inward on a cohesive engine and its supporting internal packages,
|
||||
but internal production packages must not import the root. Explicit forwarding
|
||||
and local conversion are acceptable where they preserve type identity,
|
||||
ownership, callback lifetime, and inspection behavior. The accepted
|
||||
root-wrapper boundary and its migration rationale are recorded in
|
||||
[ADR 0006](../adr/0006-public-facade.md); its implementation remains tracked by
|
||||
the public-facade roadmap.
|
||||
|
||||
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
|
||||
|
||||
@@ -181,6 +181,35 @@ distinguish decision from implementation, and documentation links pass.
|
||||
Run `go test . -run 'LocalDocumentationLinks|DependencyImportBoundary|Example|Facade'`
|
||||
and the everyday check. No engine migration in this stage.
|
||||
|
||||
### Completion
|
||||
|
||||
Status: complete (2026-09-12).
|
||||
|
||||
Baseline behavior was verified at `28e7fc5f690b36c60e4d03586afcff00fb1dee90`;
|
||||
this plan was introduced by `eb7de8e40ab944f022a2b6984f4d4e0086f1484d`. The
|
||||
complete root surface was inventoried with `go doc -all .`: lifecycle and generic
|
||||
entry points; root value/input types (`Path`, `Source`, `Secret`); callback and
|
||||
option records; metadata, provenance, diagnostics, history, and rendering
|
||||
records; typed errors and bootstrap reports; and the scalar enum families. The
|
||||
inventory also covered receiver methods, generic instantiations, and relevant
|
||||
interfaces (`error`, `fmt.Formatter`, `fmt.Stringer`, `json.Marshaler`, and
|
||||
`io.WriterTo`). Existing behavioral tests remain the source of detailed API
|
||||
semantics; `facade_compatibility_test.go` supplies compact external-package
|
||||
coverage for the migration boundary.
|
||||
|
||||
Added ADR 0006 and the architecture rule for root-owned public wrappers and
|
||||
inward-only implementation dependencies. They describe the accepted target, not
|
||||
an already-completed extraction. Repaired the development guide, source-origins
|
||||
record, and remediation record to identify the old provenance plan by its Git
|
||||
revision instead of linking to this plan. No engine or lifecycle migration was
|
||||
introduced.
|
||||
|
||||
Validation on Linux with Go 1.26.7 passed: the focused documentation,
|
||||
import-boundary, executable-example, and facade checks, followed by
|
||||
`./scripts/check.sh`. There were no deviations. The next handoff copies the
|
||||
unchanged root implementation into the bounded internal relocation candidate;
|
||||
it must retain the documented public behavior while proving engine independence.
|
||||
|
||||
## Stage 2 — Establish the internal relocation candidate
|
||||
|
||||
Status: not started.
|
||||
|
||||
@@ -22,8 +22,9 @@ displaced/default paths that the view cannot query. This adds allocation and cop
|
||||
work proportional to retained history even for a resolver that never calls the
|
||||
new methods. No wall-clock or memory threshold was measured or is asserted here.
|
||||
|
||||
The Stage 5 completion record in [implementation.md](implementation.md) also states
|
||||
that the view "does not retain history"; the constructor contradicts that claim.
|
||||
The historical completion record at
|
||||
`28e7fc5:docs/roadmap/implementation.md` also states that the view "does not
|
||||
retain history"; the constructor contradicts that claim.
|
||||
|
||||
### Correction
|
||||
|
||||
|
||||
@@ -38,11 +38,13 @@ confinement check.
|
||||
|
||||
## Evidence and handoff
|
||||
|
||||
The completed staged record in [implementation.md](implementation.md) maps all
|
||||
twelve acceptance criteria to focused lifecycle, provenance, ownership, consumer,
|
||||
explanation, and secret tests. The final implementation commit is expected to run
|
||||
the source checker and the documented two-toolchain gate before any release
|
||||
candidate is selected.
|
||||
The completed staged record is preserved at
|
||||
`28e7fc5:docs/roadmap/implementation.md`; retrieve it with
|
||||
`git show 28e7fc5:docs/roadmap/implementation.md`. It maps all twelve acceptance
|
||||
criteria to focused lifecycle, provenance, ownership, consumer, explanation, and
|
||||
secret tests. The final implementation commit is expected to run the source
|
||||
checker and the documented two-toolchain gate before any release candidate is
|
||||
selected.
|
||||
|
||||
Publication remains a maintainer decision. Release preparation must choose the
|
||||
version, write a version-matched note, retire this completed roadmap with link
|
||||
|
||||
Reference in New Issue
Block a user