Assess ReleaseKit adoption and shared release validation

This commit is contained in:
2026-10-07 16:08:26 +00:00
parent 4b8169da28
commit 7310ef34a4

276
docs/roadmap/releasekit.md Normal file
View File

@@ -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.