diff --git a/README.md b/README.md index 70a1807..fad14d3 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,16 @@ The [consumer guide](docs/consumers/guide.md) links to two maintained examples: - [Command line reference](docs/cli.md) - [Consumer guide](docs/consumers/guide.md) - [Internal package overview](docs/internal/overview.md) +- [Maintainer release procedure](docs/release.md) - [Architecture policy](docs/policy/architecture.md) - [Policy provenance](docs/policy/meta.md) ## Planning history and future work - [Initial delivery and deferred capabilities](docs/roadmap/initial.md) -- [Completed implementation record](docs/roadmap/implementation.md) +- [Completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) +- [ReleaseKit adoption roadmap](docs/roadmap/releasekit.md) +- [Release tooling implementation plan](docs/roadmap/implementation.md) - [Historical CLI planning](docs/roadmap/01-cli-plan.md) - [Completed dispatcher planning](docs/roadmap/02-dispatch.md) - [Completed backend planning](docs/roadmap/03-backend.md) diff --git a/docs/development.md b/docs/development.md index 6d3d0b7..f15f626 100644 --- a/docs/development.md +++ b/docs/development.md @@ -53,16 +53,19 @@ canonical documentation owners. | 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), and the architecture policy | | Deferred capabilities and delivery scope | [Initial feature target](roadmap/initial.md#deferred-capability-targets) and [explicit deferrals](roadmap/initial.md#explicit-deferrals) | -| Initial planning history | [CLI](roadmap/01-cli-plan.md), [dispatcher](roadmap/02-dispatch.md), [backend](roadmap/03-backend.md), [facade](roadmap/04-facade.md), and [completed staged plan](roadmap/implementation.md) | +| Initial planning history | [CLI](roadmap/01-cli-plan.md), [dispatcher](roadmap/02-dispatch.md), [backend](roadmap/03-backend.md), [facade](roadmap/04-facade.md), and [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) | +| Release tooling | [Maintainer release procedure](release.md), [ReleaseKit adoption roadmap](roadmap/releasekit.md), and [release tooling implementation plan](roadmap/implementation.md) | | Licensing or incorporated material | [Project grant](../COPYRIGHT), [license texts](../LICENSE), and [attribution](oss/attribution.md) | | Policy provenance | [Policy provenance](policy/meta.md) | Read all applicable rows for cross-cutting work. Go declarations and GoDoc own -current exported contracts; the CLI reference owns operator behavior. Numbered -roadmaps are completed planning records. Retained illustrations and historical -staged instructions are not current API references or assignments to restart -implementation. Future capabilities remain explicitly identified in the feature -roadmap. +current exported contracts; the CLI reference owns operator behavior. The +initial numbered roadmaps are completed planning records. The +[ReleaseKit adoption roadmap](roadmap/releasekit.md) and its +[implementation plan](roadmap/implementation.md) track current maintainer +tooling work. Retained illustrations and historical staged instructions are not +current API references or assignments to restart implementation. Future +capabilities remain explicitly identified in their feature roadmaps. ## Documentation validation @@ -86,9 +89,20 @@ references, not build dependencies. Implemented contracts belong in CommandKit under their canonical owners. Run `go test ./...` from the repository root to compile the module and run its -deterministic tests. Format changed Go files with `gofmt`. The release procedure -and publication tooling will be introduced with a releasable module under the -release policy. +deterministic tests. Format changed Go files with `gofmt`. The +[maintainer release procedure](release.md) owns candidate preparation and +publication commands. + +## Release tooling development + +The local publication exercise is opt-in and uses disposable Git repositories. +Prepare the module cache before running it; ordinary tests do not bootstrap or +publish a release: + +```sh +GOWORK=off GOTOOLCHAIN=local go mod download +COMMANDKIT_RELEASE_INTEGRATION=1 GOWORK=off GOTOOLCHAIN=local GOPROXY=off GONOPROXY=none GOSUMDB=off go test -mod=readonly -count=1 ./scripts -run '^TestReleaseIntegration$' +``` Follow the [local commit policy](policy/agents.md#git-commit-policy). Completed units receive local commits by default, subject to explicit user instructions. diff --git a/docs/policy/release.md b/docs/policy/release.md index e8ab213..4917533 100644 --- a/docs/policy/release.md +++ b/docs/policy/release.md @@ -2,7 +2,7 @@ **Base Policy Version:** 1.4 -**Last Updated**: 2026-10-06 +**Last Updated**: 2026-10-08 **Upstream Source:** [release.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md) @@ -20,13 +20,10 @@ policy and link to it rather than introduce additional release requirements. CommandKit releases source-only Go modules. Standard CLI behavior is exposed by consuming applications; CommandKit does not declare binary deliverables or a -cross-platform build matrix. The publication procedure and its tooling will be -introduced with a releasable module. Do not create a placeholder publisher or -claim that a release command exists before implementation. - -ReleaseKit may provide future publication mechanics, but its integration has not -been selected. Adopt concrete checks for CommandKit's risks; do not copy another -repository's platform commitments or validation gates. +cross-platform build matrix. ReleaseKit v0.2.0 is selected as the maintainer +publication tool. The [release procedure](../release.md) owns its source-only +workflow and repository-specific commands; the integration adds no application +command family or runtime ReleaseKit import. ## Release Model And Completion diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000..1c6dbf9 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,133 @@ +# CommandKit release procedure + +## Scope and prerequisites + +CommandKit publishes source-only Go module releases: an immutable annotated +version tag for one committed candidate and its matching checked-in release +note. This procedure does not publish a hosted release page, binaries, +checksums, or other delivery assets, and it requires no delivery credentials. + +Use branch `main`, remote `origin`, and the expected effective push endpoint +`https://gitea.maximumdirect.net/eric/CommandKit.git`. The profile enforces that +endpoint during publication. The maintainer needs a local Go toolchain +compatible with the module's Go 1.25.5 minimum, Git with push access to `origin`, +and a POSIX shell. + +This procedure follows the [release policy](policy/release.md); the release-note +footer follows the [OSS discoverability policy](policy/oss.md#discoverability). + +ReleaseKit v0.2.0 owns candidate validation, publication guards, annotated tag +creation, tag publication, and outcome reporting. The repository profile selects +only its default candidate suite. The launcher bootstraps the module-selected +native executable into ignored `.releasekit/` storage and invokes its `publish` +command. The upstream [CLI reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/cli.md), +[profile reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/config.md), +and [publication guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/consumers/publish.md) +own detailed command, profile, and status contracts. + +## Prepare and publish a candidate + +Choose a fresh, unused stable Semantic Version tag in the form +`vMAJOR.MINOR.PATCH`, with no leading zeroes. Before `v1.0.0`, a minor release +may change a documented contract if its note explains the impact and consumer +action; a patch release must not intentionally break contracts within its +minor line. Never reuse a version previously published through any release +channel. The first version is selected during release preparation, not embedded +in the tool or profile. + +Start from `main` and prepare a note at `docs/releases/.md`. Begin with +a heading containing `CommandKit` and the exact version. Include a useful +summary and any compatibility impact or upgrade instructions. End it with the +license and attribution links at that version's immutable source tag, replacing +`VERSION` with the selected tag: + +```markdown +[COPYRIGHT](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/COPYRIGHT) | +[LICENSE](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/LICENSE) | +[ATTRIBUTION](https://gitea.maximumdirect.net/eric/CommandKit/src/tag/VERSION/docs/oss/attribution.md) +``` + +Review these paths in the candidate; the future tag URLs do not need to resolve +before publication. + +Prepare dependencies separately from the offline candidate suite: + +Run these commands in the same shell session so the version variable remains +set: + +```sh +commandkit_version=vX.Y.Z +GOWORK=off GOTOOLCHAIN=local go mod download +``` + +If dependency preparation changes `go.mod` or `go.sum`, review and commit those +changes with the candidate. Commit the note and all candidate changes on `main`, +then publish that commit to `origin`: + +```sh +git push origin HEAD:refs/heads/main +./scripts/release "$commandkit_version" +``` + +The launcher builds the ReleaseKit version selected by the module in readonly +mode. After preflight, `publish` runs the offline default Go suite once, checks +the candidate and remote guards, creates an annotated tag from the committed +note, and pushes only that tag object. The launcher does not push `main`; push +the candidate first. Do not require a separate `check` before `publish` or repeat +the same suite. Successful source publication does not wait for CI, module +availability, or consumer installation. + +## Completion and statuses + +Publication is complete when the intended annotated tag is successfully pushed +to the expected endpoint, or when an exact tag-object query confirms that push +after an error. Status 0 reports confirmed publication. Status 1 reports a +known failure or conflict; status 2 reports invalid input or profile; status 3 +means the push outcome remains unresolved. See the upstream [CLI status +contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e030794969fb7787e647a90bbc4eb81bd0610f07/docs/cli.md). + +For a failed or ambiguous push, use the exact endpoint, version, and annotated +tag object reported by the invocation. Confirm that Git still resolves the +captured endpoint to itself before querying only that tag ref: + +```sh +releasekit_endpoint='COPY THE CAPTURED ENDPOINT EXACTLY' +releasekit_version='vX.Y.Z' +releasekit_tag_object='COPY THE REPORTED TAG OBJECT ID' +releasekit_ref="refs/tags/$releasekit_version" + +releasekit_resolved_endpoint=$(git ls-remote --get-url -- "$releasekit_endpoint") || { + printf '%s\n' 'publication state is unresolved: endpoint resolution failed' >&2 + exit 1 +} +if [ "$releasekit_resolved_endpoint" != "$releasekit_endpoint" ]; then + printf '%s\n' 'publication state is unresolved: endpoint resolution changed' >&2 + exit 1 +fi +releasekit_remote_tag=$(git ls-remote --refs -- "$releasekit_endpoint" "$releasekit_ref") || { + printf '%s\n' 'publication state is unresolved: remote query failed' >&2 + exit 1 +} +printf '%s\n' "$releasekit_remote_tag" +``` + +`--refs` returns the annotated tag object's ID, not its peeled commit. Compare +that ID with `releasekit_tag_object`: an exact match confirms publication; a +different object is a conflict; successful output with no matching ref proves +absence at the captured endpoint. A failed query or changed URL resolution is +unresolved, never evidence of absence. Do not query a different fetch URL or +follow a rewritten endpoint to infer the captured destination's state. + +ReleaseKit retains a local tag after a failed push, so the tag blocks an ordinary +retry. After proving the tag absent at the captured endpoint, +confirm that it was never published or used by another release channel before +deliberately removing the unpublished local tag: + +```sh +git tag -d "$releasekit_version" +``` + +Do not move, overwrite, recreate, or delete a published tag. If the exact tag +object is present remotely, keep it. Resolve conflicts with a fresh version; +corrections to published source require a new version. A transport failure +alone does not require a new version. diff --git a/docs/roadmap/01-cli-plan.md b/docs/roadmap/01-cli-plan.md index 66b1940..5df155b 100644 --- a/docs/roadmap/01-cli-plan.md +++ b/docs/roadmap/01-cli-plan.md @@ -9,8 +9,8 @@ Original review: 2026-10-06. Reconciled: 2026-10-07. This document preserves the initial command-suite review and identifies remaining future work. Its completed implementation tasks and obsolete contract drafts have been retired. The [initial feature target](initial.md) and -[completed implementation plan](implementation.md) record delivery scope and -execution history. +[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) +record delivery scope and execution history. The [CLI reference](../cli.md) owns implemented commands, syntax, formats, and outcomes. Go declarations and GoDoc own exact exported APIs; the diff --git a/docs/roadmap/02-dispatch.md b/docs/roadmap/02-dispatch.md index efe1d20..04faa89 100644 --- a/docs/roadmap/02-dispatch.md +++ b/docs/roadmap/02-dispatch.md @@ -10,7 +10,8 @@ Original planning: 2026-10-06. Reconciled: 2026-10-07. registry, and typed-input decisions and rationale. The [architecture policy](../policy/architecture.md) owns responsibility boundaries. This document records completion of the initial dispatcher design; the -[implementation plan](implementation.md) preserves its execution history. +[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) +preserves its execution history. The registry, typed inputs, command/group APIs, invocation coordination, and outcomes are implemented. Their exact contracts are owned by Go declarations diff --git a/docs/roadmap/03-backend.md b/docs/roadmap/03-backend.md index 71e311d..116da56 100644 --- a/docs/roadmap/03-backend.md +++ b/docs/roadmap/03-backend.md @@ -27,7 +27,8 @@ The [CLI reference](../cli.md) owns observable syntax and presentation. The initial implementation translated registered metadata through a neutral bridge, rebuilt backend state for each invocation, and adapted backend routing, local flags, operands, presence, help, and syntax failures to selected semantics. -The [completed plan](implementation.md) records these stages and their checks. +The [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) +records these stages and their checks. The earlier discussion of rejecting repeated singletons was superseded by the accepted last-occurrence rule in [ADR 0006](../adr/0006-command-grammar.md). diff --git a/docs/roadmap/04-facade.md b/docs/roadmap/04-facade.md index d74a9d4..5e3e9d7 100644 --- a/docs/roadmap/04-facade.md +++ b/docs/roadmap/04-facade.md @@ -16,7 +16,7 @@ the [consumer guide](../consumers/guide.md) explains their use. The [internal overview](../internal/overview.md) owns the actual package inventory, and [go.mod](../../go.mod) owns dependency versions. -The [initial target](initial.md) and [completed implementation plan](implementation.md) +The [initial target](initial.md) and [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) record the chosen layout and delivered API work. The initial implementation requires no further facade package construction. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index ab79e6d..4d5bfd3 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -369,7 +369,7 @@ the stage. ## Stage 5: document operation and reconcile release navigation -**Status:** pending. **Prerequisite:** Stage 4. +**Status:** complete. **Prerequisite:** Stage 4. **Files:** new `docs/release.md`; `docs/policy/release.md`, README, `docs/development.md`; historical roadmap references listed below; and stage @@ -444,6 +444,18 @@ licensing footer navigation, intended release URL paths, changed historical references, provenance, and Markdown whitespace. No publisher invocation on CommandKit or another full test suite is needed for these prose edits. +Observed 2026-10-08: added `docs/release.md` with source-only preparation, +publication, status, and exact-object recovery instructions. The runbook was +reviewed against the profile, launcher, release policy, OSS policy, and ReleaseKit +v0.2.0 references. The policy retains its base version and upstream provenance +with an updated local date. README and developer navigation link to the runbook; +the developer guide records the optional local exercise. Historical references +now use the immutable initial-plan snapshot, while current ReleaseKit work links +to its roadmap and this plan. A link check found 228 valid local destinations and +fragments across 11 affected documents; Markdown whitespace checks passed. The +README's licensing and attribution footer remains intact. No real publication +or full test suite was run for this prose stage. + **Completion:** implemented tooling has one canonical runbook, policy status is accurate, and old library history is distinguishable from current ReleaseKit work. Commit the stage. diff --git a/docs/roadmap/initial-plan.md b/docs/roadmap/initial-plan.md index 1d9cfd7..a6a2eac 100644 --- a/docs/roadmap/initial-plan.md +++ b/docs/roadmap/initial-plan.md @@ -5,9 +5,10 @@ Status: roadmap preparation and implementation-plan handoff complete. Date: 2026-10-07. The [feature roadmap](initial.md) records the selected initial target and its -completion. The [implementation plan](implementation.md) was prepared from that -review and has been executed. Checked entries below record the completed -preparation process; they are not assignments to restart planning. +completion. The [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md) +was prepared from that review and has been executed. Checked entries below +record the completed preparation process; they are not assignments to restart +planning. ## Historical preparation process diff --git a/docs/roadmap/initial.md b/docs/roadmap/initial.md index 03946ac..94d5f2c 100644 --- a/docs/roadmap/initial.md +++ b/docs/roadmap/initial.md @@ -9,7 +9,7 @@ Date: 2026-10-07. This document defines the selected initial target for the library: packages, features, integration contracts, dependencies, and completion evidence. It was prepared using [the agreed checklist](initial-plan.md). Implementation steps and -stage evidence belong in [the completed implementation plan](implementation.md). +stage evidence belong in the [completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md). Detailed specifications below preserve the selected design baseline; they are planning history, not a parallel current API or operator reference. The included target is implemented; the table below records feature status. @@ -592,11 +592,11 @@ framework, general dependency injection, concurrent-dispatch guarantees, and implementation of additional library families. None is needed to prove the initial selected feature target. Application-owned commands remain extensible. -Consumer migrations, release publication, and ReleaseKit integration are separate -work. Initial implementation should be a usable module with maintained examples; -source-release tooling is planned under the release policy when preparing a -releasable candidate. Do not create placeholder publisher commands or a binary -build matrix. +Consumer migrations and source publication were kept outside the initial +library target. Current ReleaseKit adoption is tracked in the +[adoption roadmap](releasekit.md) and its [implementation plan](implementation.md). +The initial implementation targeted a usable module with maintained examples; +it did not create placeholder publisher commands or a binary build matrix. ## Completion criteria diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index c32821b..d861578 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -138,7 +138,8 @@ labeled the retained process and outline as historical. ## D-06: clarify completed feature and implementation records -Owners: [initial.md](initial.md) and [implementation.md](implementation.md). +Owners: [initial.md](initial.md) and the +[completed initial implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3871d837489b9955998b362587a52b47282dc021/docs/roadmap/implementation.md). - [x] Replace ownership statements written in future tense in the feature roadmap with links to the existing GoDoc and CLI reference. Clearly identify detailed