diff --git a/docs/roadmap/migration.md b/docs/roadmap/migration.md new file mode 100644 index 0000000..7d3ea36 --- /dev/null +++ b/docs/roadmap/migration.md @@ -0,0 +1,217 @@ +# Vanity Module Path Migration + +Status: target defined; implementation has not begun. +Planning baseline: `21c9bc0ad0315c4ac96268b487a52376558a18d7`. + +This roadmap defines the target and work needed to adopt +`go.maximumdirect.net/configkit` before ConfigKit's initial v1.0.0 release. +It is not a staged implementation plan or authorization to push or publish. +The [configuration contract](../config.md), public declaration comments, and +[release policy](../policy/release.md) continue to own behavior outside the +module-identity migration. + +## Purpose And Scope + +Give ConfigKit a stable, project-owned Go module identifier independent of its +repository host, while retaining its existing package name, public facade, +configuration behavior, and implementation boundaries. + +The migration changes the module path and therefore Go package/type identities. +It also brings ConfigKit's release endpoint references into agreement with its +current Forge hosting. These are related identity updates, not changes to the +loading lifecycle, YAML syntax, composition, provenance, history, or secrets. +No runtime API redesign or compatibility-shim system is needed for this scope. + +## Current Baseline + +| Area | Baseline | Target | +| --- | --- | --- | +| Module declaration | `gitea.maximumdirect.net/eric/ConfigKit` in [go.mod](../../go.mod) | `go.maximumdirect.net/configkit` | +| Self-imports | Old module prefix throughout production packages, tests, benchmarks, and examples | New module prefix with the same package layout | +| Public package | Root-owned `configkit` facade over private internal packages | Same name and ownership under the new module identifier | +| Vanity discovery | Root and nested requests already advertise the Forge repository | Existing discovery continues to locate the migrated module | +| Git remote | `origin` uses `ssh://git@forge.maximumdirect.net:22222/base-layer/configkit.git` | The selected authoritative Forge endpoint agrees with release configuration | +| Release configuration | [releasekit.json](../../releasekit.json), its test, and [runbook](../release.md) still name the old Gitea HTTPS endpoint | Consistent Forge publication references and vanity-path consumer commands | + +Path-sensitive test expectations include +[import_boundary_test.go](../../import_boundary_test.go), +[facade_candidate_test.go](../../facade_candidate_test.go), and +[releasekit_profile_test.go](../../releasekit_profile_test.go). Compilation alone +will not identify every stale literal: a boundary test using the old prefix can +silently stop checking the intended imports. + +### Preliminary External Verification + +Checks against the baseline, using Go 1.26.10 and disposable modules/caches +outside the repository, established: + +- HTTPS discovery at the module root and a nested package path returns a + `go-import` mapping from `go.maximumdirect.net/configkit` to + `https://forge.maximumdirect.net/base-layer/configkit`. +- Anonymous HTTPS Git access returns the expected `main` revision and release + tags, including v0.10.2. +- Go resolves and downloads v0.10.2 through direct retrieval and the standard + public-proxy/fallback configuration, with checksum verification enabled. +- A disposable consumer's `go get go.maximumdirect.net/configkit@v0.10.2` + reaches the repository but rejects its old module declaration. That is the + expected remaining mismatch, not a discovery failure. + +These observations demonstrate that discovery and retrieval infrastructure work; +they do not establish that the migrated module builds or can be installed yet, +nor promise continuing external-service availability. No vanity-service change +was identified as necessary by these checks. + +## Targeted End State + +### Canonical Go Identity + +The module declares `go.maximumdirect.net/configkit`. Production imports, +external-package tests, maintained examples, and path-sensitive expectations use +that prefix consistently. The package name remains `configkit`, and the root +remains the sole supported consumer import surface. Existing internal packages +stay internal; the migration does not expose them or change dependency direction. + +The v1 module uses the unsuffixed path, with ordinary root-level release tags such +as `v1.0.0`. There is no `/v1` import suffix or module subdirectory to introduce. +The [Go module reference](https://go.dev/ref/mod#major-version-suffixes) owns the +language/toolchain conventions behind that choice. + +Existing dependency and tool module identities are separate from ConfigKit's +identity. In particular, this work does not automatically rename or upgrade the +ReleaseKit requirement/tool declaration because the vanity service also advertises +a ReleaseKit path. Any dependency-path change should be assessed separately +against that upstream module's declared identity and available versions. The +current Go minimum and dependency versions are not selected for change here. + +### Consumer Migration + +Current installation/import examples identify the vanity path. The consumer guide +explains updating the module requirement and Go imports together, including +transitive libraries that exchange ConfigKit types with an application. Packages +loaded under the old and new prefixes have different Go identities; changing a +requirement alone does not make those types interchangeable. + +This is a coordinated pre-v1 identity change. Old tags keep their original module +declarations and contents. The migration does not rewrite them to make historical +versions installable under the new path. Requesting an older tag through the +vanity identifier can still produce the observed module-declaration mismatch +even after this migration; consumers need a revision declaring the new path. + +Maintained examples in this repository migrate with the library. Updating other +applications or maintaining a separate old-path compatibility module is outside +this effort; neither is required to declare the repository changes complete. + +### Repository And Publication Identity + +The vanity path identifies Go packages. Forge URLs identify the source repository, +browser pages, and publication transport. They remain distinct: Go HTTPS discovery +can use the public Forge HTTPS repository while maintainers push through SSH. + +The selected publication endpoint is used consistently by the effective `origin` +push URL, ReleaseKit's exact `expected_push_url`, its existing profile test, and +the runbook's literal publication/recovery commands. Browser/tag links in current +release guidance refer to the Forge project, not to the vanity import path. +The endpoint choice is the remaining open decision below. + +The existing release sequence, validation profile, permissions, immutable tags, +and successful-publication completion point are unchanged. This migration does +not introduce CI waiting, proxy-propagation waiting, native macOS checks, or +consumer installation as permanent release gates. + +## Work Needed From The Baseline + +### Module Declaration, Imports, And Tests + +Update the module directive and all ConfigKit self-imports as one coordinated +change across root wrappers, engine/document/YAML packages, tests, benchmarks, +and maintained examples. Preserve the existing package layout and public symbol +names. Do not mechanically replace every old-host URL: dependency identities, +upstream attribution, and historical references have different owners. + +Review import-boundary predicates, reflection package-path assertions, and any +other literal module checks alongside imports. Retain their existing protection +with the new identity rather than removing assertions to make the migration pass. +Review module metadata/tidiness as appropriate after changing the module path, +without using that review to bundle unrelated upgrades or tool migrations. + +### Release Configuration And Current Guidance + +Resolve the Forge publication endpoint, then align `releasekit.json`, its test, +and the runbook's module identity, push/recovery commands, source links, and +consumer verification examples. Reflect only necessary endpoint wording changes +in the adopted release policy if its current text requires them; its release +guarantees and gates remain the same. + +Review README, declaration documentation, the consumer guide, and applicable +development/internal documentation for current identity references. Describe the +consumer import/type-identity migration in the existing consumer migration +guidance. New release documentation, when prepared through the normal procedure, +should explain the change and use version-matched Forge source/license links. + +Preserve historical release records, accepted ADR decision content, revision-pinned +audit evidence, upstream provenance links, and third-party module paths where +they describe their original material. A historical old-host reference is not an +unmigrated self-import. This roadmap does not authorize rewriting that history or +changing licensing arrangements. + +### Proportionate Verification + +Use the existing [development checks](../development.md#baseline-validation) +and [testing policy](../policy/testing.md). Verify the migrated module builds, +the default suite and maintained examples pass, and public/dependency boundary +checks still enforce the root/internal separation under the new prefix. The +eventual release retains its existing validation, rather than acquiring a second +validation framework or an expanded platform matrix. + +When the migrated commit is available remotely, a one-time disposable consumer +check should retrieve that exact revision through the vanity path, without a +local replacement or workspace override, and compile a small public-API use. +An exact revision before tagging can exercise the migration without creating a +test release. Report direct retrieval and default proxy/fallback results +separately where both are checked; do not infer a successful install from +`go list` or archive download alone. + +This remote check is migration evidence when the revised commit is available, +not authorization to push and not a new publication-completion gate. Keep network +checks outside the deterministic default suite, avoid polling external services, +and preserve the policy that successful tag publication completes a release. +After publication, retrieval of the exact released version remains optional and +non-gating under the existing procedure. Record any unavailable verification +honestly instead of claiming that baseline retrieval validates migrated code. + +## Completion Criteria + +- The repository consistently declares and imports the vanity module path, + while preserving the package name, facade ownership, and configuration behavior. +- Current documentation, examples, path-sensitive tests, and Forge publication + references agree with the implemented identities. +- Applicable local checks pass, without unrelated dependency or contract changes. +- Migration evidence distinguishes the preliminary infrastructure checks from + any later successful consumer installation of the actual migrated revision. +- Historical releases remain unchanged, and downstream migration guidance + explains both import changes and distinct Go type identities. + +Repository implementation completion, external retrieval evidence, downstream +application adoption, and release publication are separate outcomes. No push, +tag, or downstream change is authorized merely by completing this roadmap. + +## Open Decisions + +### Authoritative Forge Publication Endpoint + +**Recommendation:** retain the existing SSH `origin` endpoint, +`ssh://git@forge.maximumdirect.net:22222/base-layer/configkit.git`, and align +ReleaseKit's expected URL and runbook with it. This matches the current maintainer +checkout and avoids an unnecessary transport/credential change. Public Go +retrieval can continue using the verified Forge HTTPS endpoint independently. +Authenticated write capability still belongs to ordinary authorized release +preparation; anonymous HTTPS read success does not prove push access. + +**Alternative:** standardize publication on +`https://forge.maximumdirect.net/base-layer/configkit.git`, updating the effective +`origin` push URL, ReleaseKit expectation, profile test, and runbook together. +HTTPS may fit other maintainer/automation credentials and resembles the previous +runbook's transport. It also changes the current push configuration and requires +appropriate HTTPS write credentials, which the read-only checks did not test. +Either option can preserve existing release integrity; the important requirement +is agreement on the selected endpoint, not imposing one Git transport universally.