69 lines
3.2 KiB
Markdown
69 lines
3.2 KiB
Markdown
# ADR 0002: Own public contracts behind an internal CLI backend
|
|
|
|
## Status
|
|
|
|
Accepted. Consolidated during the [alpha ADR cleanup](README.md#alpha-consolidation).
|
|
|
|
## Date
|
|
|
|
2026-11-07; consolidates decisions made on 2026-10-06 and 2026-10-09.
|
|
|
|
## Context
|
|
|
|
CommandKit needs established routing, parsing, and help machinery while retaining
|
|
control of its consumer contracts. Exposing a backend framework directly would
|
|
couple applications and integration handlers to that framework's objects and
|
|
configuration model.
|
|
|
|
## Decision
|
|
|
|
Use the root `commandkit` package as the core module's public facade. Optional
|
|
integrations own their public contracts in separate modules under
|
|
[ADR 0004](0004-optional-integration-modules.md).
|
|
|
|
Use Cobra with pflag as the internal CLI backend. Confine their types and
|
|
operations to an internal adapter that translates CommandKit declarations and
|
|
selected semantics into backend machinery. Registry logic, shared definitions,
|
|
and standard handlers remain independent of backend structures. Do not mirror
|
|
the complete backend API through renamed wrappers.
|
|
|
|
Public types and handles expose deliberate contracts and keep implementation
|
|
state private. Exports must not reveal internal or backend types through aliases,
|
|
embedding, signatures, method sets, loosely typed values, or backend-owned
|
|
syntax errors. Translate those syntax failures into CommandKit diagnostics and
|
|
outcomes. Caller-supplied objects and errors retain their documented handling;
|
|
this boundary does not require transforming arbitrary application content.
|
|
|
|
Standard Go contracts remain appropriate. Deliberate upstream public types may
|
|
be exposed by integrations that own those dependencies. Implementation may live
|
|
in the owning public package; introduce internal layers and conversions where
|
|
they simplify the code or protect the backend boundary.
|
|
|
|
There is one concrete backend, without a public backend-selection framework.
|
|
A replacement must preserve public contracts or accompany deliberate
|
|
compatibility changes. Backend defaults do not independently define CommandKit
|
|
behavior.
|
|
|
|
## Alternatives considered
|
|
|
|
- Exposing Cobra directly would reduce adapter work but make the framework part
|
|
of the consumer contract.
|
|
- A forwarding-only facade with duplicate internal representations would enforce
|
|
layering at the cost of conversions without a demonstrated need.
|
|
- pflag alone or the standard flag package would leave more routing and help
|
|
machinery to implement. Other full CLI frameworks are credible alternatives;
|
|
Cobra's adoption was the preferred maintenance tradeoff.
|
|
- Interchangeable backends would add public assembly and behavior contracts
|
|
before a concrete need exists.
|
|
|
|
## Consequences
|
|
|
|
Consumers depend on CommandKit's selected contracts while internal implementation
|
|
can evolve. The adapter still needs to preserve typed inputs, presence, public
|
|
error identity, and invocation lifetimes; package placement alone is insufficient.
|
|
|
|
The [architecture policy](../policy/architecture.md) owns dependency constraints,
|
|
GoDoc owns exact exports, and the [internal overview](../internal/overview.md)
|
|
owns package mechanics. Backend construction and reuse strategies are
|
|
implementation choices within the invocation-isolation contract.
|