Retire completed roadmaps and collect future work
This commit is contained in:
@@ -43,7 +43,7 @@ ckprompt v0.2.0; the published v0.2.0 pair remains matched. See the
|
||||
- [Maintainer release procedure](docs/release.md)
|
||||
- [Architecture policy](docs/policy/architecture.md)
|
||||
- [Policy provenance](docs/policy/meta.md)
|
||||
- [Deferred capabilities and proposals](docs/roadmap/deferred.md)
|
||||
- [Future work and proposals](docs/roadmap/future.md)
|
||||
|
||||
CommandKit is licensed under the [LGPL v3.0 or later](COPYRIGHT).
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ canonical documentation owners.
|
||||
For application-owned aliases, use the
|
||||
[CLI reference](cli.md#application-owned-aliases),
|
||||
[Go declarations and GoDoc](../command.go), and
|
||||
[ADR 0013](adr/0013-application-alias-routing.md). Keep deferred capabilities in
|
||||
[deferred work](roadmap/deferred.md).
|
||||
[ADR 0013](adr/0013-application-alias-routing.md). Keep unfinished work and
|
||||
capability proposals in [future work](roadmap/future.md).
|
||||
|
||||
## Initial orientation
|
||||
|
||||
@@ -54,17 +54,17 @@ For application-owned aliases, use the
|
||||
| Task | Read |
|
||||
| --- | --- |
|
||||
| Implemented CLI behavior | [CLI reference](cli.md) |
|
||||
| Invocation reporting | [CLI reporting contract](cli.md#reporting), [consumer guide](consumers/guide.md#invocation-reporting), core GoDoc, [reporting roadmap](roadmap/reporting.md), and [ADR 0014](adr/0014-invocation-reporting.md) |
|
||||
| Invocation reporting | [CLI reporting contract](cli.md#reporting), [consumer guide](consumers/guide.md#invocation-reporting), core GoDoc, and [ADR 0014](adr/0014-invocation-reporting.md) |
|
||||
| Application-owned aliases | [CLI reference](cli.md#application-owned-aliases), [Go declarations and GoDoc](../command.go), [consumer guide](consumers/guide.md#application-owned-aliases), and [ADR 0013](adr/0013-application-alias-routing.md) |
|
||||
| Public API usage and standard-suite wiring | [Consumer guide](consumers/guide.md), [ckconfig package](../integrations/ckconfig/doc.go), [ckprompt package](../integrations/ckprompt/doc.go), and applicable ADRs |
|
||||
| Dispatcher, registration, or typed inputs | [Command declarations](../command.go), [bindings](../binding.go), [invocation](../execute.go), and [ADR 0001](adr/0001-command-dispatch-and-inputs.md), refined by [ADR 0011](adr/0011-captured-declarations-and-installation.md) |
|
||||
| Backend integration | [Internal overview](internal/overview.md), [adapter implementation](../internal/cobra/parse.go), and [ADR 0002](adr/0002-cobra-backend.md) |
|
||||
| Public facade or adapter boundaries | [Internal overview](internal/overview.md), [ADR 0003](adr/0003-public-facade.md) as scoped by [ADR 0010](adr/0010-optional-integration-modules.md), and the architecture policy |
|
||||
| Module ownership and public contracts | [Consumer guide](consumers/guide.md), [internal overview](internal/overview.md), [core GoDoc](../doc.go), [ckconfig GoDoc](../integrations/ckconfig/doc.go), [ckprompt GoDoc](../integrations/ckprompt/doc.go), and applicable ADRs |
|
||||
| Deferred capabilities and proposals | [Deferred work](roadmap/deferred.md) |
|
||||
| Unfinished work and capability proposals | [Future work](roadmap/future.md) |
|
||||
| Completed planning and implementation history | [Completed dependency upgrades, PromptKit validation, discovery, smoke testing, and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/a6278a6d9f940948ec7745955d745523aaff0734/docs/roadmap), [earlier ConfigKit and PromptKit adoption and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/8a82620dfcd34c0ae56bbecb0d014eb49786bc92/docs/roadmap), [earlier retired records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap), and [completed module implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/bb2528532b78d30e52f5082e491a5e1fd9b0fb99/docs/roadmap) in Git history |
|
||||
| Release tooling | [Maintainer release procedure](release.md) |
|
||||
| Performance maintenance | [Internal overview](internal/overview.md), existing benchmarks, and [deferred efficiency work](roadmap/deferred.md#possible-further-efficiency-work) |
|
||||
| Performance maintenance | [Internal overview](internal/overview.md), existing benchmarks, and [possible further efficiency work](roadmap/future.md#possible-further-efficiency-work) |
|
||||
| Licensing or incorporated material | [Project grant](../COPYRIGHT), [license texts](../LICENSE), and [attribution](oss/attribution.md) |
|
||||
| Policy provenance | [Policy provenance](policy/meta.md) |
|
||||
|
||||
@@ -72,11 +72,12 @@ Read all applicable rows for cross-cutting work. Go declarations and GoDoc own
|
||||
current exported contracts; the CLI reference owns operator behavior. The
|
||||
[maintainer release procedure](release.md) owns current release operations.
|
||||
Completed roadmaps and implementation evidence remain available in Git history,
|
||||
including [application-owned alias planning, implementation, and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/f42aefe02d84e154855ac922173e6f367180929f/docs/roadmap)
|
||||
including [ConfigKit adoption, reporting, release-tooling, and remediation records](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/260256d722f52bc947103d078cb67a129f4cc9f1/docs/roadmap),
|
||||
[application-owned alias planning, implementation, and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/f42aefe02d84e154855ac922173e6f367180929f/docs/roadmap)
|
||||
and [PromptKit requirements implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/40499a43608bf60d1104cd8ee24caf18ac0e9e66/docs/roadmap).
|
||||
These records are not assignments to restart completed work. The
|
||||
[deferred-work record](roadmap/deferred.md) preserves future capability targets
|
||||
and unselected proposals separately from current contracts.
|
||||
[future work record](roadmap/future.md) preserves unfinished work and unselected
|
||||
proposals separately from current contracts.
|
||||
|
||||
## Documentation validation
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ invariant, not from the convenience of the selected implementation. Explain the
|
||||
specific failure it prevents and why a less restrictive implementation cannot
|
||||
satisfy the contract.
|
||||
|
||||
The [deferred-work record](../roadmap/deferred.md) distinguishes future proposals
|
||||
The [future work record](../roadmap/future.md) distinguishes future proposals
|
||||
from accepted contracts. Do not approve proposed commands, grammar, statuses, or
|
||||
illustrative API declarations
|
||||
merely by repeating them in implementation or tests. Cobra/pflag defaults do not
|
||||
|
||||
@@ -294,7 +294,7 @@ recommended for application-owned commands; their names and domain behavior
|
||||
remain application choices.
|
||||
|
||||
Accepted ADRs and current CLI/API owners define selected contracts; the
|
||||
[deferred-work record](../roadmap/deferred.md) preserves remaining proposals.
|
||||
[future work record](../roadmap/future.md) preserves remaining proposals.
|
||||
Backend defaults and incidental consumer behavior do not establish new contracts.
|
||||
A replacement backend must preserve published CLI behavior or follow deliberate compatibility
|
||||
changes under the release policy.
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
# ConfigKit v1.1.0 adoption
|
||||
|
||||
Status: the selected ckconfig adoption is implemented and prepared for a later
|
||||
release; source publication and ckprompt migration remain pending. This roadmap
|
||||
defines the embedded `ckconfig` dependency and source-report target.
|
||||
[Selected scope decisions](#selected-scope-decisions) distinguish adoption from
|
||||
deferred extensions. The [implementation plan](implementation.md) owns stage
|
||||
order, concrete changes, and validation steps.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Adopt `go.maximumdirect.net/configkit v1.1.0` and expose its capabilities through
|
||||
CommandKit's existing configuration commands in a neutral, consistent way.
|
||||
ConfigKit owns configuration loading, composition, resolution, inspection, and
|
||||
their semantics. CommandKit owns command selection, coordination, presentation,
|
||||
and invocation outcomes. Adapt upstream capabilities faithfully, using current
|
||||
upstream terminology, without adding independent guarantees or commentary
|
||||
qualifying upstream limitations.
|
||||
|
||||
This follows the clarified integration goal and the existing
|
||||
[architecture policy](../policy/architecture.md#backend-and-library-integration).
|
||||
The [agent](../policy/agents.md), [testing](../policy/testing.md),
|
||||
[documentation](../policy/documentation.md), [release](../policy/release.md), and
|
||||
[OSS](../policy/oss.md) policies govern implementation. This roadmap records
|
||||
the selected target; current contracts remain in GoDoc, the
|
||||
[CLI reference](../cli.md), and the [consumer guide](../consumers/guide.md) until
|
||||
implementation lands.
|
||||
|
||||
## Current baseline and review evidence
|
||||
|
||||
Initial review revision: `60841227b7e2928d3fefd3326f0e3f4694f41e6d`.
|
||||
API coverage follow-up revision: `7a9e3a1f7cdd0475f06a63ce0aababefe08651bc`;
|
||||
library code and module selections are unchanged between these revisions.
|
||||
The completed [dependency alignment roadmap](integration-dependency-alignment.md)
|
||||
records the preceding vanity migration and releases.
|
||||
|
||||
| Component | Current selection |
|
||||
| --- | --- |
|
||||
| Core | `go.maximumdirect.net/commandkit v0.3.0`; Go 1.26.0 minimum |
|
||||
| ckconfig | `go.maximumdirect.net/ckconfig v0.2.0`; Go 1.26.0 minimum |
|
||||
| ckconfig dependencies | Core v0.3.0, `gitea.maximumdirect.net/eric/ConfigKit v0.8.0`, YAML v4.0.0-rc.6 |
|
||||
| ckprompt | v0.2.0; ckconfig v0.2.0, old-path ConfigKit v0.8.0 and PromptKit v0.16.0; Go 1.26.0 minimum |
|
||||
| Maintainer release toolchain | Go 1.26.8, with `GOTOOLCHAIN=local` |
|
||||
|
||||
The ConfigKit vanity endpoint and direct Go module discovery resolve v1.1.0 to
|
||||
published commit `191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9`. Its module declares
|
||||
Go 1.27.0 and retains the YAML dependency and LGPL-3.0-or-later library grant.
|
||||
The upstream [v1.0 migration notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v1.0.0.md)
|
||||
and [v1.1 release notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v1.1.0.md)
|
||||
describe the adopted API and behavior changes. Upgrading from v0.8.0 also crosses
|
||||
the import, collection, CLI-assignment, and discovery changes documented in the
|
||||
[v0.9 notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v0.9.0.md)
|
||||
and [v0.10 notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v0.10.0.md).
|
||||
|
||||
A disposable ckconfig copy passed its complete module suite and maintained
|
||||
simple example tests on Go 1.27.0 after changing the dependency/import path,
|
||||
minimum, two source-reader fields, and affected test APIs. This establishes that
|
||||
the existing adapter structure remains suitable. It did not exercise the
|
||||
proposed report-field renames, additional source evidence, or a migrated
|
||||
ckprompt; final implementation still needs validation of those selected changes.
|
||||
|
||||
### API coverage findings
|
||||
|
||||
The follow-up compared the public API of the pinned v1.1.0 module with
|
||||
ckconfig's provider facets, adapters, and report projections. These are gaps in
|
||||
current integration coverage, not necessarily APIs newly introduced in v1.1.0.
|
||||
|
||||
| Capability | Current ckconfig exposure | Recommendation |
|
||||
| --- | --- | --- |
|
||||
| `SourceInfo.EmptyImportSelections` | Omitted from the source report. | Include in adoption; OD-2. |
|
||||
| `Result.Metadata()`, `Metadata.Lookup`, and `IsExplicit` | No metadata facet in `View`; explanation reports do not expose explicit input presence. | Prioritize optional field-metadata inspection as the next functional expansion; OD-3. |
|
||||
| `Metadata.HistoricalPaths` and `History` | Operators must already know a path to request an explanation; metadata history records are not exposed. | Pair path discovery and provenance history with metadata inspection; OD-3. |
|
||||
| `LoadError.Sources()` and `Source(id)` | Acquired sources support diagnostic context, but `config sources` returns before reporting an inventory on acquisition failure. | Consider failed-load source inspection separately; OD-4. |
|
||||
| Full `Difference` records | The Go comparison provider returns native records; the CLI reduces them to additions, right-side changes, and deletion paths. | Consider an additional detailed comparison report; OD-5. |
|
||||
| Structured `Diagnostic` records | Native writers present diagnostic content; there is no structured native diagnostic report. | Lower-priority candidate, coordinated with shared reporting; OD-6. |
|
||||
|
||||
The upstream [metadata API](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/metadata.go),
|
||||
[source and diagnostic records](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/records.go),
|
||||
[load-error API](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/diagnostic.go),
|
||||
and [comparison API](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/diff.go)
|
||||
own the returned evidence and its semantics.
|
||||
|
||||
The current explanation projection covers every field of v1.1.0's
|
||||
`Explanation`: effective and historical snapshots, origin and inheritance,
|
||||
reasons, dependencies, and secret-reference names. Improved list-history
|
||||
behavior can flow through that existing adapter. Metadata queries add distinct
|
||||
information: explicitness and null state from `FieldInfo`, observed paths
|
||||
including removed ones, and `Change` records with previous origins and operation
|
||||
paths. They need not replace the value-oriented explanation report.
|
||||
|
||||
`Result.Source(id)` is a convenient lookup of records already available through
|
||||
the source inventory. A source-ID filter is a possible usability refinement;
|
||||
it does not inherently require another command or a required lookup method on
|
||||
every custom source provider. Discovery, import defaults, collection identities,
|
||||
and field-level resolution recording fit the application-supplied loader.
|
||||
Source resource contexts and explicit secrets-directory bootstrap primarily
|
||||
serve application loading and startup; there is no immediate recommendation to
|
||||
add standard inspection operations for them. A consumer need could motivate
|
||||
later presentation of their upstream results.
|
||||
|
||||
## Targeted end state
|
||||
|
||||
### Dependency and toolchain
|
||||
|
||||
The [ckconfig module](../../integrations/ckconfig/go.mod) requires
|
||||
`go.maximumdirect.net/configkit v1.1.0`, and its production code, tests, and
|
||||
maintained example use that import identity. Raise its consumer minimum to
|
||||
Go 1.27.0. Retain its core v0.3.0 requirement unless implementation identifies
|
||||
a concrete need for a newer core API. Core remains independent of ConfigKit
|
||||
and retains its own Go minimum.
|
||||
|
||||
Use a Go 1.27 toolchain for ckconfig dependency preparation and validation.
|
||||
Update the [maintainer procedure](../release.md#release-toolchain) to select an
|
||||
available Go 1.27 release and distinguish the per-module consumer minimums.
|
||||
The existing host-native, workspace-off launcher can use that toolchain without
|
||||
a new toolchain-selection mechanism.
|
||||
|
||||
### Faithful adaptation and reports
|
||||
|
||||
Retain the existing scope, loader, comparison, diagnostic, and reporting
|
||||
structure. Continue using ConfigKit's public results, native rendering, and
|
||||
diff APIs rather than reproducing its domain logic locally. New collection,
|
||||
discovery, and resolution features can be used by application loaders through
|
||||
the adopted library; they do not inherently require additional CLI flags or
|
||||
CommandKit-owned loading policy.
|
||||
|
||||
Align the existing source report with ConfigKit's current vocabulary:
|
||||
|
||||
| Current API or report spelling | Target |
|
||||
| --- | --- |
|
||||
| `SourceInfo.DestinationUnresolved` | `SourceInfo.DestinationIsFallback` |
|
||||
| `SourceInfo.VersionCheck` / `SourceVersionCheck` | `SourceInfo.VersionEvidence` / `SourceVersionEvidence` |
|
||||
| Text/YAML `destination_unresolved` | `destination_is_fallback` |
|
||||
| Text/YAML `version_check` | `version_evidence` |
|
||||
| Native main layer value `base` | Native main layer value `main` |
|
||||
|
||||
Update DTOs and both report formats together. Preserve the upstream evidence
|
||||
and its supported presence, null, location, ordering, and redaction information
|
||||
through adaptation. Use the upstream terms directly in help and documentation;
|
||||
link to the owning inspection contract for their semantics. Describe the report
|
||||
migration plainly in the release note. The target uses the new field names
|
||||
without duplicate legacy report fields.
|
||||
|
||||
Include `EmptyImportSelections` as `empty_import_selections` in both text and
|
||||
YAML source reports under OD-2. Project each declaration path, location, and
|
||||
native selector in the returned record order. Emit `empty_import_selections: []`
|
||||
when there are no records. The [CLI reference](../cli.md#list-configuration-sources)
|
||||
owns the implemented report contract.
|
||||
|
||||
### Deferred inspection expansion
|
||||
|
||||
Metadata inspection and path discovery are the next functional work proposed
|
||||
after adoption (OD-3). Failed-load source inventory, detailed comparison,
|
||||
and structured diagnostics remain separate later proposals (OD-4 through OD-6).
|
||||
The [configuration inspection extensions](deferred.md#configuration-inspection-extensions)
|
||||
record owns their proposed capabilities and design considerations. None is part
|
||||
of this adoption scope or a new requirement on existing providers.
|
||||
|
||||
### Consumer migration and module coordination
|
||||
|
||||
Public ckconfig signatures expose ConfigKit types, so switching import identity
|
||||
requires consumers to migrate the ConfigKit values they pass across those
|
||||
boundaries. Use the adopted upstream API names in maintained consumers and
|
||||
fixtures. Known test changes include `Definition.Secret` to `Sensitive` and
|
||||
`Resolution.Record(..., ChangeNormalization, ...)` to `RecordNormalization`.
|
||||
Review other removed pre-v1 symbols where actually used.
|
||||
|
||||
Migration guidance should link to upstream for source-root `configkit` controls
|
||||
becoming `config`, `optional` becoming `required` with changed defaults,
|
||||
identified-collection registrations and operations, and CLI-assignment ordering.
|
||||
Change affected maintained fixtures when present. Application configuration and
|
||||
validation choices remain application-owned; CommandKit does not introduce a
|
||||
compatibility loader or impose new configuration restrictions.
|
||||
|
||||
ckprompt's current ConfigKit types come from the old package identity. It cannot
|
||||
simply select the new ckconfig release while retaining that wiring. Its later
|
||||
adoption needs a coordinated ConfigKit/PromptKit migration and review of its
|
||||
own adapters and composed example. Under OD-1, prepare ckconfig independently
|
||||
first and review ckprompt next. This roadmap does not select an unreviewed
|
||||
PromptKit release or claim a new matched integration set.
|
||||
|
||||
### Independent module compatibility
|
||||
|
||||
Once local ckconfig uses the vanity ConfigKit types, the usual three-module
|
||||
`go.work` selects it for local ckprompt as well. Until ckprompt migrates, its
|
||||
old-path ConfigKit inspection and comparison types cannot satisfy the new
|
||||
ckconfig contracts. This is a temporary composition mismatch, even though each
|
||||
module can be validated independently against its own dependencies.
|
||||
|
||||
During that interval, each module's independent validation uses its own declared
|
||||
dependencies with workspace discovery off. The unchanged ckprompt and composed
|
||||
example retain published ckconfig v0.2.0 and their existing upstream libraries;
|
||||
their success does not establish compatibility with migrated local ckconfig.
|
||||
Development and consumer guidance explain the temporary mismatch. Existing
|
||||
ignored workspace files remain local; restoring aligned workspace composition
|
||||
belongs to the later ckprompt migration.
|
||||
|
||||
### Release preparation
|
||||
|
||||
The target candidate is ckconfig v0.3.0, with full tag
|
||||
`integrations/ckconfig/v0.3.0`, subject to the existing fresh-version guards.
|
||||
A pre-v1 minor fits the intentional ConfigKit type-identity, consumer-minimum,
|
||||
and report-schema changes. Its checked-in note explains these changes and
|
||||
consumer migration, with the usual immutable licensing footer. Current module
|
||||
notices describe the selected graph and pinned upstream source.
|
||||
|
||||
Adoption includes release preparation, not source publication or hosted
|
||||
delivery. The existing [release procedure](../release.md) owns those operations
|
||||
and their separate outcomes when requested; this target adds no release gate.
|
||||
|
||||
## Completion evidence
|
||||
|
||||
Implementation is complete when ckconfig's actual module metadata and imports
|
||||
select the new dependency, the selected report changes faithfully expose its
|
||||
returned evidence, the module suite and maintained consumer pass independently,
|
||||
and current documentation, notices, and release preparation describe that state.
|
||||
Completion evidence distinguishes independent module validation from the
|
||||
temporary workspace composition mismatch. OD-3 through OD-6 remain in deferred
|
||||
work; their implementation is not a completion condition for adoption. A future
|
||||
source release is reported separately from implementation completion.
|
||||
|
||||
## Selected scope decisions
|
||||
|
||||
These dispositions record the user's selected adoption scope.
|
||||
They record the selected target and do not authorize publication. Deferred
|
||||
features still need focused API and CLI design.
|
||||
|
||||
| Decision | Selected disposition | Reason |
|
||||
| --- | --- | --- |
|
||||
| OD-1: Integration sequencing | Implement and prepare ckconfig independently first; review ckprompt next. | Independent releases keep adoption focused. Document the temporary workspace mismatch and lack of a newly aligned release pair. |
|
||||
| OD-2: Empty-import evidence | Include `empty_import_selections`, with `[]` when empty, in text and YAML source reports. | Exposes existing upstream evidence alongside the other report-schema changes. |
|
||||
| OD-3: Metadata and path discovery | Defer to the next functional work after adoption. | A coherent optional capability needs its own field/history report and command design. |
|
||||
| OD-4: Failed-load source inventory | Defer to a separate source-inspection enhancement. | Requires source evidence on error and deliberate report/failure coordination. |
|
||||
| OD-5: Detailed comparison | Defer; retain the existing reduced report during adoption. | A richer form needs a report-selection and compatibility decision. |
|
||||
| OD-6: Structured diagnostics | Defer; retain native diagnostic rendering during adoption. | Coordinate machine-readable records with shared reporting and outcome delivery. |
|
||||
|
||||
Adoption therefore covers dependency and API migration, source-report
|
||||
terminology and empty-import evidence, documentation and notices, independent
|
||||
module validation, and ckconfig release preparation. Core retains its own Go
|
||||
minimum. Application loaders continue to own discovery and loading policy.
|
||||
|
||||
Coordinating both integrations before release remains an alternative if a
|
||||
matched adoption path becomes necessary. It would expand the scope to include
|
||||
PromptKit review and ckprompt migration; publication would still proceed in
|
||||
dependency order. The [deferred feature record](deferred.md#configuration-inspection-extensions)
|
||||
retains the capability proposals and unresolved design choices for OD-3 through
|
||||
OD-6, plus the possible source-ID filter.
|
||||
@@ -1,22 +1,57 @@
|
||||
# Deferred work
|
||||
# Future work
|
||||
|
||||
Status: retained future work and unselected proposals; no implementation schedule.
|
||||
Status: pending release and integration work, plus future capability proposals.
|
||||
No delivery dates are selected here.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Completed initial delivery, performance, ReleaseKit upgrade, and remediation
|
||||
records have been retired. This document preserves remaining deferred
|
||||
capabilities and unselected ideas under the
|
||||
Completed roadmaps, implementation plans, and review findings have been retired.
|
||||
This document preserves unfinished work and unselected ideas under the
|
||||
[release policy](../policy/release.md#release-documentation-and-preparation).
|
||||
The original records remain available in
|
||||
[Git history](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap).
|
||||
The completed ConfigKit adoption, reporting, dependency alignment, release-tooling,
|
||||
and remediation records remain available at the
|
||||
[retirement snapshot](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/260256d722f52bc947103d078cb67a129f4cc9f1/docs/roadmap).
|
||||
[Earlier retired records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap)
|
||||
also remain in Git history. Completed records are not assignments to restart work.
|
||||
|
||||
Accepted [ADRs](../adr/) and the [architecture policy](../policy/architecture.md)
|
||||
govern any future implementation. The [CLI reference](../cli.md), public GoDoc,
|
||||
and [consumer guide](../consumers/guide.md) own implemented behavior. Retaining
|
||||
an idea here does not select its syntax, API, priority, or delivery date.
|
||||
|
||||
## Deferred capability targets
|
||||
## Pending release and integration work
|
||||
|
||||
### ckconfig release and hosted delivery
|
||||
|
||||
The ckconfig v0.3.0 candidate adopts ConfigKit v1.1.0 and Go 1.27.0; its
|
||||
implementation and audits are complete. Its
|
||||
[candidate release note](../../integrations/ckconfig/docs/releases/v0.3.0.md)
|
||||
is prepared, but source publication and hosted delivery remain pending. Complete
|
||||
those operations when requested through the [release procedure](../release.md),
|
||||
using the existing fresh-version guards and reporting source publication and
|
||||
hosted Gitea delivery separately. Publishing this roadmap cleanup does not
|
||||
publish a module version tag or deliver a release page.
|
||||
|
||||
### ckprompt dependency migration and workspace alignment
|
||||
|
||||
Review the upstream PromptKit vanity release and select compatible ConfigKit
|
||||
and PromptKit dependencies before migrating ckprompt's adapters and maintained
|
||||
composed consumer. The new ckconfig uses vanity ConfigKit types; ckprompt v0.2.0
|
||||
still uses published ckconfig v0.2.0 and old-path ConfigKit v0.8.0. Their local
|
||||
sources do not currently compose in the three-module workspace. See the
|
||||
[consumer guide](../consumers/guide.md#module-selection) for the current module
|
||||
relationship.
|
||||
|
||||
The follow-up includes migrating affected imports and public type boundaries,
|
||||
selecting real released dependency versions and the required Go minimum,
|
||||
updating notices and migration guidance, and validating both ckprompt's
|
||||
independent graph and the aligned composed consumer. Restore three-module
|
||||
workspace guidance when those dependencies align, updating the ignored workspace
|
||||
Go version as needed. Until then, preserve local workspace files and validate
|
||||
with workspace discovery off as described in the [development guide](../development.md).
|
||||
No unreviewed PromptKit version or new compatibility bridge is selected here.
|
||||
|
||||
## Future capability targets
|
||||
|
||||
### Comparison extensions
|
||||
|
||||
@@ -27,8 +62,8 @@ relevant ADRs.
|
||||
|
||||
### Configuration inspection extensions
|
||||
|
||||
The [ConfigKit v1.1.0 adoption review](configkit-v1.1.0.md#selected-scope-decisions)
|
||||
recommends the following work after dependency and source-report adoption.
|
||||
The [completed ConfigKit v1.1.0 adoption review](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/260256d722f52bc947103d078cb67a129f4cc9f1/docs/roadmap/configkit-v1.1.0.md#selected-scope-decisions)
|
||||
retained the following work after dependency and source-report adoption.
|
||||
Metadata inspection is the recommended next functional sprint; the other
|
||||
features have no selected sequence or delivery date. These proposals do not
|
||||
establish command grammar, report schemas, or new provider requirements.
|
||||
@@ -51,7 +86,7 @@ ConfigKit's public APIs own the evidence and its semantics.
|
||||
failures together; current diagnostic context remains available meanwhile.
|
||||
- **Detailed comparison (OD-5).** Consider an additional form projecting native
|
||||
`Difference` paths, both snapshots, presence/redaction fields, and
|
||||
`HiddenChanged`. The adoption sprint retains the reduced
|
||||
`HiddenChanged`. The current comparison retains the reduced
|
||||
additions/changes/deletions report. Decide later whether a detailed form
|
||||
complements it or replaces it through a deliberate compatibility change.
|
||||
- **Structured diagnostics (OD-6).** Consider machine-readable native codes,
|
||||
@@ -83,7 +118,28 @@ A later design should determine how alias suggestions are presented alongside
|
||||
canonical suggestions while ensuring inserted continuations form valid next
|
||||
steps. No delivery date or final API is selected here.
|
||||
|
||||
## Other deferred proposals
|
||||
### Reporting extensions
|
||||
|
||||
Error-conversion helpers such as `WarnError` remain deferred pending demonstrated
|
||||
value; applications can already use `report.Warn(err.Error())`. Terminal redraw
|
||||
and progress-bar presentation were outside the completed reporting scope and
|
||||
remain unselected. Whole-run buffering to make failed runs show only errors
|
||||
was also outside that scope. Any later extension needs a deliberate API and
|
||||
presentation decision rather than assuming those behaviors are already provided.
|
||||
|
||||
### Release workflow extensions
|
||||
|
||||
Historical hosted-page backfilling and automated CI delivery remain separate
|
||||
future choices. The current local page-only delivery workflow is implemented;
|
||||
these extensions are not prerequisites for using it. The release procedure owns
|
||||
delivery, immutable content, and recovery behavior.
|
||||
|
||||
Additional validation options, including race testing, full vet, compilation
|
||||
matrices, size limits, and more forbidden-file paths, can be considered for
|
||||
demonstrated needs. None is selected by retaining it here, and the existing
|
||||
candidate checks do not become general prohibitions on development workspaces.
|
||||
|
||||
## Other future proposals
|
||||
|
||||
These capabilities remain outside the delivered scope and require a concrete
|
||||
operator or consumer need and an appropriate ownership/behavior decision:
|
||||
@@ -1,332 +0,0 @@
|
||||
# ConfigKit v1.1.0 adoption implementation plan
|
||||
|
||||
Status: Stages 1–6 complete.
|
||||
|
||||
This plan is for a Luna coding agent implementing the selected
|
||||
[ConfigKit adoption target](configkit-v1.1.0.md). Follow Stage 1 through Stage 6
|
||||
in order as one end-to-end sprint. Intermediate editing states need not compile
|
||||
or form independently usable releases. Reach and validate the complete selected
|
||||
end state before claiming completion; do not introduce compatibility machinery
|
||||
merely to make an intermediate stage pass.
|
||||
|
||||
This planning pass changes documentation only. Execution prepares a ckconfig
|
||||
release candidate; source publication, hosted delivery, ckprompt migration, and
|
||||
the deferred inspection extensions are outside this sprint. Do not push or
|
||||
create release tags as part of these stages. The user's later publication
|
||||
instructions and the [release procedure](../release.md) govern those operations.
|
||||
|
||||
Start with [development guidance](../development.md) and follow the
|
||||
[agent](../policy/agents.md), [architecture](../policy/architecture.md),
|
||||
[testing](../policy/testing.md), [documentation](../policy/documentation.md),
|
||||
[release](../policy/release.md), and [OSS](../policy/oss.md) policies for the work
|
||||
they govern. Use the repository's codebase-memory tools for code discovery.
|
||||
The completed [vanity migration plan and publication evidence](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/16584084b1b8a87dac959334ede8a47a8cfb8c0b/docs/roadmap/implementation.md)
|
||||
remain in Git history; do not restart that work or the completed ReleaseKit
|
||||
adoption/remediation.
|
||||
|
||||
## Baseline and fixed choices
|
||||
|
||||
Source/review baseline: `16584084b1b8a87dac959334ede8a47a8cfb8c0b`.
|
||||
The planning commit changes roadmap documents, not module code.
|
||||
|
||||
| Item | Baseline | Selected end state |
|
||||
| --- | --- | --- |
|
||||
| ckconfig module | `go.maximumdirect.net/ckconfig`, published v0.2.0 | Same module identity; prepare v0.3.0 |
|
||||
| ConfigKit | `gitea.maximumdirect.net/eric/ConfigKit v0.8.0` | `go.maximumdirect.net/configkit v1.1.0` |
|
||||
| ckconfig Go minimum | Go 1.26.0 | Go 1.27.0 |
|
||||
| Core dependency | `go.maximumdirect.net/commandkit v0.3.0` | Retain v0.3.0 |
|
||||
| Maintainer toolchain | Go 1.26.8 | Go 1.27.0 for preparation, validation, and ReleaseKit execution |
|
||||
| Other module minimums | Core and ckprompt: Go 1.26.0 | Retain their independent minimums |
|
||||
|
||||
ConfigKit v1.1.0 is published at
|
||||
`191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9`. Its module requires Go 1.27.0;
|
||||
the prior disposable migration passed ckconfig and its example tests on that
|
||||
toolchain. The selected report changes have not yet been implemented or tested.
|
||||
|
||||
The feature roadmap's selected OD-1/OD-2 choices apply: migrate ckconfig first
|
||||
and include empty-import-selection evidence. OD-3 through OD-6 and source-ID
|
||||
filtering remain in [deferred work](deferred.md#configuration-inspection-extensions).
|
||||
Retain the existing configuration operations, provider facets, loading and
|
||||
comparison coordination, diagnostics, outcomes, and reduced diff report.
|
||||
ConfigKit owns domain semantics; this sprint adapts its public capabilities.
|
||||
|
||||
Retain root ReleaseKit v0.9.0, the release launchers and profiles, physical
|
||||
module directories, and integration tag prefixes. Core and ckprompt code and
|
||||
module selections are outside this adoption. Published old releases and notes
|
||||
remain immutable. A new adapter layer, legacy import bridge, duplicate legacy
|
||||
report fields, or local reimplementation of ConfigKit semantics is unnecessary.
|
||||
|
||||
Preserve ignored `go.work`, `go.work.sum`, and `.releasekit/gitea-token` without
|
||||
reading credential contents. Use `GOWORK=off GOTOOLCHAIN=local` throughout module
|
||||
preparation, validation, and example runs. Local ckprompt will not compose with
|
||||
migrated local ckconfig until its later ConfigKit/PromptKit migration; its
|
||||
independent suite continues to use published ckconfig v0.2.0. Do not edit
|
||||
ckprompt or introduce replacements to conceal this temporary mismatch.
|
||||
|
||||
## Stage 1: Migrate the dependency, imports, and removed Go APIs
|
||||
|
||||
**Completed.** Ckconfig now selects ConfigKit v1.1.0 and Go 1.27.0, with
|
||||
authentic downloaded sums and migrated imports and native API accesses. An
|
||||
offline compile of its packages and example passed with Go 1.27.0.
|
||||
|
||||
1. Inspect the worktree and preserve unrelated work. Select Go 1.27.0 on
|
||||
`PATH` and confirm it with `GOWORK=off GOTOOLCHAIN=local go version`.
|
||||
This version was available during planning. Reuse an existing installation,
|
||||
or install/download `golang.org/dl/go1.27.0` using the established SDK setup
|
||||
pattern in the release procedure. Do not change the ignored workspace to
|
||||
select the toolchain.
|
||||
2. In `integrations/ckconfig/go.mod`, set `go 1.27.0`, remove the old ConfigKit
|
||||
requirement, and require `go.maximumdirect.net/configkit v1.1.0`. Keep the
|
||||
core requirement and YAML selection unless ordinary resolution establishes
|
||||
a required change. Do not tidy root/ckprompt merely to raise their minima.
|
||||
3. Migrate ckconfig-owned Go imports, including tests and the simple example,
|
||||
to the new ConfigKit identity. Preserve the package alias `configkit`.
|
||||
Inspect literals and documentation references separately from imports;
|
||||
old repository URLs in published history are not import-path defects.
|
||||
4. Adapt the native source-field accesses in `sources.go` to
|
||||
`DestinationIsFallback` and `VersionEvidence`. Use
|
||||
`configkit.SourceVersionEvidence` in affected test fixtures. The public
|
||||
`SourceReader` contract still returns `[]configkit.SourceInfo` through the
|
||||
new import identity; it needs no additional methods.
|
||||
5. Update removed APIs actually used by the tests: `Definition.Secret` becomes
|
||||
`Sensitive` in `comparison_adapter_test.go`, `diff_execution_test.go`, and
|
||||
`diff_report_render_test.go`; the normalization call in
|
||||
`TestFromConfigKitCompareIgnoresDefaultAndResolutionHistoryForEqualValues`
|
||||
becomes `RecordNormalization(path, reason)`. Preserve the existing
|
||||
application mutation and assertions. Search for any other used removed
|
||||
symbols and use the pinned upstream migration mapping, not aliases or
|
||||
replacement domain logic.
|
||||
6. After import migration, prepare dependencies and run `go mod tidy` from
|
||||
ckconfig with workspace discovery off and the selected local toolchain.
|
||||
Use normal dependency retrieval during preparation; inspect the authentic
|
||||
resulting `go.mod`/`go.sum` changes. Do not fabricate sums or use a sibling
|
||||
checkout as a dependency. Format changed Go files.
|
||||
|
||||
**Stage result:** ckconfig selects the released vanity dependency and current
|
||||
Go APIs. Report spelling and new evidence are completed by the next stages;
|
||||
there is no requirement to keep this intermediate state independently usable.
|
||||
|
||||
## Stage 2: Align source-report vocabulary and add empty-import evidence
|
||||
|
||||
**Completed.** Text and YAML projections use the new vocabulary and include
|
||||
ordered empty-import selections, including empty lists and nil version evidence.
|
||||
The packages compile offline with Go 1.27.0; focused behavioral tests follow.
|
||||
|
||||
Work in `integrations/ckconfig/sources.go`. Keep its existing report preparation
|
||||
and delivery path; no new provider capability or operation is needed.
|
||||
|
||||
1. Rename DTO fields/types and both text/YAML keys to match the upstream terms:
|
||||
`DestinationIsFallback` / `destination_is_fallback`, and
|
||||
`VersionEvidence` / `version_evidence`. Rename `sourceVersionCheckDTO` to
|
||||
`sourceVersionEvidenceDTO`. Continue projecting all existing version,
|
||||
location, presence, null, and redaction fields as returned. Allow the native
|
||||
main layer value to appear as `main`; do not translate it back to `base`.
|
||||
2. Add `EmptyImportSelections` to each source DTO, serialized as
|
||||
`empty_import_selections` after `version_evidence`. Use an ordinary slice of
|
||||
a small DTO with fields in this order: `path` string, `location` using the
|
||||
existing `locationDTO`, and `selector` string. No `omitempty` is needed:
|
||||
initialize the slice so sources without records serialize as `[]`.
|
||||
3. For every native record, project `Path.String()`, its supplied location's
|
||||
source ID/line/column, and `string(Selector)`. Preserve source and record
|
||||
order, source-local coordinates, empty strings, and zero coordinates.
|
||||
Forward selector strings without validating or remapping them. Apply no
|
||||
additional import discovery, filesystem access, or domain interpretation.
|
||||
4. Extend the text writer with the same field names and field order. For an
|
||||
empty slice, print `empty_import_selections: []`. For nonempty slices, print
|
||||
one indented record per entry with `path`, `location`, and `selector`.
|
||||
Follow the existing text style: quote path/source-ID/selector strings with
|
||||
`strconv.Quote` and render a location as
|
||||
`{source_id: "...", line: N, column: N}`. YAML uses the equivalent mapping.
|
||||
5. The current text writer uses `continue` after printing a null version check.
|
||||
Restructure that conditional so a null `version_evidence` does not skip the
|
||||
new empty-import field. Every reported source includes both fields, with
|
||||
`version_evidence: null` where the upstream pointer is nil.
|
||||
|
||||
**Stage result:** both report forms use the current vocabulary and expose
|
||||
empty-import evidence, including when no version evidence exists. Existing
|
||||
source inventory, explanation, diagnostic, and outcome semantics are retained.
|
||||
|
||||
## Stage 3: Update focused report and adapter coverage
|
||||
|
||||
**Completed.** Focused source tests cover the new text and YAML keys, native
|
||||
main layer, ordered selections, empty lists, and nil/redacted evidence. The
|
||||
offline `TestSources` suite passed with Go 1.27.0.
|
||||
|
||||
1. Extend `TestSourcesProjectNativeEvidenceInTextAndYAML` in `sources_test.go`
|
||||
rather than building another report-test framework. Update fixtures and
|
||||
assertions to the new native fields and report keys. Check that legacy
|
||||
`destination_unresolved` and `version_check` keys are absent from emitted
|
||||
source records; existing published history need not be scanned away.
|
||||
2. Add controlled empty-import records to the source-reader fixture. Use
|
||||
multiple records with distinguishable paths, selectors, and locations so
|
||||
the test detects loss, reordering, or incorrect projection. Include a
|
||||
source with nil version evidence and nonempty import records to cover the
|
||||
text-writer conditional, and a source with no import records to verify `[]`
|
||||
in both forms. Preserve the existing null/redacted version-evidence cases,
|
||||
source order, zero-value coverage, and inventory-read count assertions.
|
||||
3. Use the native `LayerMain` value in an appropriate fixture and verify that
|
||||
returned source/explanation layer names are presented faithfully. Reuse
|
||||
existing assertions where they already cover native origin projection;
|
||||
do not add a separate test of ConfigKit's layer or provenance rules.
|
||||
4. Keep existing tests of loader request forwarding, comparison coordination,
|
||||
diagnostics, cancellation, error identity, output failures, and safe native
|
||||
snapshot adaptation. Adjust removed APIs or intentionally changed report
|
||||
expectations only. Do not rewrite behavior assertions merely to make an
|
||||
unexpected regression pass.
|
||||
5. Run the focused source tests with prepared dependencies, from ckconfig:
|
||||
|
||||
```sh
|
||||
GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off \
|
||||
go test -mod=readonly -count=1 -run '^TestSources' .
|
||||
```
|
||||
|
||||
**Stage result:** durable coverage establishes CommandKit's new report
|
||||
projection. The fake native inventory supplies evidence; tests do not establish
|
||||
whether ConfigKit discovers imports, checks versions, matches records, or
|
||||
classifies sensitive data correctly.
|
||||
|
||||
## Stage 4: Update current guidance and prepare the release note
|
||||
|
||||
**Completed.** Current guidance describes the new source report, consumer and
|
||||
toolchain migration, and temporary ckprompt mismatch. The v0.3.0 candidate
|
||||
note is prepared; published notes remain unchanged.
|
||||
|
||||
1. Update ckconfig README, GoDoc, and `examples/simple/README.md` for the new
|
||||
dependency identity and Go minimum, and the planned ckconfig v0.3.0 with
|
||||
core v0.3.0. Keep package/provider usage consistent with actual code.
|
||||
Review maintained fixtures for source controls or removed APIs; migrate
|
||||
genuine old controls where present, without changing application fields
|
||||
merely because they have similar names.
|
||||
2. Update `docs/cli.md`'s configuration-source section with the renamed keys,
|
||||
main layer value, and `empty_import_selections` schema from Stage 2,
|
||||
including the empty-list shape. Update origin-layer examples where they
|
||||
describe adopted ConfigKit results. Retain existing command grammar,
|
||||
formats, status behavior, and reduced comparison report. Use upstream terms
|
||||
directly and link to the pinned upstream contracts for their semantics.
|
||||
3. Update `docs/consumers/guide.md` and README's module-selection summary to
|
||||
distinguish two cases: the newly prepared ckconfig v0.3.0 with ConfigKit
|
||||
v1.1.0, and the existing matched ckconfig/ckprompt v0.2.0 pair. Do not imply
|
||||
that ckprompt v0.2.0 composes with new ckconfig. Qualify upstream links where
|
||||
ckconfig and unchanged ckprompt now use different ConfigKit versions.
|
||||
4. Document the consumer migration: ConfigKit import/type identity, Go 1.27.0,
|
||||
changed report keys, and added source evidence. Link to upstream migration
|
||||
guidance for source-root `configkit` controls becoming `config`, import
|
||||
requiredness/defaults, collection registrations/operations, removed public
|
||||
APIs, and CLI-assignment order. Keep the detailed configuration reference
|
||||
upstream rather than creating a parallel CommandKit contract.
|
||||
5. In `docs/release.md`, select Go 1.27.0 as the maintainer toolchain and adapt
|
||||
its existing install/download/PATH example. In that procedure and the
|
||||
consumer guide, distinguish ckconfig's Go 1.27.0 minimum from core and
|
||||
unchanged ckprompt's Go 1.26.0 minima. Keep ReleaseKit v0.9.0 and its
|
||||
existing launcher, profiles, guards, publication, delivery, and recovery
|
||||
workflow. This does not require code or profile changes.
|
||||
6. Replace the development guide's unqualified three-module workspace advice
|
||||
with interim guidance: preserve ignored workspace files and use
|
||||
`GOWORK=off GOTOOLCHAIN=local` for preparation, suites, and example runs.
|
||||
Explain that ckprompt's independent suite and composed example use its
|
||||
published ckconfig v0.2.0 dependency; full local workspace composition is
|
||||
pending the later ckprompt migration. Restore aligned workspace guidance
|
||||
during that later work, including the workspace Go version as needed.
|
||||
7. Create `integrations/ckconfig/docs/releases/v0.3.0.md`, subject to the
|
||||
existing fresh-version selection, explaining the complete v0.2.0-to-candidate
|
||||
changes and migration actions. End with `COPYRIGHT | LICENSE | ATTRIBUTION`
|
||||
links to the corresponding module-local paths under
|
||||
`https://forge.maximumdirect.net/base-layer/commandkit/src/tag/integrations/ckconfig/v0.3.0/integrations/ckconfig/`.
|
||||
Future tag links need not resolve before publication. Preserve old notes.
|
||||
|
||||
**Stage result:** current owners describe implemented adoption and the interim
|
||||
module relationship; a checked-in candidate release note is ready. No deferred
|
||||
feature, release publication, or external application migration is claimed.
|
||||
|
||||
## Stage 5: Align module attribution with the actual selected graph
|
||||
|
||||
**Completed.** The workspace-off module graph selects ConfigKit v1.1.0 and
|
||||
vanity ReleaseKit v0.9.0; old-path ReleaseKit is no longer selected. Attribution
|
||||
now reflects that graph and the pinned ConfigKit copyright and license source.
|
||||
|
||||
1. From ckconfig, inspect `GOWORK=off GOTOOLCHAIN=local go list -m -json all`
|
||||
after tidy. Compare it with the existing module attribution. ConfigKit's
|
||||
own tool requirement does not select CommandKit's release tool: retain the
|
||||
root-selected ReleaseKit v0.9.0 and inspect the effective transitive graph.
|
||||
2. Update `integrations/ckconfig/docs/oss/attribution.md`'s ConfigKit entry to
|
||||
`go.maximumdirect.net/configkit v1.1.0` and pinned commit
|
||||
`191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9` on the new forge. Verify its
|
||||
actual copyright, grant, license, and applicable notices. Reuse existing
|
||||
complete standard license texts when they match the selected terms.
|
||||
3. Remove/update entries for dependencies no longer selected or whose selected
|
||||
versions changed; the baseline includes old-path ReleaseKit v0.4.1 and its
|
||||
dependencies as well as vanity ReleaseKit v0.9.0. Follow the actual graph,
|
||||
not a global old-host replacement or an assumption that every tool module
|
||||
disappears. Keep the House Format and exact-revision notice/source links.
|
||||
4. Core and ckprompt dependency selections remain unchanged. Preserve their
|
||||
corresponding notices and published release records. Update shared material
|
||||
only if its actual scope or selection changes; adoption alone does not
|
||||
require revising unrelated grants or copying upstream policy documents.
|
||||
|
||||
**Stage result:** ckconfig's notices correspond to its real selected modules,
|
||||
with authentic source/license references and no unrelated attribution rewrite.
|
||||
|
||||
## Stage 6: Validate the final state and finish the sprint
|
||||
|
||||
**Completed.** With Go 1.27.0 and workspace discovery off, the complete core,
|
||||
ckconfig, and ckprompt suites passed offline with read-only metadata. Ckconfig's
|
||||
suite was repeated after adding an explicit native main-layer explanation
|
||||
assertion. The simple example's text and YAML source reports and fixture diff
|
||||
ran successfully; the focused source fixture covers nonempty import evidence.
|
||||
Core and ckprompt were tested against their own declared dependency graphs,
|
||||
not against local migrated ckconfig. Full local workspace composition remains
|
||||
pending the later ckprompt migration. The v0.3.0 note is a candidate; no source
|
||||
release or hosted delivery was performed.
|
||||
|
||||
1. Format changed Go files; inspect final diffs and module metadata. Confirm
|
||||
ckconfig-owned Go imports use the vanity ConfigKit identity, the old
|
||||
requirement is gone, its Go minimum is 1.27.0, core stays at v0.3.0, and no
|
||||
local replacements/workspaces enter tracked module inputs. Confirm root
|
||||
and ckprompt still have their existing module selections and Go minima.
|
||||
2. Prepare any missing dependency caches for all three modules using normal
|
||||
retrieval with workspace discovery off. On Go 1.27.0, run each independent
|
||||
complete suite with read-only offline dependencies:
|
||||
|
||||
```sh
|
||||
GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off \
|
||||
go test -mod=readonly -count=1 ./...
|
||||
(cd integrations/ckconfig && \
|
||||
GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off \
|
||||
go test -mod=readonly -count=1 ./...)
|
||||
(cd integrations/ckprompt && \
|
||||
GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off \
|
||||
go test -mod=readonly -count=1 ./...)
|
||||
```
|
||||
|
||||
This includes ckconfig's maintained example tests. Record the unchanged
|
||||
modules' results as validation of their own published dependency graphs,
|
||||
not composition with local migrated ckconfig. Do not add a workspace shim
|
||||
or change ckprompt to obtain a green three-module workspace.
|
||||
3. Exercise the simple example's `config sources` text/YAML reports and its
|
||||
existing fixture comparison with workspace discovery off. Use a controlled
|
||||
native source fixture from Stage 3 for nonempty import evidence; a new
|
||||
application import system or live service is unnecessary. Confirm only the
|
||||
selected presentation and wiring behavior, not upstream domain correctness.
|
||||
4. Check affected current documentation, local links/fragments, whitespace,
|
||||
candidate note paths, attribution entries, and pinned-source provenance.
|
||||
Ensure future behavior is not described as implemented, and distinguish
|
||||
prepared v0.3.0 from a published release. Run `git diff --check` and the
|
||||
staged counterpart, including intended new files in the review.
|
||||
5. Record stage completion, final validation evidence, and the temporary
|
||||
workspace mismatch in this plan. Mark the feature roadmap's implementation
|
||||
status accordingly while leaving publication and external adoption pending.
|
||||
Keep deferred capabilities in their owning record without starting them.
|
||||
6. Review the worktree and staged changes, commit completed units under the
|
||||
agent policy with concise messages, and finish with a clean worktree apart
|
||||
from explicitly preserved unrelated work. Summarize the module/dependency
|
||||
changes, report migration, tests, commits, and remaining ckprompt follow-up.
|
||||
Do not publish; the normal selected-module release workflow remains the
|
||||
owner of future candidate validation, guards, and publication outcomes.
|
||||
|
||||
**Stage result:** the selected ckconfig adoption is implemented, documented,
|
||||
validated, committed, and prepared for a later release request. Intermediate
|
||||
compile failures and deferred work are not substitutes for this final result.
|
||||
|
||||
No required scope questions remain open. Routine implementation choices follow
|
||||
the selected upstream contracts and the report shape fixed above; deferred
|
||||
extensions do not need to be designed to complete this sprint.
|
||||
@@ -1,207 +0,0 @@
|
||||
# Integration dependency alignment and vanity-path migration
|
||||
|
||||
Status: the vanity migration and matched source releases are complete. The
|
||||
[completed implementation record](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/16584084b1b8a87dac959334ede8a47a8cfb8c0b/docs/roadmap/implementation.md) records candidate commits, validation,
|
||||
and publication outcomes; this roadmap retains the target and review history.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Align the independently released integrations with the core APIs their current
|
||||
source already uses, and migrate all three CommandKit modules to the supplied
|
||||
vanity paths. Publish compatible module versions in dependency order so each
|
||||
integration builds and validates against its declared, downloaded dependencies
|
||||
with workspace discovery off.
|
||||
|
||||
The [release procedure](../release.md) owns publication commands and release
|
||||
order. The [release policy](../policy/release.md),
|
||||
[agent policy](../policy/agents.md), [testing policy](../policy/testing.md),
|
||||
[documentation policy](../policy/documentation.md), and
|
||||
[OSS policy](../policy/oss.md) govern the work. This roadmap selects the target
|
||||
and release-preparation scope; it does not change those policies.
|
||||
|
||||
## Baseline and investigation evidence
|
||||
|
||||
Reviewed baseline: `289a171e97699ad9aa57ee2cc40bdad1c0b680a9`.
|
||||
Vanity-path review baseline: `d7cbaed3ed18bc2909c8144f308e2dfd58ade7ec`.
|
||||
Module declarations and library source were unchanged between these revisions.
|
||||
|
||||
- Both integration module declarations require core v0.2.0. The
|
||||
[ckprompt declaration](../../integrations/ckprompt/go.mod) also requires
|
||||
ckconfig v0.1.0; the [ckconfig declaration](../../integrations/ckconfig/go.mod)
|
||||
has no dependency on ckprompt.
|
||||
- Current integration source uses newer core APIs including `CompletionHint`,
|
||||
`Explanation`, and `Reporter`. Both independent Go 1.26.8 suites fail to
|
||||
compile with `GOWORK=off` and their existing read-only module graphs.
|
||||
- Updating core alone is insufficient for ckprompt: published ckconfig v0.1.0
|
||||
still uses removed core APIs, including `Invocation.Streams`,
|
||||
`Outcome.Diagnostics`, and `SeverityError`, plus the old `Failure(error)`
|
||||
call shape.
|
||||
- The authoritative `origin` tag listing contains core v0.1.0 and v0.2.0, and
|
||||
the two integration v0.1.0 tags. The proposed next versions below were unused
|
||||
at review. Remote `main` was `230187296fae5253cb1773f16c2f1d1a39499ed0`;
|
||||
the reviewed local changes still need normal publication to the authoritative
|
||||
branch as part of candidate preparation.
|
||||
- A checked-in [core v0.3.0 draft](../releases/v0.3.0.md) already describes the
|
||||
reporting and alias migration. It is an unpublished draft, not proof that
|
||||
the module version can be downloaded.
|
||||
|
||||
The investigation used disposable alternate module files, Go 1.26.8,
|
||||
`GOWORK=off`, and read-only offline tests. Only temporary dependency selections
|
||||
changed; the real module declarations, sums, and source remained unchanged.
|
||||
|
||||
| Current source under test | Temporary dependency selection | Result |
|
||||
| --- | --- | --- |
|
||||
| ckconfig | Current core source | Module suite and maintained example passed. |
|
||||
| ckprompt | Current core source, published ckconfig v0.1.0 | Compilation failed in the old ckconfig implementation. |
|
||||
| ckprompt | Current core and current ckconfig source | Module suite and maintained example passed. |
|
||||
|
||||
The successful cases retained ConfigKit v0.8.0 and PromptKit v0.16.0. These
|
||||
results isolate the CommandKit dependency alignment needed here; they do not
|
||||
prove that future published versions or their downloaded sums already exist.
|
||||
|
||||
### Verified vanity discovery
|
||||
|
||||
The core endpoint at `https://go.maximumdirect.net/commandkit?go-get=1` serves
|
||||
the mapping to `https://forge.maximumdirect.net/base-layer/commandkit`. Go direct
|
||||
discovery finds the existing core v0.1.0 and v0.2.0 tags. Fetching v0.2.0 through
|
||||
the vanity path reaches its source but reports a module-path mismatch because
|
||||
that release declares `gitea.maximumdirect.net/eric/CommandKit`.
|
||||
|
||||
Both integration endpoints now return HTTP 200 with these `go-import` contents:
|
||||
|
||||
| Vanity path | VCS | Repository URL | Subdirectory field |
|
||||
| --- | --- | --- | --- |
|
||||
| `go.maximumdirect.net/ckconfig` | `git` | `https://forge.maximumdirect.net/base-layer/commandkit` | `integrations/ckconfig` |
|
||||
| `go.maximumdirect.net/ckprompt` | `git` | `https://forge.maximumdirect.net/base-layer/commandkit` | `integrations/ckprompt` |
|
||||
|
||||
Go 1.26.8 direct discovery finds each integration's v0.1.0 tag. Disposable
|
||||
consumer fetches reach the correct nested `go.mod` and report its old declared
|
||||
module path, confirming subdirectory routing. Discovery is working; the
|
||||
existing tags have not migrated. The optional fourth metadata field is
|
||||
supported from Go 1.25, within the existing Go 1.26.0 consumer minimum; see the
|
||||
[Go discovery reference](https://go.dev/ref/mod#vcs-find).
|
||||
|
||||
## Targeted end state
|
||||
|
||||
### Compatible independently released modules
|
||||
|
||||
Use the following proposed next versions, subject to the existing fresh-version
|
||||
publication guards:
|
||||
|
||||
| Module path | Physical module directory | Next release | Required CommandKit dependencies | Full tag |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `go.maximumdirect.net/commandkit` | `.` | v0.3.0 | None | `v0.3.0` |
|
||||
| `go.maximumdirect.net/ckconfig` | `integrations/ckconfig` | v0.2.0 | `go.maximumdirect.net/commandkit v0.3.0` | `integrations/ckconfig/v0.2.0` |
|
||||
| `go.maximumdirect.net/ckprompt` | `integrations/ckprompt` | v0.2.0 | `go.maximumdirect.net/commandkit v0.3.0` and `go.maximumdirect.net/ckconfig v0.2.0` | `integrations/ckprompt/v0.2.0` |
|
||||
|
||||
Minor integration releases fit the existing pre-1.0 compatibility policy: the
|
||||
reporting migration changes consumer-facing behavior and adopts a core version
|
||||
with incompatible API changes. The vanity migration also deliberately changes
|
||||
Go module and import identities. Migration notes explain the new imports and
|
||||
dependency set, provider results, invocation reporting, and application changes.
|
||||
|
||||
The three modules retain independent versions and source tags. Their candidates
|
||||
may identify successive commits: core publication need not wait for integration
|
||||
metadata that depends on that newly published core. Each selected module's
|
||||
final release suite runs against its actual declared dependencies.
|
||||
|
||||
### Module and import identity
|
||||
|
||||
Change each module declaration and all CommandKit-owned imports to the matching
|
||||
new path. Core self-imports, including its `internal` packages, use
|
||||
`go.maximumdirect.net/commandkit/...`; integration self-imports use
|
||||
`go.maximumdirect.net/ckconfig/...` or `go.maximumdirect.net/ckprompt/...`.
|
||||
Cross-module imports and requirements use the complete new paths in the table,
|
||||
including ckprompt's ckconfig dependency. Core component-version discovery uses
|
||||
`go.maximumdirect.net/commandkit` as its build-info identity, retaining the
|
||||
existing `version --scope commandkit` behavior with the new module path.
|
||||
|
||||
Update production files, tests, maintained examples, and any import-path-based
|
||||
test expectations together. A declared vanity module that still imports the
|
||||
old core path would select a different Go package identity and can violate
|
||||
`internal` import rules. The matched new releases compose through one core
|
||||
identity rather than mixing old-path and new-path CommandKit types.
|
||||
|
||||
Keep physical directories, repository URLs, and Git tag prefixes as shown. The
|
||||
Go subdirectory metadata makes the short integration vanity paths resolve to
|
||||
the existing layout. The existing release profiles select physical directories;
|
||||
the migration does not rename those directories or flatten integration tags.
|
||||
|
||||
Published old-path versions remain immutable. This scope selects the new paths
|
||||
for new releases and updates consumer guidance; it makes no new promise of
|
||||
type interoperability between the two identities and adds no old-path forwarding
|
||||
module or compatibility layer.
|
||||
|
||||
### Retained architecture and scope
|
||||
|
||||
Preserve exported declaration shapes and runtime behavior while deliberately
|
||||
changing module/import identities. Retain the integration adapters, Go 1.26.0
|
||||
consumer minimum, Go 1.26.8 maintainer toolchain, and root-selected ReleaseKit
|
||||
v0.9.0. The earlier successful diagnostic suites establish the dependency fix
|
||||
before renaming; the migrated source still needs its own validation. This work
|
||||
selects no API rollback or shim for old reporting APIs.
|
||||
|
||||
Retain ConfigKit v0.8.0, PromptKit v0.16.0, and other dependency selections
|
||||
unless ordinary tidy changes the resolved graph as a consequence of the
|
||||
CommandKit updates. Inspect and explain the resulting graph rather than
|
||||
bundling unrelated upgrades. In particular, transitive tools with different
|
||||
module paths may coexist; attribution must reflect the actual selection.
|
||||
|
||||
Preserve the existing launchers, three release profiles, generic validators,
|
||||
credential handling, and separate source-publication and hosted-delivery
|
||||
outcomes. Development workspaces remain useful and ignored. Diagnostic local
|
||||
replacements and the earlier temporary Go shim remain development evidence;
|
||||
release validation uses normal downloaded dependencies without that redirection.
|
||||
|
||||
## Release-preparation deliverables
|
||||
|
||||
The core v0.3.0 draft describes the complete candidate, including completion,
|
||||
reporting, aliases, tool maintenance, and the vanity-path migration. New
|
||||
integration notes at `integrations/ckconfig/docs/releases/v0.2.0.md` and
|
||||
`integrations/ckprompt/docs/releases/v0.2.0.md` explain the matched dependency set
|
||||
and consumer migration. Their source and licensing links follow the current
|
||||
release procedure; published notes and tags remain immutable.
|
||||
|
||||
Current installation examples, README module selections, consumer/developer
|
||||
guidance, affected GoDoc, and maintained examples use the implemented new
|
||||
identities. Import-path-aware tests retain their existing boundary assertions.
|
||||
Source-hosting and license URLs remain repository links, distinct from Go
|
||||
import paths. Module-local attribution describes each actual resolved graph.
|
||||
|
||||
The final record identifies module paths, versions, candidate revisions,
|
||||
validation evidence, and independent source-publication outcomes. Current
|
||||
readiness guidance reflects the aligned state; historical failures remain in
|
||||
completed investigation records. The implementation plan owns the ordered
|
||||
migration, dependency preparation, release, and evidence-recording steps.
|
||||
|
||||
## Validation and completion boundaries
|
||||
|
||||
Review current CommandKit-owned source and dependency selections for stale
|
||||
self-imports or old direct dependency keys. Historical notes, source URLs, and
|
||||
unrelated upstream module identities are outside that mechanical rename.
|
||||
Confirm release identity still pairs each new module path with its existing
|
||||
physical directory and tag prefix. The verified redirects are preparation
|
||||
evidence; publishing the renamed modules is needed for real consumers to use
|
||||
them through those paths.
|
||||
|
||||
Use the selected module's ordinary deterministic offline suite with
|
||||
`GOWORK=off` and read-only metadata after dependency preparation. Its maintained
|
||||
consumer compiles and runs with that suite. ReleaseKit's publication command
|
||||
owns the final candidate suite and selected file checks; validation-only checks
|
||||
remain optional diagnostics. Reuse successful evidence for unchanged candidates
|
||||
instead of adding a required check-then-publish repetition.
|
||||
|
||||
Retrieving a newly published dependency is preparation for the next module's
|
||||
release. It does not turn proxy availability or consumer installation into a
|
||||
completion gate for the preceding source release. Continue to resolve failed
|
||||
or ambiguous publication using the existing policy and upstream recovery flow.
|
||||
Hosted Gitea delivery keeps its separate outcome; this roadmap adds no CI
|
||||
polling, live provider calls, or additional publication gate.
|
||||
|
||||
Alignment is complete when the matched source versions are published under all
|
||||
three vanity module paths, owned imports and examples use the new identities,
|
||||
each integration declares the compatible vanity-path versions with authentic
|
||||
downloaded sums, each final selected-module suite passes without workspace or
|
||||
replacement redirection, and current documentation and attribution agree with
|
||||
that graph. Temporary local-source success alone does not establish that end
|
||||
state.
|
||||
@@ -1,198 +0,0 @@
|
||||
# Release tooling simplification
|
||||
|
||||
Status: the selected release-tooling design has been implemented. All four
|
||||
generic file checks, registered-tool execution, page-only hosted delivery, and
|
||||
protection of the supplied token path are selected.
|
||||
The [completed implementation record](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/87eb84ccb462bf54e6250c8b287ac217efe90883/docs/roadmap/implementation.md)
|
||||
contains stage order, tasks, validation, and completion evidence. Current release
|
||||
behavior stays with its canonical owners.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Reduce CommandKit's release infrastructure to declarative module profiles,
|
||||
a small launcher, and focused tests of CommandKit-owned wiring. Delegate
|
||||
reusable candidate validation and publication mechanics to ReleaseKit while
|
||||
retaining CommandKit's domain-specific checks in their existing owners. Add
|
||||
hosted Gitea release pages as a separate local delivery operation after source
|
||||
publication.
|
||||
|
||||
The [agent policy](../policy/agents.md),
|
||||
[release policy](../policy/release.md#candidate-validation), and
|
||||
[testing policy](../policy/testing.md#upstream-integration-testing-ownership)
|
||||
govern implementation. The [release procedure](../release.md) continues to own
|
||||
the current workflow.
|
||||
|
||||
## Targeted end state
|
||||
|
||||
### Ownership
|
||||
|
||||
CommandKit retains module selectors, product identities, profile locations,
|
||||
the authoritative endpoint selection, release order, release-note meaning,
|
||||
compatibility decisions, and attribution accuracy. Its existing public API,
|
||||
CLI, integration-adaptation, and consumer-example tests remain local and run
|
||||
through the owning module's suite. No parallel release-only domain suite is
|
||||
needed unless a concrete CommandKit requirement is otherwise unprotected.
|
||||
|
||||
ReleaseKit supplies the standard offline candidate suite, selected generic file
|
||||
checks, candidate/note and publication guards, tag creation and publication,
|
||||
hosted delivery, outcome reporting, and recovery. CommandKit's launcher delegates
|
||||
those operations. Existing source-release completion and immutability rules
|
||||
continue to apply. Hosted pages are the added delivery channel; binary
|
||||
deliverables and platform support commitments remain unchanged.
|
||||
|
||||
### Profiles
|
||||
|
||||
Select these existing ReleaseKit options in each profile:
|
||||
|
||||
| Selection | Intended protection |
|
||||
| --- | --- |
|
||||
| `validation.go_format: true` | Detect unformatted committed Go source. |
|
||||
| `validation.markdown: {}` | Detect broken local Markdown destinations and supported heading fragments. |
|
||||
| `validation.module_distribution.workspace_files: true` | Detect committed development workspace files in selected inputs. |
|
||||
| `validation.module_distribution.local_replacements: true` | Detect filesystem replacements in selected committed module declarations. |
|
||||
|
||||
Also select
|
||||
`validation.forbidden_files: [".releasekit/gitea-token"]` in all three profiles.
|
||||
This delegates protection of the supplied credential path to ReleaseKit's
|
||||
existing check. The path is repository-relative and the check applies across
|
||||
the captured repository even for an integration release. It does not read token
|
||||
contents, scan other paths, or inspect Git history.
|
||||
|
||||
Retain the explicit shared-file lists and use ReleaseKit's existing input scope.
|
||||
The root profile does not run every nested module's suite. File checks inspect
|
||||
committed inputs and do not replace formatting worktree changes or reviewing
|
||||
documentation meaning, attribution, and external links. Markdown keeps its
|
||||
default treatment of outside-checkout destinations; no stricter boundary mode
|
||||
is proposed.
|
||||
|
||||
The pinned [ReleaseKit configuration reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/config.md)
|
||||
owns exact scope and behavior, including nested-module boundaries and vendored
|
||||
inputs. Do not expand an option's scope into a general repository prohibition.
|
||||
Race testing, full vet, compilation matrices, size limits, and additional
|
||||
forbidden-file paths are not selected by this roadmap. They can be considered
|
||||
separately for demonstrated needs.
|
||||
|
||||
### Launcher and recovery
|
||||
|
||||
Use the root module's registered `go tool releasekit` through `exec`, keeping
|
||||
the current selector interface and publication argument mapping.
|
||||
Retain host normalization, workspace-off execution, the local toolchain, and
|
||||
read-only module metadata. Preserve other effective Go settings while arranging
|
||||
read-only selection.
|
||||
The implementation plan specifies the wrapper interface and invocation details.
|
||||
|
||||
Go's cache supplies executable storage; the launcher creates no persistent
|
||||
binary directory. `/.releasekit/` remains ignored for the credential file, with
|
||||
an explanatory comment. Recovery instructions use the registered tool or the
|
||||
entry point printed for the saved attempt, preserving ReleaseKit's distinction
|
||||
between publication outcome and record-storage errors.
|
||||
|
||||
Share module selection and host-safe tool invocation between publication,
|
||||
delivery, and recovery where applicable. Delivery selects the same module
|
||||
profile as publication; recovery uses its recorded attempt rather than inferring
|
||||
identity from a current profile. Keep the existing publication interface and
|
||||
provide an explicit delivery invocation without automatically chaining the two
|
||||
operations. Keep one selector mapping and shared invocation plumbing.
|
||||
|
||||
ReleaseKit v0.9.0 shipped host-safe consumer launcher examples and regression
|
||||
coverage. The earlier simplification used v0.8.0, which already supported
|
||||
registered tools. Keep host normalization locally because the reviewed
|
||||
`go tool` invocation inherited foreign `GOOS`/`GOARCH` values and failed to run.
|
||||
Do not switch tool-version selection from the root module to each integration
|
||||
merely to match the upstream multi-module example.
|
||||
|
||||
### Hosted Gitea release pages
|
||||
|
||||
Configure this delivery selection in each module profile:
|
||||
|
||||
| Field | Selected value |
|
||||
| --- | --- |
|
||||
| `delivery.forge` | `gitea` |
|
||||
| `delivery.base_url` | `https://forge.maximumdirect.net` |
|
||||
| `delivery.owner` | `base-layer` |
|
||||
| `delivery.repository` | `commandkit` |
|
||||
| `delivery.token_file` | `.releasekit/gitea-token` |
|
||||
|
||||
Preserve the profiles' distinct product identities and physical module
|
||||
directories. All pages belong to the same Gitea repository and are keyed by
|
||||
the complete tag: `vX.Y.Z` for core, `integrations/ckconfig/vX.Y.Z` for ckconfig,
|
||||
and `integrations/ckprompt/vX.Y.Z` for ckprompt. Pass the selected profile and
|
||||
semantic version to `deliver`; ReleaseKit derives the complete module tag.
|
||||
|
||||
With no build targets, delivery is page-only. ReleaseKit uses the complete
|
||||
checked-in module release note, including its licensing footer, as the hosted
|
||||
body. No binary assets, receipts, or checksum manifests are added. Use current
|
||||
forge URLs and the full module tag for future notes' immutable source and
|
||||
licensing links. Existing published tags and notes remain unchanged.
|
||||
|
||||
After source publication succeeds, explicitly invoke delivery from a clean
|
||||
checkout whose `HEAD` identifies that published tag's commit. For later retries,
|
||||
use the original tagged source and its recorded module files. Report the source
|
||||
publication outcome and hosted-delivery outcome separately, including the hosted
|
||||
URL on success. A delivery failure leaves the source release complete; repair
|
||||
delivery without republishing or moving its tag.
|
||||
|
||||
Delivery performs its own read-only credential preflight, without rerunning
|
||||
candidate validation or publishing a tag. Hosted-service availability and the
|
||||
Gitea token do not become source-publication gates. A nonblank
|
||||
`RELEASEKIT_GITEA_TOKEN` environment value takes precedence over the configured
|
||||
file. The file path resolves from the repository root for all three modules.
|
||||
|
||||
ReleaseKit accepts matching hosted content and reports conflicting content
|
||||
without overwriting it. Resolve uncertain hosted writes before retrying the
|
||||
same immutable version. The pinned
|
||||
[delivery guide](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/consumers/delivery.md)
|
||||
owns exact delivery behavior and recovery. Start with tags containing the new
|
||||
delivery configuration; historical page backfilling remains a separate decision.
|
||||
This local workflow needs no CI delivery job or additional secret distribution.
|
||||
|
||||
### Focused local tests
|
||||
|
||||
Replace the release-test scaffolding with a small controlled Go-command boundary
|
||||
that invokes the actual launcher. Cover:
|
||||
|
||||
- Selector-to-profile/module routing for core, ckconfig, and ckprompt, including
|
||||
consistency with the checked-in profiles' intended module and product.
|
||||
- Invalid argument handling before tool invocation.
|
||||
- Invocation from another directory and paths containing spaces.
|
||||
- Host normalization and workspace/toolchain/read-only settings.
|
||||
- Publication and delivery argument, output-stream, and child exit-status
|
||||
forwarding, with the selected module profile reaching the delivery operation.
|
||||
- Profile wiring for the shared Gitea destination, token path, and its selected
|
||||
committed-path protection; assertions do not read the credential file.
|
||||
|
||||
Exercise module routing separately from exit statuses rather than multiplying
|
||||
every combination. Assert behavior and meaningful selections, not helper
|
||||
implementation details or exact usage prose.
|
||||
|
||||
The resulting local suite omits the disposable publication exercise, generic
|
||||
tag inspection, assertion-helper self-tests, and custom build-call log/parser.
|
||||
Upstream publication and delivery coverage owns those generic behaviors. No
|
||||
replacement publication engine or exported test-helper API is needed. There is
|
||||
no line-count target for the replacement tests.
|
||||
|
||||
## Selected choices and rationale
|
||||
|
||||
All four generic file checks are selected as release-time checks, in addition
|
||||
to the agreed forbidden token path. Formatting and local-link validation automate
|
||||
existing contributor review work. Workspace-file and filesystem-replacement
|
||||
checks address accidental inclusion of development metadata that a successful
|
||||
local test run can overlook. This adds specific release checks; it does not
|
||||
make every optional ReleaseKit validator mandatory or prohibit development
|
||||
workspaces and replacements outside the selected committed candidate inputs.
|
||||
Selecting only formatting and Markdown would change less release behavior, but
|
||||
would leave these distribution mistakes to manual review. The selected upstream
|
||||
checks avoid a second local implementation.
|
||||
|
||||
Host-normalized registered-tool execution is selected because the root module
|
||||
already registers ReleaseKit and Go caches the executable. Retaining a persistent
|
||||
native executable would provide a recovery entry point independent of a later
|
||||
Go-driver invocation, but would retain executable-storage and bootstrap test
|
||||
maintenance. Recovery instead uses the registered tool or ReleaseKit's reported
|
||||
entry point. The credential directory remains ignored under either approach.
|
||||
|
||||
The implementation plan records the existing integration dependency-version
|
||||
mismatch separately from validation of the current source. This infrastructure
|
||||
sprint does not publish releases or select new library dependency versions.
|
||||
Historical hosted-page backfilling and CI delivery remain separate future
|
||||
choices, not prerequisites for the selected local page-only workflow.
|
||||
@@ -1,184 +0,0 @@
|
||||
# ReleaseKit v0.9.0 adoption
|
||||
|
||||
Status: R1 and R2 remediation, ReleaseKit v0.9.0 adoption, and the completion
|
||||
assertion repair are complete. The [completed implementation record](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/c8d659dfe5ae3e834b3aeabdfd0fe29b736dc05a/docs/roadmap/implementation.md)
|
||||
records stage order, tasks, and validation evidence. This document owns the
|
||||
target and selected choices; it does not authorize source or hosted publication.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Adopt ReleaseKit v0.9.0's improved recovery behavior while preserving
|
||||
CommandKit's existing release-tooling architecture. Update current dependency
|
||||
and maintainer documentation together, and make the validation evidence clear
|
||||
about existing local defects.
|
||||
|
||||
The [agent policy](../policy/agents.md),
|
||||
[release policy](../policy/release.md#candidate-validation),
|
||||
[testing policy](../policy/testing.md#upstream-integration-testing-ownership),
|
||||
and [documentation policy](../policy/documentation.md) govern the work. Current
|
||||
behavior remains owned by the [release procedure](../release.md), Go declarations,
|
||||
and owning package tests until implementation updates them.
|
||||
|
||||
## Current baseline and review evidence
|
||||
|
||||
Reviewed CommandKit code baseline: `4d92ee4ee6a8403b22a4172e0f04face802b9499`.
|
||||
The original upgrade review used `98e7e9933353cf43f2be4a96cb0436a0bce068d2`;
|
||||
its findings and validation history are retained below.
|
||||
|
||||
- The root [module](../../go.mod) selects
|
||||
`go.maximumdirect.net/releasekit v0.8.0` as a Go tool. Its selected version
|
||||
serves core, ckconfig, and ckprompt operations.
|
||||
- The [shared helper](../../scripts/releasekit) already normalizes the Go host,
|
||||
disables workspace discovery, selects the local toolchain, retains read-only
|
||||
metadata, and invokes the full executable package path. The
|
||||
[legacy entry point](../../scripts/release) delegates publication to it.
|
||||
- All three profiles already select the agreed generic file checks, forbidden
|
||||
token path, and page-only Gitea destination. Source publication and hosted
|
||||
delivery are separate operations. The local token directory remains ignored.
|
||||
- [R1 and R2](remediation.md) are complete. Commit `7eac3fe` rejects invalid
|
||||
legacy selectors before invoking Go; commit `4d92ee4` restores explicit,
|
||||
optional POSIX-shell invocation in launcher tests. The remediation record owns
|
||||
their acceptance evidence, including passing focused tests, shell syntax
|
||||
checks, and profile assertions running when no shell is available.
|
||||
- Both integrations still require older published CommandKit dependencies than
|
||||
their current source needs. The completed [release-tooling implementation record](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/87eb84ccb462bf54e6250c8b287ac217efe90883/docs/roadmap/implementation.md#stage-5-verify-the-final-source-and-record-validation-boundaries)
|
||||
distinguishes workspace-backed tests from independent release readiness.
|
||||
|
||||
The upstream v0.9.0 tag identifies commit
|
||||
`2180aa868ec2caa95fc8279fd59d5f0ebac41bd4`. The tag and direct Go-module
|
||||
resolution were verified. The default proxy initially returned v0.8.0 for
|
||||
`@latest`; select v0.9.0 explicitly rather than changing repository-wide proxy
|
||||
settings to work around that observation.
|
||||
|
||||
Upstream [release notes](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/docs/releases/v0.9.0.md)
|
||||
describe host-safe launchers and generated recovery commands, full package-path
|
||||
tool selection, preservation of wildcard and version-specific replacements in
|
||||
API-only recovery, and safer manual hosted-page retries. Public Go APIs,
|
||||
profiles, record formats, and the Go 1.26.0 consumer minimum remain unchanged.
|
||||
The v0.8.0-to-v0.9.0 comparison also left upstream module requirements, checksums,
|
||||
copyright, and license texts unchanged.
|
||||
|
||||
A disposable CommandKit upgrade changed only the selected ReleaseKit version in
|
||||
`go.mod`. With Go 1.26.8, the root suite passed on a subsequent run, both
|
||||
workspace-backed integration suites passed, and the real helper reported v0.9.0
|
||||
under foreign target settings. No production publication or delivery was run.
|
||||
|
||||
A later disposable review at `7eac3fe` confirmed that downloading and tidying
|
||||
v0.9.0 changed only the ReleaseKit requirement and its checksum entries. The
|
||||
offline root suite and both workspace-backed integration suites passed with
|
||||
Go 1.26.8, and the helper reported v0.9.0 under Windows/ARM64 target settings.
|
||||
That snapshot excluded the then-uncommitted R2 change; it does not replace
|
||||
validation of the eventual adoption commit.
|
||||
|
||||
The initial upgrade run failed in
|
||||
[`TestCompletionCommandContext`](../../completion_context_test.go). The same
|
||||
alias-order failure reproduced four times in 30 focused repetitions on the
|
||||
unchanged v0.8.0 baseline. A single passing rerun therefore does not establish
|
||||
stable validation. The test compares an internal alias slice in a fixed order;
|
||||
commit `0acbbf4` deliberately changed completion to use unsorted lookup records
|
||||
before this upgrade review.
|
||||
|
||||
## Targeted end state
|
||||
|
||||
### Tool adoption and retained architecture
|
||||
|
||||
The root module selects ReleaseKit v0.9.0 with authentic downloaded checksums.
|
||||
Its existing tool declaration and root-owned selection remain. No integration
|
||||
dependency version, library import path, Go minimum, or selected Go 1.26.8
|
||||
maintainer toolchain changes as part of adoption.
|
||||
|
||||
Keep host normalization and full-package invocation in the existing helper:
|
||||
upgrading a dependency does not update or replace local shell scripts. Keep one
|
||||
module/profile mapping and the established wrapper forms. Retain the selected
|
||||
profiles, token-file handling, credential-directory ignore rule, and separation
|
||||
of source and hosted outcomes. No new validator, binary target, CI workflow,
|
||||
publication channel, credential preflight gate, or runtime API is needed.
|
||||
|
||||
The new generated Go recovery commands complement the helper's existing host
|
||||
handling. Recovery continues to use saved publication evidence and the upstream
|
||||
record formats; CommandKit does not acquire a parallel recovery implementation.
|
||||
|
||||
### Release-code simplification review
|
||||
|
||||
The v0.9.0 review identified no additional local release implementation to remove.
|
||||
The earlier simplification already delegated generic validation, publication,
|
||||
delivery, and recovery to ReleaseKit. This release improves launcher examples
|
||||
and generated recovery commands without adding validation options that replace
|
||||
the remaining CommandKit code.
|
||||
|
||||
Retain the shared helper's module/profile selection and execution environment.
|
||||
Host normalization must happen before Go compiles and runs ReleaseKit. Retain
|
||||
the legacy publication wrapper to preserve the established maintainer interface.
|
||||
The upstream multi-module launcher example adds a module map and temporary
|
||||
metadata preparation for a different tool-selection model; replacing our
|
||||
root-owned registered-tool helper with it would add machinery.
|
||||
|
||||
Retain the focused [wiring tests](../../scripts/release_test.go) for profile
|
||||
selections, argument forwarding, environment, streams, status, and optional-shell
|
||||
handling. ReleaseKit owns validation and recovery semantics; CommandKit's tests
|
||||
continue to cover its own adapter. The adoption work therefore preserves the
|
||||
release-code structure while updating the dependency and documentation, alongside
|
||||
the separately planned completion assertion repair.
|
||||
|
||||
### Current documentation and history
|
||||
|
||||
Current release procedure, project-specific release policy, consumer Go-tool
|
||||
selection summary, and root attribution describe v0.9.0. Upstream contract and
|
||||
notice links use the corresponding immutable source revision. Record that the
|
||||
host-safe launcher request has shipped upstream instead of describing it as
|
||||
pending in the earlier feature roadmap.
|
||||
|
||||
Continue linking to upstream recovery and delivery contracts from the maintainer
|
||||
procedure. Use ReleaseKit's generated recovery commands and keep local guidance
|
||||
focused on CommandKit's entry points and selections.
|
||||
|
||||
Preserve the baseline and validation history in completed implementation and
|
||||
review records. Do not mechanically replace every historical v0.8.0 reference.
|
||||
Integration attribution describes its own selected published dependency graph;
|
||||
update it only if that actual selection changes. No license-text replacement
|
||||
is needed for the unchanged upstream texts.
|
||||
|
||||
### Completed remediation and remaining correctness work
|
||||
|
||||
R1 and R2 were delivered before the dependency upgrade, with their completion
|
||||
markers and acceptance evidence in [remediation.md](remediation.md). Preserve
|
||||
their selector rejection, legitimate raw helper forms, and optional-shell test
|
||||
boundary during adoption; no further implementation of those findings remains.
|
||||
|
||||
The completion assertion compares the expected alias source/target records
|
||||
without depending on their iteration order, while detecting missing, unexpected,
|
||||
or duplicate records. Its routing and visible-completion assertions remain.
|
||||
Production alias ordering and public contracts are unchanged. This correction
|
||||
was completed as part of the maintenance scope, separate from R1/R2 remediation;
|
||||
the implementation plan records the test changes and focused verification.
|
||||
|
||||
Ordinary releases retain their single selected-module publication suite and
|
||||
separate hosted-delivery outcome. One-time upgrade diagnostics are maintenance
|
||||
evidence, with no new recurring release gate. Credentials and live publication
|
||||
are unnecessary for this adoption.
|
||||
|
||||
## Completion evidence
|
||||
|
||||
Adoption is demonstrated by authentic module metadata, the real helper reporting
|
||||
v0.9.0 for the host, aligned current documentation and attribution, and recorded
|
||||
validation of the final source. The reviewed upgrade introduced no other module
|
||||
version change; verify rather than assume that result during implementation.
|
||||
|
||||
R1/R2 acceptance evidence is complete in the remediation record. Completion of
|
||||
the remaining maintenance work also includes a stable, order-independent
|
||||
completion assertion and validation that the adopted helper retains the
|
||||
corrected launcher behavior. Independent integration dependency alignment
|
||||
remains separate release-preparation work; this roadmap selects no future
|
||||
versions or sums.
|
||||
|
||||
## Resolved choices
|
||||
|
||||
R1 and R2 were corrected in separate commits before adoption, resolving the
|
||||
former OD-1 scheduling question. Their acceptance evidence remains in
|
||||
[remediation.md](remediation.md).
|
||||
|
||||
The selected maintenance scope is the completion assertion repair, root tool
|
||||
upgrade, aligned current documentation and attribution, and validation of the
|
||||
resulting source. The older integration dependency-version mismatch remains
|
||||
separate release-preparation work. The implementation plan defines execution
|
||||
and commit sequencing.
|
||||
@@ -1,116 +0,0 @@
|
||||
# Release tooling review findings
|
||||
|
||||
Status: R1 and R2 complete; no open findings. Review baseline:
|
||||
`124a9fa57fb3f815bedbafe2d4819f6aa265ee7d`, covering the implementation commits
|
||||
after `cb40f1d`. The findings below preserve the review evidence; completion
|
||||
markers record the subsequent corrections. No implementation was changed during
|
||||
the original review.
|
||||
|
||||
The selected architecture is substantially present: three declarative profiles,
|
||||
one host-normalized registered-tool helper, separate publication and page-only
|
||||
delivery, retained credential-directory ignoring, and focused wiring tests.
|
||||
Both issues identified by the review have been addressed.
|
||||
|
||||
## R1 — P2: Reject raw helper command names as legacy module selectors
|
||||
|
||||
**Completed.** The legacy entry point now checks its three module selectors
|
||||
before delegating to the helper, retaining the single profile/module mapping
|
||||
there. Regression cases cover all three raw-command collisions and require
|
||||
usage status 2 with no Go invocation. The new regression failed before the fix;
|
||||
the complete focused scripts suite and shell syntax checks passed afterward
|
||||
with Go 1.26.8, including valid legacy and direct raw-command forwarding.
|
||||
|
||||
**Location:** [scripts/release](../../scripts/release), lines 9–10, delegating to
|
||||
the first-argument dispatch in [scripts/releasekit](../../scripts/releasekit),
|
||||
lines 10–15. The invalid-form cases in
|
||||
[scripts/release_test.go](../../scripts/release_test.go), lines 186–200, miss
|
||||
these collisions.
|
||||
|
||||
The legacy interface is `scripts/release MODULE VERSION`, with three module
|
||||
selectors. It now delegates its first argument directly into a helper that also
|
||||
accepts `version`, `publication-attempts`, and `reconcile` as raw commands. These
|
||||
invalid module names consequently bypass selector rejection and invoke Go.
|
||||
|
||||
For example, `./scripts/release version v1.2.3` reaches the tool as
|
||||
`version publish v1.2.3`. With the real pinned tool it returns upstream's
|
||||
"version takes no arguments" diagnostic after tool resolution. In a disposable
|
||||
copy with a controlled Go boundary returning status 73, each of the three raw
|
||||
command names returned 73 and invoked Go; an ordinary unknown selector returned
|
||||
2 without invoking Go. Thus invalid legacy input depends on tool availability
|
||||
and behavior instead of being rejected at the wrapper boundary.
|
||||
|
||||
**Required correction:** Make legacy module selection unambiguous before raw
|
||||
command dispatch. Keep one profile/module mapping and the supported raw helper
|
||||
forms; a small selector check is preferable to another routing framework.
|
||||
Preserve upstream ownership of version and flag validation.
|
||||
|
||||
**Verification:** Add all three raw command names as invalid legacy selectors.
|
||||
Each must return usage status 2 before any Go command runs. Valid legacy
|
||||
publication and the helper's direct raw forms must retain their forwarding and
|
||||
exit-status behavior. This restores the requested malformed-wrapper handling;
|
||||
it adds no new accepted-version restriction.
|
||||
|
||||
## R2 — P2: Restore the tests' optional POSIX-shell execution boundary
|
||||
|
||||
**Completed.** Launcher execution tests now discover `sh`, invoke it explicitly
|
||||
with the script path, and skip when it is unavailable. Profile assertions remain
|
||||
independent of shell availability. A regression case removes the fixture
|
||||
script's executable permission to verify interpreter invocation; it failed
|
||||
before the correction and passes afterward. The focused scripts suite and shell
|
||||
syntax checks passed with Go 1.26.8 on the available POSIX host. Running the
|
||||
compiled test binary with an empty `PATH` confirmed that every launcher
|
||||
execution case skips while all three profile assertions pass. Native Windows
|
||||
execution was not tested and no new platform guarantee is introduced.
|
||||
|
||||
**Location:** [scripts/release_test.go](../../scripts/release_test.go), especially
|
||||
`fixture.run` at line 63 and the launcher test setup.
|
||||
|
||||
The rewritten tests execute extensionless POSIX shell scripts directly through
|
||||
`exec.Command`. They neither discover a shell nor skip launcher execution when
|
||||
it is unavailable. The previous suite resolved `sh`, skipped shell-dependent
|
||||
tests when it was missing, and passed the script as an argument to that shell.
|
||||
|
||||
Direct execution works on this review's Linux host, but relies on Unix script
|
||||
execution semantics. Native Windows process creation does not supply a POSIX
|
||||
interpreter for these files. Go's
|
||||
[os/exec documentation](https://pkg.go.dev/os/exec#hdr-Overview) explicitly notes
|
||||
that it does not invoke a system shell. Consequently the default repository
|
||||
suite now fails on hosts without compatible script execution rather than
|
||||
preserving the previous optional-shell behavior. This portability finding is
|
||||
based on the changed execution path and platform implementation; a native
|
||||
Windows test run was not available during review.
|
||||
|
||||
**Required correction:** Discover a POSIX shell for launcher execution tests,
|
||||
invoke it explicitly with the script path, and skip those tests when the shell
|
||||
is unavailable. Keep profile-only JSON assertions runnable without requiring a
|
||||
shell. Preserve the reduced test architecture and existing argv/status checks.
|
||||
No native Windows release launcher or additional supported-platform guarantee
|
||||
is requested.
|
||||
|
||||
**Verification:** Confirm that launcher tests use the discovered interpreter
|
||||
and handle its absence explicitly, while profile assertions still run. Rerun
|
||||
the focused suite on the available POSIX host. Broader platform matrices are
|
||||
not a new release gate; this correction removes an incidental environment
|
||||
restriction introduced by the test rewrite.
|
||||
|
||||
## Review evidence and limits
|
||||
|
||||
- Go 1.26.8 offline root tests and the temporary-workspace suites for both
|
||||
integrations passed. Both production scripts passed shell syntax checks.
|
||||
- The real helper reported ReleaseKit v0.8.0 under foreign target settings.
|
||||
- ReleaseKit checks passed for a disposable committed source snapshot using
|
||||
the actual profiles: ordinary root validation, then both integration checks
|
||||
with the implementation plan's temporary workspace-backed test process.
|
||||
Selected file checks continued to inspect the committed declarations.
|
||||
- Local documentation destinations and applicable Markdown fragments passed
|
||||
inspection. The credential file remained ignored and its contents were not
|
||||
read. No real publication or hosted-delivery operation was invoked.
|
||||
- Library code and dependency declarations were unchanged by the sprint. The
|
||||
documented integration dependency-version mismatch remains a pre-existing
|
||||
independent-release-readiness limitation; the workspace-backed results do
|
||||
not establish that published dependencies are aligned.
|
||||
|
||||
No additional architecture gaps or unrequested runtime/public-API guarantees
|
||||
were identified. The selected file checks and forbidden token path match the
|
||||
finalized scope. R2 concerns the default tests' execution environment rather
|
||||
than a new production validator or library contract.
|
||||
@@ -1,890 +0,0 @@
|
||||
# Output policy and invocation reporting
|
||||
|
||||
Status: behavioral decisions selected through OD-4. Message categories, all four
|
||||
output modes, uniform treatment of help and version, message prefixes, and
|
||||
OD-1's flag grammar and scope (including independent Progress control) are selected.
|
||||
OD-2's unified reporting direction, the terminal failure model, and application
|
||||
ownership of domain-specific error decisions are selected.
|
||||
OD-3's failure presentation and retention boundaries are selected.
|
||||
OD-4's delivery lifecycle, write-failure handling, and quiet-mode rendering are
|
||||
selected. The consumer API signatures, presentation-result model, provider
|
||||
diagnostic boundary, fallback explanations, and rendering callback boundary
|
||||
below are also selected. Architectural preparation is complete:
|
||||
[ADR 0014](../adr/0014-invocation-reporting.md) is accepted, and the
|
||||
[architecture policy](../policy/architecture.md) is aligned. Implementation and
|
||||
final validation are complete; Stages 1–20 are complete. The [implementation
|
||||
plan](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/230187296fae5253cb1773f16c2f1d1a39499ed0/docs/roadmap/implementation.md) records the stage order and validation evidence.
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide consistent handling of `--quiet`, `--verbose`, `--debug`, and
|
||||
`--progress` across application commands and optional integrations. Reduce
|
||||
repeated output classification, diagnostic presentation, and delivery bookkeeping
|
||||
where CommandKit can provide a meaningful benefit.
|
||||
|
||||
Ordinary Go writers and formatting functions already make application output
|
||||
straightforward. Design reporting conveniences around the shared output policy
|
||||
and invocation lifecycle. Applications continue to own their report content,
|
||||
domain behavior, and operation outcomes.
|
||||
|
||||
## CLI presentation and error-handling ownership
|
||||
|
||||
Applications decide how to respond to domain-specific errors: recover, retry,
|
||||
continue silently, report a Warning, or end the invocation with a failure.
|
||||
CommandKit may provide shared helpers for carrying, inspecting, and presenting
|
||||
errors while leaving those decisions with the application. A Go `error` alone
|
||||
does not determine a CLI message category. Warnings may describe issues with or
|
||||
without an underlying Go error, and handling an error does not require emitting
|
||||
a message.
|
||||
|
||||
CommandKit handles the presentation the application requests: message category,
|
||||
visibility, formatting, timing, and delivery. For terminal application failures,
|
||||
the application supplies a non-zero outcome and an operator-facing explanation.
|
||||
It may also supply an optional Go error cause for the execution caller to inspect.
|
||||
CommandKit preserves that cause and its existing `errors.Is`/`errors.As` behavior.
|
||||
Supplying a cause alone does not select an outcome, generate an operator-facing
|
||||
message, or change visibility.
|
||||
|
||||
Applications can explicitly present `err.Error()` as a Warning through the
|
||||
ordinary message API, illustrated by `report.Warn(err.Error())`. Defer a separate
|
||||
`WarnError` convenience helper pending demonstrated value; this conversion
|
||||
already requires little code.
|
||||
|
||||
CommandKit retains responsibility for handling its own errors, including
|
||||
routing, parsing, and reporting failures. Integration-owned commands similarly
|
||||
adapt their upstream APIs into deliberate command outcomes and presentations.
|
||||
Ordinary Go error returns from CommandKit APIs and writers remain available where
|
||||
appropriate.
|
||||
|
||||
## Current baseline
|
||||
|
||||
[`Streams` and `Invocation`](../../identity.go) expose caller-selected output
|
||||
and diagnostic writers. [`Outcome` and `Diagnostic`](../../outcome.go) carry
|
||||
operation causes, diagnostic writers, and delivery state. Handlers can return
|
||||
`Failure(err)` or attach diagnostics to an outcome for presentation after the
|
||||
handler returns. `MessageDiagnostic` currently writes the supplied message with
|
||||
a newline; severity does not add a label automatically.
|
||||
|
||||
CommandKit coordinates final diagnostic delivery and retains delivery failures
|
||||
separately from the operation cause. Custom handlers can also write directly to
|
||||
the supplied streams and retain responsibility for their output. The existing
|
||||
outcome and channel ownership decisions are recorded in
|
||||
[ADR 0005](../adr/0005-invocation-outcomes.md).
|
||||
|
||||
Integration adapters already translate upstream diagnostic records into
|
||||
CommandKit diagnostics while preserving native rendering and source context.
|
||||
Some adapters wrap multiple records in one diagnostic writer and classify the
|
||||
batch by its highest severity. This matters when designing selective visibility.
|
||||
|
||||
There is currently no shared verbosity policy or invocation reporter API.
|
||||
|
||||
## Selected output policy
|
||||
|
||||
Distinguish substantive application output from diagnostic message categories:
|
||||
|
||||
- **Substantive output (Normal):** The requested report or command result.
|
||||
- **Error:** Terminal presentation of an unrecoverable invocation failure,
|
||||
resulting in a non-zero status code.
|
||||
- **Warning:** Something went wrong or deserves attention, but the invocation
|
||||
can still succeed. The application chooses whether to report such an issue.
|
||||
- **Info:** Informational context and useful explanation, such as which profile
|
||||
was selected or a final operation summary.
|
||||
- **Progress:** Streaming updates about work underway, such as items processed.
|
||||
- **Debug:** Troubleshooting detail, including intermediate decisions and
|
||||
execution-path information.
|
||||
|
||||
Debug mode adds troubleshooting detail to verbose output:
|
||||
|
||||
| Output category | `--quiet` | No flag | `--verbose` | `--debug` |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Substantive application output | Suppressed | Shown | Shown | Shown |
|
||||
| Error | Shown | Shown | Shown | Shown |
|
||||
| Warning | Suppressed | Suppressed | Shown | Shown |
|
||||
| Info | Suppressed | Suppressed | Shown | Shown |
|
||||
| Debug | Suppressed | Suppressed | Suppressed | Shown |
|
||||
| Progress, without an explicit setting | Suppressed | Suppressed | Suppressed | Shown |
|
||||
|
||||
Info belongs in verbose mode; debug includes verbose messages. Normal output
|
||||
remains a substantive result category, separate from diagnostic severity.
|
||||
The category of a message determines its visibility; stream destination alone
|
||||
cannot distinguish a warning from an error.
|
||||
|
||||
Progress is distinct from Info and is controlled separately as specified below.
|
||||
Applications and integrations are not required to generate messages in any
|
||||
category. Enabling a category adds no output when there are no messages in it;
|
||||
other output remains subject to its own visibility rules.
|
||||
|
||||
Error presentation follows the terminal failure model below. An application
|
||||
may report a recovered problem as a Warning or continue without a message.
|
||||
|
||||
Apply the same policy to help and version. There are no command-specific
|
||||
exceptions for successful output:
|
||||
|
||||
```text
|
||||
app help --quiet # succeeds silently
|
||||
app version --quiet # succeeds silently
|
||||
```
|
||||
|
||||
Usage and operational failures still report their errors in quiet mode.
|
||||
The feature must distinguish successful output suppression from failure
|
||||
diagnostic delivery.
|
||||
|
||||
### Message prefixes and channels
|
||||
|
||||
Substantive output uses the result destination, conventionally stdout. Warning,
|
||||
Info, Progress, Debug, and terminal explanations use the diagnostic destination,
|
||||
conventionally stderr. Callers supply both destinations.
|
||||
|
||||
Use `WARN:`, `DEBUG:`, and `ERROR:` prefixes for simple warning, debug, and error
|
||||
messages respectively. Substantive output and Info messages have no prefix.
|
||||
For multiline diagnostics, prefix the opening line and preserve the structured
|
||||
detail. Integration adapters coordinate native diagnostic rendering to avoid
|
||||
duplicate severity labels or loss of upstream formatting.
|
||||
|
||||
Usage guidance belongs to the terminal usage explanation and remains visible in
|
||||
quiet mode. Successful help output follows the substantive-output policy.
|
||||
|
||||
Initially, Progress messages are unprefixed streamed lines. The diagnostic
|
||||
destination keeps them separate from substantive output such as JSON or YAML.
|
||||
Terminal redraw and progress-bar behavior are outside this implementation.
|
||||
|
||||
### Terminal failure model
|
||||
|
||||
During execution, applications can produce substantive output, Progress, Info,
|
||||
Debug, and Warnings. An unrecoverable failure ends the handler by returning a
|
||||
failed outcome. There is no standalone `report.Error(...)` method. Detailed
|
||||
error explanations accompany the returned failure and are presented as part of
|
||||
that terminal step.
|
||||
|
||||
CommandKit finalizes reporting, presents the terminal failure explanation, and
|
||||
returns the non-zero outcome to the application entry point. It accepts no
|
||||
further normal output for that invocation after terminal error presentation.
|
||||
The same boundary applies to core routing and parsing failures that prevent
|
||||
handler execution. The application entry point retains ownership of process
|
||||
exit; CommandKit ends the invocation and returns its outcome.
|
||||
|
||||
For example, if an export operation fails and the application decides it cannot
|
||||
continue, the handler returns a non-zero outcome with an explicit explanation
|
||||
such as "Unable to export the requested report." The application can choose to
|
||||
include detail from a Go error in that explanation. CommandKit presents the
|
||||
supplied explanation without automatically deriving text from an application
|
||||
error. The selected API below provides failure constructors for this purpose.
|
||||
When a failed outcome supplies no explanation, CommandKit supplies the generic
|
||||
fallback defined under terminal outcomes below.
|
||||
|
||||
Output streamed before the failure remains visible according to its selected
|
||||
mode; terminal failure does not withdraw earlier bytes. Deferred messages,
|
||||
cleanup writes, and delivery failures must respect the end of normal reporting.
|
||||
Their finalization and late-write behavior follow OD-4 below. A terminal
|
||||
failure may have multiple explanatory records, all belonging to that failure.
|
||||
|
||||
### Failure explanations and presentation ownership (OD-3)
|
||||
|
||||
Make a non-zero outcome with an explicit message the convenient failure path.
|
||||
Support structured explanations, including multiple records, through the same
|
||||
presentation facility for richer application and integration reports. Neither
|
||||
form requires an underlying Go error.
|
||||
|
||||
The application or integration explicitly identifies the context belonging to
|
||||
a terminal explanation. Present that context with the failure in every mode,
|
||||
including quiet. Independent warnings and other messages retain their own
|
||||
visibility rules. For mixed upstream batches, adapters preserve useful native
|
||||
rendering while distinguishing terminal explanatory context from independent
|
||||
messages. Core does not infer those relationships from error chains or text.
|
||||
|
||||
Assign each submitted message one presentation path. Returning a terminal
|
||||
explanation schedules its presentation once; core does not append another
|
||||
message derived from an application error cause. Native renderers can supply
|
||||
already-labelled content without receiving duplicate prefixes. Avoid text-based
|
||||
deduplication: separate events may legitimately produce identical messages.
|
||||
|
||||
Constructing a failure result attaches explanatory content without emitting or
|
||||
independently scheduling an Error. Returning that result hands the explanation
|
||||
to CommandKit for terminal delivery through the invocation's reporting facility.
|
||||
The selected API expresses this distinction for both simple and structured
|
||||
explanations. For example:
|
||||
|
||||
| Handler action | Presentation |
|
||||
| --- | --- |
|
||||
| Construct a non-zero result with "Unable to export the requested report," then return it. | Construction emits nothing. CommandKit presents the message once during terminal delivery. |
|
||||
| Return a failure with native diagnostic records and their source context, submitting independent warnings separately. | CommandKit presents the structured terminal explanation in every mode. Independent warnings follow their own visibility policy. |
|
||||
|
||||
### Retention boundary (OD-3)
|
||||
|
||||
CommandKit provides invocation-scoped CLI presentation. Logging and message
|
||||
history collection remain application concerns. Keep terminal explanations and
|
||||
any supplied cause with the returned outcome, and keep the temporary state needed
|
||||
for deferred delivery, parser events awaiting mode selection, and delivery
|
||||
bookkeeping. The reporting facility does not collect a transcript or retain other
|
||||
emitted or suppressed messages for later inspection. No optional message-history
|
||||
facility is planned for this implementation.
|
||||
|
||||
## Selected flag grammar and scope
|
||||
|
||||
### Mode selection and resets
|
||||
|
||||
Model quiet, ordinary, verbose, and debug as mutually exclusive presentation
|
||||
modes. Each invocation starts in ordinary mode. Process flag occurrences in
|
||||
invocation order; the last enabled mode wins. Repetition does not increment
|
||||
verbosity, and debug is selected explicitly.
|
||||
|
||||
Accept presence and the existing explicit boolean syntax, including
|
||||
`--quiet=true` and `--quiet=false`. A false occurrence clears its mode only if
|
||||
that mode is currently selected, returning to ordinary mode. It does not restore
|
||||
an earlier selection or disable a different mode. Every occurrence is converted;
|
||||
invalid boolean values remain usage errors even when a later flag would replace
|
||||
the selection.
|
||||
|
||||
| Flag sequence | Final mode |
|
||||
| --- | --- |
|
||||
| `--quiet --verbose` | Verbose |
|
||||
| `--debug --quiet` | Quiet |
|
||||
| `--verbose --verbose` | Verbose |
|
||||
| `--verbose --verbose=false` | Ordinary |
|
||||
| `--quiet --verbose=false` | Quiet |
|
||||
| `--verbose --quiet --quiet=false` | Ordinary |
|
||||
| `--quiet=false --debug` | Debug |
|
||||
|
||||
Keep verbosity a presentation choice: quiet preserves the requested operation's
|
||||
semantics and rendering failures. Delivery failures depend on the output actually
|
||||
requested; suppressing a destination write can avoid a delivery failure. Apply
|
||||
the policy through CommandKit-managed reporting and streams. Output written
|
||||
directly to process streams or external destinations remains application-owned.
|
||||
|
||||
### Progress selection
|
||||
|
||||
`--progress` enables Progress without enabling Info, Warning, or Debug messages.
|
||||
`--progress=false` explicitly disables it. Accept the existing boolean syntax;
|
||||
repeated canonical or aliased progress settings use the last value. Retain
|
||||
whether a setting was explicitly supplied, separately from its boolean value.
|
||||
|
||||
Determine effective Progress visibility from the final presentation mode and
|
||||
explicit progress setting:
|
||||
|
||||
1. Quiet mode always suppresses Progress.
|
||||
2. Otherwise, an explicit progress setting controls visibility.
|
||||
3. Without an explicit setting, debug enables Progress; ordinary and verbose
|
||||
modes leave it disabled.
|
||||
|
||||
An explicit progress setting overrides the mode's default regardless of its
|
||||
position relative to mode flags. It does not select or reset the presentation
|
||||
mode. Debug includes verbose detail and defaults Progress on; verbose alone
|
||||
does not enable Progress.
|
||||
|
||||
| Flags | Result |
|
||||
| --- | --- |
|
||||
| `--verbose` | Warning and Info, without Progress. |
|
||||
| `--verbose --progress` | Warning, Info, and Progress. |
|
||||
| `--debug` | Warning, Info, Debug, and Progress. |
|
||||
| `--debug --progress=false` or `--progress=false --debug` | Debug detail without Progress. |
|
||||
| `--quiet --progress` or `--progress --quiet` | Only failure diagnostics. |
|
||||
| `--debug --verbose` | Verbose detail without Progress, absent an explicit progress setting. |
|
||||
|
||||
Passing `--progress` to an application that emits no Progress messages adds no
|
||||
visible output. It does not suppress that application's substantive results or
|
||||
require a progress implementation.
|
||||
|
||||
### Placement, availability, and aliases
|
||||
|
||||
Core supplies `--quiet`, `--verbose`, `--debug`, and `--progress` for application
|
||||
commands, integrations, the root, canonical groups, and alias-only discovery help.
|
||||
Consumers do not register them individually. Preserve the existing placement
|
||||
grammar: flags follow the complete command path and may be interspersed with
|
||||
operands after that path. For example:
|
||||
|
||||
```text
|
||||
app config show --quiet
|
||||
app export destination --verbose
|
||||
app help config show --quiet
|
||||
app version --quiet
|
||||
```
|
||||
|
||||
Options before or between command-path components are outside this grammar.
|
||||
Tokens consumed as values and tokens following `--` retain their ordinary
|
||||
meaning.
|
||||
|
||||
Reserve the four long spellings. Applications may add `-q`, `-v`, or `-d`
|
||||
through the alias API; no built-in short spellings are selected. An application
|
||||
flag declaration that defines a reserved long name fails installation with a
|
||||
collision error. Aliases may target these flags but may not overload canonical
|
||||
spellings. Apply the existing collision and atomic installation rules, including
|
||||
later registration.
|
||||
|
||||
Aliased and canonical occurrences participate in the same ordering. With
|
||||
`-q → --quiet`, `app export --verbose -q` selects quiet mode. Document the newly
|
||||
reserved canonical names as a compatibility change.
|
||||
|
||||
### Routing and parsing failures
|
||||
|
||||
Determine the mode through the normal parser before execution or successful
|
||||
help/report presentation. Do not add a separate verbosity scanner. This keeps
|
||||
token interpretation consistent and avoids reinterpreting values or operands.
|
||||
|
||||
Routing and parsing failures report their errors regardless of verbosity. For
|
||||
example, `app export --quiet --unknown` still reports the unknown flag. Error
|
||||
visibility follows the selected output policy independently of how the mode is
|
||||
determined; avoiding a separate scanner is an implementation simplification.
|
||||
|
||||
## CommandKit's own diagnostics
|
||||
|
||||
Use the shared reporting system for CommandKit's invocation diagnostics so
|
||||
parser, integration, and application messages follow the same visibility and
|
||||
delivery policy. Installation errors occur before an invocation exists and
|
||||
continue to be returned to the application without automatic printing.
|
||||
|
||||
Supported repetition and last-occurrence overrides are routine decisions.
|
||||
Repeated singleton flags, including `--verbose --verbose`, may produce debug
|
||||
detail; repetition alone does not warrant a warning. Repeatable flags retain
|
||||
their intended accumulation behavior. Add warnings for concrete concerns an
|
||||
operator can act on, such as a deprecated spelling if deprecation is introduced.
|
||||
Unknown flags, invalid values, and invalid command paths remain invocation
|
||||
failures with error diagnostics.
|
||||
|
||||
Start debug instrumentation with routing, alias resolution, verbosity selection,
|
||||
and handler completion. Other useful candidates can be added where they
|
||||
explain a consequential decision:
|
||||
|
||||
| Event | Useful detail |
|
||||
| --- | --- |
|
||||
| Command-alias resolution | Entered path, intermediate redirects, and final canonical path. |
|
||||
| Flag-alias resolution | Entered spelling and canonical flag name. |
|
||||
| Scoped alias selection | A command-scoped mapping took precedence over an application-wide mapping. |
|
||||
| Verbosity selection | A later occurrence selected a different mode; for `--verbose --debug`, debug wins because it appears last. |
|
||||
| Help-route selection | A canonical command or alias-only discovery context was selected. |
|
||||
| Repeated singleton flag | A later occurrence replaced an earlier occurrence, without printing their values. |
|
||||
| Input preparation | Canonical input validation completed and the handler is starting. |
|
||||
| Handler completion | Canonical command and the handler's returned classification and status, before final delivery. |
|
||||
|
||||
The handler-completion event describes the handler's result. The final returned
|
||||
invocation outcome also includes delivery failures and remains authoritative.
|
||||
Present this event before terminal failure presentation; do not emit a completion
|
||||
message afterward.
|
||||
|
||||
Use the final selected mode to present earlier parser decisions. Collect the
|
||||
relevant events during parsing and apply visibility after mode selection:
|
||||
`--verbose --debug` shows the selection explanation, while `--debug --quiet`
|
||||
suppresses it. This collection of parser events does not require whole-run
|
||||
output buffering.
|
||||
|
||||
Debug messages should explain operator-relevant decisions independently of
|
||||
incidental implementation steps. Use command paths, flag names, and decision
|
||||
descriptions rather than raw argument or configuration-value dumps. Upstream
|
||||
libraries retain ownership of their diagnostic detail and disclosure rules.
|
||||
|
||||
## Selected delivery lifecycle and quiet execution (OD-4)
|
||||
|
||||
### Ordering and finalization
|
||||
|
||||
Use synchronous delivery. Present immediate messages and substantive writes in
|
||||
submission order. After the handler returns:
|
||||
|
||||
1. Deliver eligible deferred messages in queue order, without sorting by severity.
|
||||
2. Finish ordinary reporting, including any handler-completion debug message and
|
||||
flushing any CommandKit-owned buffers for ordinary output. Account for failures
|
||||
discovered during this delivery before preparing the terminal explanation.
|
||||
3. Present any terminal failure explanation and complete its delivery, including
|
||||
any CommandKit-owned buffering of that explanation.
|
||||
4. Close the invocation's reporting facility and return the final outcome.
|
||||
|
||||
Deferred messages remain eligible when the operation fails, subject to verbosity.
|
||||
Deferral controls timing; applications queue success summaries only after the
|
||||
relevant operation succeeds. Ordering governs CommandKit's writes; separate
|
||||
stdout and stderr destinations may be buffered or displayed differently by the
|
||||
caller.
|
||||
|
||||
CommandKit finalizes automatically. Consumers do not need a separate flush or
|
||||
finish call. Handler cleanup, including Go `defer` functions, runs before the
|
||||
handler returns and participates in normal reporting. Applications complete any
|
||||
reporting goroutines before returning. After finalization, writes and message
|
||||
submissions return a closed-reporter error and emit nothing.
|
||||
|
||||
Reporter operations within an invocation are safe to call concurrently.
|
||||
Serialize access to reporting state and delivery so individual messages do not
|
||||
interleave. Concurrent submissions have no predetermined order; deferred messages
|
||||
follow the order in which they enter the queue. Multiple writes composing one
|
||||
application report still require application coordination if they must remain
|
||||
together. This contract covers operations through one invocation's reporter;
|
||||
coordination with writes outside that reporter remains caller-owned.
|
||||
|
||||
Finalize any buffers owned by CommandKit. Caller-supplied writers remain
|
||||
caller-owned; CommandKit does not automatically close them or invoke arbitrary
|
||||
flushing interfaces.
|
||||
|
||||
Visibility applies when output is emitted. A verbose or debug run may show
|
||||
informational detail before subsequently failing. Progress and substantive
|
||||
output may likewise be partially delivered before a failure. Previously written
|
||||
bytes cannot be withdrawn. Whole-run buffering solely to make failed runs
|
||||
contain only error output is outside this implementation.
|
||||
|
||||
Keep errors understandable in every mode, including source locations and
|
||||
related explanatory context. Unrelated warnings and informational messages
|
||||
remain subject to the selected mode. Apply the selected retention boundary
|
||||
without accumulating a message history.
|
||||
|
||||
### Rendering failures, write failures, and execution flow
|
||||
|
||||
Distinguish who invokes a renderer and whether its destination failed:
|
||||
|
||||
| Failure source | Responsibility and handling |
|
||||
| --- | --- |
|
||||
| An encoder or renderer called directly by the application | The application handles its returned error and chooses the outcome and explanation. |
|
||||
| A rendering callback invoked by CommandKit | CommandKit handles its returned error as a presentation failure and reflects it in the invocation outcome. |
|
||||
| A destination rejects a write | CommandKit records the delivery failure and stops further writes to that destination. |
|
||||
|
||||
A rendering failure may occur before any write or while the destination remains
|
||||
healthy. It does not by itself establish a failed destination. CommandKit can
|
||||
explain its rendering failure through a working diagnostic destination. These
|
||||
responsibilities also apply when rendering into a discard destination under
|
||||
quiet mode.
|
||||
|
||||
Failure to deliver requested output makes an otherwise successful invocation
|
||||
unsuccessful. Apply this rule to substantive output, Warning, Info, Progress,
|
||||
Debug, and terminal explanations. Intentional suppression requests no delivery
|
||||
and is not a delivery failure.
|
||||
|
||||
Standard writer operations return write errors normally. Immediate reporting
|
||||
methods also expose delivery errors. CommandKit records bounded delivery-failure
|
||||
information so an ignored write error cannot yield a successful invocation.
|
||||
Deferred delivery failures appear in the final outcome.
|
||||
|
||||
Apply ADR 0005's outcome rules when presentation fails. For standard outcomes,
|
||||
return operational failure with status `1`, including when the original outcome
|
||||
was a usage failure. Preserve the original explanation and any supplied cause;
|
||||
record the presentation failure separately in `Presentation`.
|
||||
|
||||
Application-defined domain outcomes retain their domain classification. Preserve
|
||||
an already non-zero domain status. If the domain status was `0`, change the
|
||||
suggested status to `1` so presentation failure cannot yield a successful
|
||||
invocation. The application entry point retains control of process exit.
|
||||
|
||||
| Outcome before presentation fails | Final outcome |
|
||||
| --- | --- |
|
||||
| Success, status `0` | Operational failure, status `1`. |
|
||||
| Usage failure, status `2` | Operational failure, status `1`. |
|
||||
| Operational failure, status `1` | Operational failure, status `1`. |
|
||||
| Domain outcome, non-zero status | Same domain classification and status. |
|
||||
| Domain outcome, status `0` | Same domain classification, status `1`. |
|
||||
|
||||
These rules apply to both destination-write failures and rendering failures from
|
||||
callbacks invoked by CommandKit. Reporting failures remain CommandKit's own
|
||||
error-handling responsibility.
|
||||
|
||||
Stop writing to a destination after it fails. A substantive-output failure can
|
||||
receive a terminal explanation through the diagnostic destination if it still
|
||||
works. If diagnostic delivery fails, return that information to the caller.
|
||||
Do not redirect diagnostics into substantive output or recursively attempt to
|
||||
report the reporting failure.
|
||||
|
||||
A failed write does not stop application code. The handler can inspect the error
|
||||
and return immediately; otherwise, CommandKit records the failure and finalizes
|
||||
when the handler returns. CommandKit does not use process exit or panic to
|
||||
interrupt execution. Terminal failure presentation ends normal output.
|
||||
|
||||
### Quiet-mode rendering and suppression
|
||||
|
||||
Initially, run substantive report generation normally with its managed writer
|
||||
discarding output in quiet mode. This preserves report generation, validation,
|
||||
and serialization failures while changing presentation. For example, a report
|
||||
encoder failure still fails the invocation under `--quiet`; the handler remains
|
||||
responsible for handling errors returned by an encoder it calls.
|
||||
|
||||
Simple suppressed messages need no formatting or destination writes. For richer
|
||||
report renderers, initially render into a discard destination. Rendering may be
|
||||
skipped later where doing so preserves the command's operation and failure
|
||||
semantics.
|
||||
|
||||
Treat suppression as intentional suppression, never as failed or incomplete
|
||||
delivery. Do not retain suppressed content. Delivery needs only the deferred
|
||||
queue, reporting lifecycle state, and bounded delivery-failure information,
|
||||
alongside the temporary parser state and returned explanations described above.
|
||||
|
||||
## Selected consumer reporting API
|
||||
|
||||
Provide one reporting facility per invocation for substantive output, immediate
|
||||
messages, and end-of-run diagnostics. The consumer API is chosen for its intended
|
||||
long-term design; with no current consumers, preserving existing API shapes
|
||||
carries no weight in this decision.
|
||||
|
||||
The following declarations specify the target API and are not yet implemented.
|
||||
|
||||
The reporter owns presentation: output visibility, progress settings, prefixes,
|
||||
ordering, and delivery bookkeeping. Its views share invocation state, allowing
|
||||
already-emitted messages, deferred messages, suppression, and write failures to
|
||||
be coordinated in one place. Helpers may receive the reporter or a narrow
|
||||
application-defined interface. Domain libraries can continue returning
|
||||
diagnostic data for the handler to submit, independently of CommandKit.
|
||||
|
||||
Use the reporter as the common diagnostic submission path, replacing the earlier
|
||||
proposal to split submission between a reporter and `Outcome.Diagnostics`.
|
||||
Terminal explanations accompany returned outcomes and are delivered through the
|
||||
same facility. Caller-selected destinations remain at `App.Execute`; handlers
|
||||
use `Invocation.Reporter()` in place of raw invocation streams.
|
||||
|
||||
### Invocation reporter and structured detail
|
||||
|
||||
```go
|
||||
func (inv Invocation) Reporter() *Reporter
|
||||
|
||||
type Reporter struct {
|
||||
// Private invocation state.
|
||||
}
|
||||
|
||||
func (r *Reporter) Output() io.Writer
|
||||
func (r *Reporter) RenderOutput(write func(io.Writer) error) error
|
||||
|
||||
func (r *Reporter) Info(message string, details ...Detail) error
|
||||
func (r *Reporter) Warn(message string, details ...Detail) error
|
||||
func (r *Reporter) Debug(message string, details ...Detail) error
|
||||
func (r *Reporter) Progress(message string, details ...Detail) error
|
||||
|
||||
func (r *Reporter) AtEnd() DeferredReporter
|
||||
|
||||
type Detail func(io.Writer) error
|
||||
```
|
||||
|
||||
`Output()` supports ordinary writers and encoders. `RenderOutput()` coordinates
|
||||
an entire rendering operation, captures its rendering error, and prevents other
|
||||
reporter operations from interleaving with it. Rendering callbacks write through
|
||||
their supplied writer. Each complete categorized message, including its details,
|
||||
is likewise coordinated as one reporter operation.
|
||||
|
||||
Rendering callbacks use their supplied writer only during the callback. They may
|
||||
call rendering helpers that write through it. While a callback is running, it
|
||||
must not recursively submit messages, queue deferred messages, start another
|
||||
rendering operation, or write through a separate `Output()` handle belonging to
|
||||
the same invocation's reporter. Make additional reporter submissions before or
|
||||
after the callback. A callback must also avoid waiting for another goroutine to
|
||||
submit through that reporter, since the submission may be waiting for the
|
||||
callback to finish.
|
||||
|
||||
This boundary applies to `RenderOutput`, immediate and deferred message details,
|
||||
and terminal explanation details. Ordinary concurrent reporter calls remain
|
||||
supported and serialized. Keeping each rendering operation together motivates
|
||||
the boundary; it does not prescribe a lock implementation or promise runtime
|
||||
detection of recursive calls.
|
||||
|
||||
Message strings are literal; consumers use `fmt.Sprintf` when formatting is
|
||||
needed. Initially omit parallel `Infof`, `Warnf`, and similar methods. CommandKit
|
||||
formats the opening message with its category's prefix and a terminating newline.
|
||||
Optional details follow in order with their formatting preserved. An empty
|
||||
opening message produces no heading, prefix, or blank opening line, supporting
|
||||
native renderers that supply a complete, labelled diagnostic:
|
||||
|
||||
```go
|
||||
_ = report.Warn("Using the default profile")
|
||||
_ = report.Warn("Some configuration settings need attention.", writeNativeWarnings)
|
||||
_ = report.Warn("", writeNativeWarnings)
|
||||
```
|
||||
|
||||
These are alternative calls; `writeNativeWarnings` represents an
|
||||
application- or integration-supplied function with signature
|
||||
`func(io.Writer) error`. No generic logging method or severity enumeration is
|
||||
needed to submit messages. Applications need not check verbosity before reporting
|
||||
or implement categories they do not use.
|
||||
|
||||
Immediate methods return rendering or delivery errors, and CommandKit records
|
||||
the corresponding presentation failure even if the caller ignores the error.
|
||||
A caller can inspect the returned error and end its handler immediately.
|
||||
|
||||
### Deferred messages
|
||||
|
||||
```go
|
||||
type DeferredReporter struct {
|
||||
// Private reference to the same invocation state.
|
||||
}
|
||||
|
||||
func (r DeferredReporter) Info(message string, details ...Detail) error
|
||||
func (r DeferredReporter) Warn(message string, details ...Detail) error
|
||||
func (r DeferredReporter) Debug(message string, details ...Detail) error
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```go
|
||||
_ = report.AtEnd().Warn("Three optional files were unavailable.")
|
||||
```
|
||||
|
||||
Copies of the deferred view share invocation state. Its methods return submission
|
||||
errors, such as attempting to use a closed reporter. Errors encountered during
|
||||
deferred rendering appear in the final invocation outcome. Progress remains an
|
||||
immediate streaming operation; substantive output uses the main reporter.
|
||||
|
||||
Copy callback lists when accepting a submission. Callers retain ownership of
|
||||
data captured by rendering callbacks and keep that data valid until presentation.
|
||||
|
||||
### Terminal outcomes
|
||||
|
||||
Outcome construction requires no invocation state and emits nothing:
|
||||
|
||||
```go
|
||||
type Explanation struct {
|
||||
Message string
|
||||
Details []Detail
|
||||
}
|
||||
|
||||
type Outcome struct {
|
||||
Kind OutcomeKind
|
||||
Status int
|
||||
Domain string
|
||||
Cause error
|
||||
Explanation Explanation
|
||||
Presentation PresentationResult
|
||||
}
|
||||
|
||||
func Success() Outcome
|
||||
func Failure(message string, details ...Detail) Outcome
|
||||
func Usage(message string, details ...Detail) Outcome
|
||||
func Domain(name string, status int) Outcome
|
||||
|
||||
func (o Outcome) WithExplanation(message string, details ...Detail) Outcome
|
||||
func (o Outcome) WithCause(cause error) Outcome
|
||||
```
|
||||
|
||||
`Success` returns a successful outcome with status `0`. `Failure` produces an
|
||||
operational failure with status `1`; `Usage` produces a usage failure with status
|
||||
`2`. `Domain` constructs an outcome with the supplied application-defined
|
||||
classification and status. Subsequent presentation failures follow OD-4's rules:
|
||||
domain classification is preserved, and a zero status becomes `1` if presentation
|
||||
fails.
|
||||
`OutcomeKind` retains the success, usage, operational, and domain classifications.
|
||||
|
||||
`WithExplanation` returns a modified outcome value and replaces its terminal
|
||||
explanation. Explanations belong to failed outcomes; successful summaries use
|
||||
Info or substantive output. Ordinary application failure, native failure
|
||||
rendering, and a custom domain failure respectively can be expressed as:
|
||||
|
||||
```go
|
||||
return commandkit.Failure("Unable to export the requested report.")
|
||||
```
|
||||
|
||||
```go
|
||||
return commandkit.Failure("", writeNativeFailure)
|
||||
```
|
||||
|
||||
```go
|
||||
return commandkit.Domain("validation", 3).
|
||||
WithExplanation("The document failed validation.", writeFindings)
|
||||
```
|
||||
|
||||
The named renderers above have signature `func(io.Writer) error` and preserve the
|
||||
owning library's safe diagnostic formatting. They run during terminal delivery,
|
||||
not when constructing the outcome.
|
||||
|
||||
Before terminal delivery, supply the explanation `Command failed.` when a
|
||||
non-zero outcome has an empty `Explanation.Message` and no non-nil callback in
|
||||
`Explanation.Details`. This produces `ERROR: Command failed.` in every mode,
|
||||
including quiet, and becomes the explanation retained in the returned outcome.
|
||||
Adding the fallback leaves classification, status, and cause unchanged;
|
||||
presentation failures still follow OD-4's rules. The fallback is based on the
|
||||
failed outcome and absent explanation, without deriving text from `Cause.Error()`.
|
||||
|
||||
An empty heading with a non-nil detail renderer is an explicitly supplied
|
||||
explanation. Trust that renderer to provide its content. Do not buffer or replay
|
||||
it to decide whether the explanation is sufficiently informative, and do not
|
||||
add the fallback merely because it writes no bytes.
|
||||
|
||||
| Returned outcome | Terminal presentation |
|
||||
| --- | --- |
|
||||
| `Failure("")` | Generic fallback, operational classification and status `1`. |
|
||||
| `Domain("validation", 3)` | Generic fallback, domain classification and status `3`. |
|
||||
| `Failure("").WithCause(err)` | Generic fallback; the supplied cause remains available without automatic rendering. |
|
||||
| `Failure("", writeNativeFailure)` | Native explanation without an added generic heading. |
|
||||
|
||||
`Cause` is optional. `WithCause` returns a modified outcome value, replacing the
|
||||
cause without changing the classification, status, or explanation. For example:
|
||||
|
||||
```go
|
||||
return commandkit.Failure("Unable to open the configuration file.").
|
||||
WithCause(err)
|
||||
```
|
||||
|
||||
CommandKit presents the supplied explanation and carries the original error
|
||||
through to the execution caller, which can inspect it with expressions such as
|
||||
`errors.Is(outcome.Cause, fs.ErrNotExist)`. It does not automatically present
|
||||
`Cause.Error()` or use the cause to decide success, failure, or message category.
|
||||
Providing a cause is independent of choosing the terminal explanation; neither
|
||||
is inferred from the other. Warnings do not require supplying or retaining causes.
|
||||
|
||||
Outcome processing preserves supplied causes, including their existing Go error
|
||||
identity, when a subsequent rendering or delivery failure occurs. Presentation
|
||||
failures are recorded separately in `Presentation`. The returned outcome retains
|
||||
its terminal explanation and optional cause, with other retention limited to the
|
||||
presentation needs described above.
|
||||
|
||||
### Provider-returned diagnostic data
|
||||
|
||||
Providers return values and diagnostic data without needing a reporter parameter.
|
||||
Retain `Acquired[T]` with separate fields for independent messages and failure
|
||||
explanations:
|
||||
|
||||
```go
|
||||
type Acquired[T any] struct {
|
||||
Value T
|
||||
Diagnostics []Diagnostic
|
||||
Explanation Explanation
|
||||
}
|
||||
```
|
||||
|
||||
`Diagnostics` carries independent, nonterminal messages. `Diagnostic` and
|
||||
`Severity` remain passive data types for those messages, with each diagnostic
|
||||
carrying its `Severity` and a `Write func(io.Writer) error` renderer. Adapt their
|
||||
contracts to the nonterminal reporting categories. Integrations submit the
|
||||
records through the corresponding reporter methods, including the deferred view
|
||||
where appropriate. Removing `Outcome.Diagnostics` removes a submission path;
|
||||
provider-returned records remain available for the integration to submit.
|
||||
|
||||
`Explanation` carries context to attach when the integration returns a failed
|
||||
outcome. Terminal Error content uses this field rather than an independently
|
||||
submitted diagnostic. An upstream warning that helps explain the failure may
|
||||
belong in the explanation; unrelated warnings remain in `Diagnostics` and follow
|
||||
their ordinary visibility rules. Adapters preserve this distinction and useful
|
||||
native formatting when translating mixed upstream batches, instead of assigning
|
||||
the whole batch its highest severity.
|
||||
|
||||
Providers may return acquired data alongside a Go error. The owning integration
|
||||
chooses the command outcome, attaches any terminal explanation, and decides which
|
||||
cause to preserve. Returning diagnostic data does not itself emit messages or
|
||||
select the invocation outcome. Diagnostic renderers follow the same callback
|
||||
boundary as other details when invoked through the reporter.
|
||||
|
||||
### Presentation observations and closed reporters
|
||||
|
||||
```go
|
||||
type PresentationResult struct {
|
||||
Output DeliveryResult
|
||||
Diagnostics DeliveryResult
|
||||
}
|
||||
|
||||
type DeliveryResult struct {
|
||||
State DeliveryState
|
||||
RenderError error
|
||||
WriteError error
|
||||
}
|
||||
|
||||
type DeliveryState uint8
|
||||
|
||||
const (
|
||||
DeliveryNone DeliveryState = iota
|
||||
DeliverySuppressed
|
||||
DeliveryComplete
|
||||
DeliveryIncomplete
|
||||
)
|
||||
|
||||
var ErrReporterClosed = errors.New("reporter is closed")
|
||||
```
|
||||
|
||||
| State | Meaning |
|
||||
| --- | --- |
|
||||
| `DeliveryNone` | No content was submitted for this destination. |
|
||||
| `DeliverySuppressed` | All submitted content was intentionally suppressed, and rendering succeeded. |
|
||||
| `DeliveryComplete` | All requested delivery completed; other content may have been suppressed. |
|
||||
| `DeliveryIncomplete` | Rendering or destination writing failed. |
|
||||
|
||||
Retain the first rendering failure and first destination-write failure for each
|
||||
destination. This provides bounded evidence without collecting an event history.
|
||||
`Outcome.Presentation` is populated by CommandKit during execution and
|
||||
finalization; it is observation data, not another submission API.
|
||||
|
||||
The invocation supplies the reporter. Consumers neither construct nor finalize
|
||||
it. After closure, message submissions and writer operations return
|
||||
`ErrReporterClosed`, including in quiet mode. The initial API needs no explicit
|
||||
flush method, transcript accessor, or verbosity checks. Error-conversion helpers
|
||||
are deferred pending demonstrated value.
|
||||
|
||||
### Application example
|
||||
|
||||
This target-API handler uses an application-owned `exportData` operation that
|
||||
returns a JSON-encodable result with a `UsedDefaults` field:
|
||||
|
||||
```go
|
||||
func runExport(inv commandkit.Invocation) commandkit.Outcome {
|
||||
report := inv.Reporter()
|
||||
|
||||
result, err := exportData(inv.Context)
|
||||
if err != nil {
|
||||
return commandkit.Failure("Unable to export the requested data.")
|
||||
}
|
||||
|
||||
if result.UsedDefaults {
|
||||
_ = report.Warn("Some optional settings used defaults.")
|
||||
}
|
||||
|
||||
if err := report.RenderOutput(func(w io.Writer) error {
|
||||
return json.NewEncoder(w).Encode(result)
|
||||
}); err != nil {
|
||||
return commandkit.Failure("Unable to present the export result.")
|
||||
}
|
||||
|
||||
_ = report.AtEnd().Info("Export completed.")
|
||||
return commandkit.Success()
|
||||
}
|
||||
```
|
||||
|
||||
Ignored immediate reporting errors are still recorded and can make the final
|
||||
invocation unsuccessful. The renderer runs in quiet mode against the discard
|
||||
destination, preserving serialization failures. The deferred summary follows
|
||||
the selected verbosity policy and describes the completed export operation;
|
||||
the final invocation outcome also accounts for presentation failures.
|
||||
|
||||
## Upstream diagnostic ownership
|
||||
|
||||
ConfigKit and PromptKit remain authoritative for their diagnostic semantics,
|
||||
severity, source context, and disclosure rules. Integration adapters expose
|
||||
those capabilities through the shared CommandKit presentation policy.
|
||||
|
||||
Support consistent reporting of ConfigKit errors and warnings as its adopted
|
||||
public API evolves. This roadmap does not assume that a future warning API
|
||||
already exists or prescribe its upstream shape. Integration-owned commands
|
||||
select the outcome and submit useful native diagnostic detail for presentation.
|
||||
Core presents those records under the shared policy. Applications using upstream
|
||||
libraries directly choose how to respond to domain-specific errors and which
|
||||
outcomes and messages to supply, as for their other operations.
|
||||
|
||||
An integration may receive both a useful substantive report and an operation
|
||||
failure, as PromptKit smoke testing supports. Preserve the report under the
|
||||
ordinary substantive-output policy, then present the terminal explanation.
|
||||
Quiet mode suppresses the report while retaining the explanation. Having a
|
||||
report does not imply a successful outcome, and returning a failure does not
|
||||
discard substantive output already prepared for delivery before the terminal step.
|
||||
|
||||
Debug output follows the same upstream disclosure and safe-rendering contracts.
|
||||
Enabling debug does not authorize secret disclosure or bypass owning-library
|
||||
rules.
|
||||
|
||||
## Delivery scope
|
||||
|
||||
The completed feature includes the selected reporter and outcome API, ordered
|
||||
mode/progress selection through normal parsing, shared core presentation, and
|
||||
both optional integration migrations. Passive provider diagnostics distinguish
|
||||
independent messages from terminal explanations while preserving native evidence
|
||||
and rendering. Existing command behavior remains unchanged outside the selected
|
||||
reporting policy.
|
||||
|
||||
Maintained consumers demonstrate ordinary output, immediate/deferred messages,
|
||||
silent recovery, explicit warnings, failure after partial output, optional cause
|
||||
transport, and structured terminal explanations. Integration consumers include
|
||||
native diagnostic context and useful reports returned alongside failures.
|
||||
|
||||
Behavioral coverage establishes CommandKit-owned parsing, visibility, ordering,
|
||||
concurrent reporter coordination, closure, presentation observations, and failure
|
||||
handling. It preserves existing alias, input/state, discovery, native-report,
|
||||
and upstream-adapter protections without testing upstream domain correctness.
|
||||
GoDoc, CLI documentation, consumer guidance, internal documentation, and release
|
||||
notes describe the implemented boundary under their canonical ownership.
|
||||
|
||||
The [implementation plan](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/230187296fae5253cb1773f16c2f1d1a39499ed0/docs/roadmap/implementation.md) defines the concrete migration
|
||||
steps, focused validation, and completion criteria. This roadmap defines the
|
||||
target behavior and selected policy choices.
|
||||
|
||||
## Architectural preparation completed
|
||||
|
||||
- [x] Review and accept [ADR 0014](../adr/0014-invocation-reporting.md) as an
|
||||
extension for shared reporting, retaining ADR 0005's outcome and supplied-error
|
||||
preservation decisions.
|
||||
- [x] Align the [architecture policy](../policy/architecture.md) with the reporting
|
||||
ownership model, including application ownership of domain-specific error
|
||||
decisions and scope for useful shared error helpers.
|
||||
|
||||
OD-1 through OD-4 and the consumer API signatures are selected. The target end
|
||||
state includes maintained, executable consumers using those APIs; the
|
||||
[implementation plan](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/230187296fae5253cb1773f16c2f1d1a39499ed0/docs/roadmap/implementation.md) owns their delivery sequence.
|
||||
Reference in New Issue
Block a user