Accept optional integration modules architecture
This commit is contained in:
@@ -2,7 +2,11 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted.
|
||||
Partially superseded by [ADR 0010](0010-optional-integration-modules.md).
|
||||
|
||||
ADR 0010 narrows the root facade and public-type ownership decision to the core
|
||||
module and places optional library dependencies in integration modules. The
|
||||
remaining principles continue to apply; this record's decision text is retained.
|
||||
|
||||
## Date
|
||||
|
||||
|
||||
94
docs/adr/0010-optional-integration-modules.md
Normal file
94
docs/adr/0010-optional-integration-modules.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# ADR 0010: Separate the core facade from optional integration modules
|
||||
|
||||
## Status
|
||||
|
||||
Accepted. Partially supersedes
|
||||
[ADR 0003](0003-public-facade.md) as described below.
|
||||
|
||||
## Date
|
||||
|
||||
2026-10-09
|
||||
|
||||
## Context
|
||||
|
||||
CommandKit serves consumers that need its command infrastructure with different
|
||||
combinations of library integrations, including none. A consumer using only the
|
||||
core should not acquire dependencies belonging to optional integrations.
|
||||
|
||||
ADR 0003 establishes deliberate public contracts and an internal CLI backend
|
||||
boundary. Those principles remain appropriate. Its initial single root facade,
|
||||
however, combines core and integration responsibilities. Separate packages within
|
||||
one module would separate imports while retaining shared module requirements.
|
||||
|
||||
## Decision
|
||||
|
||||
Retain the root `commandkit` package as the core module's public facade. It owns
|
||||
core command declarations, registration, typed inputs, dispatch, help/version,
|
||||
shared syntax, diagnostics, and invocation outcomes.
|
||||
|
||||
Provide optional library integrations as separate Go modules with their own
|
||||
public package contracts. Each integration owns the standard command handlers,
|
||||
provider contracts, reports, and adapters appropriate to its responsibility.
|
||||
Applications select integrations and explicitly register their commands; importing
|
||||
an integration does not install a command family.
|
||||
|
||||
Integrations provide convenient registration of their standard command families,
|
||||
with standard declarations and handlers supplied by the integration. Applications
|
||||
provide acquisition and domain-specific context without assembling individual
|
||||
standard commands or repeating adapter plumbing. More specialized composition
|
||||
remains available where concrete consumer needs justify it.
|
||||
|
||||
Dependencies point from integrations toward the core. The core's public API,
|
||||
implementation, and module requirements remain independent of optional
|
||||
integration libraries. An integration may depend on another integration when
|
||||
its responsibility requires that relationship. Document such dependencies so
|
||||
consumers can understand the modules they select.
|
||||
|
||||
Integrations compose through supported public core contracts and preserve
|
||||
CommandKit's standard grammar, command ownership, help, and outcome conventions.
|
||||
They do not access private core state or backend structures. Add public contracts
|
||||
where concrete integration needs justify them, without requiring a general plugin
|
||||
or backend-selection framework.
|
||||
|
||||
### Relationship to ADR 0003
|
||||
|
||||
The root-facade and public-type ownership provisions of ADR 0003 now apply to
|
||||
the core module. Integration-owned public types and operations belong in their
|
||||
respective public packages. The permission to expose deliberately selected
|
||||
upstream library types applies within the integrations that depend on them;
|
||||
it does not justify optional integration dependencies in the core.
|
||||
|
||||
ADR 0003's remaining principles continue to apply across the core and
|
||||
integrations: deliberate exports, private implementation state, proportionate
|
||||
internal layering, no exposure of internal or backend types, and preservation of
|
||||
documented ownership, presence, callback lifetime, and error semantics. Application
|
||||
input types and caller-supplied values and errors retain their existing handling.
|
||||
Cobra/pflag remain behind the core's internal adapter.
|
||||
|
||||
This decision changes the scope of the single-facade decision rather than
|
||||
replacing its contract discipline. ADR 0003 is partially superseded and its
|
||||
original decision text remains intact.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
| Alternative | Analysis |
|
||||
| --- | --- |
|
||||
| Keep integrations in the root package | Preserves existing imports and simplifies releases, but core consumers acquire optional library dependencies. |
|
||||
| Use separate packages within one module | Separates compiled imports and retains one release unit, but keeps integration requirements in the shared module graph. |
|
||||
| Have applications implement integration handlers | Keeps the core independent, but recreates duplicated inspection commands and weakens consistent operator behavior. |
|
||||
| Introduce universal provider contracts in the core | Could support several libraries through a common model, but adds abstractions and conversion obligations before concrete needs justify them. |
|
||||
|
||||
## Consequences
|
||||
|
||||
Consumers can adopt the core independently and add supported integrations as
|
||||
needed. Integrations remain maintained parts of CommandKit, with shared CLI
|
||||
conventions and owning-library semantics. Dependency independence does not mean
|
||||
the core has no external implementation dependencies.
|
||||
|
||||
Moving existing integration APIs requires a documented consumer migration.
|
||||
Integration modules add module-specific dependency, validation, and release work.
|
||||
Core tests, examples, and tools must not reintroduce the optional dependencies
|
||||
that this boundary removes.
|
||||
|
||||
Exact registration mechanics and release cadence are not selected here.
|
||||
Current GoDoc and CLI contracts continue to own implemented behavior.
|
||||
@@ -1,6 +1,7 @@
|
||||
# Optional integration modules
|
||||
|
||||
Status: proposed implementation roadmap; no module extraction has begun.
|
||||
Status: module boundary accepted in ADR 0010; implementation planning remains
|
||||
in progress and no module extraction has begun.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
@@ -11,11 +12,13 @@ module dependencies. ConfigKit-only consumers should not acquire PromptKit.
|
||||
|
||||
This roadmap records the targeted end state, selected module layout, and
|
||||
migration work. Recommendations under [Open Decisions](#open-decisions) remain
|
||||
proposals. It does not supersede accepted ADRs or describe these changes
|
||||
as implemented. The [architecture policy](../policy/architecture.md) and
|
||||
[ADR 0003](../adr/0003-public-facade.md) govern the current boundary; an accepted
|
||||
successor decision is needed before changing it. Current contracts remain in
|
||||
GoDoc, the [CLI reference](../cli.md), and the
|
||||
proposals. It does not describe these changes as implemented.
|
||||
[ADR 0010](../adr/0010-optional-integration-modules.md) owns the accepted module
|
||||
boundary and convenient registration principles; it partially supersedes
|
||||
[ADR 0003](../adr/0003-public-facade.md), whose remaining principles still apply.
|
||||
Alignment of the [architecture policy](../policy/architecture.md) remains part of
|
||||
the work below. Current implemented contracts remain in GoDoc, the
|
||||
[CLI reference](../cli.md), and the
|
||||
[consumer guide](../consumers/guide.md).
|
||||
|
||||
## Current baseline
|
||||
@@ -108,21 +111,24 @@ is an intentional consumer migration.
|
||||
|
||||
## Work sequence
|
||||
|
||||
### 1. Settle boundaries and record the decision
|
||||
### 1. Align policy and settle implementation boundaries
|
||||
|
||||
Completed: ADR 0010 is accepted and ADR 0003 is marked partially superseded,
|
||||
with its decision text preserved. The partial status follows the explicitly
|
||||
authorized exception to the documentation policy for this decision.
|
||||
|
||||
- Resolve the remaining choices under Open Decisions before moving public
|
||||
symbols, using the selected module paths and package names above.
|
||||
- Create a successor ADR for the changed facade/module boundary and mark
|
||||
ADR 0003 superseded according to the
|
||||
[documentation policy](../policy/documentation.md#architecture-decision-records).
|
||||
Preserve its decision history. Align the architecture policy and review other
|
||||
- Align the architecture policy with ADR 0010 and review other
|
||||
ADRs for affected ownership statements without reopening unrelated decisions.
|
||||
- Inventory root exports, imports, private helper use, and family registration
|
||||
behavior. Assign each to core or an integration; document the consumer-facing
|
||||
old-to-new API mapping rather than freezing a full inventory in this roadmap.
|
||||
- Sketch three representative consumers: core only, ConfigKit only, and both
|
||||
libraries. Confirm that combined configuration scopes remain straightforward
|
||||
and that moving code does not replace removed boilerplate with new plumbing.
|
||||
and that registration meets ADR 0010's convenience principle without replacing
|
||||
removed boilerplate with new plumbing. Use these examples to evaluate the
|
||||
registration API; no fixed call count or particular options pattern is selected.
|
||||
|
||||
Completion: the dependency direction, public migration, and registration approach
|
||||
are concrete enough to implement without inventing a general plugin framework.
|
||||
@@ -220,6 +226,10 @@ Semantic comparison retains the upstream-contract dependency recorded in
|
||||
|
||||
### Registration across the new public boundary
|
||||
|
||||
ADR 0010 selects convenient family registration with specialized composition
|
||||
where needed. The remaining decision is how to support it across module
|
||||
boundaries.
|
||||
|
||||
**Recommendation:** first reuse public command/group registration and duplicate
|
||||
path checks. Add only a narrow core registration capability if preserving the
|
||||
existing standard-family ownership contract requires it. This keeps integrations
|
||||
|
||||
Reference in New Issue
Block a user