Files
configkit/docs/roadmap/migration.md

269 lines
15 KiB
Markdown

# Vanity Module Path Migration
Status: repository implementation and exact-revision remote consumer verification
complete.
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` | Retain this SSH endpoint and align release configuration with it |
| 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 authoritative publication endpoint remains
`ssh://git@forge.maximumdirect.net:22222/base-layer/configkit.git`. Retaining the
existing SSH `origin` avoids an unnecessary transport/credential change.
ReleaseKit's exact `expected_push_url`, its existing profile test, and the
runbook's literal publication/recovery commands agree with that endpoint.
Browser/tag links in current release guidance refer to the Forge HTTPS project,
not to the SSH transport or vanity import path. Public Go retrieval continues
using the verified Forge HTTPS repository independently. Authenticated write
capability still belongs to ordinary authorized release preparation; anonymous
HTTPS read success does not prove push access.
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
Align `releasekit.json`, its test, and the runbook's publication/recovery commands
with the retained SSH endpoint. Update the runbook's module identity, HTTPS source
links, and consumer verification examples accordingly. 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.
No significant open decision remains for this migration.
## Implementation And Verification
The module declaration and all ConfigKit self-imports now use
`go.maximumdirect.net/configkit`, including internal packages, external-package
tests, maintained examples, and benchmarks. The import-boundary predicates and
root-type reflection expectations use the new prefix. Review of every changed
Go hunk confirmed only the intended module-prefix replacements and publication
URL expectation; no loading behavior or public symbol names changed.
`releasekit.json`, its profile test, and the runbook now use the retained Forge
SSH publication endpoint, matching the existing effective `origin` push URL.
The runbook distinguishes that transport from Forge HTTPS browser links and
vanity-path consumer retrieval. README and the consumer guide identify the new
import path; migration guidance covers named-type identity and historical tags.
The Go minimum, dependency/tool versions, and `go.sum` are unchanged. Historical
release records, accepted ADRs, adopted policies, and upstream attribution were
left intact. Remaining old ConfigKit path references describe the migration's
baseline, consumer upgrade instructions, or historical releases.
Local validation passed on Linux with Go 1.26.10 and cached dependencies:
```sh
GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off ./scripts/check.sh
GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go mod tidy -diff
GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./...
```
The everyday check included maintained examples, documentation links, root type
ownership, dependency boundaries, and the release profile. Module/package
inspection reported the new main-module identity and no old ConfigKit imports
in the assembled test dependency graph. The module-selected ReleaseKit built
outside the checkout and reported v0.4.2. Module tidiness produced no diff.
### Remote Consumer Verification
With subsequent user authorization, migration commit
`587f407a32dec1e00d2aa17d2790c293d994721d` was pushed to authoritative `main`
through the retained Forge SSH endpoint. No release tag was created or published.
Two disposable consumer modules outside the repository retrieved that exact
revision through `go.maximumdirect.net/configkit`, using separate fresh module
caches and Go 1.26.10:
- Direct retrieval with `GOPROXY=direct` passed.
- Retrieval with `GOPROXY=https://proxy.golang.org,direct` passed. This verifies
the standard proxy/fallback configuration, not a proxy-only availability claim.
Checksum verification was enabled, `GOWORK=off` disabled workspace overrides, and
neither consumer had a `replace` directive. Go selected
`v0.10.3-0.20261101141937-587f407a32de`; the downloaded origin metadata identified
the exact migration commit in the Forge HTTPS repository. Both consumers received
the same module and module-file checksums.
After retrieval, each consumer passed `GOPROXY=off go test -mod=readonly -v ./...`.
The smoke test compiled and exercised the public API: explicit false/zero input
over typed defaults, effective provenance with `LayerMain`, source lookup by an
origin's source ID, and effective YAML rendering. Module inspection confirmed
that ConfigKit came from the corresponding fresh download cache, not the checkout.
This completes the one-time remote migration verification. The Go-generated
pseudo-version identifies an untagged commit; it is not an additional release.
No CI waiting or release gate was introduced.