diff --git a/docs/releases/v0.9.0.md b/docs/releases/v0.9.0.md
new file mode 100644
index 0000000..5c1d278
--- /dev/null
+++ b/docs/releases/v0.9.0.md
@@ -0,0 +1,41 @@
+# ReleaseKit v0.9.0
+
+ReleaseKit's maintained launchers and generated Go recovery commands now
+prepare and run the release tool for the Go host when inherited `GOOS` and
+`GOARCH` select another target. Release profiles still select the targets for
+application builds.
+
+## Launcher, delivery, and recovery fixes
+
+- Local launchers and Woodpecker templates select the host before preparing
+ tool dependencies or compiling the CLI. Module-based launchers invoke
+ ReleaseKit by its full Go package path, so another registered tool named
+ `releasekit` does not make the invocation ambiguous.
+- Generated Go recovery commands select the host when run in a POSIX shell
+ and find the Go executable through `PATH`. Recovery for API-only consumers
+ preserves both wildcard and version-specific module replacements when
+ relocating relative paths, fixing a panic after a failed publication.
+- The manual hosted-page retry stops if fetching or checking out the tag fails,
+ or if local edits remain. It checks the tagged checkout before downloading
+ dependencies or building the CLI.
+
+## Compatibility and upgrade
+
+The module path remains `go.maximumdirect.net/releasekit` and the Go consumer
+minimum remains 1.26.0. Public Go APIs, release profiles, and publication
+record formats are unchanged.
+
+Update copied launchers and CI templates to get the host and tool selection
+fixes. Updating the module dependency alone does not update those files.
+Configured product checks inherit the launcher's host target; if a check
+needs an application target, set it explicitly in the check's `env` map
+or command.
+
+See the [adoption guide](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/docs/consumers/adoption.md),
+[delivery guide](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/docs/consumers/delivery.md),
+and [maintainer runbook](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/docs/release.md)
+for updated recipes.
+
+[COPYRIGHT](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/COPYRIGHT) |
+[LICENSE](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/LICENSE) |
+[ATTRIBUTION](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.9.0/docs/oss/attribution.md)
diff --git a/docs/roadmap/commandkit-feature-request.md b/docs/roadmap/commandkit-feature-request.md
deleted file mode 100644
index c621f4b..0000000
--- a/docs/roadmap/commandkit-feature-request.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# CommandKit feature request: host-safe consumer launchers
-
-Status: proposed; not an accepted contract or implementation assignment.
-
-## Consumer need
-
-CommandKit selects ReleaseKit v0.8.0 as a Go tool and uses a small launcher to
-publish its core and two optional integration modules. Maintainers can inherit
-`GOOS` and `GOARCH` from application cross-build work. The release tool must run
-on the maintainer's host even when those variables name another target.
-
-CommandKit currently handles this by querying `go env GOHOSTOS` and
-`go env GOHOSTARCH`, then using those values when building its native ReleaseKit
-executable. Its `TestReleaseLauncherDelegatesPublication` test supplies foreign
-target variables and checks native bootstrap behavior together with argument
-and exit-status forwarding. Consumer evidence is in CommandKit's
-`scripts/release` and `scripts/release_test.go` at local commit
-`a74fcb20041cbccde93f9b9a1e3b24cb8dd131e7`.
-
-Please incorporate this behavior and regression coverage into ReleaseKit's
-maintained consumer launcher example so downstream projects can reuse the
-recipe and rely on upstream tests for its generic bootstrap mechanics.
-
-## Observed failure
-
-Reviewed ReleaseKit v0.8.0, commit
-`23203f235cc414c4ffe0fd3941030eb0c9f9943f`. The
-[multi-module launcher](../../examples/multi-module/release.sh) invokes
-`go tool` without normalizing the inherited target environment.
-
-On Linux/amd64 with Go 1.26.8, from a prepared consumer module registering
-`go.maximumdirect.net/releasekit/cmd/releasekit` at v0.8.0:
-
-```sh
-GOWORK=off GOTOOLCHAIN=local GOFLAGS=-mod=readonly \
- GOPROXY=off GONOPROXY=none GOSUMDB=off \
- GOOS=windows GOARCH=arm64 go tool releasekit version
-```
-
-The command built a Windows executable and failed to launch it with an
-`exec format error`. Repeating the command with `GOOS=linux GOARCH=amd64`
-succeeded and printed `releasekit v0.8.0`. These observations establish the
-tool-execution failure; the complete upstream launcher was inspected rather
-than executed in this reproduction. No publication was attempted.
-
-## Requested change
-
-Update the maintained launcher to select the native host target when preparing
-and executing ReleaseKit, regardless of inherited application target variables.
-Resolve the host through the selected Go toolchain rather than hard-coding a
-platform. Scope this change to running the maintainer tool; preserve the
-application targets selected through existing release profiles.
-
-Retain the launcher's existing module/version selection, profile routing,
-source-file preservation, workspace/toolchain settings, and child exit-status
-behavior. Document the host-target handling in the
-[consumer adoption guidance](../consumers/adoption.md) where appropriate.
-
-Prefer a small change to the supported example and its tests. This request does
-not require a new validation option, public bootstrap API, or test-helper
-package. CommandKit's choice to select one tool version from its root module
-remains consumer-owned; this request does not change ReleaseKit's example policy
-of selecting the tool from the chosen module.
-
-## Acceptance evidence
-
-Extend the existing
-[multi-module launcher tests](../../cmd/releasekit/multi_module_example_test.go)
-with a controlled foreign-target environment. Demonstrate that:
-
-1. The selected tool executes on the host despite foreign `GOOS` and `GOARCH`.
-2. The selected module's tool version and publication arguments still reach the
- child, and child statuses 0, 1, 2, and 3 are preserved.
-3. Source module files remain unchanged and existing bootstrap cleanup behavior
- is preserved.
-
-Reuse existing coverage for unaffected behavior rather than adding a parallel
-suite. A host-run test can use a synthetic local tool and needs no real release
-or external service. Synthetic module downloads must use test-owned caches as
-described in [the developer guide](../development.md#testing-synthetic-modules).
-
-## Ownership and downstream follow-up
-
-CommandKit's review found no locally maintained candidate validator that needs
-to become a new ReleaseKit feature. Existing formatting, Markdown, and module
-distribution options already cover their respective reusable checks; selecting
-them as CommandKit release gates is a separate consumer decision.
-
-ReleaseKit already owns publication-engine tests for annotated tags, exact
-remote objects, nested tag prefixes, and endpoint preflight. CommandKit can
-narrow its local publication exercise to its launcher and profile wiring
-without upstreaming a duplicate engine test suite. Its selectors, product names,
-publication endpoint, and release order remain local responsibilities.
diff --git a/docs/roadmap/host-native-launchers.md b/docs/roadmap/host-native-launchers.md
deleted file mode 100644
index 32265ed..0000000
--- a/docs/roadmap/host-native-launchers.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Roadmap: host-native consumer launchers
-
-Status: implemented.
-
-## Purpose
-
-Make ReleaseKit's maintained launchers and generated recovery commands prepare
-and execute the release tool for the maintainer's host when inherited `GOOS`
-and `GOARCH` select a different application target. Centralize the recipe and
-regression coverage so consumers can retain small launchers and product-specific
-wiring tests.
-
-This is a launcher correctness improvement. It requires no public bootstrap API,
-validation option, or test-helper package. This roadmap selects no release version.
-
-## Baseline before implementation
-
-The [CommandKit feature request](commandkit-feature-request.md) describes a
-prepared v0.8.0 tool invocation on Linux/amd64 with `GOOS=windows GOARCH=arm64`
-that built a Windows executable and failed with an exec format error.
-CommandKit's local launcher already selects the Go host target before
-building the release executable. The report's reproduction exercised tool
-execution without attempting publication.
-
-The maintained [multi-module launcher](../../examples/multi-module/release.sh)
-already selected a module and profile, copied module metadata into temporary
-storage, prepared the selected ReleaseKit dependency, and invoked
-`go tool releasekit`. It set `GOWORK=off` and `GOTOOLCHAIN=local` while passing
-inherited `GOOS` and `GOARCH` to dependency inspection and tool execution.
-
-The [adoption guide](../consumers/adoption.md) included a minimal `go tool`
-launcher. The [single-module CI template](../../examples/woodpecker/tag-delivery.yml)
-and [multi-module CI template](../../examples/multi-module/woodpecker.yml) also
-invoked the selected tool without explicit host-target normalization.
-
-The [maintainer launcher](../../scripts/release),
-[source delivery template](../../examples/woodpecker/releasekit-source-delivery.yml),
-and [manual delivery retry](../release.md) built and executed the tool with the
-same inherited-target assumption. The CLI's [generated recovery command](../../cmd/releasekit/main.go)
-inherited the target from the shell where it ran, and [recovery dependency
-preparation](../../internal/gotool/recovery.go) also inherited the target.
-
-Existing [launcher tests](../../cmd/releasekit/multi_module_example_test.go)
-exercised synthetic module selection, publication arguments, child statuses
-0 through 3, and preservation of source module metadata. Those fixtures provided
-the starting point for foreign-target regression coverage.
-
-## Targeted end state
-
-Maintained launchers and module-based recovery use `GOHOSTOS` and `GOHOSTARCH`
-from the selected Go toolchain as `GOOS` and `GOARCH` while preparing and running
-ReleaseKit. The tool executes on that host even when the caller was working with
-a foreign application target. Normalize before target-dependent dependency
-inspection as well as tool execution. Generated recovery commands select the
-host when run, using the Go toolchain that will execute the command.
-
-Application targets continue to come from existing release profiles. The
-launcher's host selection preserves module-selected tool versions, profile and
-argument routing, source-file preservation, temporary-file cleanup, existing
-workspace/toolchain settings, and child exit statuses. Consumers retain their
-own selectors, products, endpoints, and release order.
-
-The scope is inherited `GOOS` and `GOARCH` handling for the maintainer tool. It
-does not establish a hermetic environment, broaden hardware or platform support,
-or add release gates. Existing Go/toolchain failures remain ordinary bootstrap
-failures. No new fallback toolchain or download policy is introduced.
-
-The [implementation plan](implementation.md) defines the work to reach this
-state.
-
-## Completion evidence
-
-Completion requires host selection before dependency inspection and successful
-host execution under a foreign target, including for generated recovery commands.
-Preserve selected tool identity and arguments, child-status forwarding, unchanged
-source metadata, and existing cleanup behavior. The maintained local and CI
-recipes and adoption guidance must use the same host-selection approach.
-Application build targets must retain their existing profile-driven behavior.
diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md
deleted file mode 100644
index 2027539..0000000
--- a/docs/roadmap/implementation.md
+++ /dev/null
@@ -1,193 +0,0 @@
-# Implementation plan: host-native ReleaseKit launchers
-
-Follow the stages in order as one sprint. The
-[feature roadmap](host-native-launchers.md) defines the intended behavior and
-scope. The focused checks below describe regression coverage; intermediate
-stages need no separate review, release, or passing build. Run the assembled
-checks in Stage 6.
-
-## Stage 1: Normalize the local multi-module launcher
-
-**Completed.**
-
-1. In [the multi-module launcher](../../examples/multi-module/release.sh), after
- entering the selected module and exporting its existing `GOWORK=off` and
- `GOTOOLCHAIN=local` settings, insert the following before the first Go
- bootstrap command. Reuse this shell recipe in the subsequent stages:
-
- ```sh
- releasekit_host_os=$(go env GOHOSTOS) || exit $?
- releasekit_host_arch=$(go env GOHOSTARCH) || exit $?
- export GOOS="$releasekit_host_os" GOARCH="$releasekit_host_arch"
- ```
-
- Keep the checked assignments separate from `export` so a failed Go query
- stops the launcher. Keep host selection inside the existing launcher scope;
- preserve selected module metadata, dependency preparation, publication
- arguments, traps, and the child status. Application targets still come from
- release profiles.
-
-2. Extend [the existing launcher tests](../../cmd/releasekit/multi_module_example_test.go).
- In `TestMultiModuleLauncherUsesSelectedModuleAndProfile`, let the Go shim
- answer the two host queries and assert the exported target at
- `go list -deps` in the selected module. In
- `TestMultiModuleLauncherRunsToolFromSelectedDependency`, supply a foreign
- target to the launcher and retain real Go tool preparation and execution.
- Keep the checks for the nested module's version, forwarded profile and
- arguments, statuses 0 through 3, unchanged source, and bootstrap cleanup.
- For these fixtures, choose `windows` unless the host OS is `windows`
- (then `linux`), and `arm64` unless the host architecture is `arm64` (then
- `amd64`). This makes both variables differ from the host pair. Keep
- synthetic versions in a test-owned `GOMODCACHE`.
-
-## Stage 2: Normalize consumer Woodpecker templates
-
-**Completed.**
-
-1. Apply the Stage 1 recipe in the
- [single-module](../../examples/woodpecker/tag-delivery.yml) and
- [multi-module](../../examples/multi-module/woodpecker.yml) tag delivery
- commands, under the existing Go settings and in the selected module. Insert
- it after tag verification and checkout, before the first Go bootstrap
- command. Write the new shell variable references as
- `$${releasekit_host_os}` and `$${releasekit_host_arch}` so Woodpecker
- passes them through. Keep the verified commit, selected tool, profile
- mapping, credentials, alternate module and sum files, cleanup, and
- `ci-deliver --prepared` invocation.
-
-2. Update the existing
- [single-module](../../cmd/releasekit/woodpecker_test.go) and
- [multi-module](../../cmd/releasekit/multi_module_woodpecker_test.go) workflow
- harnesses. Teach the controlled Go shim to answer host queries before
- enforcing its alternate module file checks. In both Go shims, log the
- target at `go list -deps`. Feed a foreign target to
- `TestWoodpeckerTagDeliveryTemplate`,
- `TestWoodpeckerTagDeliveryUsesTaggedModuleVersion`,
- and `TestMultiModuleWoodpeckerDelivery` and check that dependency inspection
- uses the host pair. Retain real execution where the fixture already uses it,
- and keep the existing checks that a rejected tag or commit reaches no Go
- command.
-
-## Stage 3: Normalize source-built launchers
-
-**Completed.**
-
-1. Apply the same recipe in the [maintainer launcher](../../scripts/release)
- before building and executing ReleaseKit. Prefix the two queries with
- `GOTOOLCHAIN=local` to match its existing build. Preserve usage checking,
- output location, build settings, and the final `exec`.
-2. Apply the recipe in the
- [source delivery template](../../examples/woodpecker/releasekit-source-delivery.yml)
- after tag verification and checkout, under its existing Go settings and
- before the source build. Use the Woodpecker escaping from Stage 2. Keep
- its temporary build output, dependency preparation through the existing
- build, and prepared delivery arguments.
- Exercise `TestWoodpeckerSourceDeliveryTemplateSelfBootstraps` with a foreign
- target; log and assert the host pair at the real `go build`, retain actual
- execution, and keep the checkout, cleanup, and dependency preparation
- assertions.
-3. Update the manual delivery retry in the [maintainer runbook](../release.md).
- After fetching and checking out the tagged version, run host selection,
- dependency download, build, and delivery inside a subshell so the caller's
- target environment stays intact. Query with `GOTOOLCHAIN=local` as above;
- make the sequence stop on failure inside the subshell. Preserve the
- dependency download before the offline build, the build-only proxy and sum
- settings, the output path, and the older-tag credential example.
-
-## Stage 4: Normalize module-based recovery preparation
-
-**Completed.** The CLI adapter and assembled handoff tests follow in the next stage.
-
-1. In [the Go recovery implementation](../../internal/gotool/recovery.go),
- keep the existing registered-tool, API-only, and no-dependency selections.
- Have `RecoveryTool` return `(*RecoveryInvocation, error)` within the
- internal package. Give the descriptor `Directory string` and
- `Args []string` fields. A nil result still selects the native executable fallback.
- Set the directory to the original module for a registered tool or the
- durable bootstrap root for an API-only consumer. Put `tool -modfile=`
- and the existing full command package path in `Args`; the caller supplies
- the working directory. Preserve the selected version, local and versioned
- replacements, private module and sum files, and their existing lifetime.
-2. Immediately before the API-only branch runs `go list -deps`, query
- `go env -json GOHOSTOS GOHOSTARCH` in its private root with its existing
- `GOWORK=off` and `GOTOOLCHAIN=local` overrides. Reuse the internal
- `discover` runner with the existing context. Decode both fields, treat
- missing values as a preparation error, and add only `GOOS` and `GOARCH`
- to the environment of the dependency command. Keep the target-independent
- module-selection query and the registered-tool early return. Use the
- existing preparation error and cleanup paths; leave candidate Go settings,
- proxy policy, and fallback selection as they are.
-3. Update the direct `RecoveryTool` callers in
- [the handoff tests](../../cmd/releasekit/publication_handoff_test.go) to run
- the descriptor's arguments in its directory. In
- `TestRecoveryToolPreservesVersionedReplacement`, set a foreign target for
- the preparation call, log the target of the real `go list -deps` through a
- delegating shim, and verify the host pair there. Run the test's subsequent
- direct tool invocation with the host pair and retain its version and
- metadata assertions. Retain the source-module and vendored API-only cases.
- Update the CLI caller in Stage 5.
-
-## Stage 5: Normalize the printed recovery command when it runs
-
-**Completed.**
-
-1. In `selectedPublicationRecoveryCommand` in
- [the CLI](../../cmd/releasekit/main.go), render the descriptor as one
- copyable POSIX shell command. Use this structure, with `
`,
- ``, and `` standing for shell-quoted operands:
-
- ```sh
- (export GOWORK=off GOTOOLCHAIN=local && releasekit_host_os=$(go -C env GOHOSTOS) && releasekit_host_arch=$(go -C env GOHOSTARCH) && GOOS="$releasekit_host_os" GOARCH="$releasekit_host_arch" go -C tool '-modfile=' reconcile --record )
- ```
-
- Build the common `go -C` prefix from the descriptor directory and render
- its tool arguments using the existing diagnostic redaction and shell
- quoting. Keep the explicit absolute record operand. Both host queries run
- in the invocation directory with the same Go settings as the final command.
- A failed query stops the command, and the subshell returns the final command
- status when launched. Leave the native executable command, handoff timeout
- and cancellation behavior, and existing fallback and diagnostic behavior
- intact.
-2. In `TestColdGoToolRecoverySurvivesLauncherExit`, execute the printed
- command in a separate shell with a foreign target, after the original
- launcher and its temporary files are gone. Exercise both registered and
- API-only handoffs and retain status checks for 0 through 3. For the
- alternate-record cases, replace the quoted original record operand inside
- the command instead of appending flags after the closing subshell.
- Retain the vendored API-only, native fallback, record-selection, and
- redaction checks. Exercise the printed command itself; running the Go
- descriptor directly would miss a regression in the shell recipe.
-
-## Stage 6: Align consumer guidance and verify the sprint
-
-**Completed.**
-
-1. In the [adoption guide](../consumers/adoption.md), make the minimal
- launcher use the Stage 1 recipe followed by `exec go tool releasekit "$@"`.
- Run it from the selected module, retaining that consumer's workspace and
- toolchain settings. Move the registration smoke check to follow the launcher
- example and invoke `version` through that launcher. In the
- [multi-module README](../../examples/multi-module/README.md), apply the same
- recipe to the direct `check` smoke commands: enter each selected module in
- its own subshell, select the host there, then run the existing check with
- its repository-root profile and version. Preserve the source-selected
- fixture instructions and avoid turning the smoke check into publication.
-2. Align the [consumer delivery guide](../consumers/delivery.md),
- [CLI contract](../cli.md), and [internal Go tool guide](../internal/gotool.md)
- with the maintained recipes and handoff behavior. Explain that consumers
- update copied launchers and templates separately from upgrading the module
- dependency. ReleaseKit tests generic bootstrap behavior; consumers can
- focus their own wiring tests on selectors and profile mapping. Profile
- build targets continue to select application binaries.
-3. Run the focused launcher, workflow, and recovery fixtures from the preceding
- stages with the existing local Git and module proxy fixtures. Run
- `go test ./...` and `go run ./internal/apicheck` as documented in the
- [development guide](../development.md#validation). Check shell syntax,
- including Woodpecker command blocks after interpolation, local documentation
- links, and `git diff --check`. Use the existing offline fixtures; no hosted
- delivery, live publication, or external runner is needed.
-4. Include the following entry in the next release note during release
- preparation, when its version is selected: “Maintained launchers and
- generated Go recovery commands now use the host target to prepare and run
- ReleaseKit. Update copied launchers and CI templates to get the fix;
- release profiles still select application build targets.”
diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md
deleted file mode 100644
index 2c2a784..0000000
--- a/docs/roadmap/remediation.md
+++ /dev/null
@@ -1,289 +0,0 @@
-# Host-native launcher review findings
-
-Reviewed the implementation from `bf07bed` through `0269648` against the
-[feature roadmap](host-native-launchers.md) and
-[implementation plan](implementation.md).
-
-The maintained launchers select the Go host before preparing and running the
-tool. API-only recovery prepares its private module on the host; printed Go
-handoffs discover the host again when run. The CLI retains the native fallback
-and saved-record selection. Application build targets still come from the
-profile, and the public Go facades and dependency boundaries are unchanged.
-
-## Make the adoption smoke command runnable
-
-**Completed.** The smoke command runs the saved launcher through `sh`; verified with a non-executable file and a foreign target.
-
-**Evidence:** The [adoption guide](../consumers/adoption.md#cli-tool-dependency)
-tells readers to save the launcher as `releasekit` and run
-`./releasekit version`. A newly saved shell file ordinarily lacks its execute
-bit. In a disposable directory, the documented command failed with status 126
-and “Permission denied.” Invoking the same snippet through `sh` ran a
-module-registered fixture tool on Linux/amd64 with inherited
-`GOOS=windows GOARCH=arm64`.
-
-**Fix:** Use `sh ./releasekit version` in the smoke instructions, or give an
-explicit `chmod +x ./releasekit` step before direct execution. Verify the
-published instructions from a newly created file under a foreign target.
-
-## Limit the recovery guarantee to GOOS and GOARCH
-
-**Completed.** The CLI reference names the two target variables and identifies the shell syntax.
-
-**Evidence:** The [CLI contract](../cli.md) says Go handoffs select the host
-“independently of inherited cross-compilation settings.” The
-[command formatter](../../cmd/releasekit/main.go) overrides `GOOS` and
-`GOARCH` and retains other build settings. For example, building the actual CLI
-with the native target, `CGO_ENABLED=1`, and an unavailable C compiler named
-by `CC` still fails in `runtime/cgo`. This is consistent with the roadmap's
-scope, but the CLI wording implies broader independence.
-
-**Fix:** Say that generated Go handoffs set `GOOS` and `GOARCH` from the
-selected Go toolchain at invocation time. Preserve the other inherited settings
-and the existing workspace and toolchain overrides. The documented handoff
-uses POSIX shell syntax; identify that syntax when telling operators where to
-paste the command.
-
-## Exercise a profile target that differs from the launcher host
-
-**Completed.** The binary delivery fixture selects a non-host Linux target and checks the uploaded ELF machine as well as the filename.
-
-**Evidence:** The binary-delivery case in
-[`TestMultiModuleWoodpeckerDelivery`](../../cmd/releasekit/multi_module_woodpecker_test.go)
-supplies a foreign target to the workflow and checks the uploaded
-`core-v2.1.0-linux-amd64` asset. The profile itself selects `linux/amd64`.
-On the Linux/amd64 review host, the test cannot distinguish using the
-profile target from accidentally using the normalized launcher target. The
-current build code still applies the selected profile target explicitly.
-
-**Fix:** In that fixture, select a supported profile target distinct from the
-host and assert the uploaded asset matches it. Where practical, inspect the
-uploaded executable header as well as the name, so the test catches a
-host-built payload with a profile-derived filename. Keep the existing local
-forge fixture and native version check; the cross-built asset need not run on
-the host.
-
-## Reconcile the feature roadmap with the completed implementation
-
-**Completed.** The feature roadmap records implementation and labels the pre-change baseline. The release-note entry remains in the implementation plan.
-
-**Evidence:** The [feature roadmap](host-native-launchers.md) still declares
-“implementation pending” and describes the pre-change launchers as the current
-baseline. All six stages in the [implementation plan](implementation.md) are
-marked complete, and the maintained launchers and recovery code implement the
-host selection described there.
-
-**Fix:** Mark the roadmap implemented and label the old baseline as historical,
-or retire the completed planning documents after review. Preserve the planned
-release-note entry for the next selected release version.
-
-## Verification
-
-`go test ./...`, `go run ./internal/apicheck`, and syntax checks for the
-maintained shell scripts passed. The Go suite exercised real tool preparation,
-Woodpecker command blocks with local fixtures, and later execution of printed
-recovery commands. Disposable smoke probes also verified the maintainer
-launcher forwards the child status and the manual retry preserves the calling
-shell's target variables. The review made no changes to production code or
-tests.
-
-## Integration audit
-
-The audit below examines how the new bootstrap paths interact with existing
-invocation recipes, product checks, and publication recovery.
-
-### Use the external Go executable in printed recovery commands
-
-**Completed.** All three Go invocations use external lookup through `PATH`. The handoff regression reproduces the shell-function failure before the fix and verifies reconciliation afterward.
-
-**Evidence:** Before host normalization, the
-[command formatter](../../cmd/releasekit/main.go) emitted
-`env GOWORK=off GOTOOLCHAIN=local go ...`, which resolves Go through `PATH`.
-[Recovery preparation](../../internal/gotool/recovery.go) still executes an
-external Go command. The new printed command uses bare `go` for both host
-queries and the later tool invocation, so a function named `go` in the
-operator's shell can intercept it. In a local rejected-push fixture, the
-actual printed command reconciled the saved record in an ordinary shell.
-With `go() { GOOS=windows GOARCH=arm64 command go "$@"; }` defined, the same
-command failed with an exec format error. The function overrode the final
-assignments even though the host queries reported the correct host. In this
-case both paths exited with status 1, but only one produced a reconciliation
-result.
-
-**Fix:** Restore external command lookup for the host queries and tool
-invocation, for example by using `env go -C ...` throughout the subshell.
-Keep selection through the operator's current `PATH`, including executable
-shims, and keep the exact record and exit status. Exercise a generated
-handoff from a POSIX shell that defines a cross-build Go function; assert
-the reconciliation result as well as the status.
-
-### Explain how host normalization affects configured product checks
-
-**Completed.** The adoption guide explains inherited host variables and points checks that need an application target to the existing environment overlay.
-
-**Evidence:** The updated launchers export `GOOS` and `GOARCH` to the
-ReleaseKit process. Existing [configured checks](../config.md) inherit that
-process environment unless their `env` maps override it;
-[`RunChecks`](../../cmd/releasekit/internal/cli/config.go) adds the configured
-and ReleaseKit-owned values to the child. This differs from built-in
-application compilation, which chooses its target from the profile. A
-disposable consumer's check using shell defaults for an application target
-passed with the previous direct `go tool` invocation and no target
-variables, then failed through the updated launcher because it observed
-`linux/amd64`. Adding explicit `GOOS=windows` and `GOARCH=arm64` to that
-check's `env` restored its behavior.
-
-**Fix:** In the launcher adoption guidance, explain that host variables
-reach configured child checks and that checks which need an application
-target should set it explicitly in their existing `env` map or command.
-Link to the configuration contract. Keep the current environment overlay
-semantics and the separate profile selection for built-in builds.
-
-### Align direct source and standalone CI recipes with the launcher guidance
-
-**Completed.** The source examples link to host selection, and the standalone install recipe scopes the same settings to `go install`. Both paths were verified under a foreign target.
-
-**Evidence:** The [README quick start](../../README.md) and
-[CLI reference](../cli.md) still recommend bare `go run ./cmd/releasekit`
-for source invocation. The [consumer delivery guide](../consumers/delivery.md#woodpecker-tag-workflows)
-also recommends bare `go install ...@PIN` for consumers who install the
-delivery executable separately. These older recipes remain target-sensitive
-alongside the new host-native launchers. On Linux/amd64 with inherited
-`GOOS=windows GOARCH=arm64`, the README's actual `version` command failed
-with an exec format error. A versioned install from a disposable local
-module proxy failed under the same variables with `GOBIN` set; the native
-install succeeded and its binary ran.
-
-**Fix:** Link these recipes to the host-selection instructions and make the
-native target requirement explicit at the source invocation and at the
-standalone installation step. Use the existing recipe where a copyable
-command is useful. Keep the selected version, install location, and
-`go run` exit-status caveat. An already installed native binary does not
-need a new bootstrap step.
-
-## Algorithmic audit
-
-The host normalization itself adds a fixed number of Go invocations per
-launch. The CLI renders a fixed argument list, so quoting and formatting take
-time and space linear in the lengths of the directory and record paths. Go
-dependency inspection and compilation retain their existing roles. The
-findings below concern a pre-existing algorithm on the audited recovery path
-and a new module-selection defect in the smoke recipe.
-
-### Relocate recovery replacements in one pass without merging selectors
-
-**Completed.** Recovery rewrites relative destinations in one pass. The CLI regression verifies both selectors, the selected tool, the rejected-push status, and later reconciliation.
-
-**Evidence:** The API-only path in
-[`RecoveryTool`](../../internal/gotool/recovery.go) walks the parsed
-`go.mod` replacements. It calls `modfile.AddReplace` for each relative
-local replacement. In the pinned `golang.org/x/mod` implementation,
-each call scans the entire replacement slice. With `R` total directives
-and `L` relative local directives, relocation visits `O(R × L)` entries,
-and takes quadratic time when all or most entries require relocation.
-This loop predates host normalization and still runs before the new host
-query.
-
-The same loop can panic on a valid module that declares both an unversioned
-and a version-specific replacement for the same dependency. When the
-unversioned directive appears first and uses a relative path, calling
-`AddReplace` with an empty old version treats both directives as matches
-and clears the version-specific entry. The outer loop then visits that
-cleared entry as if it were another relative replacement. In a disposable
-API-only consumer with both forms for ReleaseKit, Go accepted the module
-and validation passed. After a local hook rejected the tag push, ReleaseKit
-saved the publication record, then panicked in `modfile.addReplace`. It
-exited with status 2 instead of reporting the rejected push and a recovery
-handoff.
-
-**Fix:** Rewrite each relative right-hand path on its existing parsed
-directive in one pass, preserving the exact left-hand path and version
-selector. For example, update the typed replacement and its corresponding
-syntax token before formatting. This takes `O(R)` directive visits plus
-the bytes processed for the paths and avoids selector merging. Keep the
-existing relocation policy, the separate synthetic replacement for the
-original module, and the private module lifetime. Add a recovery fixture
-with distinct local destinations for a wildcard and a version-specific
-replacement. Check that the handoff preserves both directives, selects the
-version-specific destination, and reports the original publication status.
-
-### Anchor smoke-check module paths to the intended checkout
-
-**Completed.** Both nested paths use `./`; verified the full smoke recipe with a conflicting `CDPATH`.
-
-**Evidence:** The [multi-module smoke recipe](../../examples/multi-module/README.md)
-replaced `go -C integrations/...` with subshells that run
-`cd integrations/...` before host discovery. A shell with `CDPATH` set can
-resolve these relative names in another checkout. In a disposable probe
-with matching module paths under two directories, the published snippet
-sent both nested checks to the checkout named by `CDPATH` and returned
-success. If the other checkout has valid profiles and tools, the smoke
-result can appear valid for the wrong candidate.
-
-**Fix:** Use `cd ./integrations/ckconfig` and `cd ./integrations/core/v2`,
-or clear `CDPATH` for those two directory changes. The number of lookups is
-already fixed; the change corrects which directory is selected. Verify the
-copyable recipe with a conflicting `CDPATH` entry.
-
-## Follow-up review after remediation
-
-Reviewed all six implementation stages at `9797f43`. The focused launcher,
-delivery, and recovery tests and the public API and dependency checks passed.
-The host discovery work remains bounded to a fixed number of calls per
-invocation, and recovery replacement relocation now visits each directive
-once. No additional scaling issue was identified.
-
-### Stages 1, 2, and 6: Invoke the exact registered Go tool
-
-**Completed.** The launchers, templates, and consumer recipes use the full
-package path. The real Go launcher regression verifies tool selection and
-exit statuses with a second registered tool of the same short name.
-
-**Evidence:** The [multi-module launcher](../../examples/multi-module/release.sh)
-and both consumer Woodpecker templates
-([single-module](../../examples/woodpecker/tag-delivery.yml),
-[multi-module](../../examples/multi-module/woodpecker.yml)) register the
-full ReleaseKit package path, but invoke the short name `releasekit`. The
-[adoption launcher](../consumers/adoption.md#select-the-go-host-target) and
-[multi-module smoke recipe](../../examples/multi-module/README.md) also use
-the short name. Go allows two different package paths with the same final
-component in the tool declarations. With a second local tool ending in
-`/cmd/releasekit`, the maintained launcher and both extracted CI command
-blocks prepared the intended module, then exited with an ambiguous-tool
-error. Changing only the invocation to the full package path ran the
-intended host-native tool in all three probes. Recovery already invokes
-the full path and is unaffected.
-
-**Fix:** Invoke the same full package path used for registration in the
-maintained launchers, templates, and copyable consumer recipes. Preserve
-the selected module version, arguments, and exit status. Extend an
-existing launcher fixture with a second registered tool of the same short
-name and verify that only the intended tool runs.
-
-### Stage 3: Build the manual retry tool only from a clean tagged checkout
-
-**Completed.** The retry resolves and checks out the fetched tag and checks
-cleanliness before invoking Go. Local probes verified that fetch failure,
-checkout failure, and remaining edits stop before Go, and a clean retry
-builds and runs the tagged tool for the host.
-
-**Evidence:** The [manual retry block](../release.md) runs `git fetch` and
-`git checkout --detach` before the subshell that enables `set -e`. A
-failed checkout can therefore be followed by dependency preparation, a
-build, and execution from the wrong source. A successful checkout can
-also carry local edits forward. Both cases were reproduced with the
-documented block in disposable Git repositories and a local bare remote:
-a checkout refused because of conflicting edits still ran a fixture
-built from the edited source, and checking out the already selected tag
-succeeded while retaining and executing a local edit. The fixture exited
-successfully in both cases. ReleaseKit's normal delivery guards check
-the tagged checkout after the executable has already been built and
-started; they do not protect this bootstrap.
-
-**Fix:** Include the fetch and checkout in the fail-fast subshell. Resolve
-the literal tag to its commit and require a clean checkout before
-downloading dependencies or building the CLI, as the
-[source delivery template](../../examples/woodpecker/releasekit-source-delivery.yml)
-does. Preserve the scoped host target, dependency download before the
-offline build, and the existing retry arguments. Verify that checkout
-failure and carried-over edits both stop before the first Go command.