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)
|
- [Maintainer release procedure](docs/release.md)
|
||||||
- [Architecture policy](docs/policy/architecture.md)
|
- [Architecture policy](docs/policy/architecture.md)
|
||||||
- [Policy provenance](docs/policy/meta.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).
|
CommandKit is licensed under the [LGPL v3.0 or later](COPYRIGHT).
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ canonical documentation owners.
|
|||||||
For application-owned aliases, use the
|
For application-owned aliases, use the
|
||||||
[CLI reference](cli.md#application-owned-aliases),
|
[CLI reference](cli.md#application-owned-aliases),
|
||||||
[Go declarations and GoDoc](../command.go), and
|
[Go declarations and GoDoc](../command.go), and
|
||||||
[ADR 0013](adr/0013-application-alias-routing.md). Keep deferred capabilities in
|
[ADR 0013](adr/0013-application-alias-routing.md). Keep unfinished work and
|
||||||
[deferred work](roadmap/deferred.md).
|
capability proposals in [future work](roadmap/future.md).
|
||||||
|
|
||||||
## Initial orientation
|
## Initial orientation
|
||||||
|
|
||||||
@@ -54,17 +54,17 @@ For application-owned aliases, use the
|
|||||||
| Task | Read |
|
| Task | Read |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Implemented CLI behavior | [CLI reference](cli.md) |
|
| 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) |
|
| 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 |
|
| 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) |
|
| 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) |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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) |
|
| 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) |
|
| Licensing or incorporated material | [Project grant](../COPYRIGHT), [license texts](../LICENSE), and [attribution](oss/attribution.md) |
|
||||||
| Policy provenance | [Policy provenance](policy/meta.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
|
current exported contracts; the CLI reference owns operator behavior. The
|
||||||
[maintainer release procedure](release.md) owns current release operations.
|
[maintainer release procedure](release.md) owns current release operations.
|
||||||
Completed roadmaps and implementation evidence remain available in Git history,
|
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).
|
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
|
These records are not assignments to restart completed work. The
|
||||||
[deferred-work record](roadmap/deferred.md) preserves future capability targets
|
[future work record](roadmap/future.md) preserves unfinished work and unselected
|
||||||
and unselected proposals separately from current contracts.
|
proposals separately from current contracts.
|
||||||
|
|
||||||
## Documentation validation
|
## 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
|
specific failure it prevents and why a less restrictive implementation cannot
|
||||||
satisfy the contract.
|
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
|
from accepted contracts. Do not approve proposed commands, grammar, statuses, or
|
||||||
illustrative API declarations
|
illustrative API declarations
|
||||||
merely by repeating them in implementation or tests. Cobra/pflag defaults do not
|
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.
|
remain application choices.
|
||||||
|
|
||||||
Accepted ADRs and current CLI/API owners define selected contracts; the
|
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.
|
Backend defaults and incidental consumer behavior do not establish new contracts.
|
||||||
A replacement backend must preserve published CLI behavior or follow deliberate compatibility
|
A replacement backend must preserve published CLI behavior or follow deliberate compatibility
|
||||||
changes under the release policy.
|
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
|
## Purpose and authority
|
||||||
|
|
||||||
Completed initial delivery, performance, ReleaseKit upgrade, and remediation
|
Completed roadmaps, implementation plans, and review findings have been retired.
|
||||||
records have been retired. This document preserves remaining deferred
|
This document preserves unfinished work and unselected ideas under the
|
||||||
capabilities and unselected ideas under the
|
|
||||||
[release policy](../policy/release.md#release-documentation-and-preparation).
|
[release policy](../policy/release.md#release-documentation-and-preparation).
|
||||||
The original records remain available in
|
The completed ConfigKit adoption, reporting, dependency alignment, release-tooling,
|
||||||
[Git history](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap).
|
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)
|
Accepted [ADRs](../adr/) and the [architecture policy](../policy/architecture.md)
|
||||||
govern any future implementation. The [CLI reference](../cli.md), public GoDoc,
|
govern any future implementation. The [CLI reference](../cli.md), public GoDoc,
|
||||||
and [consumer guide](../consumers/guide.md) own implemented behavior. Retaining
|
and [consumer guide](../consumers/guide.md) own implemented behavior. Retaining
|
||||||
an idea here does not select its syntax, API, priority, or delivery date.
|
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
|
### Comparison extensions
|
||||||
|
|
||||||
@@ -27,8 +62,8 @@ relevant ADRs.
|
|||||||
|
|
||||||
### Configuration inspection extensions
|
### Configuration inspection extensions
|
||||||
|
|
||||||
The [ConfigKit v1.1.0 adoption review](configkit-v1.1.0.md#selected-scope-decisions)
|
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)
|
||||||
recommends the following work after dependency and source-report adoption.
|
retained the following work after dependency and source-report adoption.
|
||||||
Metadata inspection is the recommended next functional sprint; the other
|
Metadata inspection is the recommended next functional sprint; the other
|
||||||
features have no selected sequence or delivery date. These proposals do not
|
features have no selected sequence or delivery date. These proposals do not
|
||||||
establish command grammar, report schemas, or new provider requirements.
|
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.
|
failures together; current diagnostic context remains available meanwhile.
|
||||||
- **Detailed comparison (OD-5).** Consider an additional form projecting native
|
- **Detailed comparison (OD-5).** Consider an additional form projecting native
|
||||||
`Difference` paths, both snapshots, presence/redaction fields, and
|
`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
|
additions/changes/deletions report. Decide later whether a detailed form
|
||||||
complements it or replaces it through a deliberate compatibility change.
|
complements it or replaces it through a deliberate compatibility change.
|
||||||
- **Structured diagnostics (OD-6).** Consider machine-readable native codes,
|
- **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
|
canonical suggestions while ensuring inserted continuations form valid next
|
||||||
steps. No delivery date or final API is selected here.
|
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
|
These capabilities remain outside the delivered scope and require a concrete
|
||||||
operator or consumer need and an appropriate ownership/behavior decision:
|
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