From cb40f1d9f8ed3ebe227d6e4be1efc075b11e7a12 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Tue, 3 Nov 2026 15:36:23 +0000 Subject: [PATCH] Finalize release tooling implementation plan --- docs/roadmap/implementation.md | 328 +++++++++++++++++++++++++ docs/roadmap/release-simplification.md | 212 ++++------------ 2 files changed, 374 insertions(+), 166 deletions(-) create mode 100644 docs/roadmap/implementation.md diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md new file mode 100644 index 0000000..44da13f --- /dev/null +++ b/docs/roadmap/implementation.md @@ -0,0 +1,328 @@ +# Release tooling implementation plan + +Status: ready for the implementation sprint; Stages 1–6 are pending. + +Follow the stages in integer order. This is one end-to-end sprint: intermediate +stages may temporarily leave scripts, tests, and documentation inconsistent. +Do not add compatibility scaffolding or repeat complete suites merely to make +each intermediate stage independently releasable. Follow the local commit +policy for completed, validated units; stage boundaries do not require commits. + +The [feature roadmap](release-simplification.md) owns the target and selected +choices. Read [development guidance](../development.md), the +[agent policy](../policy/agents.md), [testing policy](../policy/testing.md), +[documentation policy](../policy/documentation.md), and the applicable +[release policy](../policy/release.md) before implementation. Use codebase-memory +tools for code discovery as instructed by `AGENTS.md`. + +## Baseline and fixed decisions + +Planning baseline: `3d396b1a66bfafc509472cd74a3f8029def3d432`. At that revision: + +- `go.mod` registers ReleaseKit v0.8.0. The root module owns the selected tool + version even when releasing an integration. Keep that dependency selection, + all library module paths and versions, and Go minimums unchanged. +- Three JSON profiles select core, ckconfig, and ckprompt. Their only file + selection is the explicit root shared-file list; hosted delivery is absent. +- `scripts/release` is a 49-line native-build launcher. The 506-line + `scripts/release_test.go` and 399-line `scripts/release_integration_test.go` + contain the test scaffolding being replaced. +- `.releasekit/gitea-token` is a maintainer-supplied ignored credential file. + Its contents are not input to implementation or tests. Preserve the file and + directory ignore rule. Do not add the credential to fixtures, logs, or commits. +- Both integrations declare core v0.2.0, while their current source requires + newer APIs. Workspace-off Go 1.26.8 tests fail at baseline with missing + `commandkit.CompletionHint`, `Explanation`, and other symbols. This is an + existing release-readiness issue, not a reason to change dependency versions + or weaken validation in this sprint. Stage 5 distinguishes this limitation + from verification of the current source and selected file checks. + +The former open decisions are resolved for this plan: select all four proposed +generic file checks and use host-normalized registered-tool execution. Add the +agreed forbidden token path and local page-only Gitea delivery. Keep ordinary +source publication and hosted delivery separate. No binary delivery, CI job, +library API change, dependency upgrade, or production publication is part of +this sprint. No implementation-blocking design question remains. + +## Stage 1: Configure the three release profiles + +Edit `releasekit.json`, `integrations/ckconfig/releasekit.json`, and +`integrations/ckprompt/releasekit.json`. + +1. Preserve each profile's `product`, `module_dir`, `remote`, + `expected_push_url`, and explicit `validation.shared_files`. The endpoint + remains `ssh://git@forge.maximumdirect.net:22222/base-layer/commandkit.git`. +2. Add `validation.go_format: true`, `validation.markdown: {}`, and + `validation.module_distribution` with `workspace_files` and + `local_replacements` both true. +3. Add `validation.forbidden_files` containing only + `.releasekit/gitea-token`. This is a literal repository-relative selection + applying to the captured repository, including integration releases. +4. Add `delivery` with `forge: "gitea"`, + `base_url: "https://forge.maximumdirect.net"`, `owner: "base-layer"`, + `repository: "commandkit"`, and `token_file: ".releasekit/gitea-token"`. + Leave `token_env` omitted, preserving ReleaseKit's default environment + override. Add no build targets or additional validators. +5. Retain `/.releasekit/` in `.gitignore`; revise its comment from executable + storage to local ReleaseKit credentials. Do not remove existing local files. + +Check that all three files parse as JSON. Use the pinned +[configuration reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/config.md) +for field semantics. Root file checks stop at independent module boundaries; +the forbidden-path check has its separately documented repository scope. +Do not create custom validators, broader forbidden lists, or blanket exclusions. + +**Stage result:** the intended checks and delivery destination are represented +entirely by the existing upstream profile schema. + +## Stage 2: Centralize tool invocation and module routing + +Create executable POSIX-shell `scripts/releasekit` as the shared entry point. +Keep executable `scripts/release` as the existing publication convenience entry +point. No shell library, module-map file, generated script, or JSON parser is +needed in the launcher. + +The shared entry point has these forms: + +| Invocation | Handling | +| --- | --- | +| `./scripts/releasekit MODULE publish [ARGS...]` | Select module defaults and invoke upstream `publish`. | +| `./scripts/releasekit MODULE check [ARGS...]` | Select module defaults and invoke upstream `check`. | +| `./scripts/releasekit MODULE deliver [ARGS...]` | Select module defaults and invoke upstream `deliver`. | +| `./scripts/releasekit version [ARGS...]` | Forward without module/profile inference. | +| `./scripts/releasekit publication-attempts [ARGS...]` | Forward without module/profile inference. | +| `./scripts/releasekit reconcile [ARGS...]` | Forward without module/profile inference. | + +`ARGS` are ordinary upstream arguments, including the version where required; +forward them as separate quoted arguments, without shell evaluation. This +wrapper covers the selected maintainer workflow; it does not reimplement the +ReleaseKit parser. Let upstream validate versions, flags, records, and candidate +state. Reject a missing selector/operation or unsupported wrapper form with +usage on stderr and status 2 before running Go. Preserve meaningful argv +boundaries; exact usage prose is not a compatibility target. + +Implement the only selector mapping in `scripts/releasekit`: + +| Selector | Module directory | Profile | Product for profile-wiring tests | +| --- | --- | --- | --- | +| `core` | `.` | `releasekit.json` | `CommandKit` | +| `ckconfig` | `integrations/ckconfig` | `integrations/ckconfig/releasekit.json` | `CommandKit ckconfig` | +| `ckprompt` | `integrations/ckprompt` | `integrations/ckprompt/releasekit.json` | `CommandKit ckprompt` | + +Implementation details: + +1. Resolve the repository root from the script location using quoted POSIX + shell operations safe with spaces and inherited `CDPATH`; change there. +2. Set `GOWORK=off` and `GOTOOLCHAIN=local` before querying Go. Resolve native + `GOHOSTOS` and `GOHOSTARCH` through the selected `go`, then export them as + `GOOS` and `GOARCH` for tool execution. Do not inherit a cross-build target. +3. Read the effective flags with `go env GOFLAGS`. Append `-mod=readonly` to + that string and export it as `GOFLAGS`, preserving the other effective + flags. Appending gives read-only selection precedence over an inherited + `-mod` setting. Do not parse or evaluate the string in the shell. Go 1.26.8 + does not accept `go tool -mod=readonly`; do not use that unsupported form. +4. For module operations, prepend `OPERATION --repo ROOT --config ABS_PROFILE`. + For `publish` only, also prepend `--expected-module MODULE_DIR`. Neither + ordinary `check` nor `deliver` accepts that publication flag. Append the + supplied upstream arguments unchanged; upstream owns its flag semantics. +5. For the three raw forms, forward the command and supplied arguments without + adding profile, module, or publication flags. The working directory is the + repository root. Relative record paths therefore resolve there; document + absolute record paths in examples for clarity, without prohibiting relative + ones. Recovery identity comes from the selected saved record. +6. Finish through `exec go tool go.maximumdirect.net/releasekit/cmd/releasekit`. + Preserve the child's output streams and exit status. Do not create or build + an executable in `.releasekit/bin/`, preflight Gitea, or chain delivery after + publication. + +Reduce `scripts/release` to checking its existing two-argument shape, then +executing the sibling helper with `MODULE publish VERSION`. Delegate selector +validation to that helper, avoiding a second mapping. Keep +`./scripts/release MODULE VERSION` usable from outside the repository. + +**Stage result:** all selected operations share root-tool execution and one +module mapping; publication and delivery remain explicitly separate commands. + +## Stage 3: Replace release-test scaffolding with focused wiring tests + +Rewrite `scripts/release_test.go` around the actual scripts and a small fake Go +executable at the subprocess boundary. Remove +`scripts/release_integration_test.go` and helpers with no remaining users. + +Use temporary directories, including a repository path with spaces and an +outside invocation directory. Copy the scripts and actual profiles into the +fixture. The fake Go needs only to answer the queried `go env` values and to +record the tool invocation, selected environment values, and controlled output +and status. Simple argument recording suffices: remove `goCall`, its bespoke +record parser, native-build assertions, and tests of assertion helpers. Do not +retain a fake build stage, fake publisher executable, Git repository fixture, +tag inspector, suite marker, or release-note generator. + +Cover these behaviors with compact cases: + +- Check the selector table against the copied profiles' module/product and the + selected destination, forbidden token path, shared files, and validation + selections. This checks CommandKit's choices, not upstream parsing semantics. +- Exercise each selector with `publish`, `check`, and `deliver`. Verify absolute + repository/profile arguments, publication-only `--expected-module`, and + unchanged forwarding of supplied upstream arguments. +- Exercise the legacy publication entry point and raw recovery/version forms. + Verify recovery receives the explicit record/options without inferred module + identity or a profile argument. +- Use foreign target values, workspace/toolchain overrides, and effective + `GOFLAGS` containing an unrelated flag and `-mod=mod`. The recorded tool + environment must select the host, disable workspace discovery, use the local + toolchain, preserve the unrelated flag, and give read-only mode precedence. + Assert effective settings rather than an incidental count/order of queries. +- Exercise statuses 0, 1, 2, and 3 on a representative operation, stdout/stderr + forwarding, and a nonzero legacy-publication result. Do not multiply all + module/operation combinations by all exit statuses. +- Exercise malformed wrapper invocations and confirm no Go command ran. Leave + invalid semantic-version and upstream-flag classification to ReleaseKit. + +Use no credential file, authenticated request, or external service. Keep existing +domain package and maintained-consumer tests unchanged. Run the focused scripts +suite during development as needed; Stage 5 owns final complete validation. + +**Stage result:** local tests protect CommandKit routing and invocation behavior; +upstream tests own publication, credential handling, and hosted reconciliation. + +## Stage 4: Align current documentation with the implemented workflow + +Update `docs/release.md`, the CommandKit-specific scope in +`docs/policy/release.md`, and release-tooling guidance in `docs/development.md`. +Keep adopted general policy text and provenance intact. Change current owners +with the implementation; the feature roadmap supplies the design rationale. + +Document these concrete invocation examples, using placeholders rather than +selecting a new release version: + +- Publish: `./scripts/release core vX.Y.Z`, with corresponding integration + selectors. Keep the existing core-then-ckconfig-then-ckprompt order. +- Diagnose: `./scripts/releasekit core check vX.Y.Z`; optional, never a required + step before publication repeats validation. +- Deliver: `./scripts/releasekit core deliver vX.Y.Z`, or either integration + selector with its own semantic version. The profile derives the full tag. +- Discover/reconcile: `./scripts/releasekit publication-attempts` and + `./scripts/releasekit reconcile --record /absolute/path/to/attempt.json`. +- Inspect the tool: `./scripts/releasekit version`. + +Include the clean tagged-checkout prerequisite for delivery, later retries from +the original tagged source, the page-only body and module-specific full tags, +environment-token precedence over the repository-relative token file, and +retention of the ignored credential directory. Explain that successful source +publication completes the source release, while hosted delivery has a separate +outcome and URL. Credentials and Gitea availability do not gate publication. +Refer to upstream delivery and recovery contracts rather than duplicating an +HTTP implementation or a second status model. + +Remove native executable-storage commands and the retired +`COMMANDKIT_RELEASE_INTEGRATION` exercise instructions. Explain that selected +upstream file checks inspect committed inputs, cover modules independently, +and do not replace domain review. Document future licensing footer URLs using +`https://forge.maximumdirect.net/base-layer/commandkit/src/tag/FULL_TAG/` plus +the correct repository-relative module file path. Keep existing published notes +and tags unchanged; add no speculative release note or historical backfill. +No CI workflow, provider call, runtime API, or attribution update is required. + +Search affected documentation for stale `.releasekit/bin/` and retired test +references. Keep the credential-path references. Where baseline documentation +mentions a deleted source file, use its inline path and baseline revision +instead of leaving a broken local hyperlink. Keep stage tracking in this plan, +not in the feature roadmap. + +**Stage result:** the maintainer runbook describes the actual wrapper commands, +selected checks, separate outcomes, and recovery without obsolete scaffolding. + +## Stage 5: Verify the final source and record validation boundaries + +Use Go 1.26.8 on `PATH`, `GOTOOLCHAIN=local`, and prepared dependency caches. +Reuse checks for unchanged final content instead of repeating them for each +stage. Preserve the existing ignored `go.work` (currently declaring Go 1.26.10); +use an external temporary Go 1.26.8 workspace when testing current source. + +Perform the following one-time migration checks; add no persistent validation +script or new recurring publication gate: + +1. Check shell syntax and executable modes for both scripts, parse the profiles, + review documentation links/fragments, and run `git diff --check`. Verify only + the intended files changed and the token remains ignored and untracked. +2. Exercise the real helper's `version` with foreign `GOOS`/`GOARCH`, an inherited + workspace, and an unrelated effective Go flag. Confirm ReleaseKit v0.8.0 runs + natively without changing module files. In a disposable module copy, remove + required tool checksum metadata and use inherited `-mod=mod`; confirm the + helper fails instead of repairing metadata. Do not alter the real sum files. +3. Review and stage only the intended sprint changes, including new files, for + verification. Obtain the staged tree with `git write-tree` and archive that + tree into a disposable directory; do not archive `HEAD` and accidentally + test the old implementation. Initialize and commit that snapshot in a new + local Git repository on `main`, with no copied tag refs or publication + remote. This verifies intended content before committing it in CommandKit. + Do not include ignored files, unrelated staged work, or real credentials. + Existing notes can label these local-only diagnostics: core `v0.3.0`, + integrations `v0.1.0`. No tag is created or reused in an authoritative + repository. +4. Build the pinned ReleaseKit executable once into temporary storage, using + the selected root module and read-only metadata. Run ordinary upstream + `check` on the snapshot's core profile with workspace discovery off. This + runs the root suite, including the new scripts tests, and all selected file + checks. Temporary native storage here is diagnostic setup, not launcher code. +5. For the integrations, create an external temporary workspace containing all + three snapshot modules. ReleaseKit v0.8.0 intentionally forces `GOWORK=off` + for its child suites, so exporting a workspace or alternate module-file flag + on the outer command cannot redirect those suites. For this diagnostic only, + put a temporary `go` shim on the executable's `PATH`: forward all invocations + to the absolute real Go binary, but for `go test` set `GOWORK` to that temporary + workspace before executing the real command. Do not skip tests or alter their + remaining arguments. Run upstream `check` for both integration profiles. + Real package suites then exercise current source; upstream file checks still + inspect unchanged committed inputs, including ordinary `go.mod` files. This + procedure was verified during planning and needs no committed helper. +6. Record workspace-backed integration results separately from independent + release-readiness evidence. The baseline standalone failures listed above + must remain visible. If needed, compare workspace-off tests with baseline to + distinguish new failures. Do not claim the shimmed diagnostic proves that + published dependencies are aligned, and do not add the shim to ordinary + `check`, `publish`, or the default test suite. Dependency/version alignment + and preparation of real integration candidates remain separate release work. + +Planning evidence: the four generic file checks passed for the baseline core; +all five selected file checks passed for both baseline integration snapshots +using their real workspace-backed suites. The corresponding workspace-off +integration suites failed with the known missing-core-symbol errors. Repeat +the relevant diagnostics for the final sprint content, not merely the baseline. +Investigate new failures without turning the baseline limitation into a false +green result or disabling an agreed validator. + +Do not invoke `publish`, `deliver`, or `ci-deliver` against a real destination +for verification. Configuration and forwarding are the local responsibility; +ReleaseKit owns authenticated preflight, hosted writes, and content matching. + +**Stage result:** the changed infrastructure, real current-source suites, and +selected committed-file checks are verified, with independent integration +release-readiness limits accurately reported. + +## Stage 6: Review, document completion, and commit + +Review the complete diff against the feature roadmap. Confirm that all three +profiles have the selected options and destination; one shared launcher owns +module routing; the old publication exercise and unused helpers are gone; +domain tests remain; documentation uses the new invocation and separate +outcomes; and `/.releasekit/` still protects the local token directory. + +Record stages completed and final validation results in this document, including +the dependency-version limitation. Do not retire these roadmap documents during +this sprint: retain the target and completion evidence for review, then apply +the normal roadmap lifecycle during later release preparation. No new release +version or source/hosted publication is required to finish this implementation. + +Follow the local commit policy, review staged changes, and commit the intended +implementation units with short plain-English messages. Report the commit IDs, +remaining work, and verification limits. Preserve unrelated changes and private +files; do not force a clean worktree by deleting or including them. With only +the planned sprint changes present, the resulting tracked worktree should be +clean. Intermediate failures do not justify leaving the final selected scope +partially implemented. + +**Stage result:** a reviewable, committed implementation of the selected target +with accurate validation evidence and no production publication. diff --git a/docs/roadmap/release-simplification.md b/docs/roadmap/release-simplification.md index 5cbfdc9..335f733 100644 --- a/docs/roadmap/release-simplification.md +++ b/docs/roadmap/release-simplification.md @@ -1,10 +1,11 @@ # Release tooling simplification -Status: implementation roadmap; no implementation has started. Local page-only -Gitea delivery and protection of the supplied token path are selected for -implementation. The recommendations in Open Decisions remain unselected. -Current release behavior stays with its canonical owners until implementation -updates them. +Status: target design finalized for the release-tooling sprint; implementation +has not started. All four generic file checks, registered-tool execution, +page-only hosted delivery, and protection of the supplied token path are selected. +The [implementation plan](implementation.md) owns stage order, tasks, validation, +and completion evidence. Current release behavior stays with its canonical owners +until implementation updates them. ## Purpose and authority @@ -21,44 +22,6 @@ The [agent policy](../policy/agents.md), govern implementation. The [release procedure](../release.md) continues to own the current workflow until implementation updates it. -## Current baseline - -Baseline: CommandKit commit `a74fcb20041cbccde93f9b9a1e3b24cb8dd131e7`. - -- The root [module](../../go.mod) selects - `go.maximumdirect.net/releasekit v0.8.0` as a Go tool. The release toolchain - remains Go 1.26.8, and the consumer minimum remains Go 1.26.0. -- [Core](../../releasekit.json), - [ckconfig](../../integrations/ckconfig/releasekit.json), and - [ckprompt](../../integrations/ckprompt/releasekit.json) have separate profiles. - They select their physical module directories, the current SSH endpoint, and - an explicit repository-root shared-file list. They enable no optional file - checks or additional product checks, and configure no hosted delivery. -- The 49-line [launcher](../../scripts/release) maps the three selectors, changes - to the repository root, builds the root-selected tool into ignored - `.releasekit/bin/` storage for the host, and delegates publication to ReleaseKit. -- [Launcher tests](../../scripts/release_test.go) occupy 506 lines, including - custom command recording, fake build/publisher processes, and tests of the - assertion helpers themselves. -- The 399-line [publication exercise](../../scripts/release_integration_test.go) - creates disposable Git repositories, release notes, and suite markers. It - checks tag structure, exact remote objects, suite counts, nested tag prefixes, - and endpoint rejection in addition to exercising CommandKit's launcher. -- CommandKit's API, CLI, integration, and maintained consumer behavior is tested - in the owning package suites. There is no separate CommandKit-specific - candidate-validation implementation to replace or preserve. - -After the baseline review, the maintainer supplied the local credential file -`.releasekit/gitea-token`. Its contents were not read. The file was confirmed -ignored, untracked, and mode `0600`; authentication was not tested. The existing -directory ignore rule now serves credential storage as well as executable -storage and remains needed after executable-storage removal. - -During review, a temporary core profile enabled all four proposed file checks -below. ReleaseKit's local `check` accepted the committed core candidate with -Go 1.26.8. This was diagnostic evidence only: no profiles changed, no publication -occurred, and equivalent integration-module checks remain outstanding. - ## Targeted end state ### Ownership @@ -79,7 +42,7 @@ deliverables and platform support commitments remain unchanged. ### Profiles -Subject to OD-1, select these existing ReleaseKit options in each profile: +Select these existing ReleaseKit options in each profile: | Selection | Intended protection | | --- | --- | @@ -88,7 +51,7 @@ Subject to OD-1, select these existing ReleaseKit options in each profile: | `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. | -Separately from OD-1, select +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 @@ -111,27 +74,25 @@ separately for demonstrated needs. ### Launcher and recovery -Subject to OD-2, use the root module's registered `go tool releasekit` through -`exec`, keeping the current selector interface and publication argument mapping. +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 rather than -silently replacing them while arranging read-only selection. Go 1.26.8's -`go tool` does not accept `-mod=readonly` directly; use its supported Go settings -mechanism and verify the intended behavior. +read-only module metadata. Preserve other effective Go settings while arranging +read-only selection. +The implementation plan specifies the wrapper interface and invocation details. -Remove explicit executable storage when the launcher no longer creates it. -Retain `/.releasekit/` in `.gitignore` for the credential file, and update its -comment to describe that purpose. Update recovery instructions to use the -registered tool or the entry point printed for the saved attempt. Preserve -ReleaseKit's distinction between publication outcome and record-storage errors. +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. Choose a small wrapper arrangement during implementation rather -than adding a coordination framework or duplicating selector tables. +operations. Keep one selector mapping and shared invocation plumbing. A pending upstream request concerns host-safe consumer launcher examples and regression coverage. It is not a dependency of this work: v0.8.0 already supports @@ -204,115 +165,34 @@ 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. -Remove the disposable publication exercise and its Git fixtures, synthetic -notes, markers, tag inspection, and environment-isolation helpers when no longer -used. Remove assertion-helper self-tests and the custom build-call log/parser -with their obsolete consumers. Trust upstream publication and delivery coverage; -do not move a duplicate suite into a different local package or export a new -test-helper API. There is no line-count target for the replacement tests. +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. -## Work from baseline to target +## Selected choices and rationale -### 1. Configure validation and hosted delivery +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. -- [ ] Resolve OD-1 and record the chosen scope here. -- [ ] Update the three profiles for the selected options while preserving their - module identities, endpoint, and shared-file selections. -- [ ] Add the agreed delivery destination and forbidden token path to each - profile. Preserve the ignored token file and the directory ignore rule. -- [ ] Run the selected checks against each module's committed candidate inputs. - Review findings against existing contracts; fix relevant defects without - introducing broad exclusions or unrelated remediation by default. -- [ ] Update the release policy's delivery scope and the release procedure's - selected-check and hosted-delivery descriptions with the profile changes. +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. -### 2. Simplify the launcher and its tests - -- [ ] Resolve OD-2 and implement the selected invocation path. -- [ ] Add or adapt focused wiring tests before deleting the coverage they replace. -- [ ] Remove `scripts/release_integration_test.go`, assertion-helper self-tests, - and unused build/publisher scaffolding after reviewing their coverage ownership. -- [ ] If registered-tool execution is selected, remove executable-storage setup - while retaining `/.releasekit/` for credentials and updating its comment. - Do not delete user-local files as part of the refactor. -- [ ] Expose explicit module-aware delivery using shared invocation plumbing. - Keep publication and delivery independently invocable and retryable. -- [ ] Update recovery commands, delivery prerequisites and retry instructions, - and token environment/file precedence. Remove obsolete opt-in publication - exercise instructions from the release and development guides with the - corresponding behavior change. - -### 3. Validate and finish - -- [ ] Validate with Go 1.26.8 and prepared dependencies. Exercise the real - registered tool's host execution and read-only behavior once where the local - wiring tests use a controlled process; use nonpublishing operations. -- [ ] Run the owning module suites and selected ReleaseKit checks against the - final candidates. ReleaseKit `check` already runs the selected module's suite; - avoid repeating the same successful suite solely for another checklist item. -- [ ] Distinguish workspace behavior evidence from each module's independent - dependency graph. For disposable committed-candidate checks, use matching - notes and existing module metadata; do not invent future dependency versions - or checksums to make validation pass. -- [ ] Review the documentation, local links, and final diff. Confirm that - domain-specific package tests remain and that removed helpers have no users. - Check future-note guidance for module-specific full tags and immutable forge - links; do not rewrite published notes to adopt the new workflow. -- [ ] Verify delivery profile routing and operation forwarding with controlled - processes. Rely on upstream tests for Gitea authentication, HTTP writes, and - content reconciliation rather than adding a duplicate local delivery engine - suite. No real token or hosted writes are needed for these migration checks. -- [ ] Record validation results and completed work here. Retire the completed - roadmap through the usual documentation lifecycle when appropriate. - -These are migration tasks, not additional permanent release gates. Verification -needs no production tag push or hosted delivery. Ordinary releases continue to -use one publication command, with no required preliminary `check` run, followed -by a separate hosted-delivery operation. Confirmed source publication remains -the source-release completion point; hosted-delivery failure is reported and -handled separately. - -## Open Decisions - -### OD-1: Which optional checks become release gates? - -**Recommendation:** Select all four options in the profiles table. Formatting -and local link checks automate existing contributor review work. The two module -distribution checks address accidental inclusion of development-only metadata -that a successful local test run can overlook. Reusing upstream mechanisms keeps -this protection declarative and avoids maintaining local checker code. - -This is a deliberate addition to release-time validation, not merely deletion -of duplicate code. The observed core pass does not establish every module's -compatibility with the selected input scope. Resolve integration findings and -the applicability of vendored or fixture inputs before treating the selection -as adopted. Record the chosen release scope in the release procedure. -The specific forbidden token path and page-only delivery are already selected -for implementation and are not part of this open decision. - -**Viable alternative:** Select formatting and Markdown now and defer the module -distribution checks. This automates familiar review work with less change to -accepted release contents, and preserves flexibility for legitimate committed -module fixtures. It leaves accidental workspace files or filesystem replacements -to ordinary review. Choose this alternative if the broader distribution checks -would reject justified inputs or their added protection does not warrant the -restriction. Do not compensate by writing equivalent local validators. - -### OD-2: Registered tool or persistent native executable? - -**Recommendation:** Use host-normalized `go tool releasekit`. The tool is already -registered in the root module, the Go cache supplies the executable, and the -launcher can forward its exit status without managing `.releasekit/bin/`. -This also removes executable-storage test machinery and documentation, while -the directory ignore rule remains for the token. Preserve read-only metadata -selection and test the effective environment before replacing the current -bootstrap. - -**Viable alternative:** Retain the current native build and persistent executable -while simplifying profiles and tests. It is already proven to handle inherited -cross-build targets, accepts an explicit build-time read-only flag, and provides -a durable recovery entry point independent of a later Go-driver invocation. -It retains storage, bootstrap, and recovery-documentation maintenance, so it -removes less local infrastructure. Prefer it only if verification identifies a -meaningful recovery or tool-resolution need that the registered-tool path does -not meet; the pending upstream example change alone is not such a blocker. +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.