Plan the multi-module implementation sprint
This commit is contained in:
749
docs/roadmap/implementation.md
Normal file
749
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,749 @@
|
||||
# Implement the optional integration modules and captured registration API
|
||||
|
||||
Status: decision-complete plan for the module/API transition; implementation pending.
|
||||
Execute the stages in order. Each stage is sized as a separate Luna coding-agent
|
||||
assignment. This document authorizes no publication or changes to sibling
|
||||
repositories.
|
||||
|
||||
## Scope and authority
|
||||
|
||||
Deliver the target in the [module roadmap](modules.md), the exact declarations
|
||||
and behavior in the [registration API](registration-api.md), and the selected
|
||||
mechanics in the [registration backend design](registration-backend.md).
|
||||
Read [development orientation](../development.md) and its applicable policy guide
|
||||
before implementation. The [architecture policy](../policy/architecture.md) and
|
||||
accepted ADRs control if a planning instruction conflicts with them.
|
||||
|
||||
The governing decisions include [optional modules](../adr/0010-optional-integration-modules.md),
|
||||
[captured declarations](../adr/0011-captured-declarations-and-installation.md),
|
||||
[dispatch and inputs](../adr/0001-command-dispatch-and-inputs.md),
|
||||
[Cobra](../adr/0002-cobra-backend.md), [facades](../adr/0003-public-facade.md),
|
||||
[inspection families](../adr/0004-standard-inspection-surface.md),
|
||||
[outcomes](../adr/0005-invocation-outcomes.md),
|
||||
[grammar](../adr/0006-command-grammar.md), [native reports](../adr/0007-native-yaml-reports.md),
|
||||
and [configuration scopes](../adr/0009-configuration-scopes.md).
|
||||
The [CLI reference](../cli.md) supplies existing selected operator/report details;
|
||||
its prototype registration names are replaced by the finalized API.
|
||||
|
||||
Give the prototype implementation zero design priority. Implement the final
|
||||
public API directly, without forwarding wrappers, duplicate installation APIs,
|
||||
temporary compatibility adapters, or a downstream migration project. Intermediate
|
||||
commits need not compile or pass tests. Do not keep competing implementations,
|
||||
add stubs, or disable valid contract tests merely to make those commits green.
|
||||
Reuse code only where it serves the selected end state.
|
||||
|
||||
The two backend composition questions are resolved: use
|
||||
`ckconfig.WithScopeError`; ignore selector bindings unused by generated
|
||||
inspection commands while retaining adapter-construction errors. Runnable parents
|
||||
use `CommandSpec.Children`. Do not reopen these choices during implementation.
|
||||
|
||||
Keep the current inspection subset: config scopes/validate/show/sources/explain,
|
||||
PromptKit named prompt/profile show, help, and version. Do not add diff, catalogs,
|
||||
JSON output, additional integration families, a public backend interface,
|
||||
concurrency guarantees, generic configuration providers, or the other
|
||||
[deferred features](deferred.md).
|
||||
Keep ConfigKit v0.5.0, PromptKit v0.12.0, Cobra v1.10.1, pflag v1.0.9, and the
|
||||
current YAML v4 dependency; ConfigKit v0.6.0/PromptKit v0.13.0 adoption is separate.
|
||||
All three consumer modules retain Go 1.26.0. The release toolchain remains
|
||||
Go 1.26.8.
|
||||
|
||||
## Baseline and concrete delivery choices
|
||||
|
||||
The planning review found one module, integration source and examples in the
|
||||
root, ReleaseKit v0.3.0 selected as a Go tool, and a root-only release launcher.
|
||||
The [backend findings](registration-backend.md#baseline-findings) identify the
|
||||
parallel installation paths, repeated validation, mixed input/state storage, and
|
||||
help special case that this sprint replaces.
|
||||
|
||||
One factual correction to earlier planning is necessary: core `v0.1.0` is
|
||||
already published on `origin`. The observed annotated tag object is
|
||||
`27bcfc84bb15d8fcf40801e073425da71754871d`, pointing to source commit
|
||||
`9ee6ca43ef900fa89f79336c64a2f47ef323a6c8`. Preserve that tag and its release
|
||||
note. This fact does not change the selected final API or introduce compatibility
|
||||
wrappers. Under the [release policy](../policy/release.md#versioning-and-compatibility),
|
||||
prepare the incompatible core change as `v0.2.0`, with its impact explained in
|
||||
the new note. Each new integration starts at `v0.1.0`, independently versioned.
|
||||
If any intended version becomes occupied before release preparation, select the
|
||||
next appropriate unused version and update requirements/notes consistently;
|
||||
never replace a published version.
|
||||
|
||||
ReleaseKit v0.4.0 supplies the selected module-release support. Its tagged source
|
||||
is `b96262eb0ce9c8f2eb3e948a5841db2b799bc91b`. Consume its released
|
||||
[profile contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/b96262eb0ce9c8f2eb3e948a5841db2b799bc91b/docs/config.md)
|
||||
and [CLI contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/b96262eb0ce9c8f2eb3e948a5841db2b799bc91b/docs/cli.md);
|
||||
do not inspect, copy, or change its internal release machinery. Its module
|
||||
requirements do not introduce ConfigKit or PromptKit.
|
||||
|
||||
| Owner | Target artifacts and dependencies |
|
||||
| --- | --- |
|
||||
| Root module `gitea.maximumdirect.net/eric/CommandKit` | Public package `commandkit`; core commands/bindings/outcomes/dispatch, private neutral metadata, internal Cobra adapter; no ConfigKit/PromptKit requirements, imports, tests, or examples |
|
||||
| `integrations/ckconfig` | Module `gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig`, package `ckconfig`; core v0.2.0 and ConfigKit v0.5.0; no PromptKit dependency |
|
||||
| `integrations/ckprompt` | Module `gitea.maximumdirect.net/eric/CommandKit/integrations/ckprompt`, package `ckprompt`; core v0.2.0, ckconfig v0.1.0, PromptKit v0.12.0 |
|
||||
| Maintained consumers | `examples/core`, `integrations/ckconfig/examples/simple`, `integrations/ckprompt/examples/composed` |
|
||||
| Publication tooling | One root-selected ReleaseKit v0.4.0 tool, `scripts/release`, and `releasekit.json` in each module directory |
|
||||
| Distribution documentation | Root canonical guides plus module-local READMEs, grants, license texts, applicable attribution, and release notes in each integration |
|
||||
|
||||
The file layout within an owning package can follow cohesive responsibilities.
|
||||
Keep most core logic private in the root; create `internal/commandmeta` for the
|
||||
existing neutral core/adapter exchange, without copying the same DTOs into
|
||||
another layer. No fourth utility module is planned.
|
||||
|
||||
Dependency exclusions concern CommandKit-owned packages/modules and the
|
||||
purpose-built consumer checks. They do not prohibit applications from importing
|
||||
other libraries for their own domain behavior or using those types in caller-owned
|
||||
inputs and state.
|
||||
|
||||
## Working and validation rules for the sprint
|
||||
|
||||
- Follow stages sequentially and commit each completed nonempty unit under the
|
||||
[agent policy](../policy/agents.md#git-commit-policy). Record completed-stage
|
||||
evidence in the implementation report; do not declare later stages complete
|
||||
because a partial module happens to build.
|
||||
- Before code discovery, prefer the repository knowledge graph. Inventory exports
|
||||
and callers as evidence, not as an API-preservation list.
|
||||
- Move or rewrite existing tests with their owner as code lands. Add focused
|
||||
evidence for the selected new contracts where existing tests do not cover them;
|
||||
use public boundaries where useful and narrowly scoped internal checks where
|
||||
they protect important mechanics. Do not freeze exact error prose, private
|
||||
function names, allocation counts, aggregate-error representation, or incidental
|
||||
backend defaults. Follow the [testing policy](../policy/testing.md).
|
||||
- Run focused tests once the affected owner compiles. Stage 16 supplies the full
|
||||
end-state validation. Format changed Go files. Update GoDoc as exports land;
|
||||
current prose owners are reconciled after the complete API exists.
|
||||
- Use an ignored local `go.work` composing these three modules during
|
||||
development. Preserve unrelated local workspace content; do not commit
|
||||
`go.work`/`go.work.sum` or filesystem replacements in distributed manifests.
|
||||
Sibling ConfigKit, PromptKit, and ReleaseKit checkouts are review evidence, not
|
||||
consumer/build dependencies.
|
||||
- Final manifests require the actual intended versions. The new core/integration
|
||||
versions are not published during this sprint. Workspace-off prepublication
|
||||
validation therefore uses disposable alternate module files as specified in
|
||||
Stage 16. Report its limits honestly; a local workspace is not evidence that
|
||||
a future version is already downloadable.
|
||||
- This plan selects one-time migration checks. Do not silently turn them into
|
||||
extra permanent publication gates. ReleaseKit retains one selected-module
|
||||
offline default suite per publication invocation.
|
||||
|
||||
## Stage 1: Establish module ownership and move integration material
|
||||
|
||||
**Outcome:** the three module boundaries and source owners exist, with no
|
||||
compatibility relocation layer.
|
||||
|
||||
1. Create the two nested module directories and their `go.mod` files with the
|
||||
exact paths, package names, Go minimum, and versioned requirements above.
|
||||
Leave the root module/import path intact. Keep package documentation with
|
||||
each public facade.
|
||||
2. Move configuration-owned material from `config.go`, `selectors.go`,
|
||||
`validate.go`, `show.go`, `sources.go`, and `explain.go` into ckconfig.
|
||||
Treat these as source to refactor into the selected API, not exports to retain.
|
||||
3. Move `promptkit.go` and `promptkit_scope.go` into ckprompt. Its scope adapter
|
||||
may import ckconfig, never the reverse. Remove the root integration surface.
|
||||
4. Relocate configuration and PromptKit tests/fixtures with their owning module.
|
||||
Split mixed `cancellation_test.go` and `performance_reports_test.go`
|
||||
responsibilities. Core dispatch/binding/registry/outcome and Cobra tests stay
|
||||
in the root. Retain useful benchmarks without requiring numerical targets.
|
||||
5. Move the old `examples/simple` to ckconfig's `examples/simple` and the old
|
||||
`examples/composed` to ckprompt's `examples/composed`, including READMEs.
|
||||
Create the genuine core consumer in Stage 13. No optional-library consumer
|
||||
remains inside the root module.
|
||||
6. Establish the ignored development workspace if useful. Do not mechanically
|
||||
tidy partially refactored packages or add temporary root re-exports. Final
|
||||
manifests and sums are reviewed after their owners compile.
|
||||
|
||||
**Completion evidence:** inspect source/test/example ownership and the three module
|
||||
declarations. Explain any shared test split. Compilation is not required here.
|
||||
|
||||
## Stage 2: Implement core-owned values and immutable declarations
|
||||
|
||||
**Outcome:** the core captures the selected public declarations and owns its
|
||||
neutral diagnostic/outcome model.
|
||||
|
||||
1. Replace ConfigKit severity in `Diagnostic` with the selected core `Severity`
|
||||
and warning/error constants. Provide `Acquired[T]` and retain the selected
|
||||
`Identity`, `Streams`, `Invocation`, `Supplied[T]`, outcome fields, and
|
||||
outcome/delivery behavior. Move upstream conversion to its integration owner.
|
||||
Do not replace caller-facing error identity or domain outcomes.
|
||||
2. Implement the infallible `NewCommand[I]`, `Group`, `RootGroup`,
|
||||
`WithError`, and `NoCommand` signatures from the API document. Use an opaque
|
||||
handle to a private captured record containing metadata, children, typed
|
||||
payload, retained issues, placement, and absence.
|
||||
3. Capture `CommandSpec.Children` and binding/argument metadata slices. Copy
|
||||
caller-owned collections at capture, sharing already immutable child records.
|
||||
Do not recursively clone every subtree at each ancestor.
|
||||
4. Preserve runnable parents with children. Group is the non-runnable convenience.
|
||||
Capture local declaration errors and immediate composition defects; leave
|
||||
contextual placement and occupied-name checks for installation.
|
||||
5. `WithError` retains earlier causes and markers in a new record without
|
||||
mutating the original. Installation must distinguish zero declarations from
|
||||
explicit absence. A real empty root-only group is still real.
|
||||
6. Ensure declarations contain no registry paths, installed-state cache, converted
|
||||
values, or general app pointer. App-specific built-ins are constructed for
|
||||
their app later; ordinary declarations remain reusable.
|
||||
|
||||
**Completion evidence:** focused capture/error checks cover source-slice edits,
|
||||
copied handles, prior/wrapped causes, root-only metadata, nested no-ops, invalid
|
||||
zero values, and runnable children. Do not promise arbitrary object deep copies.
|
||||
|
||||
## Stage 3: Unify typed flag and argument conversion
|
||||
|
||||
**Outcome:** ordinary bindings use one prepared-value mechanism.
|
||||
|
||||
1. Refactor `binding.go` around the finalized `ValueFlag`, `BoolFlag`,
|
||||
`RepeatFlag`, `ValueArgument`, and `RepeatArgument` signatures.
|
||||
Capture defaults/metadata and retain nil parser/setter or cardinality defects
|
||||
as construction issues rather than returning factory errors.
|
||||
2. Give each original binding a private nonzero-sized identity token. Copies
|
||||
retain the token; independently constructed lookalikes receive different
|
||||
identities. No public ID or process-global registry is needed.
|
||||
3. Prepare typed application closures from raw occurrences before input creation.
|
||||
Convert every supplied occurrence once. Preserve singleton last-value behavior,
|
||||
failure of earlier malformed occurrences, repeated ordering, comma-containing
|
||||
values, explicit empty/false/zero presence, and selected defaults.
|
||||
4. Apply prepared values to initialized storage without reconversion. Clone
|
||||
core-owned repeatable slices on each application; do not clone arbitrary
|
||||
parsed elements, callback objects, or pointer graphs.
|
||||
5. Keep operand allocation/cardinality and execution-required checks separate
|
||||
from metadata-only help conversion. All supplied malformed input still fails
|
||||
on help, but missing execution-required input does not.
|
||||
6. Use one core implementation of binding metadata validation, including
|
||||
combined names, short names, duplicate bindings, and help conflicts. Avoid
|
||||
integration-specific reserved-flag lists.
|
||||
|
||||
**Completion evidence:** existing presence/repetition/help tests, adjusted to the
|
||||
selected constructors, plus focused converter call counts and repeated-slice
|
||||
independence. Do not add a new grammar restriction.
|
||||
|
||||
## Stage 4: Implement captured flag application
|
||||
|
||||
**Outcome:** integrations compose typed inputs without parser/setter access.
|
||||
|
||||
1. Implement opaque `FlagValues[I]`, `CaptureFlags[Outer, I]`, and
|
||||
`FlagValues.ApplyTo` exactly as selected. Capture original handles and target
|
||||
accessors eagerly; retain invalid inner bindings/nil accessors for installation.
|
||||
2. Adapt the Stage 3 prepared entries into an invocation-local identity lookup.
|
||||
Conversion records values/defaults/presence, without constructing suite input
|
||||
or applying selectors to a shared template.
|
||||
3. Apply only selected original bindings to `*I`. Copied handles work; lookalikes,
|
||||
uncaptured selections, or nil destinations match `ErrFlagWiring`. A zero
|
||||
store with no selected bindings is valid for a valid destination.
|
||||
4. Defer captured inner required checks to the selected subset at `ApplyTo`.
|
||||
Preserve required help metadata. Missing required supplied values match
|
||||
`ErrFlagInput`. Core-owned repeated collections are fresh per application.
|
||||
5. Add the two public sentinel categories and common wrapped-error classification:
|
||||
wiring failures from `CheckInput` are operational; missing input and ordinary
|
||||
input-validation failures are usage. These paths stop before state/acquisition.
|
||||
6. Help converts supplied values through the same machinery but does not
|
||||
materialize or apply the target's input. Scope inapplicability never skips
|
||||
supplied-value conversion.
|
||||
|
||||
**Completion evidence:** original/copied/lookalike identity, defaults and presence,
|
||||
selected required flags, wrapped errors, nil destination, empty selection,
|
||||
repeatable independence, and no second conversion. Check both ordinary and
|
||||
captured bindings through the same preparation path.
|
||||
|
||||
## Stage 5: Compile typed runners and real built-in declarations
|
||||
|
||||
**Outcome:** built-ins and ordinary commands share capture and typed execution.
|
||||
|
||||
1. Replace the prototype factory/check/run `any` payload handoffs with a private
|
||||
compiled runner retaining `I` inside one typed invocation closure. Conversion
|
||||
precedes materialization; then initialize once, apply values, call `CheckInput`,
|
||||
and run the selected handler.
|
||||
2. Omitted `NewInput` yields the exact zero value. Do not allocate arbitrary
|
||||
pointers, repair aliases, catch arbitrary caller panics, or clone closure state.
|
||||
3. Provide a narrow private execution context containing invocation streams,
|
||||
cancellation, and current core presentation access. Public callbacks receive
|
||||
only the selected `Invocation` and `I`.
|
||||
4. Construct real help and version declarations using this same capture/compiler.
|
||||
Help's final private callback can access presentation through that context;
|
||||
it is not a second compiler or a path-name branch. Explicit help may create
|
||||
its own private input, leaving all target factories/checks/handlers untouched.
|
||||
5. Retain help targets, bare/group help, runnable-parent behavior, and version
|
||||
semantics from the CLI reference. Default version is application identity;
|
||||
`--scope commandkit` uses embedded module build information. Text/YAML choices
|
||||
and development/replacement identity behavior stay selected.
|
||||
6. Keep core outcome presentation in one coordinator, preserving supported causes,
|
||||
custom domain statuses, warning behavior, delivery bookkeeping, cancellation,
|
||||
and writer failures. Backend parse errors become neutral usage diagnostics;
|
||||
public results must not expose Cobra/pflag types.
|
||||
|
||||
**Completion evidence:** factories/checks/handlers execute only on the selected
|
||||
ordinary path; target callbacks remain untouched by help/version. Writer failure
|
||||
and wrapped wiring classifications retain causes. Stage 7 completes routing.
|
||||
|
||||
## Stage 6: Make batch installation the sole registry mutation path
|
||||
|
||||
**Outcome:** `New` and `Register` install all command sources atomically per call.
|
||||
|
||||
1. Implement one private batch installer used by both public operations.
|
||||
`New` validates identity, creates an unpublished empty app, constructs its
|
||||
real built-ins, and submits built-ins plus caller declarations in one batch.
|
||||
2. Inspect retained issues before skipping absence, including nested absence.
|
||||
Traverse captured real nodes once for contextual paths/placement and structural
|
||||
issues. Reuse captured local binding validation rather than running parsers
|
||||
or factories.
|
||||
3. Check sibling/root collisions, occupied roots, and pending-batch roots.
|
||||
`RootGroup` is rejected below root independent of its name. Real help/version
|
||||
nodes supply their reservation; installed real integration roots supply theirs.
|
||||
4. Stage only additions in a pending map and commit after the entire batch succeeds.
|
||||
A failed `New` exposes no app; a failed `Register` leaves registry and derived
|
||||
metadata intact. Separate successful calls are not one transaction.
|
||||
5. Invalidate derived metadata once for a successful nonempty batch. No-op-only
|
||||
batches leave it intact. Do not copy the existing registry or insert/rollback.
|
||||
6. Remove placeholders, direct built-in registry writes, special installers,
|
||||
`configRegistered`, integration collision prechecks, and root namespace
|
||||
allowlists. Integration factories install through the public declaration path.
|
||||
|
||||
**Completion evidence:** conflicting roots in either order, invalid final batch
|
||||
member, nested root-only commands, no-op errors, explicit absence, empty real
|
||||
groups, and declaration reuse across two apps. Inspect that registry writes have
|
||||
one boundary, without making its private name a public contract.
|
||||
|
||||
## Stage 7: Connect neutral routing, Cobra sessions, and execution
|
||||
|
||||
**Outcome:** one routing snapshot/session selects the compiled runner and supplies
|
||||
help/usage presentation.
|
||||
|
||||
1. Move existing neutral command/help/binding/parse DTOs from `internal/cobra`
|
||||
to `internal/commandmeta`. Add private snapshot-local command keys as needed.
|
||||
Public facade types remain owned declarations, not aliases to these DTOs.
|
||||
2. Build one cached neutral snapshot and matching key-to-runner table from the
|
||||
committed registry. Sort/project metadata when rebuilding, not on every parse.
|
||||
Preserve Stage 6 invalidation behavior.
|
||||
3. Build a fresh mutable Cobra session per execution and reuse it for parsing,
|
||||
help, and usage. Do not cache mutable Cobra flags across invocations or add
|
||||
hidden command families.
|
||||
4. Return the selected neutral key, path, and raw occurrences from the adapter.
|
||||
Execute against the runner table belonging to that session; remove the second
|
||||
`commandAt` path resolution. Keys are private and meaningful only within
|
||||
their snapshot.
|
||||
5. Complete the Stage 5 coordinator for parse/conversion/required/input/run/help
|
||||
paths and common outcome presentation. Remove the explicit `path == "help"`
|
||||
input assertion and competing prototype payload path.
|
||||
6. If a callback registers commands and later presentation needs current metadata,
|
||||
refresh presentation on demand without reparsing argv or replaying callbacks.
|
||||
Do not interpret an old key with a newly rebuilt table.
|
||||
7. Preserve local flags after the complete command path, interspersed operands,
|
||||
`--`, short help, malformed-input behavior, and public error isolation.
|
||||
|
||||
**Completion evidence:** run the now-complete core and adapter suites. Exercise
|
||||
registration followed by help, callback-driven metadata refresh without replay,
|
||||
runnable parents, repeated execution with fresh values, cancellation, and public
|
||||
outcome delivery. No concurrency or snapshot-isolation guarantee is added.
|
||||
|
||||
## Stage 8: Implement configuration contracts and native ConfigKit adapters
|
||||
|
||||
**Outcome:** ckconfig owns its exact public types, retained errors, and native views.
|
||||
|
||||
1. Implement `Selection`, `Operation` (Validate/Show/Sources/Explain),
|
||||
`Request`, `View` and its three facets, `Scope[I, S]`,
|
||||
`Selector[I]`, and `Suite[I, S]` from the finalized API. Keep ConfigKit-shaped
|
||||
records/paths here, with no neutral copies in the core.
|
||||
2. Implement `WithScopeError` as immutable retained-error attachment. Preserve
|
||||
earlier causes and supported wrapping across copies and operation narrowing;
|
||||
nil error preserves the scope. Do not mutate the original scope.
|
||||
Scope metadata is still captured by `Command`, not by this error-attachment
|
||||
operation; it introduces no new declaration lifecycle.
|
||||
3. Implement `FromConfigKit[I, S, T]` with the original typed loader and the
|
||||
four native supported operations. Validate original nil wiring before wrapping
|
||||
it; retain that cause even if callers later clear operations.
|
||||
4. Adapt the loaded result to native effective/source/explanation facets, preserving
|
||||
safe snapshots, redaction, provenance, validation diagnostics, and error
|
||||
identity. Do not acquire during construction or reconstruct reports from
|
||||
runtime structs/YAML reparsing.
|
||||
5. Put ConfigKit diagnostic conversion and source-legend handling here using
|
||||
core-owned severity. Preserve diagnostics returned with failures and appropriate
|
||||
warning/error behavior; caller-owned effects remain caller-owned.
|
||||
|
||||
**Completion evidence:** adapter metadata without loader calls, native view facets,
|
||||
nil original loaders, retained scope causes after repeated attachments/narrowing,
|
||||
diagnostic provenance and warning/error mapping, and public signature ownership.
|
||||
|
||||
## Stage 9: Assemble configuration families and prepare selected inputs
|
||||
|
||||
**Outcome:** one eager family factory supplies capability-driven commands and one
|
||||
invocation-local preparation path.
|
||||
|
||||
1. Implement `ckconfig.Command[I, S]` as a captured `RootGroup("config", ...)`.
|
||||
Capture scope records, operation/applicability lists, callbacks, ordered discovery
|
||||
metadata, scope lookup, and original applicable selector handles.
|
||||
2. Validate scope identifiers/duplicates, operations, applicability references,
|
||||
enabled acquisition wiring, and retained adapter issues. No named scopes is
|
||||
invalid; named metadata-only scopes are valid and produce discovery.
|
||||
3. Generate each inspection verb if at least one scope supplies it. `config scopes`
|
||||
lists actual capabilities in app/promptkit/other alphabetical order without
|
||||
input/state/provider calls. It supports the selected text/YAML reports.
|
||||
4. Use a private pointer-shaped outer command input holding standard selection,
|
||||
scope/format/path values, `FlagValues[I]`, and the prepared operation plan.
|
||||
Its own factory is separate from the suite factories. Add selector flags with
|
||||
`CaptureFlags` and ordinary standard bindings.
|
||||
5. Validate only selector bindings needed by generated inspection commands. Ignore
|
||||
bindings unused by all such commands; still validate scope/applicability
|
||||
references, enabled wiring, and retained adapter issues. Let core command
|
||||
construction check generated standard/selector flag conflicts.
|
||||
6. In shared `CheckInput` preparation, resolve operation, requested scopes,
|
||||
aggregate availability, format, and operand/path requirements from metadata.
|
||||
Default inspection scope is app; all selects every registered scope only for
|
||||
validate/show. Reject unsupported coverage before suite factories/providers,
|
||||
without skipping an unsupported scope.
|
||||
7. For each selected scope, initialize `I` independently (factory or zero),
|
||||
apply only its original applicable handles, and call
|
||||
`CheckInput(scopeName, selection, input)`. Retain successful records on the
|
||||
same outer pointer. Stop after failure; later inputs need not be initialized.
|
||||
8. When Run reaches acquisition after all applicable input checks, initialize
|
||||
one `S` (factory or zero) and share it explicitly across selected providers.
|
||||
Do not copy/project a common input pointer, clear inapplicable fields, rerun
|
||||
selection, or store an invocation plan in a declaration closure.
|
||||
9. Preserve supplied but inapplicable conversion and selected required checks.
|
||||
Missing/unknown scope/format/path failures are usage; wrapped wiring is
|
||||
operational.
|
||||
10. Implement `AppCommand[T](load)` through this same scope/suite factory with
|
||||
the standard app description and state-free private assembly. Its consumer
|
||||
needs no placeholder input/state types or forwarding wrapper. A nil loader
|
||||
retains a config/app construction error.
|
||||
|
||||
**Completion evidence:** metadata-only suites, no scopes, partial capabilities,
|
||||
all preflight, unused bindings versus invalid adapters, scope-aware validation,
|
||||
independently initialized pointer inputs, preserved initialized inapplicable
|
||||
fields, shared state once, and no callbacks on discovery/help/version.
|
||||
|
||||
## Stage 10: Port configuration reports with operation-specific timing
|
||||
|
||||
**Outcome:** the standard handlers retain selected native reports and delivery
|
||||
semantics under the new prepared input/state model.
|
||||
|
||||
1. Port validate/show/sources/explain handlers from the relocated baseline, using
|
||||
Stage 9 prepared records. Share preparation and mundane private helpers;
|
||||
retain separate acquisition/report loops where their timing differs.
|
||||
2. Validate defaults to text and supports YAML. Emit successful scope records
|
||||
in selected order; stop on acquisition/validation/output failure. Earlier
|
||||
successful records may remain. Warnings alone permit success.
|
||||
3. Show accepts YAML only. Acquire every selected view and verify required
|
||||
effective writers before any report output. Single-scope output remains native
|
||||
unchanged; all-scope output preserves native YAML document markers, comments,
|
||||
inline marker content, and selected scope boundary labeling.
|
||||
4. Preserve existing framing code where useful. Do not decode/re-encode native
|
||||
effective output or introduce a streaming redesign. Provider failure leaves
|
||||
report output empty; rendering/write failure may leave a prefix and marks
|
||||
incomplete report delivery.
|
||||
5. Sources is single-scope, text/YAML, defaults text, and reads the native source
|
||||
inventory once. Preserve field values/order, zero coordinates, synthetic
|
||||
sources, import locations, and explicit empty collections from the CLI reference.
|
||||
6. Explain is single-scope, text/YAML, defaults text, and requires a JSON Pointer
|
||||
`--path`. Explicit empty selects root. Malformed pointers fail as usage before
|
||||
acquisition; well-formed unknown paths fail operationally. Text uses the
|
||||
native writer; YAML retains safe effective/history/provenance/secret-reference
|
||||
fields and explicit empty lists.
|
||||
7. Preserve diagnostics and wrapped provider/cancellation causes across every
|
||||
operation. Return public outcomes/envelopes for core presentation. Distinguish
|
||||
diagnostic writer failure from incomplete report delivery without reporting
|
||||
the same diagnostic twice.
|
||||
|
||||
**Completion evidence:** port representative native fixtures and writer/provider
|
||||
failure tests, including aggregate preacquisition, marker edge cases, warning-only
|
||||
validation, source facet calls, pointer parsing, historical redaction, and
|
||||
cancelled acquisition. Run the complete ckconfig suite when coherent.
|
||||
|
||||
## Stage 11: Implement PromptKit engine and scope adapters
|
||||
|
||||
**Outcome:** ckprompt composes engine configuration through ckconfig and named
|
||||
inspection through PromptKit's released public APIs.
|
||||
|
||||
1. Implement `PromptRequest`, `ProfileRequest`, and `Suite[I, S]` with the
|
||||
exact selected types. Definition selectors are ordinary core flags;
|
||||
selection is ckconfig's type.
|
||||
2. Implement `ConfigScope[I, S]` returning an ordinary ckconfig scope named
|
||||
promptkit, with native engine effective/source/explanation/validation facets.
|
||||
It does not construct a configuration family or install anything.
|
||||
3. Inspect original loader wiring before wrapping it. Attach scope construction
|
||||
issues with `ckconfig.WithScopeError`; nil loader must remain invalid after
|
||||
its operation list is cleared. Do not access ckconfig private state.
|
||||
4. Implement `FromEngine[I, S]` with captured named inspection callbacks and
|
||||
private retained loader issues. Clearing both callbacks does not erase an
|
||||
original nil-loader error.
|
||||
5. Share private engine acquisition and diagnostic adaptation where the upstream
|
||||
contract is the same. Pass context, selection, typed input, and state explicitly.
|
||||
Preserve lookup diagnostics when native lookup fails and supported errors.
|
||||
6. Pass prompt version values through to PromptKit with its existing empty/default
|
||||
selection semantics; custom providers retain the presence field. CommandKit's
|
||||
adapter code does not probe credentials, contact model providers, execute prompts,
|
||||
or infer definition catalogs. Application loader/callback effects remain
|
||||
application-owned; do not intercept or constrain them.
|
||||
|
||||
**Completion evidence:** native engine configuration through public ckconfig
|
||||
facets, both adapters' nil wiring and retained errors, callback narrowing,
|
||||
diagnostics on lookup failure, and no construction-time acquisition.
|
||||
|
||||
## Stage 12: Assemble named PromptKit inspection and reports
|
||||
|
||||
**Outcome:** independent optional prompt/profile commands use the core pipeline.
|
||||
|
||||
1. Implement `ckprompt.Command[I, S]` with a root-only promptkit tree containing
|
||||
`show prompt` and/or `show profile` for supplied callbacks. Do not add
|
||||
list/catalog commands.
|
||||
2. If both callbacks are absent, return plain `NoCommand()` with any retained
|
||||
adapter issues attached via `WithError`. Ignore unused selector bindings;
|
||||
no command, help entry, or namespace remains. If a capability exists, capture
|
||||
needed selectors and let core validate generated bindings.
|
||||
3. Use a private definition-input preparation helper with `CaptureFlags`.
|
||||
Convert once, initialize suite input once, apply its selected complete flag
|
||||
set, and run scope-free `CheckInput(selection, input)`. Initialize shared
|
||||
state once only after preflight/input checks succeed, then call the selected
|
||||
inspection callback once.
|
||||
4. Preserve required ID operand, `--config`, `--overlay`, prompt-only
|
||||
`--version`, and text/YAML `--format` defaulting to text. There is no built-in
|
||||
`--scope`. Missing ID is usage; blank/unknown/ambiguous selections reach native
|
||||
lookup rather than an invented blank-ID check.
|
||||
5. Port prompt/profile report models and text/YAML writers from the baseline,
|
||||
preserving selected field values, input order, zero values, empty lists,
|
||||
opaque hashes, and nested ExtraParams. ExtraParams are not a redaction target;
|
||||
nil maps render as `{}`.
|
||||
6. Report only native credential environment-variable names and requirement
|
||||
information, without value resolution or availability claims. Preserve
|
||||
provider/lookup/cancellation causes, diagnostics, and partial-write bookkeeping.
|
||||
7. Keep engine configuration scope and definition family independently selectable.
|
||||
No import, adapter, or definition registration silently installs config.
|
||||
|
||||
**Completion evidence:** prompt-only/profile-only/both/empty trees, empty invalid
|
||||
adapter, unused malformed binding, actual installed namespace collisions,
|
||||
definition input/state lifetimes, native report fields, unknown/blank lookup,
|
||||
ExtraParams, and failed output. Run the complete ckprompt suite when coherent.
|
||||
|
||||
## Stage 13: Finish maintained consumers and module boundary evidence
|
||||
|
||||
**Outcome:** all three adoption paths use the final public API with appropriate
|
||||
dependency ownership.
|
||||
|
||||
1. Implement `examples/core` using typed core declarations, an ordinary domain
|
||||
group/runnable command, presence and repeated values, help, and version.
|
||||
It imports neither optional library nor optional integration.
|
||||
2. Rewrite ckconfig's simple example using `AppCommand`, with no dummy input/state
|
||||
types at its consumer call site. Retain a useful typed application command.
|
||||
3. Rewrite ckprompt's composed example using the finalized
|
||||
[three consumer examples](registration-api.md#complete-consumer-registration-examples)
|
||||
as API evidence: combined app/promptkit configuration scopes, applicable typed
|
||||
selectors, scope-aware checks, pointer input isolation, shared app-owned state,
|
||||
independent named inspection, and `session restore`.
|
||||
4. Keep examples runnable without real credentials, inference, or mutable services.
|
||||
Example loaders demonstrate application ownership without requiring every
|
||||
downstream application to use the same cache/loading architecture.
|
||||
5. Finish relocations and remove obsolete core/config/PromptKit constructor tests
|
||||
or assertions that solely freeze prototype shape. Retain focused regression
|
||||
coverage for parsing/presence, batch errors, lifetimes, cancellation, safe native
|
||||
reports, upstream error identity, diagnostics and report delivery.
|
||||
6. Place public cross-integration composition tests in ckprompt. Root tests/tools
|
||||
must not import nested integrations to obtain broader coverage.
|
||||
7. Compile/run the three maintained consumers and inspect package dependencies
|
||||
including test variants. Prepare the independent module graph checks in
|
||||
Stage 16; do not mistake workspace-combined graphs for isolation evidence.
|
||||
|
||||
**Completion evidence:** examples use only selected public contracts; core-only
|
||||
and ConfigKit-only package imports exclude their forbidden libraries. The
|
||||
composed consumer demonstrates both standard families and an application-owned
|
||||
command. No historical dependency-version matrix is required.
|
||||
|
||||
## Stage 14: Adopt ReleaseKit v0.4.0 and selected-module publication
|
||||
|
||||
**Outcome:** one shared launcher delegates source-only releases for each module.
|
||||
|
||||
1. Upgrade only the root-selected Go tool to ReleaseKit v0.4.0 and tidy its tool
|
||||
requirements when root packages compile. Do not introduce a runtime ReleaseKit
|
||||
import or duplicate tool requirements in integrations. Remove optional-library
|
||||
dependencies formerly reintroduced through the tool graph.
|
||||
2. Keep root `releasekit.json` and add a profile in each integration directory.
|
||||
Use this exact selection table:
|
||||
|
||||
| Launcher selector | Product | `module_dir` | Profile |
|
||||
| --- | --- | --- | --- |
|
||||
| `core` | `CommandKit` | `.` | `releasekit.json` |
|
||||
| `ckconfig` | `CommandKit ckconfig` | `integrations/ckconfig` | `integrations/ckconfig/releasekit.json` |
|
||||
| `ckprompt` | `CommandKit ckprompt` | `integrations/ckprompt` | `integrations/ckprompt/releasekit.json` |
|
||||
|
||||
3. Each profile sets `remote: origin`,
|
||||
`expected_push_url: https://gitea.maximumdirect.net/eric/CommandKit.git`, and
|
||||
`validation.shared_files` explicitly to root `COPYRIGHT`, `LICENSE`, and
|
||||
`docs/oss/attribution.md`. These are file inputs, not extra Go scope/checks.
|
||||
Do not select builds, delivery, batch publication, race/vet/platform passes,
|
||||
Markdown/file-size gates, or duplicate standard suites in `checks`.
|
||||
4. Change the launcher to exactly `./scripts/release MODULE VERSION`, using
|
||||
the three selectors above. Reject invalid selector/argument count with usage
|
||||
status 2 before bootstrap. No compatibility one-argument invocation is needed.
|
||||
5. Resolve root/profile/module from the script's own location. Bootstrap the
|
||||
module-selected native ReleaseKit from the root with readonly modules,
|
||||
host GOOS/GOARCH, `GOWORK=off`, and `GOTOOLCHAIN=local`, retaining ignored
|
||||
`.releasekit/bin` storage. Apply workspace-off/local-toolchain settings to
|
||||
delegated publication too.
|
||||
6. Delegate with options preceding VERSION:
|
||||
|
||||
`releasekit publish --repo ROOT --config PROFILE --expected-module MODULE_DIR VERSION`
|
||||
|
||||
The profile owns module selection; expected-module checks the launcher's
|
||||
routing. ReleaseKit derives full tags from the selected physical module and
|
||||
declared path. Preserve its exit status and reporting; do not duplicate
|
||||
semantic-version parsing, candidate checks, tag derivation, endpoint guards,
|
||||
or ambiguous-push reconciliation.
|
||||
7. Update the existing fake-Go launcher tests for all selectors, paths containing
|
||||
spaces, invalid input, module guard/profile selection, environment propagation,
|
||||
and delegated status. Adapt the existing opt-in disposable-Git publication
|
||||
exercise to include a nested module with a distinct prefixed tag and module
|
||||
note. Default tests remain offline and do not publish.
|
||||
|
||||
**Completion evidence:** ordinary launcher tests pass without network/publication.
|
||||
The optional disposable exercise demonstrates one root and one nested module;
|
||||
run it only when its dependencies are prepared. A sibling checkout or ad hoc
|
||||
ReleaseKit source build is not the selected consumer tool.
|
||||
|
||||
## Stage 15: Reconcile documentation, licensing, and release preparation
|
||||
|
||||
**Outcome:** current docs describe the implemented API and each module distributes
|
||||
its own usable licensing and release material.
|
||||
|
||||
1. Finish exported GoDoc for the three facades, with exact ownership, retained
|
||||
error behavior, input/state timing, binding identity, and installation semantics.
|
||||
Rewrite the root README/consumer guide to present final imports and optional
|
||||
modules directly. Replace prototype instructions; do not add a separate
|
||||
downstream migration guide or preserve old Go names.
|
||||
2. Update the CLI reference's registration/ownership prose to the implemented
|
||||
factories. Keep selected operator/report behavior; acquisition/state descriptions
|
||||
must match the implemented lifetimes, without prescribing caller internals.
|
||||
3. Update internal overview and developer reading guide for implemented module
|
||||
owners, shared compiler/installer, neutral metadata/session exchange, example
|
||||
locations, and explicit three-module validation. Follow canonical ownership;
|
||||
link rather than duplicate volatile contracts.
|
||||
4. Give each integration a module-local README and actual `COPYRIGHT`/`LICENSE`
|
||||
plus applicable `docs/oss/attribution.md` and required local license/notice texts.
|
||||
Preserve the existing project grant, holders, years, verbatim LGPL/GPL texts,
|
||||
and applicable third-party terms. Adapt scope/name only where needed.
|
||||
5. Review attribution by actual module/tool/material scope, updating ReleaseKit's
|
||||
version/source. Root repository attribution can retain clearly identified
|
||||
integration entries; module-local notices identify their relevant dependencies.
|
||||
No integration module may depend on an out-of-zip symlink or only a root-local
|
||||
link for required distributed notices. Root canonical guides may be linked
|
||||
through repository URLs for broader guidance.
|
||||
6. Update CommandKit-specific release-policy adaptations and the release procedure
|
||||
for independent versions, selected physical module, semantic-version note
|
||||
filenames under each module, and complete tag identity in links/recovery.
|
||||
Preserve accepted ADR text and general release integrity/completion rules.
|
||||
Document the three selectors, v0.4.0 public contracts, default suite once per
|
||||
selected module, selected root shared files, and existing source-only endpoint.
|
||||
7. Prepare new notes:
|
||||
|
||||
| Note | Product/title version | Full tag for immutable links |
|
||||
| --- | --- | --- |
|
||||
| `docs/releases/v0.2.0.md` | CommandKit v0.2.0 | `v0.2.0` |
|
||||
| `integrations/ckconfig/docs/releases/v0.1.0.md` | CommandKit ckconfig v0.1.0 | `integrations/ckconfig/v0.1.0` |
|
||||
| `integrations/ckprompt/docs/releases/v0.1.0.md` | CommandKit ckprompt v0.1.0 | `integrations/ckprompt/v0.1.0` |
|
||||
|
||||
Explain core API replacement and new optional imports without claiming unchanged
|
||||
compatibility. Each footer uses its full tag and actual module-local grant,
|
||||
license, and attribution paths. Preserve the existing core v0.1.0 note.
|
||||
8. Document publication order: core, then ckconfig, then ckprompt. Prepare/download
|
||||
each selected module's released dependencies and commit any resulting sums
|
||||
before that module's real candidate publication. A root publication need not
|
||||
run independently released integration suites.
|
||||
9. Do not push, create release tags, invoke real publication, or wait for CI/proxy
|
||||
availability in this implementation sprint. In ambiguous publication recovery,
|
||||
use the reported exact endpoint, full tag, and annotated tag object. Successful
|
||||
source-tag publication remains release completion.
|
||||
|
||||
**Completion evidence:** inspect affected current docs, examples, local links,
|
||||
module-local licensing contents and source links, note titles/full-tag footers,
|
||||
and policy/procedure agreement. Future tag URLs need not resolve. Release preparation
|
||||
is complete without claiming that unpublished dependencies already resolve remotely.
|
||||
|
||||
## Stage 16: Validate the complete end state and finish the sprint
|
||||
|
||||
**Outcome:** the full API, module boundaries, composition, documentation, and
|
||||
publication wiring are verified with no compatibility scaffolding.
|
||||
|
||||
1. Audit all three export sets against the finalized API and implemented selected
|
||||
contracts. Inspect imports and private ownership: integrations use public core
|
||||
declarations only; ckprompt uses public ckconfig scope/error operations;
|
||||
Cobra/pflag stay internal; core has no optional-library exports or upstream
|
||||
severity type.
|
||||
2. Tidy/check the root manifest normally once its owners compile; reconcile nested
|
||||
manifests through the temporary module files below while their required core/
|
||||
integration versions remain unpublished. Use Go's normal dependency metadata;
|
||||
do not hand-copy the old root requirements into each module or mechanically
|
||||
remove necessary indirect dependencies.
|
||||
3. Run `go test -count=1 ./...` explicitly from each module with the local
|
||||
three-module workspace and the selected toolchain. Root `./...` excludes
|
||||
nested modules. Run the maintained consumers' documented local invocations.
|
||||
4. Perform workspace-off prepublication validation using temporary alternate module
|
||||
files outside the checkout. This solves the not-yet-published core/ckconfig
|
||||
requirement problem without changing distributed manifests:
|
||||
|
||||
- Copy each module's final `go.mod` and available `go.sum` to temporary
|
||||
paired mod/sum files (for example, `core.mod` and `core.sum`). Keep
|
||||
intended versioned requirements unchanged.
|
||||
- Add filesystem replacements only in those temporary files: ckconfig's
|
||||
core requirement points to this sprint's core; ckprompt's core and ckconfig
|
||||
requirements point to this sprint's owners. The core requires no such
|
||||
integration replacement. Do not replace upstream libraries/tools with
|
||||
sibling checkouts.
|
||||
- With `GOWORK=off GOTOOLCHAIN=local`, prepare/tidy each temporary modfile's
|
||||
actual upstream dependencies, then run
|
||||
`go test -modfile=TEMP_MOD -mod=readonly -count=1 ./...` from its module.
|
||||
Review any tidy differences and carry legitimate dependency metadata back
|
||||
without carrying local replacements into the final files.
|
||||
- Inspect `go list -modfile=TEMP_MOD -mod=readonly -deps -test ./...` and
|
||||
`go list -modfile=TEMP_MOD -mod=readonly -m all` separately for each owner.
|
||||
Core package and module graphs exclude ConfigKit, PromptKit, their backends,
|
||||
and both integrations; ckconfig excludes PromptKit, its backends, and ckprompt.
|
||||
Include tool-selected modules when assessing the module graph.
|
||||
- For external consumer evidence, use disposable tiny modules with the same
|
||||
versioned core/config/composed requirements and temporary replacements for
|
||||
this sprint's unpublished modules. Compile the representative public wiring
|
||||
with workspace mode off and inspect their selected package/module graphs.
|
||||
Keep these temporary modules outside the checkout.
|
||||
- Remove temporary files. Report these as workspace-off wiring/isolation checks
|
||||
against local intended source, not as published-version availability checks.
|
||||
5. Review distributed manifests for no filesystem replacements or committed
|
||||
workspace files. Future dependency checksum entries can only be finalized
|
||||
after those dependencies are actually published; do not fabricate checksums.
|
||||
The release procedure's ordered dependency preparation then supplies each
|
||||
module's real sums and its ordinary workspace-off ReleaseKit candidate suite.
|
||||
Independent consumption of released versions uses those actual versions,
|
||||
without consumer replacements or adjacent checkouts.
|
||||
6. Assess the focused evidence listed in each stage: installed-family ownership,
|
||||
batch atomicity, eager immutable capture, original binding identity, wrapped
|
||||
input/wiring errors, all supplied conversion, target-free help, input/state
|
||||
isolation, native reports, diagnostics/delivery, and independent capabilities.
|
||||
Fill a real coverage gap, not every theoretical combination.
|
||||
7. Inspect shared installer/compiler and snapshot paths for the backend design's
|
||||
intended cost profile: capture once, one contextual install traversal,
|
||||
snapshot rebuild after change, conversion once, scope preparation once, and
|
||||
state once. Reuse representative existing benchmarks if useful for regression
|
||||
investigation; no latency/allocation threshold or benchmark release gate is
|
||||
selected.
|
||||
8. Run documentation/link/whitespace checks, review licensing distribution and
|
||||
final diffs, and confirm the launcher selects the correct profile/module and
|
||||
preserves source-only release semantics. Do not run real publication as a test.
|
||||
9. Retire completed roadmap/API/backend planning documents only after the implemented
|
||||
GoDoc/current guides/policies own their relevant material and links are repaired.
|
||||
Keep deferred work. This cleanup is release preparation, not a requirement to
|
||||
lose the stage instructions before implementation finishes.
|
||||
10. Commit the completed work under the local commit policy and report:
|
||||
modules/API delivered, suites and consumer checks actually run, important
|
||||
limitations, intended independent versions and publication order, and any
|
||||
pending real dependency/sum preparation. The workspace should contain no
|
||||
unrelated generated files or temporary replacement manifests.
|
||||
|
||||
**Completion evidence:** all three module suites and representative consumers
|
||||
succeed; module/package graph checks prove the requested exclusion boundaries;
|
||||
current docs and licensing reflect distribution ownership; publication tooling
|
||||
selects one module through released contracts. Actual publication and upstream
|
||||
version adoption remain separate from this sprint.
|
||||
|
||||
## Release handoff
|
||||
|
||||
The completed sprint leaves three independently versioned consumer modules and a
|
||||
source-only launcher ready for ordered release preparation. New integration
|
||||
dependency versions are finalized through ordinary dependency preparation after
|
||||
the prerequisite source releases exist. Do not claim that local validation has
|
||||
already published them.
|
||||
|
||||
No design questions remain for this implementation scope. Versions becoming
|
||||
occupied, unavailable network access during dependency preparation, or genuine
|
||||
conflicts with an authoritative contract are operational findings to report,
|
||||
not permission to preserve the prototype API or invent broader guarantees.
|
||||
Reference in New Issue
Block a user