Simplify ADRs and relax premature constraints

This commit is contained in:
2026-10-07 02:45:09 +00:00
parent 984d159676
commit 7e453a2df2
9 changed files with 165 additions and 310 deletions

View File

@@ -11,11 +11,11 @@ Accepted.
## Context
Several downstream consumers of the ConfigKit and PromptKit libraries include
duplicated or near-duplicated code relating to configuration inspection,
routing, parsing, help, and error handling. However, their command vocabulary
duplicated or near-duplicated code relating to configuration inspection,
routing, parsing, help, and error handling. However, their command vocabulary
and syntax have diverged. CommandKit aims to provide a single, unified CLI
implementation that will reduce duplication, provide consistent vocabulary and
grammar, and reduce the amount of code each individual applicaiton must own.
implementation that will reduce duplication, provide consistent vocabulary and
grammar, and reduce the amount of code each individual application must own.
Applications have genuine domain commands, such as Narratio's `session restore`,
that remain outside the standard suite. Merely forwarding standard families from
@@ -37,11 +37,9 @@ custom command names, domain meaning, validation, effects, artifacts, and
operational outcomes.
Use namespace-first syntax for the standard suite, which provides a clear
family ownership boundary. The initial release of CommandKit will ship with two
bundled standard command families:
(1) The `config` family provides ConfigKit inspection and validation; and
(2) the `promptkit` family provides PromptKit inspection and utilities.
CommandKit integrates ConfigKit and PromptKit through their supported public
family ownership boundary. The initial standard command families are `config`
for ConfigKit inspection and validation, and `promptkit` for PromptKit inspection
and utilities. CommandKit integrates these libraries through their supported public
semantics.
CommandKit accepts custom commands outside its reserved standard families and
@@ -100,10 +98,10 @@ Bindings support ordinary typed fields and presence-aware fields where omission
has a separate meaning. CommandKit records supplied state independently of values
and defaults, preserving explicitly supplied empty, false, and zero values.
CommandKit creates fresh input storage per invocation and keeps its previous
parsed values, collections, and presence out of subsequent invocations. Handler
closures and application state retain their own lifecycle. Fresh CommandKit state
addresses invocation lifetime; concurrent dispatch is a separate contract.
CommandKit keeps parsed values, collections, and presence from one invocation out
of subsequent invocations. Storage allocation and reuse are implementation
choices. Handler closures and application state retain their own lifecycle;
concurrent dispatch is a separate contract.
The invocation API supplies context and streams separately from CLI inputs.
CommandKit creates its declarations and bindings from metadata and defers its
@@ -117,8 +115,9 @@ an exact public API.
### Outcomes and domain behavior
Resolve the command and handle help/version before loading application state.
For execution, allocate fresh inputs, apply shared parsing and operand checks,
then invoke the typed handler. Return its invocation outcome to the application.
For execution, prepare independent invocation inputs, apply shared parsing and
operand checks, then invoke the typed handler. Return its invocation outcome to
the application.
CommandKit classifies shared usage errors and standard-family outcomes. Its
handler result contract accepts application-specific outcomes and preserves their
@@ -179,7 +178,7 @@ resources, with standard meanings preserved for operations that are installed.
| Parsed-value accessor object | Uniform handlers, but string-based lookup, runtime type errors, and repeated assembly remain. |
| Individual typed parameters | Clear for small commands; grows into long signatures and adapter machinery. Typed structs scale more naturally. |
| Reflection and struct tags | Compact declarations, but adds a tag language, field-discovery rules, and runtime declaration validation. Explicit bindings keep declarations visible. |
| Typed command objects | Can organize complex handlers. CommandKit's fresh input contract remains separate from caller-owned object lifetimes; objects are an application option. |
| Typed command objects | Can organize complex handlers. CommandKit's invocation-state contract remains separate from caller-owned object lifetimes; objects are an application option. |
| Generated bindings/adapters | Can combine compact authoring and typing, but adds tooling and generated-file maintenance without demonstrated need. |
| Raw arguments | Simple routing integration, but returns common parsing and help to applications. |
@@ -195,7 +194,8 @@ support consistent mechanics without requiring reflection or generated code.
Shared parsing defects can affect every adopter. Consumer and backend integration
evidence must protect selected semantics, including ownership conflicts, help
without configuration, presence, fresh input, cancellation, and domain outcomes.
without configuration, presence, independent invocation inputs, cancellation,
and domain outcomes.
CommandKit releases document intentional compatibility changes. Coordinated
application documentation and subprocess-caller updates are recommended migration
practices.

View File

@@ -29,11 +29,12 @@ getters stay within CommandKit's internal adapter. Independent consumer framewor
use remains application-owned. [ADR 0003](0003-public-facade.md) records the
adapter and root-owned public contracts.
Build fresh backend command/flag state and input storage per invocation. A fresh
command tree constructed from registered definitions is the initial approach.
CommandKit's tree construction uses registered metadata and leaves acquisition
callbacks uninvoked. Application startup and callback effects retain their own
lifecycle.
Invocations do not inherit parsed values or presence from previous invocations.
Rebuilding the backend command tree and input storage from registered definitions
is the initial implementation strategy; safe reuse remains an implementation
choice. CommandKit's tree construction uses registered metadata and leaves
acquisition callbacks uninvoked. Application startup and callback effects retain
their own lifecycle.
Implement one concrete backend. There is no initial public backend selector or
pluggable framework. A future replacement can change internal implementation
@@ -56,10 +57,10 @@ The framework supplies established generic CLI machinery. CommandKit still owns
registration conflicts, reserved families, typed bindings and presence, standard
help and diagnostics, provider integration, and selected reports and outcomes.
The adapter must accommodate explicit empty/false/zero values, fresh state,
selected repetition and operand rules, and help without configuration. Backend
features do not expand the standard automatically: for example, completion
commands remain deferred unless deliberately selected.
The adapter must accommodate explicit empty/false/zero values, independent parsed
state, selected repetition and operand rules, and help without configuration.
Backend features do not expand the standard automatically: for example,
completion commands remain deferred unless deliberately selected.
Backend error handling must preserve application outcomes, avoid duplicate
diagnostics, and return control to the application's entry point.

View File

@@ -10,19 +10,19 @@ Accepted.
## Context
CommandKit needs room to change its internal implementation details while
CommandKit needs room to change its internal implementation details while
consumers retain access to a stable external API. Exposing backend assembly or
extension structures would let applications ossify around implementation
details that maintainers may later decide to replace.
ConfigKit, PromptKit, and ReleaseKit demonstrate facades that own public types
and delegate through private state and explicit conversion. ConfigKit also
translates upstream YAML parser structures into an independent internal document
ConfigKit, PromptKit, and ReleaseKit demonstrate facades that own public types
and delegate through private state and explicit conversion. ConfigKit also
translates upstream YAML parser structures into an independent internal document
model.
The selection of Cobra as an internal dependency is compatible with this
decision. Public API independence needs a genuine contract boundary, and
keeping backend structures out of shared internal representations also makes
decision. Public API independence needs a genuine contract boundary, and
keeping backend structures out of shared internal representations also makes
future replacement easier.
## Decision
@@ -32,38 +32,39 @@ Define CommandKit's public named types there and expose only selected operations
extension contracts, and documented methods. Handles keep implementation state in
private fields.
Implementation packages belong under Go's `internal/` boundary. Public code
forwards inward with explicit wrappers and conversions; internal production
packages do not import the root. Shared internal contracts live inside that
boundary. Additional public packages require a deliberate decision based on a
durable consumer responsibility.
Straightforward implementation may live in the root package without expanding
its exports. Introduce internal packages, interfaces, and conversions where they
simplify implementation or protect the backend boundary. Package organization and
the amount of internal layering follow implementation needs. Additional public
packages require a deliberate decision based on a durable consumer responsibility.
Do not alias public types to internal or backend types, anonymously embed those
types to promote methods, or expose implementation bridge methods. Exported
fields, signatures, variables, callbacks, interface methods, constraints, and
method sets must not reveal internal or Cobra/pflag structures. Loosely typed
values and returned errors must not provide indirect backend-object access.
method sets must not reveal internal or Cobra/pflag structures. CommandKit does
not expose its internal backend objects or backend-specific syntax errors through
its public API, including through loosely typed values or returned errors.
Caller-supplied values and errors retain their documented handling; this boundary
does not require inspecting or transforming arbitrary application objects.
Standard contracts such as `context.Context` and `io.Writer` remain appropriate.
Public types from integration libraries, such as ConfigKit and PromptKit, may
be selected as deliberate dependencies. Application input types remain application-owned.
Go declarations and GoDoc own exact exported contracts.
be selected as deliberate dependencies. Application input types remain
application-owned. Go declarations and GoDoc own exact exported contracts.
Confine Cobra/pflag types and operations to an internal adapter. Registry logic,
standard handlers, and shared definitions use CommandKit-owned representations.
standard handlers, and shared definitions remain independent of backend structures.
The adapter translates paths, descriptions, bindings, presence, callbacks, and
selected help/outcome semantics into backend machinery. Do not reproduce Cobra's
complete API through renamed wrappers.
Typed input factories and handlers can cross the facade through private callbacks
without internal packages importing public declarations. Preserve fresh input and
backend state per invocation. Introduce narrow internal interfaces where actual
engine/adapter interaction justifies them; exact package names and splits remain
implementation choices.
Preserve independent parsed state per invocation under
[ADR 0001](0001-command-dispatch-and-inputs.md). Factories, callbacks, and shared
representations remain API and implementation design choices.
Translate backend-owned syntax failures into CommandKit diagnostics and outcomes.
Preserve useful public identity for application handler errors and cancellation
according to the invocation contract. Explicit conversions must preserve value
according to the invocation contract. Any conversions must preserve value
ownership, callback lifetime, presence, and supported error semantics.
## Alternatives considered
@@ -71,6 +72,7 @@ ownership, callback lifetime, presence, and supported error semantics.
| Alternative | Analysis |
| --- | --- |
| Keep all machinery in the public root | Less forwarding, but harder consumer navigation and easier accidental public expansion. |
| Require a forwarding-only root and separate internal representations | Enforces a uniform layering scheme. It can add duplicate types and callback plumbing before those mechanisms simplify implementation. |
| Alias or embed implementation types | Less conversion code, but couples public type identity, fields, or method sets to internal choices. |
| Hide Cobra only behind the public facade | Hides types from applications but allows backend structures to spread through internal logic, complicating replacement. |
| Mirror Cobra's API with wrappers | Removes dependency names while preserving its conceptual coupling and compatibility surface. |
@@ -84,15 +86,10 @@ collaborators, and package boundaries can evolve. Useful application registratio
capabilities still need a proportionate API; minimizing accidental exports must
not recreate repetitive consumer infrastructure.
Explicit forwarding and conversion require maintenance. Type identity, ownership,
method sets, callback lifetime, and error semantics must be protected by evidence,
not inferred from package relocation.
Compiled public API checks protect aliases, fields, signatures, constraints, and
promoted methods. Import checks keep the backend in its adapter and internal
production code independent of root. External-package tests protect consumer
semantics through the real adapter. ConfigKit and ReleaseKit provide precedents
for these checks without requiring their full validation workflows.
Forwarding and conversion add maintenance where used. Proportionate checks should
protect the public surface, backend isolation, and consumer behavior through the
real adapter. The implementation determines which checks provide useful evidence;
package relocation alone does not establish those properties.
Backend replacement can preserve the public Go API but must also preserve selected
CLI behavior or follow the release policy for intentional incompatibilities.

View File

@@ -15,13 +15,9 @@ needs. A defined operator surface establishes the infrastructure CommandKit
provides. Different integrations expose different resources and inspection
capabilities, while shared verbs benefit from consistent meanings.
[ADR 0001](0001-command-dispatch-and-inputs.md) establishes dispatch, registration,
capability-based installation, and the boundary of CommandKit policy. The remaining
decisions are the operator questions the initial standard answers.
## Decision
CommandKit supplies help and version reporting and defines ConfitKit and
CommandKit supplies help and version reporting and defines ConfigKit and
PromptKit inspection operations. Each family defines its own supported set of
operations. Registration installs handlers for the capabilities supplied by the
integration and exposes their availability through help and discovery metadata.
@@ -44,31 +40,23 @@ backend-completed named execution targets. PromptKit definition capabilities and
its configuration scope are registered according to their available provider
operations. Either can be integrated independently.
CommandKit assembles each installed family from its declared capabilities, keeping
standard handlers and metadata together. The inventory describes available
standard operations; adoption can use the supported subset. Semantic diff depends
on safe comparison snapshots for its selected scope. Its availability is
independent of display, validation, and other inspection capabilities.
Adoption can use the supported subset under
[ADR 0001](0001-command-dispatch-and-inputs.md). Missing comparison or catalog
capabilities leave other inspection operations available.
Shared verbs keep consistent purposes: `list` enumerates resources, `show`
displays a selected resource, and `diff` compares supported representations. Each
family specializes those purposes for its own resources. For example, a future
FeedKit family could supply `list` and `show` as its intended operation set.
family specializes those purposes for its own resources.
`app version` and root `app --version` report application version. The version
command defaults to `--scope app`; `app version --scope commandkit` reports the
embedded CommandKit release version. `--format` selects presentation of the same
subject. Future component identities can use registered version metadata. Version
subjects are independent of configuration scopes and loading providers.
Version subjects are independent of configuration scopes and loading providers.
CommandKit owns vocabulary and observable contracts within its standard families.
Custom execution, rendering, serving, sessions, and artifact workflows retain
their application-owned meanings. Additional shared operations enter through
versioned CommandKit releases under the
[release policy](../policy/release.md#versioning-and-compatibility).
their application-owned meanings.
The CLI reference owns exact flags, operands, defaults, and report schemas when
implemented. This record owns operation purposes and capability-based availability.
The [CLI roadmap](../roadmap/01-cli-plan.md) tracks command details and delivery.
The CLI reference will own exact flags, operands, defaults, and report schemas
when implemented.
## Alternatives considered
@@ -79,7 +67,6 @@ implemented. This record owns operation purposes and capability-based availabili
| Definition inspection through configuration operations alone | Source values and provenance share one path. Captured catalogs and completed execution targets require additional interpretation. |
| Standardize execution and mutation alongside inspection | Expands shared vocabulary to more workflows. Additional domain and state-management contracts require their own evidence and design. |
| Display dependency identities in ordinary application version output | Makes dependency information immediately visible. Application identity becomes coupled to dependency reporting. |
| A combined dependency-version option | Gives a useful diagnostic inventory. Scoped version reporting also supports selecting one identity. |
## Consequences
@@ -88,12 +75,6 @@ availability from registration. Each enabled operation needs its own data
contract: comparison needs safe snapshots, catalogs need enumeration, and profile
display needs safe execution-target inspection.
Shared operations retain clear purposes. CommandKit release notes describe changes
to its published operations. Coordinated application documentation and caller
updates are recommended migration practices.
Help and discovery describe actual supported capabilities. The
[scope model](0009-configuration-scopes.md),
[inspection lifecycle](0008-inspection-lifecycle.md), and
[comparison policy](0011-semantic-configuration-diff.md) describe the proposed
provider and behavioral contracts supporting this surface.
The [scope model](0009-configuration-scopes.md) and
[comparison policy](0008-semantic-configuration-diff.md) describe related
capability and behavioral decisions.

View File

@@ -15,58 +15,47 @@ application handler, report writing, and the application entry point. Operators
and subprocess consumers need consistent classifications for those stages.
Applications also have meaningful domain outcomes of their own.
[ADR 0001](0001-command-dispatch-and-inputs.md) establishes process and domain
ownership. [ADR 0003](0003-public-facade.md) establishes public error and backend
boundaries. The remaining decisions concern the public outcome model, report
and diagnostic channels, and standard process-status mappings.
## Decision
CommandKit returns an invocation outcome with an explicit classification and
recommended process status. The public model distinguishes successful operation,
usage error, operational failure, and application domain outcome. Failures retain
their consumer-facing cause and supported `errors.Is`/`errors.As` identity.
Exact Go declarations remain part of facade API design.
Exact Go declarations remain part of facade API design under
[ADR 0003](0003-public-facade.md).
Use these mappings for CommandKit-owned commands:
| Status | Meaning |
| --- | --- |
| `0` | The requested operation completed successfully, including help and completed comparison. |
| `0` | The requested operation completed successfully. |
| `1` | A syntactically valid operation failed during loading, validation, lookup, inspection, cancellation, diagnostics delivery, or report writing. |
| `2` | The invocation failed command, flag, scope, format, operand, repetition, or input-combination validation. |
| `2` | The invocation failed command, flag, scope, format, operand, or input-combination validation. |
CommandKit's handler result contract accepts domain classifications and suggested
process statuses supplied by the caller. CommandKit preserves that classification
when returning the handler's result.
A custom domain status and a shared usage status may have the same numeric value;
their explicit classifications retain their distinct meanings. The application
entry point controls final process termination and status mapping.
when returning the handler's result. A custom domain status and a shared usage
status may have the same numeric value; their explicit classifications retain
their distinct meanings. The application entry point controls final process
termination and status mapping.
CommandKit writes standard reports to the supplied report stream, conventionally
stdout, and its warnings and errors to the supplied diagnostic stream,
conventionally stderr. Callers choose the streams. Each CommandKit diagnostic has
one delivery owner and one emission through the selected channel. The provider
contract carries acquisition diagnostics and their delivery state so CommandKit
can present pending diagnostics once. CommandKit adapts backend
syntax failures into its public classification and safe diagnostic presentation.
Usage guidance accompanies usage errors; operational failures receive diagnostics
appropriate to the failed operation.
conventionally stderr. Callers choose the streams. CommandKit assigns responsibility
for presenting its diagnostics, avoids duplicate presentation through its own
paths, and reports write failures. Caller callbacks retain control of their own
output. CommandKit adapts backend syntax failures into its public classification
and diagnostic presentation. Usage guidance accompanies usage errors; operational
failures receive diagnostics appropriate to the failed operation.
Warning severity alone permits a successful operation. A diagnostic writer
failure is an operational failure. Source coordinates and source-ID legends are
preserved where supplied by the owning library.
failure is an operational failure.
Report writers use the application's supplied streams. Shell redirection provides
file output for the initial standard. A writer failure can leave a partial report
and returns operational failure. The outcome identifies incomplete delivery;
checking it before interpreting reports is recommended caller practice. Custom
handler output remains application-owned. Multi-scope loading and ordering follow
[the YAML report policy](0007-native-yaml-reports.md).
A completed semantic comparison returns success with its differences and coverage
gaps recorded in the report. Its outcome describes successful inspection; the
application or consuming script can interpret differences according to its task.
A writer failure can leave a partial report and returns operational failure. The
outcome identifies incomplete delivery. Custom handler output remains
application-owned. [ADR 0007](0007-native-yaml-reports.md) covers `config show` report
preparation; [ADR 0008](0008-semantic-configuration-diff.md) defines successful
comparison, including differences and coverage gaps.
## Alternatives considered
@@ -76,7 +65,6 @@ application or consuming script can interpret differences according to its task.
| Backend errors and output as the public outcome model | Reuses framework machinery directly. Backend conventions become dependencies for applications and subprocess consumers. |
| One common mapping for application domain failures | Produces uniform numeric statuses. Applications adapt existing artifact and execution outcomes to shared categories. |
| Handler-owned diagnostics for every failure | Gives each handler full presentation control. Shared diagnostic consistency requires repeated ownership and formatting coordination. |
| Dedicated file-output options | Adds direct file targeting. The standard acquires creation, replacement, and retention responsibilities alongside report writing. |
## Consequences
@@ -84,11 +72,7 @@ The outcome model supports both Go callers and executable entry points. Explicit
classification keeps domain identity intact through adapter and facade conversion.
Single diagnostic ownership supports predictable presentation.
CommandKit handlers and writers coordinate cause propagation and delivery
responsibility. Output failures may produce partial bytes; callers receive an
outcome describing delivery failure. The public result/error design preserves
these semantics
through fresh invocation state and private adapter callbacks.
Acceptance establishes the compatibility meaning of these status values and
delivery rules across standard commands.
The public result/error design must preserve cause and delivery failures across
handlers, writers, and the backend adapter. Diagnostic delivery bookkeeping
remains API design work. Acceptance establishes the compatibility meaning of the
status values and delivery rules across standard commands.

View File

@@ -11,16 +11,10 @@ Proposed
## Context
CommandKit owns routing, parsing, and help for standard and registered application
commands. The selected registry and typed-input model supply a shared source for
syntax metadata. A concrete grammar makes option placement, operands, repetition, and
commands. A concrete grammar makes option placement, operands, repetition, and
help predictable across the application suite. Shared vocabulary also reduces
the need to remember different verbs for equivalent operations.
[ADR 0001](0001-command-dispatch-and-inputs.md) establishes namespace-first
ownership, typed bindings, explicit presence, and fresh invocation inputs.
The remaining choices concern option placement, operand handling, repetition,
and discovery behavior across registered commands.
## Decision
CommandKit's standard grammar and vocabulary are part of the contract for
@@ -36,25 +30,23 @@ Applications are encouraged to use standard verbs such as `help`, `list`, and
[ADR 0004](0004-standard-inspection-surface.md).
CommandKit parses options after the complete registered command path. Within the
selected command, options and declared operands may be interspersed. Operand counts
and types come from registration; custom operand domain meaning belongs to the
handler.
selected command, options and declared operands may be interspersed. Operand
counts and types come from registration.
Standard options use lowercase names with hyphen-separated words and the `--`
prefix. Value options accept `--name value` and `--name=value`. Boolean options
accept their documented presence form and explicit values such as `--name=false`.
The `--` token ends option parsing; subsequent tokens are operands.
Registered metadata identifies each flag as singleton or repeatable. A singleton
accepts one occurrence per invocation. Repetition across either supported spelling
is a usage error. A repeatable flag accumulates values in invocation order.
Presence is recorded independently of defaults and values, preserving supplied
empty strings, false, and zero under the existing typed-input decision.
Registered metadata identifies each flag as singleton or repeatable. For a
singleton, the last occurrence supplies its value, including when the invocation
mixes supported spellings. A repeatable flag accumulates values in invocation order.
Presence follows the typed-input contract in
[ADR 0001](0001-command-dispatch-and-inputs.md).
CommandKit validates paths, flag names, conversions, operand counts, and declared
input combinations through the shared parser. Those failures use the usage
classification in [ADR 0005](0005-invocation-outcomes.md). Registered domain value
parsers and handlers receive values through the typed binding contract.
classification in [ADR 0005](0005-invocation-outcomes.md).
Root help is available through `app`, `app help`, `app --help`, and `app -h`.
Invoking a command group with no registered execution handler displays group help.
@@ -62,21 +54,8 @@ A runnable command follows its registered handler and operand requirements,
including when it also has subcommands. CommandKit-owned groups such as `config`
display help on bare invocation. `app help COMMAND ...` and a resolved command's
`--help` display the same registered help. Required execution operands are checked
for execution requests; help uses resolved command and flag
metadata. Invalid paths and flag names receive usage diagnostics.
`app version` and the root-only `app --version` shortcut report application version.
The version command also accepts explicit component selection under
[ADR 0004](0004-standard-inspection-surface.md).
Standard configuration operations have declared flag inputs. PromptKit collection
and definition commands declare their resource and ID operands. The registry
generates help, including supported formats and selector applicability, from
those declarations.
The internal Cobra/pflag adapter implements this grammar using registered
metadata and backend parsing mechanisms. Flag values beginning with `-` follow
their registered type and supported value syntax. Parser adaptation is centralized
at that boundary, following [ADR 0002](0002-cobra-backend.md).
for execution requests; help uses registered metadata. Invalid paths and flag
names receive usage diagnostics.
## Alternatives considered
@@ -84,21 +63,16 @@ at that boundary, following [ADR 0002](0002-cobra-backend.md).
| --- | --- |
| Flags before all operands | Gives argument order a simple positional rule. Operators organize values around that rule when assembling commands. |
| Common flags before or between command-path components | Supports familiar global-option styles. Routing and help need rules for options across several command levels. |
| Last singleton occurrence wins | Supports layered argv construction. Repeated assignments become an override mechanism requiring separate presence and precedence interpretation. |
| Reject repeated singleton flags | Detects repeated assignments, but prevents callers from assembling defaults followed by explicit overrides. |
| Application-selected parser conventions | Supports existing CLI implementations. Operators and shared help need per-application syntax knowledge. |
## Consequences
Operators learn one option placement and repetition policy for adopting
commands using CommandKit. Custom handlers retain their operand domain contracts.
Typed bindings and metadata support consistent parsing and generated help.
Shared vocabulary guidance encourages consistent names for equivalent
application-owned operations.
commands using CommandKit. Shared vocabulary guidance encourages consistent
names for equivalent application-owned operations.
The adapter carries the work needed to preserve the grammar across dependency
updates. Contract evidence must cover repetition, mixed spellings, explicit
presence, interspersed operands, `--`, help, and fresh state. Backend replacement
preserves the selected grammar under the release compatibility policy.
The CLI reference owns detailed command signatures and examples when implemented.
This record owns the common rules that apply across those signatures.
The internal adapter must preserve the selected grammar across backend changes.
The [CLI roadmap](../roadmap/01-cli-plan.md) tracks operation-specific syntax;
the CLI reference will own detailed command signatures and examples when
implemented.

View File

@@ -14,73 +14,39 @@ ConfigKit and PromptKit provide native YAML configuration inspection. Reusing
their writers preserves captured value semantics, ordering, and redaction. YAML
also supports automated consumption of structured reports.
The agreed initial direction is YAML-based structured inspection and separate
native documents for `config show --scope all`. The remaining choices concern
report defaults, document framing, and when output begins relative to
configuration loading.
## Decision
The initial standard uses text for concise operator reports and YAML for
structured consumption.
| Operation | Default report | Available initial formats |
| --- | --- | --- |
| `help` | Text | Text |
| `version` | Text | Text, YAML |
| `config scopes`, `validate`, `sources`, `explain`, `diff` | Text | Text, YAML |
| `config show` | Native YAML | YAML |
| `promptkit list/show` | Text | Text, YAML |
These format choices govern initial configuration and PromptKit reports and
version reporting. Additional families select formats appropriate to their own
resources through their command contracts. Custom handler formats remain
application-owned. Version format selection preserves the selected subject under
[ADR 0004](0004-standard-inspection-surface.md).
Operations with a format choice use `--format text|yaml`. Format names are
lowercase. YAML-only display uses its native writer directly. Help presents its
registered text form. Format validation follows the usage outcome policy in
[ADR 0005](0005-invocation-outcomes.md).
A single-scope `config show` writes the owning library's complete native redacted
YAML. Its output consists of the inspection document itself. The native writer
preserves effective presence, null and container distinctions, stable mapping
order, and sequence order according to its public contract.
`config show --scope all` emits one native document per registered scope in the
order defined by [ADR 0009](0009-configuration-scopes.md): application first,
PromptKit next when registered, followed by additional scopes in identifier order.
Each document begins with `---` and a `# scope: NAME` comment. A one-scope `all`
selection uses the same labeled document form.
order defined by [ADR 0009](0009-configuration-scopes.md). CommandKit supplies
document separators and scope-label comments around native writer output. Each
scope retains its own value namespace and native rendering; the documents can
be decoded individually.
CommandKit writes the separators and comments around the native writer output.
Comments label scopes for operators; document order follows the registered scope
inventory. That framing offers callers an association between documents and
scopes. Each scope retains its own value namespace and native rendering.
The combined stream is an inspection report whose documents can be decoded
individually.
CommandKit checks operation availability for selected scopes before acquisition.
It acquires their views and completes validation required by those provider
contracts before report output begins. A failure returns its diagnostic outcome
before report writing. After writing begins, a writer failure may leave partial
bytes and returns operational failure under ADR 0005.
Other structured reports use operation-specific YAML schemas and selection
metadata. They contain one document and a trailing newline. Native explanation
snapshots retain their safe YAML text and presence/redaction metadata when
projected into structured reports. The CLI reference owns exact schemas and
field names after implementation.
For `config show`, CommandKit checks operation availability for selected scopes
before acquisition. It acquires all selected views and completes validation
required by those provider contracts before report output begins. A failure
returns its diagnostic outcome before report writing. Other inspection operations
define their own output timing. After writing begins, a writer failure may leave
partial bytes and returns operational failure under
[ADR 0005](0005-invocation-outcomes.md).
Report confidentiality follows the owning libraries' sensitivity classifications.
Their safe writers and records supply redacted content. CommandKit preserves
those confidentiality semantics; arbitrary caller content retains the caller's
disclosure policy.
Report delivery uses the supplied streams and the channel policy in ADR 0005.
Configuration path syntax follows ConfigKit's JSON Pointer contract independently
of serialization format.
Additional families select formats appropriate to their resources. Custom handler
formats remain application-owned. The [CLI roadmap](../roadmap/01-cli-plan.md)
tracks per-operation formats, framing syntax, and report shapes; the implemented
CLI reference will own their exact contracts.
## Alternatives considered
@@ -89,20 +55,18 @@ of serialization format.
| A scope-keyed YAML wrapper | Carries scope identity as parsed mapping keys. Rendering needs an additional wrapper representation and indentation of native documents. |
| JSON alongside YAML initially | Serves JSON-specific tools. The library maintains another serializer and representation contract. |
| YAML as every report's default | Provides uniform structured output. Interactive help, tables, and explanation workflows use structured documents for routine discovery. |
| Output each scope as acquisition finishes | Starts reporting earlier. A later acquisition failure can leave a successful prefix representing only part of the selection. |
| Write `config show` documents as each scope is acquired | Starts reporting earlier. A later acquisition failure can leave a successful prefix representing only part of the selection. |
| Marshal application runtime structs | Reuses application data types. Presence, captured resolution, ordering, and safe historical inspection need a separate rendering lifecycle. |
## Consequences
Native display preserves owning-library behavior and keeps rendering focused.
Combined inspection requires multi-document YAML consumption and an ordered scope
contract. The comments label documents, and the ordered inventory supports
identification.
contract.
Loading all scopes before output adds preparation time and allows a failure in
one selected scope to prevent combined output. Explicit single-scope inspection
remains available for a narrower view. Writer failures remain visible through
outcomes and may leave partial output.
Loading all selected scopes before `config show` output adds preparation time and
allows a failure in one scope to prevent combined display. Explicit single-scope
display remains available for a narrower view.
Additional structured schemas are compatibility contracts owned by CommandKit.
Native concatenation can use existing writers; semantic comparison separately

View File

@@ -23,37 +23,13 @@ value semantics while making limited coverage visible to operators.
For a scope declaring safe comparison support, `config diff` compares two
independently resolved effective configurations. CommandKit checks that capability
before acquisition. Registered root, overlay, context, and override selectors
define the left side where applicable. The initial application-root/ConfigKit
integration uses `--against-config PATH`, `--against-overlay NAME`, or both to
select the right side. Other comparison
source models can declare applicable paired selectors through the input extension
contract under [ADR 0010](0010-configuration-selection.md).
Unspecified right selectors inherit the resolved left selection. Discovery is
resolved for the left selection once. An omitted right overlay inherits the left
overlay; the explicit overlay name `default` selects the base. Domain selectors
and typed overrides apply identically to both sides for the initial operation.
CommandKit requests each resolved side through the inspection provider under
[ADR 0008](0008-inspection-lifecycle.md). The provider supplies the captured result
according to its public loading and validation contract.
before acquisition. Providers supply captured results through the owning
libraries' supported public inspection APIs.
Compare values using the owning library's safe structured inspection semantics,
including defaults and recorded domain resolution. Preserve the distinctions
among absent values, null, empty mappings, and empty sequences. Mappings are
compared recursively; ordered sequences are compared as whole values. A container
replacement produces one change at the replaced path.
Changes are classified as `added`, `removed`, or `changed` and sorted by JSON
Pointer configuration paths, consistent with the ConfigKit integration. Reports
contain safe before/after snapshots and resolved selection metadata. Presentation
and source identity retain their own metadata roles, while value comparison
operates on the effective semantic representation.
CommandKit's comparison provider contract accepts effective values and
sensitivity metadata through supported public inspection APIs. The comparison
handler consumes inspection-safe data and uses supplied redaction classifications.
Secret resolution remains part of the upstream or callback loading lifecycle.
compared recursively; ordered sequences are compared as whole values.
For each path, use the union of the two sides' sensitivity classifications to
protect both before and after presentation. A value classified on either side
@@ -67,9 +43,12 @@ selection. Redaction masks are presentation data; classification metadata
determines comparison coverage.
Text and YAML reports include differences and coverage gaps. The exact report
schema belongs in the CLI reference when implemented. A completed comparison
returns success whether it finds differences or gaps; load, comparison, and
writer failures use the operational failure classification in
schema belongs in the CLI reference when implemented. Selection syntax,
inheritance rules, and detailed change records remain proposals in the
[CLI roadmap](../roadmap/01-cli-plan.md#config-diff).
A completed comparison returns success whether it finds differences or gaps;
load, comparison, and writer failures use the operational failure classification in
[ADR 0005](0005-invocation-outcomes.md).
## Alternatives considered
@@ -81,14 +60,13 @@ writer failures use the operational failure classification in
| Use one side's sensitivity policy | Simplifies classification selection. A value's disclosure treatment depends on which snapshot supplies that policy. |
| Fetch secret values for comparison | Gives access to additional equality evidence. Comparison acquires sensitive material and additional confidentiality responsibilities. |
| Element-by-element sequence diff | Gives detailed collection changes. Stable element identity and alignment need another comparison contract. |
| Independent domain selectors for each side | Supports broader context comparison. The operation acquires duplicated selector sets and pairing rules. |
| A distinct status for observed differences | Supports assertion-oriented scripts. Inspection completion and change detection share an outcome signal. |
## Consequences
Operators receive meaningful effective-value changes with explicit uncertainty
where sensitivity limits comparison. Stable path ordering and whole-sequence
comparison keep reports understandable and implementation scope focused.
where sensitivity limits comparison. Whole-sequence comparison keeps
implementation scope focused at the cost of less detailed collection changes.
Diff support depends on safe snapshots preserving value semantics and sensitivity.
CommandKit applies this comparison policy to scopes declaring that capability.
@@ -96,6 +74,4 @@ Other operations and families can be integrated independently under
[ADR 0004](0004-standard-inspection-surface.md).
Applications can use the successful report as input to domain decisions or future
assertion workflows. Separate left/right loading and safe union classification
need evidence for presence, container replacement, sensitivity changes, and
coverage gaps.
assertion workflows.

View File

@@ -15,13 +15,9 @@ and other independently meaningful configurations through the `config` family.
A scope identifies the configuration targeted by an operation. Different
providers may support different inspection operations.
Configuration scopes and command families are distinct: a future `feedkit`
family can inspect feeds through its own verbs, independently of whether FeedKit
configuration is also exposed as a configuration scope.
[ADR 0004](0004-standard-inspection-surface.md) defines initial operation purposes.
[ADR 0001](0001-command-dispatch-and-inputs.md) records
installation from declared capabilities.
Configuration scopes and command families are distinct. A scope targets
configuration; a family defines operations on its own resources. A library
integration can expose either or both.
## Decision
@@ -32,16 +28,17 @@ configuration scopes with unique identifiers.
Each scope declares its available inspection operations and their providers.
Capabilities can include validation, native effective YAML, source inventory,
path explanation, and safe semantic comparison data. Scope metadata describes
identity, supported operations, applicable selectors, and dependencies.
CommandKit checks the wiring needed by each declared capability. Additional
operations can be supported as their upstream data becomes available.
path explanation, and safe semantic comparison data. CommandKit validates declared
wiring and registers operations supplied by at least one scope under
[ADR 0004](0004-standard-inspection-surface.md). Help and scope discovery report
actual capabilities from metadata, independently of file loading.
Expose scope operations through CommandKit-owned public provider contracts.
Adapters preserve supported upstream values, provenance, and confidentiality.
Exact Go declarations remain API design work under
[ADR 0003](0003-public-facade.md). Separate capability contracts allow new
operations to evolve independently of existing provider implementations.
Define narrow integration contracts, reusing upstream public types where useful
and introducing CommandKit-owned abstractions where they simplify integration.
Preserve supported upstream values, provenance, and confidentiality. Select
provider representations against concrete integration needs; exact Go declarations
remain API design work under
[ADR 0003](0003-public-facade.md).
`--scope NAME` selects one configuration. `all` denotes all registered scopes for
`config validate` and `config show`; `sources`, `explain`, and `diff` select one.
@@ -50,30 +47,14 @@ availability across the requested selection before acquiring views. An unavailab
operation yields a usage diagnostic identifying the scope and available choices,
so an aggregate result accurately describes the requested coverage.
`show`, `sources`, `explain`, and `diff` default to `app`; `validate` defaults to
`all`. Explicit selection remains available for narrower validation. These
selection defaults operate against the registered inventory and capabilities.
`show`, `sources`, `explain`, `diff`, and `validate` default to `app`. Explicit
`--scope all` requests aggregate validation or display.
Scope order is `app` first when registered, `promptkit` next when registered,
then additional scopes sorted by identifier. `config scopes` and combined YAML
show use that order. The inventory reports identity, description, supported
operations, and selection defaults entirely from metadata. Discovery is available
independently of file loading.
CommandKit validates scope collisions, operation wiring, selector applicability,
and supported selections. It registers the standard operations supplied by at
least one scope, alongside metadata discovery. Help identifies their applicable
scopes; selection of an unsupported scope-operation pair yields a usage diagnostic.
Declared dependencies are coordinated under
[ADR 0008](0008-inspection-lifecycle.md). An inspection operation acquires its
selected scope and required prerequisites through that provider boundary.
A command family defines its own resources, supported verbs, and data contracts.
The configuration provider contract applies to configuration inspection. FeedKit
resource listing or display, for example, can use separate capabilities with
meanings consistent with shared verbs. A library integration can expose a command
family, configuration scope, or both, according to the provided capabilities.
show use that order. [ADR 0007](0007-native-yaml-reports.md) defines combined
presentation. Acquisition coordination and selector details remain design work
tracked in the [CLI roadmap](../roadmap/01-cli-plan.md).
## Alternatives considered
@@ -83,9 +64,9 @@ family, configuration scope, or both, according to the provided capabilities.
| A separate command tree for each configuration | Makes the target part of the path. Repeats common operations and help. |
| One verb set for every library family | Gives a uniform inventory. Resource domains acquire operations with little useful meaning. |
| Executable names as scope identifiers | Relates scopes to application branding. Shared scripts need application-specific identifiers. |
| Every operation defaults to `app` | Gives one selection default. Integrated validation becomes an explicit aggregate request. |
| Validation defaults to `all` | Checks every scope implicitly, but adding a scope without validation support can make bare validation unavailable. |
| Skip unsupported scopes during aggregate inspection | Produces available reports. The meaning and coverage of `all` become less apparent. |
| Public upstream result types as the provider API | Simplifies direct wiring. CommandKit acquires those type identities and release dependencies. |
| Require CommandKit-owned provider types throughout | Gives a uniform abstraction boundary, but can duplicate upstream APIs and require unnecessary adapters. |
## Consequences
@@ -94,9 +75,6 @@ inventory make operation availability explicit. Individual capabilities can be
integrated before other upstream inspection APIs exist. Default and ordering
rules remain observable CommandKit behavior.
Scoped operations validate availability before loading. An `all` request can
report unsupported coverage; an explicit supported scope remains available.
The same verb purpose can serve different families with different operation sets.
[Selection inputs](0010-configuration-selection.md) define parsing and propagation;
[native YAML reporting](0007-native-yaml-reports.md) defines combined presentation.
An `all` request can report unsupported coverage; default application inspection
remains independent of other scopes' capabilities. Provider design must balance
simple wiring against dependency coupling as concrete integrations are developed.