From 5d90d5999681ebcab192deb2f507dfab0ddc9a07 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 7 Nov 2026 02:42:54 +0000 Subject: [PATCH] Consolidate and renumber architectural decision records --- docs/adr/0001-command-dispatch-and-inputs.md | 239 ++++-------------- docs/adr/0002-cobra-backend.md | 78 ------ .../adr/0002-public-facade-and-cli-backend.md | 68 +++++ docs/adr/0003-configuration-scopes.md | 61 +++++ docs/adr/0003-public-facade.md | 104 -------- docs/adr/0004-optional-integration-modules.md | 71 ++++++ docs/adr/0004-standard-inspection-surface.md | 79 ------ docs/adr/0005-application-alias-routing.md | 65 +++++ docs/adr/0005-invocation-outcomes.md | 78 ------ docs/adr/0006-command-grammar.md | 77 ------ docs/adr/0006-invocation-reporting.md | 78 ++++++ docs/adr/0007-native-yaml-reports.md | 73 ------ docs/adr/0008-semantic-configuration-diff.md | 84 ------ docs/adr/0009-configuration-scopes.md | 80 ------ docs/adr/0010-optional-integration-modules.md | 100 -------- ...-captured-declarations-and-installation.md | 172 ------------- ...12-typed-configuration-comparison-pairs.md | 108 -------- docs/adr/0013-application-alias-routing.md | 68 ----- docs/adr/0014-invocation-reporting.md | 79 ------ docs/adr/README.md | 51 ++++ docs/development.md | 14 +- docs/policy/architecture.md | 64 ++--- docs/policy/testing.md | 4 +- docs/roadmap/future.md | 4 +- docs/roadmap/promptkit-v0.19.0.md | 58 +++-- 25 files changed, 525 insertions(+), 1432 deletions(-) delete mode 100644 docs/adr/0002-cobra-backend.md create mode 100644 docs/adr/0002-public-facade-and-cli-backend.md create mode 100644 docs/adr/0003-configuration-scopes.md delete mode 100644 docs/adr/0003-public-facade.md create mode 100644 docs/adr/0004-optional-integration-modules.md delete mode 100644 docs/adr/0004-standard-inspection-surface.md create mode 100644 docs/adr/0005-application-alias-routing.md delete mode 100644 docs/adr/0005-invocation-outcomes.md delete mode 100644 docs/adr/0006-command-grammar.md create mode 100644 docs/adr/0006-invocation-reporting.md delete mode 100644 docs/adr/0007-native-yaml-reports.md delete mode 100644 docs/adr/0008-semantic-configuration-diff.md delete mode 100644 docs/adr/0009-configuration-scopes.md delete mode 100644 docs/adr/0010-optional-integration-modules.md delete mode 100644 docs/adr/0011-captured-declarations-and-installation.md delete mode 100644 docs/adr/0012-typed-configuration-comparison-pairs.md delete mode 100644 docs/adr/0013-application-alias-routing.md delete mode 100644 docs/adr/0014-invocation-reporting.md create mode 100644 docs/adr/README.md diff --git a/docs/adr/0001-command-dispatch-and-inputs.md b/docs/adr/0001-command-dispatch-and-inputs.md index 4d7b81f..f7d0632 100644 --- a/docs/adr/0001-command-dispatch-and-inputs.md +++ b/docs/adr/0001-command-dispatch-and-inputs.md @@ -1,209 +1,78 @@ -# ADR 0001: Own dispatch through an explicit registry and typed inputs +# ADR 0001: Own dispatch through captured declarations and typed inputs ## Status -Accepted. - -[ADR 0011](0011-captured-declarations-and-installation.md) refines -declaration construction, installation, optional-family namespace reservation, -and integration input/state lifetimes. +Accepted. Consolidated during the [alpha ADR cleanup](README.md#alpha-consolidation). ## Date -2026-10-06 +2026-11-07; consolidates decisions made on 2026-10-06 and 2026-10-10. ## 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 -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 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 -separate application dispatchers would leave custom-command mechanics and root -help dependent on each application's implementation. - -Input handling also needs a common boundary. Raw argv handlers or string-based -flag retrieval leave repeated parsing and input assembly with applications. -Presence matters for configuration overrides: omitted values differ from -explicitly supplied empty strings, false, and zero. +Applications repeat routing, flag parsing, help, and inspection commands while +also needing their own domain commands. Sharing only isolated command handlers +would leave much of that infrastructure and its inconsistent behavior with each +application. Optional integrations also need to assemble commands through the +same public mechanisms as applications. ## Decision -### Ownership and namespace structure +CommandKit owns dispatch, shared parsing, presence tracking, help, syntax +failures, and standard command mechanics. Applications own their domain commands, +validation, effects, runtime construction, and executable lifecycle. CommandKit +accepts caller context and streams and returns outcomes rather than terminating +the process. -CommandKit owns the dispatcher, shared parsing and presence tracking, help, -syntax diagnostics, and standard-family handlers and outcomes. Applications own -custom command names, domain meaning, validation, effects, artifacts, and -operational outcomes. +Use an explicitly constructed, per-instance registry. Applications and +integrations supply captured declarations containing routing, parsing, help +metadata, and callback references. One declaration supplies those views of the +command. Captured metadata is insulated from later edits to its source; +application objects referenced by callbacks remain caller-owned. -Use namespace-first syntax for the standard suite, which provides a clear -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. +Declarations share one installation boundary. Construction issues are retained +for installation, and each installation batch is validated before registry +mutation. Collisions are errors rather than order-dependent replacement. +Optional standard families claim their namespaces when installed, not when +imported. Their canonical operations remain integration-owned; application +commands live outside installed standard families. -CommandKit accepts custom commands outside its reserved standard families and -reports registration errors for attempts to replace standard handlers or add -private operations beneath them. Its input extension mechanism accepts context -selectors and typed overrides for standard operations. +Handlers receive typed inputs through explicit flag and operand bindings. +Presence is separate from value so omission differs from supplied empty, false, +or zero values. Domain parsers and validation remain application-owned. Core +provides typed composition for integrations without exposing parser state or +requiring a second argument parser. -CommandKit accepts caller-supplied context, streams, handlers, and inspection -providers and returns invocation outcomes. It leaves process termination to the -caller. Executable startup, signals, runtime construction, schemas, acquisition, -and domain resolution remain application choices. +Parsed state is independent between invocations. Integration inputs for selected +scopes or comparison sides are distinct from invocation-wide acquisition state. +Applications own the objects and caches returned by their factories. CommandKit +coordinates its own preparation and calls without promising arbitrary deep copies +or concurrent dispatch. -### Explicit registry and capability installation - -Each explicitly constructed CommandKit instance owns a registry. Its API accepts -individual commands and composable groups. Registration uses explicit instance -state with caller-controlled construction and composition. - -Definitions provide paths, descriptions, flags and defaults, repetition and -presence metadata, operand requirements, and execution handlers. One definition -supplies routing, parsing, and help. Duplicate paths and attempts to replace -reserved commands return registration errors; order does not select a winner. - -Help and version are installed automatically using supplied application identity -and build metadata. CommandKit assembles standard families from declared provider -capabilities, installing their supported handlers and metadata together. Each -family defines its own resource model, supported verbs, and per-operation data -contracts. Configuration scopes declare their available inspection operations. - -The API allows supported capabilities to be integrated independently. Adding -comparison, catalogs, or other inspection features extends the installed surface -according to the supplied providers. Shared verbs have consistent purposes across -families, while the available subsets reflect their resources and capabilities. -Help and discovery expose those subsets. Registration validates the wiring of -declared capabilities and reports unsupported selections before acquisition. - -CommandKit registration validates declarations with acquisition callbacks left -uninvoked. Its construction, help, and version paths use metadata. The selected -handler requests dependencies when its operation needs them. Invalid configuration -returned by an acquisition callback is an invocation-time failure. Caller code -executed before registration and effects inside callbacks remain caller-owned. - -CommandKit installs handlers for supplied capabilities and describes actual -availability. Each enabled operation retains its standard meaning and output -contract. The exact operation inventory and remaining command contracts are -separate design decisions. - -### Typed inputs with explicit bindings - -The public binding contract accepts application-defined input structs for custom -commands and uses CommandKit-defined inputs for standard handlers. Explicit -registration binds flags and operands to fields and supplies parsing and help -metadata. CommandKit delivers parsed typed inputs to registered handlers. - -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 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 -acquisition calls to the selected handler. The binding system accepts domain value -parsers; domain interpretation and validation belong to registered callbacks. - -The public factory, binding, registration, and handler signatures and presence -type names remain API design choices. No illustrative declaration establishes -an exact public API. - -### Outcomes and domain behavior - -Resolve the command and handle help/version before loading application state. -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 -supplied classification. Scriptorium output validation and Notarius artifact -outcomes, for example, remain domain results. CommandKit translates results from -explicit classification and emits usage guidance for usage failures. - -Common mechanics do not require a common success-report format for custom -commands. The application owns its artifact and operational output contracts. -Exact result/error interfaces and unresolved grammar choices are separate design -work, not approvals implied by this decision. - -### Contract scope and consumer guidance - -This decision governs CommandKit's public contracts and implemented behavior. -Each operation specifies the inputs, result semantics, callback lifetimes, and -metadata its provider supplies. Consumers choose how to implement those callbacks -and how to structure loading, execution, startup, and process status mapping. - -Sharing acquisition and resolution between inspection and execution, and keeping -acquisition focused on producing inspection views, are recommended practices. -CommandKit supports those patterns through reusable inputs and lazy provider -hooks. Its API preserves declared results and coordinates its own calls; arbitrary -application internals remain application-owned. - -Cobra isolation applies to CommandKit's exports and internal adapter. Independent -consumer use of another CLI library remains an application choice. Additional -families and source models can use capability contracts appropriate to their -resources, with standard meanings preserved for operations that are installed. +Construction, installation, help, version, and capability discovery use metadata +without acquiring application state. The selected operation acquires what it +needs after applicable input checks. Caller startup and callback effects retain +their own lifecycle. ## Alternatives considered -### Dispatcher and ownership - -| Alternative | Analysis | -| --- | --- | -| Application-owned dispatcher forwarding standard families | Small integration surface and convenient migration, but custom syntax, root help, and errors still need cross-dispatcher coordination; removes less infrastructure. | -| Standard definitions mounted into an application's framework | Reuses routing infrastructure, but application configuration can preserve inconsistent behavior outside mounted families. Internal framework reuse remains compatible with this decision. | -| Shared metadata/help with separate routing | Unifies discovery but adds synchronization among metadata, routing, and parsing. One dispatcher avoids it. | -| Both full dispatch and embeddable family handlers | Serves established external CLI architectures but adds integration surfaces and maintenance. Add embedding only for a concrete need. | -| Raw-argument handlers for custom commands | Eases migration but leaves parsing and help responsibilities with applications. A future transition adapter would need to describe its separate parsing and help contract. | -| Universal application runtime framework | Could absorb startup and operational services, but expands beyond the demonstrated CLI boundary and domain ownership. | -| Verb-first standard paths | Groups actions, but distributes namespace ownership among individual routes. Namespace/resource-first paths keep family ownership clear. | -| Reserve root `prompt` and `profile` for PromptKit | Provides short resource paths but consumes application namespaces. A single `promptkit` family gives the library one ownership boundary. | - -### Registration - -| Alternative | Analysis | -| --- | --- | -| Declarative tree passed to construction | Makes assembly visible together; larger applications still need group composition. May become a convenience over the same registry. | -| Constructor options for every command/group | Compact setup, but excessive options can obscure commands versus application settings. Option conventions remain API design work. | -| Global registry populated by `init` | Less entry-point code, but hidden import effects, shared mutable state, and unclear ownership. Explicit instances avoid those costs. | - -### Handler inputs - -| Alternative | Analysis | -| --- | --- | -| 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 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. | +- Application dispatchers forwarding standard families would share handlers but + leave custom-command parsing, root help, and diagnostics duplicated. +- Raw-argument handlers or string-keyed input access would leave typed input + assembly and presence handling with every consumer. +- Reflection, struct tags, or generated bindings could shorten declarations but + add another declaration language or toolchain. +- Import-time registries or a separate integration registration framework would + introduce hidden state or parallel assembly conventions. ## Consequences -One command system removes repeated routing, parser setup, help assembly, and -shared error plumbing as well as standard inspection handlers. Domain handlers -and their declarations remain recognizable application code. +Applications use one command system while retaining domain ownership. Explicit +bindings and captured declarations require deliberate assembly, but integrations +can supply complete families through the same public contracts. -The public registration surface is larger than family delegation, and explicit -bindings require connecting declarations to the correct fields. Those costs -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, independent invocation inputs, cancellation, -and domain outcomes. -CommandKit releases document intentional compatibility changes. Coordinated -application documentation and subprocess-caller updates are recommended migration -practices. - -The [architecture policy](../policy/architecture.md) owns normative boundaries. -[ADR 0002](0002-cobra-backend.md) selects the backend, and -[ADR 0003](0003-public-facade.md) defines its public/internal boundary. +[GoDoc](../../command.go) owns declaration, installation, and callback contracts; +the [consumer guide](../consumers/guide.md) explains their use. Exact grammar, +commands, and outcomes belong in the [CLI reference](../cli.md). Binding identity, +absence handling, factory defaults, and operation-specific preparation timing +can evolve within this architecture through deliberate API changes. diff --git a/docs/adr/0002-cobra-backend.md b/docs/adr/0002-cobra-backend.md deleted file mode 100644 index 235423e..0000000 --- a/docs/adr/0002-cobra-backend.md +++ /dev/null @@ -1,78 +0,0 @@ -# ADR 0002: Use Cobra and pflag as the initial internal CLI backend - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -CommandKit's selected dispatcher model needs nested routing, flags and operands, -generated help, usage diagnostics, and invocation execution. Reimplementing this -generic infrastructure would add work beyond the suite-specific inspection and -consistency behavior that motivates the library. - -## Decision - -Use Cobra with pflag as the sole initial CLI backend. CommandKit translates its -registrations into backend command trees, flag bindings, and execution callbacks. -Reuse their routing, option parsing, help, context, and stream mechanisms and add -adaptation where selected CommandKit semantics require it. - -CommandKit retains its own public registration API, typed inputs, standard -families, and observable contracts. Its public registration and handler APIs -use CommandKit-owned definitions and typed inputs. Cobra commands and pflag -getters stay within CommandKit's internal adapter. Independent consumer framework -use remains application-owned. [ADR 0003](0003-public-facade.md) records the -adapter and root-owned public contracts. - -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 -while preserving the public API and selected behavioral contracts. - -## Alternatives considered - -| Alternative | Advantages | Reason not selected | -| --- | --- | --- | -| urfave/cli v3 | Destination bindings for flags and named operands, presence queries, and duplicate controls fit the chosen input model closely. | Credible alternative; Cobra's broader adoption is the preferred maintenance tradeoff. | -| pflag alone | Established parsing with a smaller integration surface. | Leaves more routing, help integration, and command infrastructure to implement. | -| Kong | Compact typed-struct and tag-driven declarations. | Its main declaration model differs from the explicit-binding API; adaptation reduces its benefit. | -| Standard `flag` alone | Familiar variable binding and custom value parsing. | First-operand stopping requires adaptation for the intended syntax, with more custom command infrastructure. | -| Expose Cobra as the public API | Less adapter code and the full framework surface. | Couples consumers to backend structures and framework-specific configuration. | -| Interchangeable backends immediately | Future integration flexibility. | Adds abstraction and behavior surfaces without a current requirement. | - -## Consequences - -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, 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. - -The [architecture policy](../policy/architecture.md) owns normative boundaries. -[ADR 0001](0001-command-dispatch-and-inputs.md) records the dispatcher and input -model. - -Reviewed primary references from the selection: - -- [Cobra API](https://pkg.go.dev/github.com/spf13/cobra). -- [Cobra command and help guide](https://github.com/spf13/cobra/blob/main/site/content/user_guide.md). -- [Cobra flag bindings](https://cobra.dev/docs/how-to-guides/working-with-flags/). -- [pflag syntax and extension points](https://github.com/spf13/pflag). -- [urfave/cli v3 API](https://pkg.go.dev/github.com/urfave/cli/v3). diff --git a/docs/adr/0002-public-facade-and-cli-backend.md b/docs/adr/0002-public-facade-and-cli-backend.md new file mode 100644 index 0000000..b733a09 --- /dev/null +++ b/docs/adr/0002-public-facade-and-cli-backend.md @@ -0,0 +1,68 @@ +# 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. diff --git a/docs/adr/0003-configuration-scopes.md b/docs/adr/0003-configuration-scopes.md new file mode 100644 index 0000000..8a5fb3a --- /dev/null +++ b/docs/adr/0003-configuration-scopes.md @@ -0,0 +1,61 @@ +# ADR 0003: Expose configuration scopes through declared capabilities + +## Status + +Accepted. Consolidated during the [alpha ADR cleanup](README.md#alpha-consolidation). + +## Date + +2026-11-07; consolidates decisions made on 2026-10-06. + +## Context + +An application may expose its own configuration and configurations belonging to +integrated libraries. Repeating a configuration command tree for each one would +duplicate operator mechanics. Requiring identical inspection capabilities would +exclude useful integrations whose upstream APIs provide only a subset. + +## Decision + +Expose independently meaningful configurations as named scopes through a shared +configuration command family. A scope identifies the configuration being +inspected; a command family defines operations on its resources. An integration +may expose either or both without requiring the other. + +Each scope declares its supported operations and providers. Assemble standard +commands from the available capabilities and describe actual availability through +metadata-driven help and discovery. An unavailable capability does not prevent +using the scope's other operations. + +Validate required provider wiring against declared capabilities. Check selected +operation availability before acquisition. Aggregate inspection must account for +its requested coverage rather than silently dropping unsupported scopes. + +Use narrow integration contracts, reusing upstream public types where useful. +Applications supply acquisition and domain context; integrations adapt supported +inspection APIs under [ADR 0004](0004-optional-integration-modules.md). Scope and +comparison inputs follow the input/state separation in +[ADR 0001](0001-command-dispatch-and-inputs.md). + +## Alternatives considered + +- A separate command tree per configuration would make the target part of the + path but repeat shared operations and help. +- Requiring every operation for every scope would make one missing capability + block otherwise useful inspection. +- One universal operation set across library families would assign operations + to resources for which they have little meaning. + +## Consequences + +Operators use a common configuration family while providers can expose supported +features incrementally. Capability declarations and help must describe actual +coverage, and provider abstractions must remain proportionate to integration +needs. + +The [CLI reference](../cli.md#configuration-scopes) owns command inventory, scope +names and defaults, selector syntax, aggregate applicability, and report ordering. +The [consumer guide](../consumers/guide.md#configkit-scopes) and +[GoDoc](../../integrations/ckconfig/contracts.go) own provider wiring and precise +input/acquisition lifetimes. Those details do not require separate ADRs merely +because they are public contracts. diff --git a/docs/adr/0003-public-facade.md b/docs/adr/0003-public-facade.md deleted file mode 100644 index acf5928..0000000 --- a/docs/adr/0003-public-facade.md +++ /dev/null @@ -1,104 +0,0 @@ -# ADR 0003: Own public contracts through a root facade and internal CLI adapter - -## Status - -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 - -2026-10-06 - -## Context - -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 -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 -future replacement easier. - -## Decision - -Use the module root `commandkit` as the sole initial supported public facade. -Define CommandKit's public named types there and expose only selected operations, -extension contracts, and documented methods. Handles keep implementation state in -private fields. - -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. 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. - -Confine Cobra/pflag types and operations to an internal adapter. Registry logic, -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. - -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. Any conversions must preserve value -ownership, callback lifetime, presence, and supported error semantics. - -## Alternatives considered - -| 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. | -| Public packages for registry, bindings, backend, and other mechanisms | Adds supported imports and assembly contracts without a distinct consumer responsibility. | -| Selectable/pluggable backends immediately | Adds selection and extension machinery before a concrete need exists. | - -## Consequences - -Consumers depend on deliberate root contracts while internal algorithms, -collaborators, and package boundaries can evolve. Useful application registration -capabilities still need a proportionate API; minimizing accidental exports must -not recreate repetitive consumer infrastructure. - -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. -Backend defaults do not independently establish new CommandKit contracts. - -The [architecture policy](../policy/architecture.md) owns normative boundaries. -[ADR 0001](0001-command-dispatch-and-inputs.md) records the dispatcher/input model, -and [ADR 0002](0002-cobra-backend.md) selects the initial backend. diff --git a/docs/adr/0004-optional-integration-modules.md b/docs/adr/0004-optional-integration-modules.md new file mode 100644 index 0000000..f43747a --- /dev/null +++ b/docs/adr/0004-optional-integration-modules.md @@ -0,0 +1,71 @@ +# ADR 0004: Separate optional CLI integrations from the core + +## Status + +Accepted. Consolidated during the [alpha ADR cleanup](README.md#alpha-consolidation). + +## Date + +2026-11-07; consolidates decisions made on 2026-10-09 and 2026-10-11. + +## Context + +Applications need CommandKit with different combinations of library integrations, +including none. A core-only consumer should not acquire optional libraries in its +module graph. Integrations also need a clear boundary between exposing operator +tasks and taking over the upstream libraries' domain functionality. + +## Decision + +Keep the core and optional integrations in separate Go modules with their own +public package contracts. Core owns shared CLI infrastructure. Integrations own +standard operator-facing commands, provider contracts, content projections, and +adapters for their libraries. They are not convenience libraries for +application-internal use of upstream APIs. + +Dependencies point from integrations toward core. Core's API, implementation, +tests, examples, tools, and module requirements remain independent of optional +integration libraries. An integration may depend on another integration when +its responsibility requires it; document that dependency for consumers. + +Applications explicitly install integration declarations through public core +contracts. Importing a module installs nothing. Integrations supply convenient +complete-family assembly and supported composition without accessing private +core state or backend structures. Add narrow public core capabilities for actual +integration needs rather than a universal provider or plugin framework. + +The integrated libraries own configuration resolution, prompt preparation, +comparison, validation, and other domain algorithms. CommandKit invokes their +supported public APIs and preserves returned meaning, supported error identity, +and safe-disclosure rules. The adopted upstream version governs those semantics; +CommandKit does not maintain a parallel domain specification or reconstruct +comparison from rendered text or redacted snapshots. + +Integrations choose report content from suitable inspection evidence, preserving +upstream confidentiality and presence distinctions. CommandKit may summarize or +project that safe evidence for operator needs. Applications retain ownership of +schemas, loading, engine construction, credentials, domain execution, and startup. +Arbitrary application content is not implicitly safe for disclosure. + +## Alternatives considered + +- Keeping integrations in core, or in packages within its module, would retain + their dependencies in the core module graph. +- Requiring applications to implement standard integration handlers would repeat + command and reporting infrastructure. +- Universal core provider types would introduce abstraction and conversion work + before concrete integrations justify it. +- Reimplementing upstream algorithms would duplicate domain ownership and could + lose evidence already withheld from safe inspection values. + +## Consequences + +Consumers can adopt core independently and add integrations as needed. Separate +modules require coordinated dependency, validation, and release work. Integrations +remain maintained parts of CommandKit with shared CLI conventions. + +Upstream changes require adapter and documentation updates against the adopted +public contract. The [CLI reference](../cli.md) owns operator behavior, GoDoc owns +provider contracts, and [ADR 0006](0006-invocation-reporting.md) owns the shared +presentation boundary. Report formats, comparison statuses, and individual +operation inventories can evolve without changing domain ownership. diff --git a/docs/adr/0004-standard-inspection-surface.md b/docs/adr/0004-standard-inspection-surface.md deleted file mode 100644 index 6237ddd..0000000 --- a/docs/adr/0004-standard-inspection-surface.md +++ /dev/null @@ -1,79 +0,0 @@ -# ADR 0004: Define standard inspection operations by family and capability - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -CommandKit serves applications with shared ConfigKit and PromptKit inspection -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. - -## Decision - -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. - -| Standard operation | Responsibility | -| --- | --- | -| `help` | Describe registered standard and application commands. | -| `version` | Report application version by default; report embedded CommandKit version when explicitly selected. | -| `config scopes` | List registered configuration scopes and supported operations. | -| `config validate` | Validate the selected configuration and its configured definitions. | -| `config show` | Display final effective configuration. | -| `config sources` | Describe the acquired and synthetic input source inventory. | -| `config explain` | Explain effective or historical values and provenance at a selected path. | -| `config diff` | Compare effective configuration selections semantically. | - -The optional PromptKit suite supplies `promptkit list prompts`, -`promptkit list profiles`, `promptkit show prompt`, and `promptkit show profile`. -These operations expose captured definition catalogs, prompt metadata, and -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. - -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. - -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. - -The [CLI reference](../cli.md) owns exact flags, operands, defaults, and report -schemas for implemented operations. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Initial operations limited to validation and display | Accelerates first integrations. Source explanation, comparison, and discovery remain repeated application infrastructure. | -| Require every operation for every integration | Gives a uniform inventory. One unavailable capability blocks other useful operations and future resource families. | -| 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. | - -## Consequences - -CommandKit supplies shared handlers with predictable meanings and discovers their -availability from registration. Each enabled operation needs its own data -contract: comparison needs supported native comparison results, catalogs need -enumeration, and profile display needs safe execution-target inspection. - -The [scope model](0009-configuration-scopes.md) and -[comparison policy](0008-semantic-configuration-diff.md) describe related -capability and behavioral decisions. diff --git a/docs/adr/0005-application-alias-routing.md b/docs/adr/0005-application-alias-routing.md new file mode 100644 index 0000000..bca2afe --- /dev/null +++ b/docs/adr/0005-application-alias-routing.md @@ -0,0 +1,65 @@ +# ADR 0005: Separate application alias routing from canonical command ownership + +## Status + +Accepted. Renumbered during the [alpha ADR cleanup](README.md#alpha-consolidation). + +## Date + +2026-11-07; original decision made on 2026-10-19. + +## Context + +Applications need alternate command paths and flag spellings that suit their +operator vocabulary. These conveniences should reuse the behavior supplied by +application commands and optional integrations. Canonical command families +already establish ownership of handlers, namespaces, inputs, and invocation +behavior. + +A routing layer allows applications to choose alternate spellings while +preserving those ownership boundaries. Commands and routing rules have distinct +roles, and their relationships require validation during application assembly. + +## Decision + +CommandKit core owns alias declaration, resolution, and coordination with parsing +and help. Applications choose their alias mappings. Alias infrastructure is +available independently of optional integrations under +[ADR 0004](0004-optional-integration-modules.md). + +Aliases belong to an application routing layer that directs invocations to +canonical commands and flags. Canonical definitions retain ownership of their +handlers, inputs, and namespaces. An alternate path within an integration's +namespace remains an application routing rule; the integration continues to own +the canonical command family and its operations. + +Canonical commands and routing rules are distinct declaration kinds installed +through the common assembly boundary in [ADR 0001](0001-command-dispatch-and-inputs.md). +Installation validates their relationships together and preserves canonical +ownership. Declaration capture, retained errors, and batch validation follow that +shared model. + +An invocation through an alias uses the canonical target's parsing, typed +bindings, validation, and ordinary invocation lifecycle. Execution behavior +remains with the canonical command and its owning application or integration. +Core coordinates alternate routing and presentation through the same command +infrastructure. + +## Alternatives considered + +- Wrapper commands would introduce additional nodes and handler delegation into + namespace ownership and invocation lifetimes. +- Application argument rewriting would repeat routing infrastructure and separate + alias handling from target validation, parsing, and help. +- A separate alias assembly API would split validation of commands and their + alternate routes across installation boundaries. + +## Consequences + +Applications can tailor vocabulary while reusing canonical behavior. Core must +coordinate routing, parsing, and help across those layers, while optional +integrations retain ownership of their command families. + +GoDoc and the [CLI reference](../cli.md#application-owned-aliases) own exact API +shapes, resolution rules, and presentation choices. Those details can evolve +within this architectural separation. diff --git a/docs/adr/0005-invocation-outcomes.md b/docs/adr/0005-invocation-outcomes.md deleted file mode 100644 index 9db3100..0000000 --- a/docs/adr/0005-invocation-outcomes.md +++ /dev/null @@ -1,78 +0,0 @@ -# ADR 0005: Return explicit outcomes and deliver reports through defined channels - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -An invocation crosses routing, parsing, provider acquisition, a standard or -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. - -## 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 under -[ADR 0003](0003-public-facade.md). - -Use these mappings for CommandKit-owned commands: - -| Status | Meaning | -| --- | --- | -| `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, 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. - -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. 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. - -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 outcomes. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| A single failure classification | Simplifies outcome handling. Callers derive syntax, operational, and domain distinctions through additional interpretation. | -| 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. | - -## Consequences - -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. - -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. diff --git a/docs/adr/0006-command-grammar.md b/docs/adr/0006-command-grammar.md deleted file mode 100644 index 3723628..0000000 --- a/docs/adr/0006-command-grammar.md +++ /dev/null @@ -1,77 +0,0 @@ -# ADR 0006: Apply common command grammar and recommend shared vocabulary - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -CommandKit owns routing, parsing, and help for standard and registered application -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. - -## Decision - -CommandKit's standard grammar and vocabulary are part of the contract for -CommandKit-owned commands. Its shared dispatcher and binding APIs implement that -grammar, so application-owned commands registered through those APIs receive the -same parsing mechanics. Applications retain ownership of their command names, -operand meanings, and domain behavior. - -CommandKit's documentation recommends the same grammar and vocabulary for -application-owned commands, including commands implemented outside its dispatcher. -Applications are encouraged to use standard verbs such as `help`, `list`, and -`show` where their operations have the corresponding purposes described in -[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. - -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. 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). - -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. -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 registered metadata. Invalid paths and flag -names receive usage diagnostics. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| 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. | -| 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. Shared vocabulary guidance encourages consistent -names for equivalent application-owned operations. - -The internal adapter must preserve the selected grammar across backend changes. -The [CLI reference](../cli.md) owns operation-specific command signatures and -examples for implemented commands. diff --git a/docs/adr/0006-invocation-reporting.md b/docs/adr/0006-invocation-reporting.md new file mode 100644 index 0000000..21f7e86 --- /dev/null +++ b/docs/adr/0006-invocation-reporting.md @@ -0,0 +1,78 @@ +# ADR 0006: Share invocation reporting while preserving application outcomes + +## Status + +Accepted. Consolidated during the [alpha ADR cleanup](README.md#alpha-consolidation). +The structured-report formatting extension is accepted but not yet implemented; +the [adoption roadmap](../roadmap/promptkit-v0.19.0.md#shared-core-report-output-prerequisite) +tracks that work. + +## Date + +2026-11-07; consolidates decisions made on 2026-10-06 and 2026-10-25 +and the accepted shared-format ownership extension. + +## Context + +An invocation crosses routing, parsing, acquisition, command execution, and output +delivery. Applications need consistent presentation and useful returned outcomes +without giving a CLI library control of domain recovery or process termination. +Separate reporting facilities would repeat visibility and failure-handling rules. + +## Decision + +Core provides one reporting facility per invocation for command results, +immediate messages, deferred messages, and final presentation. Callers choose +result and diagnostic destinations. Applications and integrations choose content, +messages, and domain outcomes; core coordinates visibility, delivery, and its +own parsing and presentation failures. + +Applications decide whether a domain error warrants recovery, a warning, or a +failed invocation. They supply explicit outcomes and explanations, optionally +with an error cause. A cause alone does not select an outcome or create an +operator-facing message. Preserve supplied causes and their supported public +identity. Integrations adapt upstream evidence without taking ownership of its +domain meaning or disclosure rules. + +Return explicit outcome classifications that distinguish shared usage and +operational failures from application-defined domain outcomes. Preserve domain +classification and keep presentation failures separately observable from the +operation's explanation and cause. Delivery failure must be visible without +silently discarding the application's result. The application entry point owns +final process status mapping and termination. + +Present terminal failure explanations after ordinary reporting finishes. Core +coordinates its own diagnostic paths to avoid duplicate presentation. Reporting +state serves delivery and the returned outcome; logging and message history +remain application responsibilities. + +The accepted structured-report extension centralizes format selection, +serialization, and rendering in core. Applications and integrations hand off +selected content, including their chosen detail level and optional text template; +core determines how to output it. New core formats should work through that +shared handoff without each command maintaining encoders. This extends the same +invocation lifecycle, with a writer API sharing rendering outside invocations. +Implementation status and initial format choices remain in the roadmap above. + +## Alternatives considered + +- Handler-owned presentation would maximize local control but repeat output, + visibility, and delivery-error infrastructure. +- Letting core interpret domain errors would give it recovery decisions that + depend on application behavior. +- One failure category or numeric status alone would lose meaningful distinctions + between usage, operational, and domain results. +- Separate facilities for results and messages, or encoders in each integration, + would spread shared behavior across independent implementations. + +## Consequences + +Commands share presentation while retaining ownership of their content and +outcomes. Core must keep operation and presentation evidence distinguishable, +including when output is partial. Caller writers retain their own lifecycle. + +GoDoc and the [CLI reference](../cli.md#reporting) own implemented APIs, numeric +statuses, visibility controls, and exact delivery behavior. Report layouts, +format defaults, YAML framing, and scope ordering are presentation contracts, +not separate architectural decisions. The shared-format extension remains +planned until its implementation and canonical contracts land. diff --git a/docs/adr/0007-native-yaml-reports.md b/docs/adr/0007-native-yaml-reports.md deleted file mode 100644 index e0a8e2f..0000000 --- a/docs/adr/0007-native-yaml-reports.md +++ /dev/null @@ -1,73 +0,0 @@ -# ADR 0007: Use native YAML and ordered documents for inspection reports - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -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. - -## Decision - -The initial standard uses text for concise operator reports and YAML for -structured consumption. - -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). 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. - -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. - -Additional families select formats appropriate to their resources. Custom handler -formats remain application-owned. The [CLI reference](../cli.md) owns exact -per-operation formats, framing syntax, and report shapes for implemented commands. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| 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. | -| 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. - -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 uses the owning -library's supported comparison API under -[ADR 0008](0008-semantic-configuration-diff.md). diff --git a/docs/adr/0008-semantic-configuration-diff.md b/docs/adr/0008-semantic-configuration-diff.md deleted file mode 100644 index f91fdc8..0000000 --- a/docs/adr/0008-semantic-configuration-diff.md +++ /dev/null @@ -1,84 +0,0 @@ -# ADR 0008: Delegate effective configuration comparison to owning libraries - -## Status - -Accepted. - -## Date - -2026-10-06; revised 2026-10-11. - -## Context - -ConfigKit provides a native configuration comparison capability. Exposing it -through CommandKit gives applications a consistent operator interface and reduces -repeated command, selection, and reporting infrastructure. ConfigKit remains the -authority for the meaning and disclosure of its comparison results. - -## Decision - -### Comparison ownership - -For ConfigKit-backed scopes declaring comparison support, `config diff` exposes -ConfigKit's native comparison API. CommandKit checks capability availability before -acquisition and coordinates selection, acquisition, adaptation, presentation, -and invocation outcomes. - -Integrations delegate comparison to their owning libraries' supported public -APIs. ConfigKit owns its comparison semantics and disclosure rules. CommandKit -follows the public contract of the ConfigKit version it adopts. When an adopted -upstream revision changes those semantics, the changes flow through to -CommandKit's integration. Upstream remains authoritative as the capability evolves. - -Application-supplied providers retain ownership of their implementation and -loading effects. [ADR 0012](0012-typed-configuration-comparison-pairs.md) governs -paired selections, provider contracts, and typed input/shared-state lifetimes. - -### Safe disclosure and presentation - -Adapt and present native comparison results in accordance with the adopted -upstream API's disclosure contract. The integration carries the upstream results -and relevant metadata through its public provider boundary. - -CommandKit owns report presentation and may summarize or transform the returned -safe comparison data for different operator needs. Reports may vary in format, -organization, and detail while respecting safe disclosure and the evidence -provided by the comparison. Each report's documented meaning defines the -conclusions an operator can draw from it. - -Report formats, schemas, and rendering choices belong in the -[CLI reference](../cli.md) when implemented. They can evolve independently of -this ownership decision under the [release policy](../policy/release.md). - -### Invocation outcomes - -A completed comparison returns success regardless of whether differences are -reported. Load, comparison, and writer -failures use the operational failure classification in -[ADR 0005](0005-invocation-outcomes.md). Applications may use comparison results -to make their own domain decisions. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Compare safe snapshots in CommandKit | Gives CommandKit direct control over comparison, but requires it to maintain equality and sensitivity logic and account for values already withheld from snapshots. Native comparison keeps those responsibilities with the owning library. | -| Compare rendered configuration text | Reuses existing output, but formatting and masking affect the apparent differences. Native comparison supplies evidence grounded in the library's effective-value model. | -| Leave comparison commands entirely to applications | Preserves application flexibility, but repeats selection, acquisition coordination, and presentation infrastructure across consumers. Integration providers retain application control within the common command system. | -| Return a distinct status when differences are found | Supports assertion-oriented scripts, but couples successful inspection with a policy judgment about the result. The selected outcome model leaves that judgment to consumers. | - -## Consequences - -CommandKit supplies consistent comparison commands while relying on owning -libraries for comparison semantics and safe disclosure. Dependency adoption -includes adapting the integration and its documentation to upstream changes. -New library integrations -are assessed through their supported comparison contracts; each scope can expose -its available capabilities independently under -[ADR 0009](0009-configuration-scopes.md). - -Reports can serve different operator needs using the same native comparison -data. Their level of detail may differ, and sensitivity rules may limit what -can be shown. Maintaining the boundary between comparison evidence and report -presentation allows those reports to evolve while preserving library ownership -and consumer control. diff --git a/docs/adr/0009-configuration-scopes.md b/docs/adr/0009-configuration-scopes.md deleted file mode 100644 index 17b0c77..0000000 --- a/docs/adr/0009-configuration-scopes.md +++ /dev/null @@ -1,80 +0,0 @@ -# ADR 0009: Select named configuration scopes with declared inspection capabilities - -## Status - -Accepted. - -## Date - -2026-10-06 - -## Context - -An application can expose its own configuration, PromptKit engine configuration, -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 scope targets -configuration; a family defines operations on its own resources. A library -integration can expose either or both. - -## Decision - -Use stable semantic scope identifiers. The `app` scope describes application -configuration; an optional `promptkit` scope describes captured engine -configuration. Registration also accepts additional independently meaningful -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. 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. - -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. -An aggregate selection retains its all-scope meaning. CommandKit checks operation -availability across the requested selection before acquiring views. An unavailable -operation yields a usage diagnostic identifying the scope and available choices, -so an aggregate result accurately describes the requested coverage. - -`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. [ADR 0007](0007-native-yaml-reports.md) defines combined -presentation. The [CLI reference](../cli.md) owns implemented selector syntax; -the [consumer guide](../consumers/guide.md) explains acquisition integration. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Require every configuration inspection operation per scope | Gives one capability set. Missing comparison or provenance blocks other useful inspection operations. | -| 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. | -| 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. | -| Require CommandKit-owned provider types throughout | Gives a uniform abstraction boundary, but can duplicate upstream APIs and require unnecessary adapters. | - -## Consequences - -A shared configuration family serves multiple configurations while help and -inventory make operation availability explicit. Individual capabilities can be -integrated before other upstream inspection APIs exist. Default and ordering -rules remain observable CommandKit behavior. - -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. diff --git a/docs/adr/0010-optional-integration-modules.md b/docs/adr/0010-optional-integration-modules.md deleted file mode 100644 index 2534178..0000000 --- a/docs/adr/0010-optional-integration-modules.md +++ /dev/null @@ -1,100 +0,0 @@ -# ADR 0010: Separate the core facade from optional integration modules - -## Status - -Accepted. Partially supersedes -[ADR 0003](0003-public-facade.md) as described below. -Partially superseded by [ADR 0011](0011-captured-declarations-and-installation.md) -for the consumer-migration consequence during the unreleased prototype -transition. It also supplies the registration and invocation-lifetime -decisions left open here. The module -boundary and remaining principles continue to apply; this record's decision -text is retained. - -## 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. diff --git a/docs/adr/0011-captured-declarations-and-installation.md b/docs/adr/0011-captured-declarations-and-installation.md deleted file mode 100644 index d27fadd..0000000 --- a/docs/adr/0011-captured-declarations-and-installation.md +++ /dev/null @@ -1,172 +0,0 @@ -# ADR 0011: Capture command declarations and install optional families explicitly - -## Status - -Accepted. Refines [ADR 0001](0001-command-dispatch-and-inputs.md) for declaration -construction, installation, optional-family namespace reservation, and integration -input/state lifetimes. Partially supersedes -[ADR 0010](0010-optional-integration-modules.md) only for its consumer-migration -consequence during the unreleased prototype transition, and refines its -convenient composition principle. - -Refined by [ADR 0012](0012-typed-configuration-comparison-pairs.md) for -two-selection configuration comparison and its input/state lifetime. The -single-selection lifecycle and other decisions remain in force. - -## Date - -2026-10-10 - -## Context - -Applications declare domain commands, while optional integrations assemble -standard command families. A common construction and installation model reduces -repeated error checks and registration plumbing. Integrations need public typed -composition contracts to assemble those families while preserving core and -backend boundaries. - -Declaration and installation have different responsibilities. An optional family -claims a namespace when installed; selecting a dependency alone should leave the -application's command surface unchanged. During execution, scope-specific CLI -inputs and application-owned shared state also have distinct lifetimes. Making -those lifetimes explicit avoids accidental aliasing between selected scopes. - -At the time of this decision, the implementation was an unreleased prototype -with no downstream consumers. Its API shapes carried no compatibility obligations -that would constrain the selected design. - -## Decision - -### Declaration capture and reuse - -Applications and integrations construct the same opaque core command declarations -and install them through core application construction or registration. Initial -integrations provide complete-family factories and focused conveniences through -that common installation API. Suite and provider types remain integration-owned. - -Factories eagerly capture metadata, bindings, capability selections, selector -applicability, and callback references. They copy the declaration collections -needed to isolate returned commands from later edits to source metadata. -Construction errors remain attached for installation to report. This model uses -eager declarations with public typed composition; a deferred preparation lifecycle -and untyped integration payload are outside the selected API. - -Declarations may be reused across applications with independent registry and -invocation state. Callback references and captured application objects retain -caller ownership. Reuse provides no deep-copy or concurrent-dispatch guarantee. -Application helpers performing other fallible work may still return errors. - -### Installation and retained errors - -Core validates each installation batch before registry mutation, checking -retained errors, bindings, placement, and collisions. Failed application -construction returns no usable application; failed later registration preserves -the existing registry. Atomicity covers one installation call. Separate calls -and arbitrary callback effects retain their own lifetimes. - -Report retained errors with useful command context and preserve supported wrapped -error identity. The aggregate-error representation remains an implementation -choice. - -An explicit absence declaration contributes no command, help entry, or namespace. -Installation checks attached errors before skipping it. A zero command declaration -remains invalid. Integrations define their own empty-suite semantics: the initial -configuration suite needs at least one named scope, and metadata-only scopes -remain discoverable. A definition suite with no capabilities contributes nothing. - -Binding validation applies to generated command declarations. Unused selector -bindings in an absent family are ignored; explicitly retained adapter-construction -errors still reach installation. A nil loader supplied to an adapter remains -invalid wiring even if its capabilities are subsequently cleared. - -### Namespace ownership and placement - -Core construction reserves help and version. An optional standard family owns -its complete root namespace upon installation. Imports and absent declarations -claim nothing. An application may occupy an uninstalled family name; installing -a conflicting declaration then fails in either registration order. Installation -preserves existing handlers and group ownership. Private application operations -remain outside installed standard families. - -Standard families carry root-only placement metadata, which core enforces when -they are nested beneath another group. Placement is a public declaration property; -its enforcement is independent of package identity or a list of integration names. -A real empty root-only group claims its namespace and obeys placement checks. -Explicit absence contributes no node to place. - -### Input and shared-state lifetimes - -Integration suites distinguish typed CLI input from typed shared acquisition -state. Ordinary configuration inspection initializes one input per selected scope, -applies its applicable selector bindings, and initializes shared state once for -the inspection invocation. Input validation receives the scope identity and its -typed input. Named definition inspection uses one input and one shared state. -Providers receive both explicitly. ADR 0012 refines this lifecycle for comparison -pairs with two selections of one scope. - -Availability preflight and applicable input checks precede shared-state -initialization and acquisition. Failures may stop later input factories. -Construction, installation, help, version, and scope discovery leave suite -input/state factories and acquisition providers uninvoked. - -An omitted factory supplies its type's zero value, including nil pointers. -Applications provide initialization needed by their accessors and providers; -providers may intentionally accept nil. Allocation of application objects, -cloning, and aliases returned by factories remain caller responsibilities. -Core-owned parsed collections stay independent when applied to separate inputs. -Caller-owned objects and callback effects retain their own lifetimes. - -### Typed binding composition - -Core provides a narrow typed contract to capture converted values and apply a -selected binding subset to initialized input. It preserves binding identity, -defaults, and presence while keeping private setters, parser state, and backend -objects behind their existing boundaries. A copied binding retains its identity; -a newly constructed lookalike has its own identity. - -Execution-required checks apply to the selected subset. Missing required input -is a usage failure; invalid binding selection or destination is a wiring failure -with operational classification at invocation. These categories remain identifiable -through supported wrapping and stop execution before shared-state initialization -and acquisition. Metadata defects detectable during assembly of generated -commands remain installation errors under the validation boundary above. - -### Relationship to earlier decisions - -For the unreleased prototype transition covered by this decision, compatibility -wrappers and a downstream migration guide were unnecessary. This exception to -ADR 0010's migration consequence is limited to that transition. Changes to -published contracts follow the [release policy](../policy/release.md). - -ADR 0001 retains dispatcher, registry, typed-input, and application-ownership -principles. ADR 0010 governs module boundaries and dependency direction, with -[ADR 0003](0003-public-facade.md) governing deliberate exports and backend isolation -within that scope. ADRs 0004 through 0009 retain their operation, grammar, report, -and outcome decisions. Go declarations and GoDoc own exact implemented signatures. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Fallible constructors plus integration-specific registration helpers | Makes each construction failure immediate, but creates several assembly conventions and repeated consumer checks. Captured errors keep one installation boundary. | -| Deferred preparation callbacks | Allows installation to construct a family, but adds lifecycle and error timing beyond eager capture. No demonstrated assembly need requires it. | -| Reserve all known optional family names at core construction | Prevents later name conflicts, but consumes namespaces for integrations the application has not selected. Installed-family ownership keeps conflicts explicit without that restriction. | -| Separate family/plugin registration framework | Could encode ownership and composition, but a captured command with root-only placement and batch validation expresses the required behavior without another installation model. | -| One shared input/state object | Uses fewer type parameters and can share a cache through references in separate input values, but leaves the distinct lifetimes implicit and scope-input isolation to application conventions. Explicit input and state types make those lifetimes visible. | -| Clone hooks or automatic pointer allocation | Can hide input construction, but adds object-graph and initialization responsibilities that belong to the application. Explicit factories keep those choices visible. | -| Public binding getters/setters or an untyped value bag | Enables integration assembly, but exposes private mechanics or returns typed-input assembly to string lookup. Narrow typed composition addresses the actual need. | - -## Consequences - -Consumers assemble domain commands and optional families through one installation -boundary. Eager assembly errors reach that boundary before provider acquisition. -Namespace collisions remain explicit choices for the application to resolve. - -Separate input and state types make initialization and sharing visible. Focused -conveniences support simple applications, while typed composition gives -integrations the public contracts needed to assemble their families. - -The [architecture policy](../policy/architecture.md) owns normative boundaries; -roadmaps own implementation status and sequencing. Application loading, cache -design, startup, domain validation, callback effects, and process exit remain -consumer responsibilities. diff --git a/docs/adr/0012-typed-configuration-comparison-pairs.md b/docs/adr/0012-typed-configuration-comparison-pairs.md deleted file mode 100644 index f8e9732..0000000 --- a/docs/adr/0012-typed-configuration-comparison-pairs.md +++ /dev/null @@ -1,108 +0,0 @@ -# ADR 0012: Prepare typed selection pairs for configuration comparison - -## Status - -Accepted. Refines [ADR 0011](0011-captured-declarations-and-installation.md) for -two-selection configuration comparison; its other decisions remain in force. -[ADR 0008](0008-semantic-configuration-diff.md) governs native comparison and -report presentation. - -## Date - -2026-10-11 - -## Context - -Native effective-configuration comparison needs two completed loads. ConfigKit -requires results of the same configuration type, which an ordinary inspection -view does not expose for pairwise comparison. A generic adapter can retain that -type without introducing result assertions or a universal core provider model. - -ADR 0011 separates a selected scope's typed input from shared acquisition state. -A comparison selects the same scope twice, potentially with different roots or -overlays. Reusing one input obscures which selection a provider receives; creating -separate shared state loses the invocation-wide lifetime chosen for inspection. - -## Decision - -### Selections and provider ownership - -Comparison selects one scope and prepares an earlier/left selection and a -later/right selection. Omitted right selection fields inherit the corresponding -left field and supplied state. An explicit right override, including an empty -value, replaces that field. Providers retain interpretation of omitted defaults -and explicit empty values. Applicable domain selector values are shared between -the two sides initially; independent per-side domain selectors may be considered -for a concrete consumer need. - -Equal selections are allowed. CommandKit does not skip acquisition merely because -their selection values are equal: caller-owned loading may produce different -effective results. Exact flag spellings belong in the CLI reference when -implemented. - -Use a narrow optional comparison provider owned by the integration. Its request -groups each side's selection with its typed input and supplies one shared state -value separately. The provider returns acquired native comparison results -with diagnostics and an error through the existing acquisition convention. -Reuse useful upstream public record types rather than duplicating them solely -to rename fields. Exact exported signatures belong in Go declarations and GoDoc. - -The typed ConfigKit adapter invokes the supplied loader for each reached side -and passes the successful typed results to `configkit.Diff`. It retains the -configuration type inside that adapter, without reflection, result type -assertions, private core access, or a comparison-facet framework. Applications -may supply their own pair provider through the same integration contract. - -Declared capabilities determine required wiring. A comparison-only scope needs -its comparison provider, without an unrelated ordinary acquisition callback. -Ordinary operations continue to use their ordinary acquisition provider. -Retained adapter construction errors still apply when capabilities are narrowed. -Other scopes and families need not support comparison under -[ADR 0009](0009-configuration-scopes.md). - -### Typed input and shared state lifetime - -Capture comparison declarations and applicable selector bindings under ADR 0011. -Convert supplied flag values through core once, including on help paths; applying -the values to both inputs does not parse them again. - -After availability preflight, initialize each reached side's typed input -separately, apply the same applicable captured selector values, and check that -input with the selected scope identity and that side's selection. Finish both -input checks before initializing shared state once and invoking the pair -provider. Failures may stop later factories or loads. Construction, installation, -help, version, and scope discovery invoke neither input/state factories nor -acquisition/comparison providers. - -Existing factory ownership rules remain unchanged: an omitted factory supplies -its type's zero value, including nil pointers. Separate factory calls do not -guarantee distinct caller-owned objects. CommandKit does not allocate arbitrary -pointer types, clone application graphs, repair caller aliases, or supply or -repair application caches. Core-owned parsed collections remain independent -when applied to the two inputs; callback effects remain caller-owned. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Symmetric independently resolved left/right selectors | Makes each side explicit and avoids inheritance. It adds vocabulary and repetition for common base-versus-overlay comparisons. | -| One typed input for both sides | Requires fewer factory calls, but obscures side-specific selection checks and leaves mutation isolation implicit. | -| Acquire a comparison facet with each ordinary view | Shares single-side acquisition across operations, but requires a public compatibility contract between heterogeneous facets and additional handle or assertion machinery. | -| Separate shared state for each side | Isolates acquisition state, but loses the invocation-wide sharing already selected for inspection. Applications can choose isolation within their own pair provider if needed. | - -## Consequences - -Pair preparation has explicit input and state lifetimes while ordinary inspection -keeps its existing lifecycle. Generic result handling stays inside the integration -adapter; core gains no owning-library dependency or universal comparison model. - -Shared state permits application-owned caches. A cache used by a pair provider -should distinguish selections and any input values affecting loading to avoid -reusing the left result for a different right selection. This is integration -guidance, not a CommandKit cache policy or guarantee about caller callbacks. - -The [architecture policy](../policy/architecture.md) owns normative boundaries. -ADR 0008 governs delegation to upstream comparison semantics, safe disclosure, -and CommandKit's presentation responsibility. This decision does not add a new -equality engine or strengthen application -loading, object ownership, or concurrency contracts. diff --git a/docs/adr/0013-application-alias-routing.md b/docs/adr/0013-application-alias-routing.md deleted file mode 100644 index b1a96f2..0000000 --- a/docs/adr/0013-application-alias-routing.md +++ /dev/null @@ -1,68 +0,0 @@ -# ADR 0013: Separate application alias routing from canonical command ownership - -## Status - -Accepted. Refines [ADR 0011](0011-captured-declarations-and-installation.md) -by extending its shared installation boundary to application routing rules. -Its canonical command ownership and declaration principles remain in force. - -## Date - -2026-10-19 - -## Context - -Applications need alternate command paths and flag spellings that suit their -operator vocabulary. These conveniences should reuse the behavior supplied by -application commands and optional integrations. Canonical command families -already establish ownership of handlers, namespaces, inputs, and invocation -behavior. - -A routing layer allows applications to choose alternate spellings while -preserving those ownership boundaries. Commands and routing rules have distinct -roles, and their relationships require validation during application assembly. - -## Decision - -CommandKit core owns alias declaration, resolution, and coordination with parsing -and help. Applications choose their alias mappings. Alias infrastructure is -available independently of optional integrations under the module boundaries -established by [ADR 0010](0010-optional-integration-modules.md). - -Aliases belong to an application routing layer that directs invocations to -canonical commands and flags. Canonical definitions retain ownership of their -handlers, inputs, and namespaces. An alternate path within an integration's -namespace remains an application routing rule; the integration continues to own -the canonical command family and its operations. - -Canonical commands and routing rules are distinct declaration kinds installed -through a common core assembly boundary. Installation validates their -relationships together, preserves canonical definitions and namespace ownership, -and applies the batch-atomicity and retained-error model of ADR 0011 to both -layers. Declaration capture and reuse follow that existing model. - -An invocation through an alias uses the canonical target's parsing, typed -bindings, validation, and ordinary invocation lifecycle. Execution behavior -remains with the canonical command and its owning application or integration. -Core coordinates alternate routing and presentation through the same command -infrastructure. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Install aliases as wrapper commands | Reuses the command tree for discovery, but introduces additional command nodes and handler delegation into namespace ownership and invocation lifetimes. | -| Have applications rewrite arguments before dispatch | Gives applications direct control over shortcuts, but repeats routing infrastructure and separates alias handling from target validation, parsing, and help. | -| Register aliases through a separate assembly API | Makes routing declarations explicit, but splits validation of commands and their alternate routes across installation boundaries. Distinct declaration kinds express the separation within one atomic batch. | - -## Consequences - -Applications can tailor operator vocabulary while reusing canonical behavior. -Core maintains the relationship between routing rules and canonical definitions -as declarations are installed. Optional integrations continue to supply their -command families through the existing ownership model. - -Routing, parsing, and help must coordinate across the two layers. Exact API -shapes, resolution rules, and presentation choices belong in GoDoc and the -[CLI reference](../cli.md) when implemented. Those details can evolve within -this architectural separation. diff --git a/docs/adr/0014-invocation-reporting.md b/docs/adr/0014-invocation-reporting.md deleted file mode 100644 index 7b02ef1..0000000 --- a/docs/adr/0014-invocation-reporting.md +++ /dev/null @@ -1,79 +0,0 @@ -# ADR 0014: Share command-line presentation within each invocation - -## Status - -Accepted. Extends [ADR 0005](0005-invocation-outcomes.md) with shared reporting -for each invocation. Its outcome classifications, standard status meanings, -output channels, error-cause preservation, and application ownership of process -exit remain in force. - -## Date - -2026-10-25 - -## Context - -Applications need consistent control over command results, messages shown during -a run, and messages shown at its end. Sharing that control reduces repeated -output code across applications and integrations. - -An application decides what an error means for its work. It may recover silently, -show a warning, or end the invocation. CommandKit needs the chosen outcome and -messages to present that decision to the operator. - -## Decision - -CommandKit core provides one reporting facility for each invocation. Application -commands, integration commands, and core commands use it for results, immediate -messages, and deferred messages. Core applies shared rules for visibility, -formatting, and delivery, and completes reporting when the invocation ends. -Callers choose the output destinations. - -Applications decide how to respond to domain-specific errors and choose their -outcomes and messages. CommandKit may provide shared helpers for carrying, -inspecting, and presenting errors while leaving those decisions with the -application. - -Applications supply explicit outcomes and explanations for failures. They may -also supply a Go error cause. CommandKit keeps that error unchanged for the caller -to inspect. Supplying a cause alone does not select an outcome or generate an -operator-facing message. CommandKit remains responsible for handling its own -errors, including routing, parsing, and presentation failures. - -Integrations adapt upstream results and diagnostics into command outcomes and -messages. The upstream libraries retain ownership of their meanings and rules -for safe disclosure. - -An Error message explains a failed invocation with a non-zero status. Its -explanation is presented at the end of the invocation, after normal reporting -finishes. The returned outcome carries that explanation. The application entry -point decides how to exit the process. - -CommandKit reports rendering and delivery failures separately from the command's -explanation. A presentation failure produces an operational failure for standard -outcomes under ADR 0005. Application-defined domain classifications are preserved, -along with an already non-zero domain status. A successful domain outcome receives -a non-zero status if presentation fails. The original explanation and any supplied -cause remain available to the caller. Intentionally suppressed output is not a -delivery failure. - -Reporting keeps the state needed to deliver messages and return the invocation -outcome. Logging and message history remain application concerns. - -## Alternatives considered - -| Alternative | Analysis | -| --- | --- | -| Let each application manage all presentation | Gives applications full control, but repeats visibility and delivery code across commands and integrations. | -| Have core decide whether domain-specific errors require recovery, a warning, or failure | Reduces some caller code, but gives core decisions that depend on application behavior. | -| Use separate facilities for results, immediate messages, and deferred messages | Lets each facility serve one purpose, but spreads visibility and final delivery across several paths. | - -## Consequences - -Applications and integrations share presentation behavior while choosing their -own results and messages. Core handles reporting failures consistently and keeps -them visible in the returned outcome. - -GoDoc and the [CLI reference](../cli.md) define the implemented API, flags, -message formats, and delivery details. Those details can evolve within this -ownership model. diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..783ffa8 --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,51 @@ +# Architectural decision records + +These records explain major structural and ownership decisions. The +[architecture policy](../policy/architecture.md) owns normative boundaries; +GoDoc and the [CLI reference](../cli.md) own implemented contracts. The +[roadmap](../roadmap/promptkit-v0.19.0.md) owns planned work and implementation status. + +| ADR | Decision | +| --- | --- | +| [0001](0001-command-dispatch-and-inputs.md) | Dispatch, captured declarations, and typed inputs | +| [0002](0002-public-facade-and-cli-backend.md) | Public facade and internal CLI backend | +| [0003](0003-configuration-scopes.md) | Configuration scopes and declared capabilities | +| [0004](0004-optional-integration-modules.md) | Optional integration modules and upstream ownership | +| [0005](0005-application-alias-routing.md) | Alias routing and canonical command ownership | +| [0006](0006-invocation-reporting.md) | Invocation reporting, outcomes, and presentation ownership | + +## Alpha consolidation + +On 2026-11-07, the maintainer authorized a one-time exception to ADR immutability +while CommandKit was in alpha. Fourteen records were consolidated, revised, and +consecutively renumbered into the six above. The normal +[ADR policy](../policy/documentation.md#architecture-decision-records) continues +to apply after this cleanup. This exception does not authorize rewriting +published releases or changing implemented behavior through documentation alone. + +The [pre-consolidation records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/76c00e32d05eb9f2f150f3554bd578192efe3a61/docs/adr) +remain available in Git history. Earlier references use that historical numbering. +The mapping below identifies where rationale or current contracts now belong; +it does not preserve removed records as parallel specifications. + +| Former record | Current owner | +| --- | --- | +| 0001 — Dispatch and inputs | ADR 0001 | +| 0002 — Cobra backend | ADR 0002 | +| 0003 — Public facade | ADR 0002; module boundaries in ADR 0004 | +| 0004 — Inspection surface | Capability rationale in ADR 0003; command inventory in the CLI reference | +| 0005 — Invocation outcomes | ADR 0006; numeric statuses and exact behavior in CLI/API contracts | +| 0006 — Command grammar | Shared parsing rationale in ADR 0001; grammar in the CLI reference | +| 0007 — Native YAML reports | Disclosure ownership in ADR 0004; presentation ownership in ADR 0006; current formats in the CLI reference | +| 0008 — Semantic comparison | Upstream ownership in ADR 0004; comparison reports and outcomes in CLI/API contracts | +| 0009 — Configuration scopes | ADR 0003 | +| 0010 — Optional modules | ADR 0004 | +| 0011 — Captured declarations | Structural decisions in ADR 0001; detailed mechanics in GoDoc | +| 0012 — Comparison pairs | Input/state separation in ADR 0001; provider lifetimes and selectors in CLI/API contracts | +| 0013 — Alias routing | ADR 0005 | +| 0014 — Invocation reporting | ADR 0006 | + +Current command and API contracts remain in force. Accepted changes to format +handling and independent comparison selections remain planned in the adoption +roadmap until implemented. Removing an ADR's detailed specification does not +silently remove those contracts or implement their planned replacements. diff --git a/docs/development.md b/docs/development.md index 6719e9e..b79f43f 100644 --- a/docs/development.md +++ b/docs/development.md @@ -15,7 +15,7 @@ canonical documentation owners. For application-owned aliases, use the [CLI reference](cli.md#application-owned-aliases), [Go declarations and GoDoc](../command.go), and -[ADR 0013](adr/0013-application-alias-routing.md). Keep unfinished work and +[ADR 0005](adr/0005-application-alias-routing.md). Keep unfinished work and capability proposals in [future work](roadmap/future.md). ## Initial orientation @@ -24,7 +24,7 @@ capability proposals in [future work](roadmap/future.md). 2. Read the [agent policy](policy/agents.md) and select other applicable policies using the guide below. 3. Read the owning roadmap for proposals and implementation status, and the - applicable ADR for accepted decisions and rationale. + applicable [ADR](adr/README.md) for accepted decisions and rationale. 4. Inspect implementation and relevant consumer contracts when they exist. ## Policy Reading Guide @@ -54,12 +54,12 @@ capability proposals in [future work](roadmap/future.md). | Task | Read | | --- | --- | | Implemented CLI behavior | [CLI reference](cli.md) | -| Invocation reporting | [CLI reporting contract](cli.md#reporting), [consumer guide](consumers/guide.md#invocation-reporting), core GoDoc, and [ADR 0014](adr/0014-invocation-reporting.md) | -| Application-owned aliases | [CLI reference](cli.md#application-owned-aliases), [Go declarations and GoDoc](../command.go), [consumer guide](consumers/guide.md#application-owned-aliases), and [ADR 0013](adr/0013-application-alias-routing.md) | +| Invocation reporting | [CLI reporting contract](cli.md#reporting), [consumer guide](consumers/guide.md#invocation-reporting), core GoDoc, and [ADR 0006](adr/0006-invocation-reporting.md) | +| Application-owned aliases | [CLI reference](cli.md#application-owned-aliases), [Go declarations and GoDoc](../command.go), [consumer guide](consumers/guide.md#application-owned-aliases), and [ADR 0005](adr/0005-application-alias-routing.md) | | Public API usage and standard-suite wiring | [Consumer guide](consumers/guide.md), [ckconfig package](../integrations/ckconfig/doc.go), [ckprompt package](../integrations/ckprompt/doc.go), and applicable ADRs | -| Dispatcher, registration, or typed inputs | [Command declarations](../command.go), [bindings](../binding.go), [invocation](../execute.go), and [ADR 0001](adr/0001-command-dispatch-and-inputs.md), refined by [ADR 0011](adr/0011-captured-declarations-and-installation.md) | -| Backend integration | [Internal overview](internal/overview.md), [adapter implementation](../internal/cobra/parse.go), and [ADR 0002](adr/0002-cobra-backend.md) | -| Public facade or adapter boundaries | [Internal overview](internal/overview.md), [ADR 0003](adr/0003-public-facade.md) as scoped by [ADR 0010](adr/0010-optional-integration-modules.md), and the architecture policy | +| Dispatcher, registration, or typed inputs | [Command declarations](../command.go), [bindings](../binding.go), [invocation](../execute.go), and [ADR 0001](adr/0001-command-dispatch-and-inputs.md) | +| Backend integration | [Internal overview](internal/overview.md), [adapter implementation](../internal/cobra/parse.go), and [ADR 0002](adr/0002-public-facade-and-cli-backend.md) | +| Public facade or adapter boundaries | [Internal overview](internal/overview.md), [ADR 0002](adr/0002-public-facade-and-cli-backend.md), [ADR 0004](adr/0004-optional-integration-modules.md), and the architecture policy | | Module ownership and public contracts | [Consumer guide](consumers/guide.md), [internal overview](internal/overview.md), [core GoDoc](../doc.go), [ckconfig GoDoc](../integrations/ckconfig/doc.go), [ckprompt GoDoc](../integrations/ckprompt/doc.go), and applicable ADRs | | Unfinished work and capability proposals | [Future work](roadmap/future.md) | | Completed planning and implementation history | [Completed dependency upgrades, PromptKit validation, discovery, smoke testing, and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/a6278a6d9f940948ec7745955d745523aaff0734/docs/roadmap), [earlier ConfigKit and PromptKit adoption and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/8a82620dfcd34c0ae56bbecb0d014eb49786bc92/docs/roadmap), [earlier retired records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap), and [completed module implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/bb2528532b78d30e52f5082e491a5e1fd9b0fb99/docs/roadmap) in Git history | diff --git a/docs/policy/architecture.md b/docs/policy/architecture.md index bcb981d..2e0ccd0 100644 --- a/docs/policy/architecture.md +++ b/docs/policy/architecture.md @@ -2,7 +2,7 @@ **Base Policy Version:** 1.3 -**Last Updated**: 2026-10-26 +**Last Updated**: 2026-11-07 **Upstream Source:** [architecture.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md) @@ -45,9 +45,8 @@ flexibility to express genuine application requirements within one command model ## Command And Application Ownership [ADR 0001](../adr/0001-command-dispatch-and-inputs.md) records the selected -CommandKit-owned dispatcher, per-instance registry, and typed-input model. -[ADR 0011](../adr/0011-captured-declarations-and-installation.md) refines declaration -capture, installation, optional-family ownership, and invocation input lifetimes. +dispatcher, captured declarations, installation boundary, and typed-input model. +The [ADR index](../adr/README.md) records the alpha consolidation and renumbering. CommandKit owns dispatch, common parsing, presence tracking, help, shared syntax diagnostics, and the handlers and CLI contracts of its standard families. @@ -72,8 +71,8 @@ semantics or success-report formats. CommandKit's grammar applies to commands using its dispatcher and binding APIs. Its documentation recommends the same grammar and vocabulary for application-owned -commands, including those outside its dispatcher, under -[ADR 0006](../adr/0006-command-grammar.md). +commands, including those outside its dispatcher. The +[CLI reference](../cli.md#registered-command-syntax) owns implemented grammar. Use explicit instance construction and composable command registration, not package-global or import-time registries. Applications and integrations supply @@ -126,8 +125,10 @@ application-owned. Use one reporting facility per invocation for command results, immediate messages, and deferred messages. Core owns shared visibility, formatting, delivery, and finalization. Applications and integrations choose their report content and -messages; callers choose the destinations. [ADR 0014](../adr/0014-invocation-reporting.md) -extends the outcome and delivery model in [ADR 0005](../adr/0005-invocation-outcomes.md). +messages; callers choose the destinations. +[ADR 0006](../adr/0006-invocation-reporting.md) records this reporting and outcome +ownership model. Its accepted structured-report extension remains planned in the +[adoption roadmap](../roadmap/promptkit-v0.19.0.md#shared-core-report-output-prerequisite). Applications decide how to respond to domain-specific errors. CommandKit may provide shared helpers for carrying, inspecting, and presenting errors while @@ -137,8 +138,8 @@ handles its own errors, including routing, parsing, and presentation failures. Preserve application-defined domain classifications and supplied error identity. Report rendering and delivery failures separately from the command's explanation -and cause, applying the outcome rules in ADR 0005 and ADR 0014. Intentionally -suppressed output is not a delivery failure. Present terminal failure explanations +and cause, applying the [CLI reporting contract](../cli.md#presentation-failures). +Intentionally suppressed output is not a delivery failure. Present terminal failure explanations after normal reporting finishes, avoid duplicate presentation through core's own paths, and retain the explanation and any supplied cause in the returned outcome. @@ -164,10 +165,12 @@ installation, help, version, and scope discovery. For two-selection configuration comparison, prepare and check each side's input separately with its scope identity and selection, applying the same applicable converted selector values to both. Finish both checks before initializing shared -state once and invoking the integration-owned pair provider under -[ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). Required provider -wiring follows declared capabilities; a comparison-only scope does not require -an unrelated ordinary acquisition callback. +state once and invoking the integration-owned pair provider. The +[consumer guide](../consumers/guide.md#configkit-scopes) and linked GoDoc own the +provider lifecycle; the [CLI reference](../cli.md#compare-configuration-selections) +owns current selector behavior. Required provider wiring follows declared +capabilities; a comparison-only scope does not require an unrelated ordinary +acquisition callback. Omitted input and state factories supply the respective type's zero value, including nil for pointers. Caller factories and callbacks retain responsibility @@ -187,8 +190,8 @@ composition does not create a second parser or a raw-argument handler model. CommandKit keeps parsed values, collections, and presence from one invocation out of subsequent runs. Storage allocation and safe reuse are implementation choices; -rebuilding backend state is the initial strategy under -[ADR 0002](../adr/0002-cobra-backend.md). Caller-owned closures and runtime state +the [internal overview](../internal/overview.md#internalcobra) describes the +current backend lifecycle. Caller-owned closures and runtime state retain their own lifecycle. Concurrent dispatch is a separate contract. Applications may interpret parsed domain values and provide domain value parsers @@ -197,11 +200,11 @@ Keep input declarations available without application initialization. ## Public Facade And Dependency Direction -[ADR 0010](../adr/0010-optional-integration-modules.md) scopes the root -`commandkit` facade to the core module and selects separate optional integration -modules with their own public package contracts. It partially supersedes -[ADR 0003](../adr/0003-public-facade.md), whose remaining facade and internal -adapter principles apply to the core and integrations alike. +[ADR 0004](../adr/0004-optional-integration-modules.md) selects separate optional +integration modules with their own public package contracts. The facade and +backend isolation principles in +[ADR 0002](../adr/0002-public-facade-and-cli-backend.md) apply within those module +boundaries. The core owns command declarations, registration, bindings, dispatch, help/version, shared syntax, diagnostics, and outcomes. Each integration owns its standard @@ -241,8 +244,8 @@ without exporting private assembly or backend structures. ## Backend And Library Integration -[ADR 0002](../adr/0002-cobra-backend.md) selects Cobra with pflag as the sole -initial backend. Their types and operations stay inside an internal adapter that +[ADR 0002](../adr/0002-public-facade-and-cli-backend.md) selects Cobra with pflag +as the sole initial backend. Their types and operations stay inside an internal adapter that translates CommandKit-owned definitions into backend machinery. Registry logic, standard handlers, and shared internal representations remain independent of backend-specific structures. @@ -275,15 +278,14 @@ packages or depend on adjacent checkouts. Use narrow integration contracts, reusing upstream public types where useful and introducing CommandKit-owned abstractions where they simplify integration. Concrete integration needs guide provider representations under -[ADR 0009](../adr/0009-configuration-scopes.md). +[ADR 0003](../adr/0003-configuration-scopes.md). -Native report writers and safe inspection data preserve owning-library semantics. -Loading all selected views before report output is a `config show` decision under -[ADR 0007](../adr/0007-native-yaml-reports.md); other inspection operations define -their own output timing. Semantic comparison exposes the adopted upstream -comparison API, carrying its results and relevant metadata through the provider -boundary. CommandKit owns report presentation under -[ADR 0008](../adr/0008-semantic-configuration-diff.md). +Use upstream safe inspection data to preserve owning-library meaning and +disclosure rules under [ADR 0004](../adr/0004-optional-integration-modules.md). +The [CLI reference](../cli.md#show-effective-configuration) owns current native +report formats and operation-specific preparation and delivery timing. Semantic +comparison exposes the adopted upstream comparison API and carries its evidence +through the provider boundary; it does not introduce a CommandKit equality engine. ## Scope And Non-goals diff --git a/docs/policy/testing.md b/docs/policy/testing.md index aed917c..053971f 100644 --- a/docs/policy/testing.md +++ b/docs/policy/testing.md @@ -2,7 +2,7 @@ **Base Policy Version:** 1.3 -**Last Updated**: 2026-10-17 +**Last Updated**: 2026-11-07 **Upstream Source:** [testing.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/testing.md) @@ -66,7 +66,7 @@ implemented: - Selected inspection/report contracts, including native YAML and document order for `config show --scope all`. - Public type ownership and the internal Cobra/pflag import boundary selected by - [ADR 0003](../adr/0003-public-facade.md). + [ADR 0002](../adr/0002-public-facade-and-cli-backend.md). Use external-package consumer tests for facade semantics and real backend integration where correctness depends on that interaction. Internal package diff --git a/docs/roadmap/future.md b/docs/roadmap/future.md index 80858ef..0abb9bc 100644 --- a/docs/roadmap/future.md +++ b/docs/roadmap/future.md @@ -206,7 +206,9 @@ Execution, serving, and session operations remain application-owned. The [request preview proposal](promptkit-v0.19.0.md#preview-and-request-flags) exposes native preparation and rendering as an agreed operator inspection target; implementation has not started. -Shared vocabulary is guidance under [ADR 0006](../adr/0006-command-grammar.md). +The [architecture policy](../policy/architecture.md#command-and-application-ownership) +recommends shared vocabulary; the [CLI reference](../cli.md#registered-command-syntax) +owns implemented grammar. Backend replacement remains possible behind the accepted facade, subject to the published API/CLI contracts and deliberate compatibility decisions. diff --git a/docs/roadmap/promptkit-v0.19.0.md b/docs/roadmap/promptkit-v0.19.0.md index d322bef..a58db58 100644 --- a/docs/roadmap/promptkit-v0.19.0.md +++ b/docs/roadmap/promptkit-v0.19.0.md @@ -41,8 +41,8 @@ operations. Applications continue to own engine construction, domain inputs, credentials, execution, and their executable lifecycle. The [architecture policy](../policy/architecture.md), -[optional-module decision](../adr/0010-optional-integration-modules.md), and -[reporting decision](../adr/0014-invocation-reporting.md) govern implementation. +[optional-module decision](../adr/0004-optional-integration-modules.md), and +[reporting decision](../adr/0006-invocation-reporting.md) govern implementation. The [CLI reference](../cli.md) and public GoDoc remain the owners of implemented contracts. This roadmap records planned work, not new guarantees about upstream behavior or permanent limits on future features. @@ -240,9 +240,10 @@ core. Never reconstruct inspection from mutable `Result.Config` or source files. Select source IDs from acquired inventory; native `Source(id)` is a convenience, not another provider requirement. Source IDs are local to one load. -[OD-9](#od-9-independent-comparison-selector-bindings) replaces ADR 0012's -inheritance while retaining its two-input/provider lifecycle. Domain defaults -and caching remain application-owned. +[OD-9](#od-9-independent-comparison-selector-bindings) replaces the +[current comparison inheritance](../cli.md#compare-configuration-selections) +while retaining the two-input/provider lifecycle. Domain defaults and caching +remain application-owned. [OD-10](#od-10-comparison-assertion-outcomes) uses native differences for assertions; source/history differences alone and changed credential bytes behind unchanged references are not necessarily effective-value differences. @@ -400,11 +401,14 @@ disclosure rules, or inspection evidence. This is an output conversion, not a replacement for upstream configuration loading or validation. No lossless YAML document model or second rendering pipeline is needed. -When implementation lands, record the deliberate replacement of -[ADR 0007](../adr/0007-native-yaml-reports.md)'s native-writer and mapping-order -requirements in a superseding ADR and update current contracts. Retain the -accepted ADR's decision text as history. The aggregate presentation decision below -also replaces its separate-document framing. +When implementation lands, update the +[current display contract](../cli.md#show-effective-configuration) to replace +native-writer and mapping-order requirements. The aggregate presentation decision +below also replaces separate-document framing. These presentation changes follow +the ownership boundary in [ADR 0006](../adr/0006-invocation-reporting.md); they do +not require a separate successor ADR. The +[alpha consolidation](../adr/README.md#alpha-consolidation) retired the former +detailed report records without changing current behavior. This approach reduces new machinery by reusing standard serialization and centralizing the remaining conversion and rendering work. Exact internal @@ -486,10 +490,10 @@ behavior: acquire all selected views and complete provider-required validation before report output begins; a failure prevents the combined display. The new shape does not introduce partial-success output. -When implementation lands, supersede ADR 0007's ordered native-document framing -and refine [ADR 0009](../adr/0009-configuration-scopes.md)'s combined-display -ordering contract through a new ADR. This decision concerns aggregate display; -it does not change scope discovery or acquisition ordering. +When implementation lands, update the CLI display contract and affected tests +for this aggregate shape. Scope discovery and acquisition ordering are unchanged. +The capability model in [ADR 0003](../adr/0003-configuration-scopes.md) does not +prescribe report framing or mapping order. ### Remaining core reporting implementation details @@ -623,7 +627,7 @@ or field order. implementation approach. Keep boundary coverage with each change. 6. **Update operator and consumer documentation.** The CLI reference owns syntax, report schemas, availability, and outcomes; GoDoc owns callback and - value contracts. Update the affected ADRs and architecture policy, and replace + value contracts. Keep architectural ownership references aligned, and replace the testing policy's old native-YAML/document-order guidance when the new report behavior lands. Extend maintained simple/composed examples to demonstrate the new CLI tasks using local fixtures, without adding application-internal @@ -731,11 +735,13 @@ rather than prescribing one test per line or exact cosmetic snapshots. - [ ] Maintained simple/composed consumers demonstrate the new CLI tasks and failure workflow with deterministic fixtures. Code remains proportionate: thin projections, one shared rendering implementation, and focused tests. -- [ ] Superseding ADRs record changes to ADR 0007/0009 reporting and ADR 0012 - comparison. Update CLI/API contracts, release notes, and examples with the - implementation, including validation delivery timing. Incorporate the ownership - principles into architecture.md and replace obsolete native-YAML/document-order - guidance in testing policy. Current documentation must match the landed scope. +- [ ] Update CLI/API contracts, release notes, and examples with the implementation, + including report framing, independent comparison selections, and validation + delivery timing. Incorporate the ownership principles into architecture.md and + replace obsolete native-YAML/document-order guidance in testing policy. The + consolidated ADRs own architectural rationale; these presentation and selector + changes need no separate successor records. Current documentation must match + the landed scope. - [ ] Final independent-module and aligned-workspace suites pass with dependency identities recorded. Deferred features remain outside this adoption. @@ -1265,12 +1271,12 @@ not implicitly shared. Domain parsing stays in declared typed bindings; no generic selector language is introduced. Retain the two input preparations and checks, one shared invocation state, and existing provider lifecycle. -This deliberately replaces the previous inheritance model, including existing -config/overlay behavior and shared application selectors. When implementation -lands, record the change in a superseding ADR for the affected decisions in -ADR 0012, retaining its accepted decision text as history, and update current -CLI/API contracts and examples. Exact helper signatures and flag collision -handling remain implementation design tasks. +This deliberately replaces the current inheritance model, including existing +config/overlay behavior and shared application selectors. Update CLI/API contracts +and examples when implementation lands. The input/state ownership in +[ADR 0001](../adr/0001-command-dispatch-and-inputs.md) remains unchanged; selector +policy does not need a separate successor ADR. Exact helper signatures and flag +collision handling remain implementation design tasks. **Agreed collection scope:** leave explicit-empty selection for application-defined repeatable selectors to application-declared bindings in this release. Omission