300 lines
18 KiB
Markdown
300 lines
18 KiB
Markdown
# Optional integration modules
|
|
|
|
Status: module boundary accepted in ADR 0010; consumer API and internal backend
|
|
design finalized, with both composition questions resolved. The
|
|
[staged implementation plan](implementation.md) is complete; no module extraction
|
|
has begun. ReleaseKit v0.4.0 provides module-release support; CommandKit adoption
|
|
is pending.
|
|
|
|
## Purpose and authority
|
|
|
|
Make CommandKit useful to consumers that use both ConfigKit and PromptKit,
|
|
ConfigKit alone, or neither library. Consumers using only CommandKit's core
|
|
should acquire neither ConfigKit nor PromptKit through CommandKit's package or
|
|
module dependencies. ConfigKit-only consumers should not acquire PromptKit.
|
|
|
|
This roadmap records the targeted end state, selected module layout, and
|
|
delivery boundaries. The [implementation plan](implementation.md) owns the ordered
|
|
steps and validation needed to reach this target. The finalized
|
|
[registration API](registration-api.md) owns the
|
|
selected declarations, installation semantics, and representative consumer
|
|
examples. The finalized [registration backend design](registration-backend.md)
|
|
owns internal structure, shared installation/execution mechanics, and the resolved
|
|
composition decisions. These documents describe the implementation target.
|
|
[ADR 0010](../adr/0010-optional-integration-modules.md) owns the accepted module
|
|
boundary and convenient registration principles; it partially supersedes
|
|
[ADR 0003](../adr/0003-public-facade.md), whose remaining principles still apply.
|
|
[ADR 0011](../adr/0011-captured-declarations-and-installation.md) records the
|
|
finalized registration and invocation-lifetime decisions. The
|
|
[architecture policy](../policy/architecture.md) is aligned with those decisions.
|
|
GoDoc, the [CLI reference](../cli.md), and the [consumer guide](../consumers/guide.md) describe the prototype baseline; they do
|
|
not make its incidental API shapes compatibility requirements for this sprint.
|
|
|
|
## Organizing principle: design the final API
|
|
|
|
Give the existing prototype implementation zero deference when selecting the
|
|
final API, as directed for this transition. Core `v0.1.0` has since been published;
|
|
preserve that release and prepare the incompatible replacement as a fresh minor
|
|
release under the release policy. Publication does not change the selected API
|
|
or require compatibility wrappers for this sprint. The goal is
|
|
the best, simplest, most coherent API for the accepted responsibilities and
|
|
representative consumers, not the smallest diff or a mechanically relocated
|
|
prototype. Accepted architectural decisions and explicitly selected behavior
|
|
remain requirements; prototype declarations, helpers, bookkeeping, and tests do
|
|
not independently establish contracts.
|
|
|
|
Complete the transition in one sprint. No backward-compatibility wrappers,
|
|
deprecation period, or migration bridge is needed. Intermediate commits need not
|
|
build or pass tests; do not add temporary machinery merely to make them do so.
|
|
Validate the complete target state before release. Reuse existing code where it
|
|
serves that design, and refactor, replace, or remove it where it does not.
|
|
|
|
## Current baseline
|
|
|
|
At the start of this roadmap, CommandKit has one Go module and one supported
|
|
public root package. It requires ConfigKit v0.5.0 and PromptKit v0.12.0 and
|
|
declares Go 1.26.0. Its internal Cobra adapter implements routing and parsing.
|
|
|
|
The root combines core command infrastructure with configuration and PromptKit
|
|
inspection. Coupling extends beyond constructors:
|
|
|
|
- `NewConfigKitScope` accepts ConfigKit results and maps their diagnostics.
|
|
- Core `Diagnostic.Severity` currently uses ConfigKit's public severity type;
|
|
moving inspection handlers alone will not remove that dependency.
|
|
- `SourceReader` returns ConfigKit source records; `ExplanationReader` accepts
|
|
ConfigKit paths and returns ConfigKit explanations.
|
|
- `PromptKitSuite` callbacks return PromptKit inspection types.
|
|
- `NewPromptKitScope` adapts engine configuration into the configuration suite.
|
|
- Standard handlers share root-private helpers and state. For example,
|
|
configuration registration accesses the application's registry and records
|
|
whether the suite has already been installed.
|
|
|
|
The [internal overview](../internal/overview.md) describes the implemented
|
|
inventory. The maintained examples and integration tests currently belong to the
|
|
root module. ReleaseKit v0.3.0 is also selected there as a Go tool dependency;
|
|
the [release procedure](../release.md) assumes one module and one version tag.
|
|
|
|
Optional command registration currently controls behavior, not dependencies.
|
|
Moving integration code into packages sharing the root `go.mod` would separate
|
|
compiled imports but retain integration requirements in the module graph.
|
|
Go's [module graph rules](https://go.dev/ref/mod#module-graph-pruning) explain
|
|
that distinction.
|
|
|
|
## Targeted end state
|
|
|
|
Provide three consumer modules in this repository with dependencies directed
|
|
toward the core. Keep the core at `gitea.maximumdirect.net/eric/CommandKit` and
|
|
give each integration its own `go.mod`:
|
|
|
|
| Directory | Module path | Package name |
|
|
| --- | --- | --- |
|
|
| Repository root | `gitea.maximumdirect.net/eric/CommandKit` | `commandkit` |
|
|
| `integrations/ckconfig` | `gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig` | `ckconfig` |
|
|
| `integrations/ckprompt` | `gitea.maximumdirect.net/eric/CommandKit/integrations/ckprompt` | `ckprompt` |
|
|
|
|
The `integrations/` grouping keeps optional modules together as their number
|
|
grows; the anticipated three to ten integrations are planning context, not a
|
|
limit or delivery commitment. Distinct package names avoid requiring local
|
|
aliases when these integrations are imported alongside ConfigKit and PromptKit.
|
|
Separate module files establish dependency isolation; directory naming alone
|
|
does not. The shared repository requires explicit multi-module testing and
|
|
publication orchestration.
|
|
|
|
| Module | Responsibility | Integration dependencies |
|
|
| --- | --- | --- |
|
|
| Core | Application construction, command/group registration, typed bindings, dispatch, help/version, common grammar, outcomes, and diagnostics | Neither ConfigKit nor PromptKit |
|
|
| ConfigKit integration | Standard configuration family, scope composition, reports, and ConfigKit adapters | Core and ConfigKit; no PromptKit |
|
|
| PromptKit integration | Named prompt/profile inspection and the PromptKit configuration-scope adapter | Core, PromptKit, and the ConfigKit integration |
|
|
|
|
The core remains an opinionated command library with its existing internal
|
|
Cobra boundary. The dependency goal is independence from ConfigKit and PromptKit,
|
|
not a standard-library-only implementation.
|
|
|
|
Integrations remain maintained parts of CommandKit. They install commands into
|
|
the same application through supported public core operations and follow its
|
|
grammar, help, invocation, and outcome conventions. Applications retain domain
|
|
commands, acquisition, runtime construction, streams, and process exit.
|
|
|
|
The selected configuration boundary moves the existing ConfigKit-shaped
|
|
contracts with their handlers into the ConfigKit integration. Only ConfigKit
|
|
support is needed for now; a generic configuration interface is outside this
|
|
migration. The PromptKit integration may depend on the ConfigKit integration,
|
|
consistent with PromptKit's own ConfigKit dependency. Document that relationship
|
|
in consumer guidance: `ckprompt` depends on `ckconfig`.
|
|
|
|
This boundary preserves one configuration suite into which
|
|
applications compose `app`, `promptkit`, and other supported scopes. PromptKit
|
|
configuration inspection and named-definition inspection remain independently
|
|
selectable. A module dependency does not automatically install a command family.
|
|
|
|
Core public signatures and implementation imports contain no ConfigKit or
|
|
PromptKit types. Integration-specific types and helpers move to their owning
|
|
modules. Do not retain root forwarding wrappers that restore those imports.
|
|
Shared helpers stay private unless a concrete cross-module interaction needs a
|
|
supported contract; extraction is not a reason to expose every existing helper.
|
|
|
|
Preserve explicitly selected operator behavior: command vocabulary, selection
|
|
and scope semantics, native reports, diagnostics, error identity, outcomes, and
|
|
help without provider acquisition. Identify and decide any changes to selected
|
|
CLI behavior separately. Do not preserve accidental prototype behavior or Go API
|
|
shapes merely because they already exist.
|
|
|
|
### Selected API and release principles
|
|
|
|
- Use the finalized [uniform registration API](registration-api.md#declaration-and-installation).
|
|
Applications and integrations produce captured core command declarations and
|
|
install them through core `New` or `App.Register`; construction errors are
|
|
retained for installation-time validation. Integration factories provide
|
|
complete families and focused conveniences. The API document owns exact
|
|
signatures and the [input/shared-state separation](registration-api.md#why-inputs-and-shared-state-have-separate-types).
|
|
- Follow the selected [namespace lifetime and reconciliation requirements](registration-api.md#namespace-reconciliation-and-implementation-handoff).
|
|
Built-in help/version remain reserved; optional integration roots are owned
|
|
when their real family is installed. ADR 0011 and the architecture policy now
|
|
record that lifetime; implementation remains pending.
|
|
- Use the finalized [internal registration and execution design](registration-backend.md).
|
|
Built-ins, application commands, and integration families share one
|
|
[installation path](registration-backend.md#one-installation-path-for-every-command)
|
|
and typed compiler. Captured metadata and invocation state have distinct owners;
|
|
the backend document defines the capture, binding, routing, and presentation
|
|
mechanics without adding another integration installation API.
|
|
- Apply the resolved [unused-binding validation boundary](registration-backend.md#resolved-unused-binding-validation-oq-1)
|
|
and [scope-error handoff](registration-backend.md#resolved-scope-error-handoff-oq-2).
|
|
The registration API incorporates the selected runnable-parent and scope-error
|
|
attachment declarations. No absence-validation overload is selected.
|
|
- Core diagnostics use a small CommandKit-owned severity type. Upstream
|
|
diagnostic conversion belongs in the integrations, preserving selected
|
|
classification, delivery, and error semantics without copying ConfigKit's
|
|
wider data model into the core.
|
|
- Version the modules independently according to their own changes and the
|
|
[release policy](../policy/release.md#versioning-and-compatibility). Do not
|
|
require integration version numbers to match either the core or upstream
|
|
dependency versions. Record selected dependencies in `go.mod` and explain
|
|
relevant upstream adoption in module release notes. Coordinate publication
|
|
when changes span modules; independent versions do not imply an exhaustive
|
|
compatibility matrix.
|
|
|
|
### Selected multi-module release approach
|
|
|
|
Adopt ReleaseKit v0.4.0 with module-release support. This is a planned tooling
|
|
upgrade from the current v0.3.0 baseline, not an implemented CommandKit capability.
|
|
Use ReleaseKit's public contracts for checking and
|
|
publishing one explicitly selected module per invocation; do not build a separate
|
|
CommandKit publication engine or temporary compatibility path.
|
|
|
|
Use one shared launcher with small per-module profiles. Each profile selects its
|
|
repository-relative module directory and product identity; each invocation
|
|
supplies that module's independently selected semantic version. ReleaseKit owns
|
|
module-tag derivation, selected-module validation, repository publication guards,
|
|
and publication outcomes. Root releases use unprefixed tags. Nested releases use
|
|
their Go module-subdirectory prefixes, and notes belong at
|
|
`<module-directory>/docs/releases/<version>.md`. Source and licensing links use
|
|
the complete Git tag, while note titles identify the product and semantic version.
|
|
|
|
Run the selected module's standard suite once with workspace mode disabled and
|
|
prepared dependencies. Repository cleanliness, branch, candidate commit, and
|
|
endpoint guards remain repository-wide. A root-module release does not implicitly
|
|
validate independently released nested modules; composition checks are selected
|
|
deliberately where needed. Keep successful source-tag publication as completion,
|
|
without CI, hosted delivery, proxy-availability, or installation gates.
|
|
|
|
CommandKit's preferred shared file inputs are repository-root `COPYRIGHT`,
|
|
`LICENSE`, and `docs/oss/attribution.md`, when present, rather than the entire
|
|
root `docs/` tree. Use v0.4.0's `validation.shared_files` field to select those
|
|
three files explicitly, as documented by ReleaseKit. Shared inputs affect enabled
|
|
file checks, not Go suite scope; resolving references does not add surrounding
|
|
directories to the inputs.
|
|
|
|
Keep module selection and profile lookup repository-relative, module-owned
|
|
validation settings and product-command execution module-relative, and diagnostic
|
|
paths repository-relative. Use the provided repository context for shared scripts.
|
|
The released [profile](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/b96262eb0ce9c8f2eb3e948a5841db2b799bc91b/docs/config.md)
|
|
and [CLI](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/b96262eb0ce9c8f2eb3e948a5841db2b799bc91b/docs/cli.md)
|
|
contracts govern profile fields, command syntax, module context, and shared-file
|
|
selection. The implementation plan specifies their adoption; no separate
|
|
publication engine is needed.
|
|
Nested-module artifact builds, hosted delivery, and batch publication are not
|
|
needed for CommandKit's source-only releases.
|
|
|
|
## Consumer examples and validation target
|
|
|
|
Three maintained public consumers demonstrate the final API:
|
|
|
|
| Adoption path | Example home | Required evidence |
|
|
| --- | --- | --- |
|
|
| Core only | `examples/core` | Typed commands/groups, presence, help/version; no optional-library imports or module requirements |
|
|
| ConfigKit only | `integrations/ckconfig/examples/simple` | Focused `AppCommand` convenience and standard config reports; no PromptKit imports or module requirements |
|
|
| ConfigKit and PromptKit | `integrations/ckprompt/examples/composed` | Combined configuration scopes, typed applicable selectors, independent scope inputs, shared state, named definition inspection, and an application-owned command |
|
|
|
|
Tests, fixtures, and benchmarks belong to the module owning their contracts.
|
|
Mixed suites are split by responsibility; root tests and examples cannot
|
|
reintroduce optional integration dependencies. Public composition checks belong
|
|
in the PromptKit integration. Relevant existing coverage is retained or rewritten
|
|
for selected behavior rather than incidental prototype API shapes.
|
|
|
|
Validation addresses package imports and each independently selected module
|
|
graph, including transitive and tool requirements. Core-only consumers exclude
|
|
both owning libraries and integrations; ConfigKit-only consumers exclude
|
|
PromptKit and its integration. Root `go test ./...` alone cannot validate nested
|
|
modules. The three modules' suites and representative public consumers provide
|
|
composition evidence without an exhaustive historical compatibility matrix.
|
|
|
|
Local workspace composition supports development; distributed manifests contain
|
|
versioned inter-module requirements, without filesystem replacements or committed
|
|
workspace files. Workspace-off prepublication checks against local intended
|
|
source establish wiring and isolation, not published-version availability.
|
|
Released consumers resolve actual independently released versions without
|
|
adjacent checkouts or consumer replacements. The implementation plan defines the
|
|
prepublication checks and ordered release handoff.
|
|
|
|
## Documentation and distribution target
|
|
|
|
Implemented GoDoc owns exact exports and error/lifetime semantics. The consumer
|
|
guide and READMEs present the final imports and optional-module selection directly;
|
|
maintained examples demonstrate it. The CLI reference retains selected operator
|
|
behavior, with registration/ownership prose matching the implemented API. Internal
|
|
inventory and contributor navigation describe implemented owners and validation.
|
|
No separate downstream prototype migration guide is required.
|
|
|
|
Each integration distributes a module-local README, project grant, complete
|
|
license texts, applicable attribution and required notices, and module-local
|
|
release notes. Required licensing material remains available in that module's Go
|
|
source distribution rather than only through an outside-module local link. The
|
|
existing grant and separately licensed material retain their terms. Repository
|
|
attribution can retain factual entries for integration material while module-local
|
|
notices identify applicable components.
|
|
|
|
Modules use independent versions. The planned core replacement is `v0.2.0`;
|
|
ckconfig and ckprompt initially use `v0.1.0`. Their dependency requirements express
|
|
that relationship explicitly. The already published root `v0.1.0` and its note
|
|
remain intact. If a planned version is occupied before preparation, select a
|
|
fresh appropriate version under the release policy. Core publication precedes
|
|
ckconfig, which precedes ckprompt; actual released dependencies and corresponding
|
|
sums are prepared for each candidate. Source-only publication still completes at
|
|
successful tag publication, without proxy-availability or installation gates.
|
|
|
|
The release procedure and CommandKit-specific release-policy adaptations describe
|
|
selected-module publication, independent versions, semantic-version note paths,
|
|
full-tag links and recovery identity, and the root shared-file selection. Release
|
|
profiles and launcher use released ReleaseKit contracts; additional delivery
|
|
services and permanent migration gates are outside the target.
|
|
|
|
## Implementation status
|
|
|
|
ADR/architecture alignment, public API design, and internal backend design are
|
|
complete. Module extraction, code refactoring, maintained consumers, validation,
|
|
current documentation, and multi-module tooling adoption are not implemented.
|
|
The [16-stage implementation plan](implementation.md) owns the sequence and
|
|
completion evidence. Earlier accepted ADR decision text remains intact.
|
|
|
|
## Scope and follow-up
|
|
|
|
This work changes packaging and integration boundaries. It does not select a
|
|
new backend, concurrent-dispatch contract, dynamic plugin system, or replacement
|
|
configuration engine. It does not lower the existing Go minimum.
|
|
|
|
Keep the PromptKit v0.13.0 and ConfigKit v0.6.0 adoption identifiable as a separate
|
|
change after extraction unless an implementation dependency justifies combining
|
|
them. Catalogs and requirement discovery are subsequent integration features.
|
|
Semantic comparison retains the upstream-contract dependency recorded in
|
|
[deferred work](deferred.md). None is needed to demonstrate module isolation.
|