Files
promptkit/docs/roadmap/implementation.md

22 KiB

ReleaseKit Adoption Implementation Plan

Implement the agreed adoption roadmap in the stages below, in order. Each stage is scoped for one Luna coding-agent prompt. This document owns the implementation steps; the roadmap owns purpose and selected policy.

Status: Stage 1's tool selection and dependency preparation are complete in 3ca01ae. The agreed series-based Go minimum supersedes the original patch-based requirement. Stage 2's example checker and shared validation profile are complete in 0d163f8. Stage 3's native tool bootstrap is complete. Resume adoption at Stage 4 after this revision.

Baseline And Working Rules

  • Planning baseline: PromptKit commit 41b2021d8cd90b8dc15483f63fb1979642acad3a. ReleaseKit is not yet a dependency; publication and validation live in scripts/release.sh and scripts/release-check.sh.
  • Select released ReleaseKit v0.2.0, whose commit is e030794969fb7787e647a90bbc4eb81bd0610f07. Use its profile, CLI, and candidate validation contracts. No upstream changes or sibling-checkout dependency are needed.
  • Start with development, then read the agent policy and applicable architecture, testing, documentation, release, and OSS policies. Reuse already-read, unchanged policies and preserve unrelated work.
  • Inspect current files before each stage. Validate and commit each completed unit under the agent policy. Follow later explicit user instructions about commits if they differ.
  • All Git publication during implementation verification targets disposable local remotes. Implementing this plan does not authorize publishing to PromptKit's actual origin, creating a real release tag, or modifying ReleaseKit.
  • Keep PromptKit's runtime API and business logic unchanged. The approved Go requirement update and tool dependency are module changes, not runtime ReleaseKit integration.
  • Retain source-only publication, the main-before-tag workflow, and completion at confirmed tag publication. Hosted pages and CI deployment are outside this adoption. Retire the credential regex without adding a replacement gate.
  • Use the latest Go installation available in the development environment. Activate it as go, set GOTOOLCHAIN=local, and use it for tool builds, candidate tests, and examples. At planning time the active local version is go1.26.8; derive the version during implementation instead of freezing it in scripts. Do not query go@latest or download another toolchain to find it.
  • Keep dependency preparation separate from offline validation. Reuse successful checks for unchanged content; do not add parallel validators, a persistent validation cache, or additional human release sign-offs.

Stage 1 — Declare The Released Tool And Advance The Go Requirement

Outcome: Module metadata selects ReleaseKit as a maintainer tool and records the initial stable version of the development environment's current Go series as the consumer minimum, subject to required higher patch minima.

Read: go.mod, go.sum, the runbook's preparation step, and the OSS policy.

Changes:

  1. From the repository root, use the active latest local Go installation: export GOTOOLCHAIN=local; capture go env GOVERSION.
  2. Follow the runbook's series-based requirement update: strip the go prefix and final patch component from the captured version, then use go mod edit "-go=${release_go_series}.0". For example, local Go 1.26.8 normally records go 1.26.0. Retain a higher patch minimum if required by a dependency or a specific correctness fix. This is preparation before the resulting candidate commit, not an operation performed inside publication.
  3. Add the tool with go get -tool gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@v0.2.0. Use a Go tool declaration, not an artificial runtime import or a tools.go workaround.
  4. Prepare dependencies with GOTOOLCHAIN=local go mod download. Review the module and checksum changes; retain necessary tool/transitive dependencies without opportunistic unrelated upgrades.
  5. Apply the OSS policy according to actual use. This is tool-only use, with no copied ReleaseKit implementation or documentation; that alone requires no new attribution entry. If a necessary existing dependency selection changes, maintain its applicable existing notices in this unit.
  6. Preserve repository independence: no committed workspace or local filesystem replacement. Do not select a PromptKit release version or write a prospective versioned release note in this stage.

Verification:

  • GOTOOLCHAIN=local go list -m gitea.maximumdirect.net/eric/ReleaseKit identifies v0.2.0; module metadata declares the intended tool.
  • Run GOTOOLCHAIN=local go test -mod=readonly ./... for the Go/module change.
  • Inspect go list -deps . to confirm the runtime facade has no ReleaseKit import dependency. Review the diff and commit the unit.

Stage 2 — Extract The Consumer Check And Declare Shared Validation

Outcome: One focused example checker and one profile express the selected validation without changing the publication entry point yet.

Read: The example-assertion block in scripts/release-check.sh, the three maintained examples, the testing policy, and ReleaseKit's profile reference.

Changes:

  1. Create scripts/check-examples.py, runnable as python3 scripts/check-examples.py. Use Python's standard library, derive the repository root from the script location, and run from that root.

  2. Move the existing semantic assertions into that checker. Preserve all current expectations: preparation ID/profile/model/message count; execution output, validity, validation status, model and token count; observation attempt/retry counts, usage completeness, and accepted assessment outcome.

  3. Execute each example once, parse its JSON, propagate compilation/process and assertion failures as nonzero results, and provide useful failure context. Keep the checker narrow; it does not run tests, vet, formatting, links, module inspection, or publication.

  4. Use the selected local Go installation for example execution. Set native host GOOS/GOARCH from that installation's go env GOHOSTOS GOHOSTARCH for the example children so ambient cross-build settings do not select an unexecutable target. Keep normal native cgo/cache settings.

  5. Create root releasekit.json with these exact selections:

    Profile field Value
    product "Promptkit"
    remote "origin"
    validation.go.race true
    validation.go.full_vet true
    validation.go_format true
    validation.markdown {}
    validation.module_distribution.workspace_files true
    validation.module_distribution.local_replacements true

    Set checks to one command whose argument vector is ["python3", "./scripts/check-examples.py"]. Its environment map selects GOTOOLCHAIN=local, GOWORK=off, GOFLAGS=-mod=readonly, GOPROXY=off, GONOPROXY=none, and GOSUMDB=off. These settings apply to the additional check; ReleaseKit owns its own shared Go environment.

  6. Omit build, delivery, expected_push_url, package-compilation targets, file-size selection, and Markdown boundary enforcement. Accept the upstream default out-of-scope handling for outside-checkout Markdown destinations.

  7. Add a concise standalone example-check command to the development guide. Keep the existing publication/checker documentation until the cutover.

Verification:

  • Run the new example checker using the offline environment above.
  • Check profile JSON syntax and the selected fields against the released reference. Detailed API/profile equivalence tests belong upstream.
  • Review the extracted assertions against the old block, then commit.

Stage 3 — Add The Native Tool Bootstrap

Outcome: A small shared invocation script builds and runs the module-selected native executable. Legacy source publication remains active until Stage 6.

Read: .gitignore, the new module declaration and profile, and the upstream CLI contract.

Changes:

  1. Create executable POSIX-shell scripts/releasekit.sh. Its role is: enter its repository root, build the declared tool, and invoke the native executable with the supplied CLI arguments.
  2. Use set -eu, GOTOOLCHAIN=local, GOWORK=off, and GOFLAGS=-mod=readonly. Build gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit with go build -mod=readonly into .releasekit/bin/releasekit. Select the native host GOOS/GOARCH for that build using the active Go installation's host values.
  3. Rebuild through Go's normal build cache on each invocation. This ensures the executable uses the active Go compiler and module selection, without a custom cache/version-validation protocol.
  4. Use exec to invoke the built executable and forward "$@" unchanged. Delegate command/version parsing, candidate guards, and exit classifications to ReleaseKit. Do not use go run for publication.
  5. Ignore the root .releasekit/ directory. Do not commit the built tool or describe it as a PromptKit binary deliverable.
  6. Bootstrap may use ordinary module access if preparation has not populated caches, while readonly mode preserves module files. Candidate validation and examples remain offline. Bootstrap does not edit the Go requirement, fetch Git refs itself, create tags, or add publication guards.
  7. Add an optional diagnostic ./scripts/releasekit.sh check VERSION invocation to the current runbook, linked to upstream requirements for a committed candidate. Make clear it is not required before publication.

Verification:

  • Run sh -n scripts/releasekit.sh.
  • Run ./scripts/releasekit.sh version; inspect the executable with go version -m to confirm its recorded Go build version matches the selected installation and its module selection is the released ReleaseKit.
  • Check that bootstrap leaves go.mod/go.sum unchanged and the tool output ignored. No real publication is performed. Commit.

Stage 4 — Add A Small Successful Publication Fixture

Outcome: A standalone offline integration check protects local bootstrap, profile wiring, and successful source publication.

Read: The production profile/bootstrap, the testing policy, and the upstream source-publication contract.

Changes:

  1. Create scripts/test-release.py, invoked explicitly with Python 3 during tooling development. Keep it outside the default Go suite and outside the profile's release checks. It is not a new per-release gate.
  2. Use standard-library temporary directories and subprocesses with real Git and the released tool. Use a synthetic working repository on main and a local bare origin; all identities and release versions are fixture data.
  3. Copy the production bootstrap, profile, and relevant ignore rule into the fixture. Copy the selected go.mod/go.sum so tool selection follows production metadata without a local replacement.
  4. Add a tiny formatted Go package and test. The test writes an invocation marker outside the checkout and records runtime.Version(). Use small race/non-race build-tag files so the test can prove the selected suite was race-enabled. This fixture never imports or retests PromptKit's full library.
  5. At the configured example-check path, install a fixture-only Python stand-in that writes an external invocation marker. Keep the real profile command and validation selections unchanged. Stage 2 verifies the real examples; this fixture verifies additional-check wiring.
  6. Add a simple version-matched release note, commit the fixture, and push its main to the local bare remote. Run the copied bootstrap's publish command from outside the fixture's repository root to exercise path handling.
  7. Keep the test invocation offline with prepared module caches, GOTOOLCHAIN=local, GOPROXY=off, GONOPROXY=none, and GOSUMDB=off. Format generated Go files before committing them.
  8. Assert native status 0, exactly one suite marker and one additional-check marker, and equal selected/tool-build/test Go versions. Verify that the local and remote tag are annotated and identify the fixture candidate, with the committed note as annotation. Confirm module bytes are unchanged and the fixture remains clean apart from ignored tool output.

Verification:

  • Run python3 scripts/test-release.py after dependency preparation.
  • Inspect that fixtures and markers use only temporary paths/local remotes.
  • Do not add upstream's full tag/recovery/checker matrix or test framework. Commit the focused success-path test.

Stage 5 — Cover Local Failure Propagation

Outcome: The same fixture demonstrates that failed product validation cannot publish a tag and that native argument failures remain classified.

Read: Stage 4's fixture and ReleaseKit's CLI exit classifications.

Changes:

  1. Extend the fixture stand-in to select failure through a test-owned environment value. In a fresh candidate/version, let shared validation pass and then fail that additional check.
  2. Assert nonzero native publication status 1, one suite and one additional-check invocation, useful failure context, and no selected tag locally or remotely. Keep the fixture clean and module metadata unchanged.
  3. Add one malformed/unsupported invocation case that exercises native status 2. Check the classification and a useful diagnostic fragment, not a complete output snapshot.
  4. Reuse the small fixture setup and production profile. Do not simulate CI, live push errors, uncertain-write reconciliation, hosted delivery, or malicious concurrent mutation; those are upstream responsibilities.
  5. Preserve cleanup of the temporary repositories and external markers. Failures must not modify the actual PromptKit checkout or its remote.

Verification:

  • Run the completed standalone integration check.
  • Review coverage for the three risks: successful wiring, failed additional validation, and native usage classification. Commit.

Stage 6 — Cut Over Publication And Its Canonical Documentation

Outcome: One publication command uses ReleaseKit; obsolete local validators and their documented gates are retired in the same unit.

Read: scripts/release.sh, scripts/release-check.sh, the released CLI and recovery guidance, and the affected canonical documentation.

Changes:

  1. Replace scripts/release.sh with a thin executable wrapper that delegates to scripts/releasekit.sh publish, forwarding supplied arguments through exec. Keep the familiar ./scripts/release.sh VERSION entry point. Add no duplicate argument, branch, remote, note, tag, or status machinery.
  2. Delete scripts/release-check.sh. The shared suite, vet, formatting, Markdown parser, and module checks now belong to ReleaseKit. The example assertions already have their focused owner.
  3. Remove the credential-pattern gate, clean-candidate diff-whitespace gates, ambient-workspace rejection, blanket vendor-path check, blanket replacement prohibition, mandatory four-heading note validator, and extra annotation commit line. Retain ordinary credential-aware change review and useful development git diff --check commands.
  4. Update scripts/test-release.py to copy and invoke the actual scripts/release.sh entry point for publication cases. The generic native invocation can continue to own the CLI classification case.
  5. Update docs/policy/release.md locally where needed: shared selections, source-only deliverables, main-before-tag publication, the simpler note convention, native recovery states, and retired gates. Preserve SemVer/compatibility rules, immutable records, catalog exceptions, the Go-update/same-toolchain requirement, and successful-tag-push completion. Preserve upstream provenance/base-policy metadata; update the local date.
  6. Update docs/policy/testing.md to describe selected race/full vet and consumer workflows, with shared machinery upstream. Document the standalone wiring check as focused development validation, not a recurring release requirement or part of default Go tests.
  7. Rewrite the relevant docs/release.md sections around: activate the latest available local Go; record its series-based minimum (or a required higher patch minimum) before the candidate commit; prepare module caches; author the note/footer; retire completed roadmaps; ordinary review/commit; push main; run the single publication command. Preparation commands may update module metadata before commit; bootstrap/validation preserve the final candidate.
  8. Document native statuses 0/1/2/3 and the upstream captured-endpoint recovery model. Link to upstream detail and include a concise usable recovery command. Never resolve uncertainty by deleting a tag before confirming authoritative absence. No CI wait, successful-push read-back, or installation check is added.
  9. Update docs/development.md: remove the old checker command/inventory and scanner reference; retain proportionate tests, formatting, examples and ordinary review for dirty development work. Identify the optional committed candidate diagnostic and the separate tooling integration command.
  10. Repair links to the removed checker. Keep existing historical release notes, licenses, runtime inventory, and public API documentation unchanged unless a concrete affected reference requires correction. No prospective release note, hosted workflow, or new consumer restriction is part of this unit.

Verification:

  • Run sh -n on the two wrappers and the completed integration check using the final publication entry point.
  • Review the diff for policy/procedure agreement and removal of the listed duplicate gates. Check links and whitespace without running a second complete package suite solely for these documentation edits. Commit the cutover.

Stage 7 — Verify The Actual Profile Against The Complete Source Snapshot

Outcome: The assembled adoption is verified without publishing a real PromptKit release.

Read: The final roadmap, profile, wrappers, runbook, and this plan's completion criteria.

Work:

  1. Confirm prior stages are committed and the working checkout is clean. Use the same active local Go installation and prepared module cache.
  2. Make a disposable local clone of the final committed PromptKit source, checkout main, and add/commit only a synthetic unused version's release note there. The note follows the adopted product/version convention and footer paths. Do not add that note to the actual checkout.
  3. Run the clone's scripts/releasekit.sh check VERSION with the real profile and actual example checker. This is the one complete final smoke check: the real race-enabled suite, full vet, formatting, Markdown, committed distribution checks, and three examples. Do not also run the old full checker or another full test/vet/example sequence for that same snapshot.
  4. Confirm module files remain unchanged, actual example checks succeed, shared Markdown/format checks inspect the final source, and the clone remains clean. This local check creates no tag and needs no remote publication.
  5. If supported upstream checks expose affected formatting or documentation defects, correct those specific issues and commit the changed candidate before repeating the snapshot check. Do not disable the selected validation to make the smoke check pass.
  6. Audit completion against the roadmap: module tool selection, native/same-Go bootstrap, all six optional validation selections, one local example check, retired validators/gates, accurate runbooks/policies, and successful fixture publication/failure protection. Reuse Stage 6's unchanged integration results.
  7. Report the implementation commits, checks, and any remaining issues. Update temporary roadmap/plan status to reflect implemented work awaiting review; keep the documents available for the user's review. Release preparation and completed-roadmap retirement remain later maintainer work.

Completion criteria:

  • The final source-only publication command delegates to released ReleaseKit; the committed profile is the single local declaration of selected checks.
  • Go metadata records the series-based minimum or a required higher patch minimum; tool build, native validation and examples use the same selected latest-local-patch Go installation, independently of that consumer minimum.
  • Profile-selected shared validation and the real consumer examples pass on the complete source snapshot, while fixture failures prevent publication.
  • No runtime ReleaseKit import, local module replacement, extra release gate, hosted workflow, provider call, real origin push, or real release tag has been introduced.
  • Canonical docs agree with implemented tooling and preserve the accepted compatibility, catalog, licensing-footer and release-completion policies.

No significant product decisions remain open. Implementation choices above settle the filenames, bootstrap, profile, validation boundaries, and test strategy needed to carry out the agreed scope.