Files
commandkit/docs/adr/0002-public-facade-and-cli-backend.md

69 lines
3.1 KiB
Markdown

# ADR 0002: Own public contracts behind an internal CLI backend
## Status
Accepted.
## 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.