diff --git a/docs/roadmap/releasekit.md b/docs/roadmap/releasekit.md new file mode 100644 index 0000000..08c9cc3 --- /dev/null +++ b/docs/roadmap/releasekit.md @@ -0,0 +1,276 @@ +# ReleaseKit Adoption Assessment + +Status: Recommendations for review. Release tooling and adopted policies have +not changed. This assessment is the basis for a later feature roadmap and +implementation plan. + +## Purpose And Evaluation Standard + +Adopt ReleaseKit to standardize PromptKit's release process and reduce the +amount and complexity of release code maintained here. Prefer the shared +workflow over reproducing every existing local behavior. Retain local checks +where they protect a substantive project requirement; propose broadly useful +validation upstream where doing so saves continuing maintenance. + +Changes to release mechanics are acceptable. Their value should be assessed +against the [release policy](../policy/release.md), +[testing policy](../policy/testing.md), and the user's preference for few, +automated, nonredundant gates. Existing local release checks are evidence to +evaluate, rather than a requirement to preserve them all. + +This document recommends future changes. The current +[release procedure](../release.md) remains authoritative until adoption lands. + +## Reviewed Baseline + +Assessment date: 2026-10-07. + +- PromptKit: commit `4b8169da286917fde7875425bb32b799b12c6af3`, with a clean + worktree before this assessment. Its release scripts contain 209 lines: + 57 in [publication](../../scripts/release.sh) and 152 in + [validation](../../scripts/release-check.sh). +- ReleaseKit: published `v0.1.0`, commit + `5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1`. The local checkout and upstream + `main` match the tag's peeled commit. See its + [configuration reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/docs/config.md), + [publication guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/docs/consumers/publish.md), + and [CLI contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/docs/cli.md). +- The preceding review ran ReleaseKit's offline Go suite successfully. Its + tests use local Git remotes and HTTP fixtures for publication and delivery; + this is not evidence of a live PromptKit integration or deployed delivery + workflow. No candidate was published as part of either review. + +The assessment examined both release scripts, their owning documentation, +ReleaseKit's candidate and publication behavior, additional-check execution, +and its controlled Go environment. Installed `go help test` confirms that +ordinary `go test` includes a subset of vet's default analyses. + +## Overall Fit + +ReleaseKit already owns stable-version parsing, committed release-note +capture, a clean candidate on `main`, unused local and authoritative remote +tags, exact candidate identity, annotated-tag creation, publication, and +bounded reconciliation after a failed push. PromptKit already uses the same +main-before-tag publication model. ReleaseKit can replace those mechanics +without a PromptKit-owned orchestration package. + +Its standard candidate suite is +`go test -mod=readonly -count=1 ./...`. It uses the available compatible local +Go toolchain, disables workspace discovery and module/toolchain downloads for +that run, and controls settings that could change the selected tests or host +target. Dependency and tool installation belong to preparation. Additional +check commands are separate children; they do not automatically inherit that +entire controlled Go environment. + +Successful source publication remains the completion point. The native CLI +also reports known failures, conflicts, and uncertain pushes. PromptKit can +use that recovery model directly, including querying the captured publication +endpoint when needed. Neither CI success nor consumer installation becomes a +release gate. + +## Assessment Of Existing Checks + +| Current check or responsibility | Recommendation | Reason and ownership | +| --- | --- | --- | +| Stable SemVer, clean `main`, unused version, synchronized authoritative branch, and candidate rechecks | Adopt ReleaseKit. | These are shared publication mechanics, already implemented and tested upstream. Remove the local equivalents. | +| Annotated tag, release-note annotation, and explicit tag-only push | Adopt ReleaseKit. | Use the committed note as the annotation. The extra `Validated commit` annotation line is unnecessary: the tag already identifies that commit. | +| Failed or ambiguous push recovery | Adopt ReleaseKit. | Its bounded reconciliation and reported endpoint replace local recovery mechanics. Retain a short maintainer runbook linked to the upstream contract. | +| Full Go test suite | Adopt the shared standard suite once. | Remove the suite invocation from additional checks. A separate `check` invocation before `publish` is diagnostic, not a required second pass. | +| Race detector | Seek a shared race-enabled standard-suite variant; resolve Open Question 1. | PromptKit has real concurrent execution and capacity management. Race detection offers distinct protection, but the current upstream suite cannot enable it. Do not attach a second complete test run just to preserve the old command. | +| Explicit `go vet ./...` | Retain as a configured command pending Open Question 2. | Ordinary `go test` runs only a subset of vet analyses. Full vet is not wholly redundant, although part of its work overlaps. Its invocation needs no custom local implementation. | +| Three offline consumer examples with semantic JSON assertions | Retain locally as a focused additional check. | Expected preparation, execution, retry, validation, and usage results are PromptKit-specific. Preserve these assembled consumer workflows without moving their expected values into ReleaseKit. | +| Tracked Go formatting | Propose shared upstream support. | Enumerating source files, invoking `gofmt`, and reporting unformatted files are reusable mechanics. Select this check for PromptKit without maintaining its shell loop here. | +| Local Markdown paths and heading fragments | Propose shared upstream support. | This is the largest generic block in the checker. Offline broken-link detection protects documentation consumers across repositories. Replace the local parser with supported upstream behavior. | +| Rejection of an ambient active Go workspace | Remove this release gate. | ReleaseKit already runs its standard suite with workspace discovery disabled. Apply suitable settings to additional Go commands as well; an unrelated active workspace need not prevent release. | +| Tracked `go.work` and `go.work.sum` | Retain the project rule through a small additional check. | The [architecture policy](../policy/architecture.md#repository-independence) expressly keeps workspace files out of PromptKit's committed source. Disabling discovery does not enforce that distribution rule. | +| Blanket rejection of every `replace` directive | Narrow to the established project requirement. | Architecture prohibits local filesystem replacements. A versioned module replacement is different; the current blanket check is broader than that stated requirement. Do not export the blanket ban as a shared standard. | +| Rejection whenever a `vendor` path exists | Remove the blanket release gate. | The architecture policy does not establish this prohibition. ReleaseKit's standard `-mod=readonly` run avoids automatic vendor selection; a local ignored directory need not block it. Review any intentional distribution change through ordinary development. | +| `git diff --check` and its staged counterpart | Keep in ordinary development; remove as release gates. | A clean, committed release candidate has no staged or unstaged diff. These commands add no source-whitespace protection at that point. A new historical or whole-tree whitespace audit would be a different check, not something to add implicitly. | +| Fixed credential-pattern scan | Recommend retiring the mandatory release gate; resolve Open Question 4. | The small regex catches some recognizable formats but is incomplete and can match synthetic data. Ordinary credential-aware change review already applies. A broader shared scanner requires its own demonstrated benefit. | +| Exact title plus mandatory Summary, Compatibility, Upgrade, and Changes headings | Adopt ReleaseKit's note convention. | Retain the substantive summary and relevant compatibility/upgrade guidance, but remove the extra structure validator. Section names are an editorial choice. Historical notes remain untouched. | +| Licensing footer and canonical documentation updates | Retain as preparation under the OSS/documentation policies. | ReleaseKit preserves the captured note, including its footer. This does not call for URL probes, a recurring attribution audit, or another publication sign-off. | +| Completed-roadmap retirement | Retain as preparation housekeeping. | Determining whether feature work is complete is project-specific. It does not justify a generic automatic gate or a new human approval step. | +| Separate builds, binary targets, provider probes, CI/module-availability waits | Keep absent from source publication. | PromptKit has no binary deliverables or live inference requirement for releases. ReleaseKit supports source-only publication. Hosted note-page delivery is considered separately below. | + +The module-file checks should express the selected requirement accurately. +Workspace-file and local-replacement rules can share reusable upstream +mechanics if there is wider demand, but their policy is not universal to Go +applications. Keeping a small local check is preferable to building a broad +configuration framework solely to eliminate a few lines. + +## Recommended Upstream Work + +### Shared Source And Documentation Checks + +The strongest immediate requests are reusable Go formatting and local +Markdown-link checks, available through the shared tooling rather than merely +through a Go helper that PromptKit must wrap in its own executable. + +The consumer needs are straightforward: inspect the selected repository's +tracked source, report actionable failures, and perform offline checks without +rewriting files. Markdown checking should cover local paths and supported +heading fragments while excluding external URL availability checks. Let +ReleaseKit establish its supported Markdown conventions; PromptKit need not +preserve its exact regex parser, anchor algorithm, or blanket rejection of +links outside the repository as universal policy. + +Propose the capabilities and rationale upstream, leaving API and internal +implementation design to ReleaseKit. Its routine-release priorities should +guide whether these checks become shared defaults or optional selections. +Either approach can reduce PromptKit-owned code. PromptKit need not prescribe +mandatory checks for every unrelated consumer. + +### One Standard Suite With Useful Go Validation + +Race-enabled execution is a credible upstream request for concurrent Go +projects. Full vet within the same standard test operation is another useful +candidate. The desired benefit is one complete suite execution with the +selected analysis, rather than duplicate test runs or custom per-project test +orchestration. + +ReleaseKit currently ignores ambient `GOFLAGS`, so setting that variable is +not a supported way to alter its suite. Do not work around the standard by +trying to filter or neutralize its mandatory tests. Request a small supported +capability if these choices remain release requirements. An arbitrary +replacement validation command is unnecessary for PromptKit's use case. + +These enhancements are not prerequisites for adopting publication. Their +acceptance affects the final validation selection, as described under Open +Questions. Shared formatting and link checks can also follow initial adoption; +until they are available, retain a transitional local implementation only for +checks selected to continue. + +### Work Not Recommended For Upstreaming Now + +Do not propose PromptKit's four note headings, example output values, +completed-roadmap judgments, or architecture-specific module restrictions as +ReleaseKit defaults. There is also no value in upstreaming the current +clean-candidate diff-whitespace checks. The narrow credential regex is not a +sufficient basis for a shared security-check subsystem. + +## Recommended Adoption Shape + +Use ReleaseKit's pinned native executable as maintainer tooling. A small +`releasekit.json` profile supplies product identity, remote selection where +needed, and additional checks. A thin repository entry point invokes the tool +and preserves its native exit status; direct `go run` publication loses the +distinction between ordinary failure and an uncertain push. + +This needs no PromptKit runtime import, `buildinfo` integration, or public API +change. Prefer a separately installed pinned tool over adding release +orchestration to the consumer library's dependency graph. Use a released +version and documented preparation rather than a sibling-checkout dependency +or local `replace` directive. + +PromptKit should own only its product facts, release-note content, substantive +compatibility choices, and focused additional checks. The selected example, +vet, and module checks should use the intended Go toolchain/module context; +dependency preparation precedes their offline execution. Keep generic +publication guards and recovery tests upstream, with a small local integration +check for the actual profile and entry point when adoption is implemented. + +Hosted note pages are supported independently of publication. The ReleaseKit +product roadmap favors pages for source-only consumers, but its implemented +`publish` operation does not require delivery configuration or credentials. +Open Question 3 distinguishes adopting that additional channel from adopting +source publication. + +## Local Changes Needed When Adoption Is Approved + +| Affected material | Proposed change | +| --- | --- | +| `scripts/release.sh` | Replace local orchestration with native ReleaseKit invocation. Preserve one publication entry point. | +| `scripts/release-check.sh` | Remove shared-suite execution and retired gates. Move the retained example assertions and module checks into focused additional checks; use upstream generic checks when available. Decide whether a standalone development command still provides value. | +| `releasekit.json` and tool preparation guidance | Introduce a small profile and a selected released tool version. Build/delivery settings depend on the chosen deliverables. | +| `docs/policy/release.md` | Adopt shared validation, note structure, and recovery behavior; preserve source/tag integrity, compatibility policy, catalog exceptions, and the no-CI-wait completion rule. Record any selected delivery channel. | +| `docs/policy/testing.md` | Update the release-candidate validation description consistently with the selected race/vet approach and retained consumer workflows. | +| `docs/release.md` | Document preparation, the single publication command, ReleaseKit failure states, and recovery. Link to upstream contracts rather than recreating them. | +| `docs/development.md` | Replace the current script inventory and prerequisites with the implemented tool/check ownership and proportionate development validation. | +| `docs/policy/architecture.md` | Preserve the explicit committed-workspace/local-replacement boundary. Only adjust text if adoption actually changes that deliberate project decision. | +| Release notes and licensing material | Describe adopted operational changes in the next appropriate release note. Preserve the OSS footer. Tool use alone requires no new attribution entry; assess any copied/adapted implementation or documentation under the [OSS policy](../policy/oss.md). | + +These are proposed changes, not permission to update unrelated policies or +distribution channels during this assessment. A later implementation plan +should use the selected released upstream contracts and resolved decisions. + +## Expected Benefit And Validation + +The immediate benefit is eliminating most of the 57-line publication script +and moving its consequential Git behavior and recovery maintenance upstream. +Most of the remaining 152 lines are validation, including a large generic +Markdown checker. Shared checks, removal of ineffective gates, and simpler +note rules can remove substantially more. Exact savings depend on upstream +capabilities and the selected validation policy; no deletion quota is needed. + +The resulting local surface should be a tool invocation, product settings, +and small project-specific checks. Validate those through a representative +offline integration using a temporary Git remote, not by reimplementing or +retesting ReleaseKit's entire publication matrix. Generic checks receive their +behavioral coverage upstream; local tests cover meaningful wiring and +PromptKit-specific expectations. Live hosted delivery validation is relevant +only if that channel is selected, and never delays source-release completion. + +## Open Questions + +### 1. Should Race Detection Remain A Release-Candidate Gate? + +**Recommendation:** Seek supported upstream race-enabled standard-suite +execution and select it for PromptKit if accepted. Concurrency is substantive +library behavior, so this protects a real failure class while retaining one +suite run. This is a capability request, not a requirement to preserve our +exact existing shell command or to enable race testing for every consumer. + +**Alternative:** Adopt the current ordinary ReleaseKit suite and use race +testing during concurrency-related development. This provides immediate +standardization and avoids an upstream option or additional release cost, but +removes a last check for races introduced outside explicitly concurrency-focused +work. If the upstream capability is unavailable, this is the recommended +fallback after deliberately updating the release/testing policies; do not +block adoption indefinitely or silently run the complete suite twice. + +### 2. How Much Static Analysis Should Publication Require? + +**Recommendation:** Keep full vet through a configured `go vet ./...` check +initially, and ask ReleaseKit to consider full vet as part of its one standard +test operation. Current `go test` includes only a subset of analyses, so full +vet can catch additional defects. The transitional command costs virtually +no local implementation, though it repeats some analysis. + +**Alternative:** Use only ReleaseKit's standard `go test` vet subset and run +full vet during ordinary development. This most closely follows the minimal +upstream baseline and removes overlapping analysis; it trades away release-time +coverage of the omitted analyses. Either choice requires updating the existing +explicit static-analysis requirement rather than assuming the checks are +equivalent. + +### 3. Should Adoption Add Hosted Gitea Release Notes? + +**Recommendation:** Adopt source publication first and leave hosted delivery +for a separately selected expansion. Source publication already provides the +desired standardization. PromptKit currently has no hosted CI, and adding a +delivery workflow and credentials is additional operational scope rather than +a prerequisite for using ReleaseKit. + +**Alternative:** Include asynchronous page-only delivery in adoption, using +the upstream maintained workflow and the committed note as the hosted body. +This follows ReleaseKit's broader consumer direction and improves release +discoverability with little bespoke code. It requires provisioning CI and a +Gitea credential, plus keeping delivery status and retries separate from source +publication. Successful tag publication still completes the release, even +when page delivery is delayed or fails. + +### 4. Is The Credential-Pattern Scan Worth Retaining As A Gate? + +**Recommendation:** Retire the mandatory release scan and retain the existing +credential-aware ordinary change review. The regex offers narrow detection +and can reject synthetic fixtures; there is no evidence in this assessment +that it provides enough additional protection to warrant preserving it as a +shared release requirement. This changes the selected check, not the obligation +to keep actual credentials out of committed source. + +**Alternative:** Keep the small check, or request an optional shared equivalent, +if catching a few recognizable accidentally committed credential formats is +worth its low execution cost and possible false positives. This provides an +independent automated signal beyond review. Its supported formats and intended +scope should remain explicit, without treating it as comprehensive detection +or making a broader scanner a prerequisite for adoption.