318 lines
19 KiB
Markdown
318 lines
19 KiB
Markdown
# Optional integration modules
|
|
|
|
Status: module boundary accepted in ADR 0010; implementation planning remains
|
|
in progress and no module extraction has begun. The next minor ReleaseKit
|
|
release will support individual module releases; 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
|
|
migration work. The finalized [registration API](registration-api.md) owns the
|
|
selected declarations, installation semantics, and representative consumer
|
|
examples. Neither document describes these changes as implemented.
|
|
[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.
|
|
Alignment of the [architecture policy](../policy/architecture.md) remains part of
|
|
the work below. 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
|
|
|
|
CommandKit is an unreleased prototype with no downstream consumers. Give the
|
|
existing implementation zero deference when selecting the final API. 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. Complete the identified durable-document
|
|
alignment before implementing that lifetime.
|
|
- 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 the next minor ReleaseKit version 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 the forthcoming configurable list or its defaults 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.
|
|
Confirm exact profile fields, command syntax, context exposure, and shared-file
|
|
selection semantics against the released public documentation during adoption.
|
|
These are integration tasks, not remaining choices between publication engines.
|
|
Nested-module artifact builds, hosted delivery, and batch publication are not
|
|
needed for CommandKit's source-only releases.
|
|
|
|
## Work sequence
|
|
|
|
### 1. Align policy and prepare the selected API for implementation
|
|
|
|
Completed: ADR 0010 is accepted and ADR 0003 is marked partially superseded,
|
|
with its decision text preserved. The partial status follows the explicitly
|
|
authorized exception to the documentation policy for this decision.
|
|
|
|
- Use the finalized [registration API](registration-api.md) and selected module
|
|
layout as the implementation target before moving public symbols.
|
|
- Align the architecture policy with ADR 0010 and complete the registration
|
|
API document's namespace reconciliation. Review other ADRs for affected
|
|
ownership statements without reopening unrelated decisions.
|
|
- Inventory root exports, imports, private helper use, and family registration
|
|
behavior. Use the inventory as evidence of responsibilities and coupling, not
|
|
as a list of APIs to preserve. Implement final exports and ownership from the
|
|
selected API and consumer needs; no compatibility mapping for the unpublished prototype is required.
|
|
- Use the API document's [three representative consumers](registration-api.md#complete-consumer-registration-examples):
|
|
core only, ConfigKit only, and both libraries. They define the target wiring,
|
|
including combined configuration scopes and independent definition inspection;
|
|
port them into maintained examples as implementation lands.
|
|
- Prepare a staged implementation plan from this roadmap and the finalized API,
|
|
preserving the unreleased-prototype organizing principle above.
|
|
|
|
Completion: the dependency direction, final API, and registration approach
|
|
are concrete enough to implement without inventing a general plugin framework.
|
|
|
|
### 2. Extract the integrations and isolate the core
|
|
|
|
- Establish the selected module layout, preserving the existing root import
|
|
path for the core.
|
|
- Move configuration declarations, registration, handlers, reports, and
|
|
ConfigKit adapters together. Move PromptKit declarations, handlers, reports,
|
|
and its configuration-scope adapter into the PromptKit integration.
|
|
- Replace access to root-private registry state and helpers with the smallest
|
|
supported interactions needed by those integrations. Preserve duplicate
|
|
registration handling and standard-family ownership; audit these boundaries
|
|
rather than assuming package relocation preserves them automatically.
|
|
- Design core outcomes, diagnostics, bindings, and command declarations as shared
|
|
contracts for the final API. Replace ConfigKit severity in core diagnostics
|
|
with the selected CommandKit-owned type. Place report encoding and upstream
|
|
diagnostic conversion with their owners. Remove redundant prototype state and
|
|
helpers; avoid copying ConfigKit's data model merely to remove imports.
|
|
- Remove integration dependencies from the core module, including dependencies
|
|
reintroduced by its tests, examples, tools, or remaining public declarations.
|
|
Review tool dependencies for that specific objective; broad removal of all
|
|
maintainer dependencies is not a prerequisite.
|
|
- Use released inter-module requirements for consumer builds. Local workspace
|
|
composition may support development, but published modules must not depend
|
|
on sibling checkouts or consumer-applied `replace` directives.
|
|
|
|
Completion: core-only and ConfigKit-only consumers have the intended dependency
|
|
boundaries, while the composed consumer retains the existing standard commands.
|
|
|
|
### 3. Move examples and validate the consumer boundaries
|
|
|
|
- Keep a genuine core-only example with no configuration-library imports. Place
|
|
ConfigKit and composed examples, fixtures, and integration tests in modules
|
|
that can legitimately depend on those integrations. Choose their exact home
|
|
with the module layout; examples in the root module must not defeat isolation.
|
|
- Move or rewrite existing tests for their final owners and selected contracts.
|
|
Remove assertions that merely freeze incidental prototype design. Retain
|
|
coverage for typed presence, repeated invocations, registration collisions,
|
|
provider errors, report delivery, and selected CLI behavior without duplicating
|
|
every suite.
|
|
- Add focused consumer checks for the three adoption paths. Verify both package
|
|
dependencies and the selected module graph, including transitive requirements.
|
|
Core-only checks exclude both libraries; ConfigKit-only checks exclude
|
|
PromptKit. Merely observing a smaller executable is insufficient.
|
|
- Exercise combined `app` and `promptkit` configuration scopes and independent
|
|
installation of named PromptKit inspection through public APIs.
|
|
- Run each module's relevant suite. Verify ordinary module consumption with
|
|
workspace mode disabled so local workspace resolution cannot hide missing
|
|
requirements. Root `go test ./...` alone will not cover nested modules.
|
|
|
|
Completion: representative public consumers demonstrate isolation and retained
|
|
composition. These checks protect the selected boundary without requiring an
|
|
exhaustive matrix of historical dependency versions.
|
|
|
|
### 4. Prepare final API documentation and initial module releases
|
|
|
|
- Update GoDoc, the consumer guide, maintained examples, README, internal
|
|
inventory, and contributor reading guide as the implementation lands. Keep
|
|
the CLI reference unchanged except where actual behavior or relevant ownership
|
|
changes require an update. Link this roadmap from contributor navigation when
|
|
integrating it into the implementation workflow.
|
|
- Document final imports, constructors, and optional module selection directly.
|
|
Rewrite prototype guidance where necessary rather than publishing a downstream
|
|
migration guide. Prepare initial module versions and notes under the
|
|
[release policy](../policy/release.md); unpublished prototype API changes do
|
|
not require a compatibility release or a version bump solely for relocation.
|
|
- Upgrade the module-selected ReleaseKit tool to the next minor release providing
|
|
module-release support. Adopt its released public API and CLI/profile contracts
|
|
through the shared launcher and per-module profiles described above. Update
|
|
launcher checks, validation context, version/tag reporting, and recovery guidance
|
|
for selected-module publication; do not duplicate ReleaseKit-owned guards.
|
|
- Align the release policy and procedure with module-local notes, independent
|
|
versions, full-tag identity, and selected-module validation. Confirm the
|
|
documented shared-file defaults or configure the selected files explicitly.
|
|
- For nested modules, use Go's module-subdirectory tag prefixes and make
|
|
release-note paths and immutable links unambiguous. Review licensing and
|
|
attribution visibility in each distributed module under the
|
|
[OSS policy](../policy/oss.md).
|
|
- Establish publication order from module dependencies and record compatible
|
|
requirements explicitly. Published consumers must resolve actual released
|
|
versions. A local workspace is not a substitute for that release sequence.
|
|
Preserve the existing successful-source-publication completion model.
|
|
|
|
Completion: every consumer module can be released and consumed independently of
|
|
local workspace state, with documentation of the final public API and optional
|
|
integration choices.
|
|
|
|
## 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.
|