# Configuration And API Migration This breaking pre-v1 minor migration adopts Promptkit's vanity module path, changes the v0.16-era keyed resources to identified lists, adopts ConfigKit v1, and removes prompt-version labels. Promptkit does not install a provider catalog; applications choose configuration inputs explicitly, and execution selects one prompt by its exact ID. This guide explains the shape changes and decisions an application must make; it is not an automatic migration tool. The [framework format reference](../formats.md) owns the current configuration contract, and the root package GoDoc owns exact API signatures and errors. ## Update Go Imports Promptkit's module and public package import path is now `go.maximumdirect.net/promptkit`, replacing `gitea.maximumdirect.net/eric/promptkit`. Update application, library, test, and generated imports, then select a release using the new declaration: ```sh go get go.maximumdirect.net/promptkit@VERSION go mod tidy ``` Replace `VERSION` with a release that declares the vanity module path. Earlier tags, including v0.16.0, retain their original module declaration and use the former import path. No permanent `replace` directive is needed for the cutover. Source browser, licensing, and hosted-release links continue to use the Forge repository URLs, independently of Go's module identifier. The package name remains `promptkit`. The path change itself does not rename exported APIs or change their behavior, but Go treats packages imported through the two paths as distinct. Update dependent packages that exchange Promptkit types together and review any old-path dependencies retained after tidying. The configuration and API adaptations below are also part of this migration. ## Select And Compose The Configuration You Need Supply each backend, profile, prompt, schema, and collection source that the application intends to use. Promptkit does not discover directories or install provider definitions implicitly. An application may select an explicit collection input with `CollectionInput`: ```go input, err := promptkit.CollectionInput( "openrouter", configkit.File("config/openrouter.yaml"), ) if err != nil { return err } engine, err := promptkit.NewEngine(promptkit.Config{ Sources: promptkit.ConfigurationSources{ Underlays: []configkit.Underlay{{Inputs: []configkit.Input{input}}}, }, }) ``` Collection resource IDs are local IDs, while their runtime identities are qualified. For example, a profile with `id: gemini-flash-latest` in collection `openrouter` is selected as `openrouter/gemini-flash-latest`. Stored backend, prompt-default, and other resource references must use their exact intended IDs; Promptkit does not rewrite references when a source is mounted. `extends` selects a sibling ID in the same list, not a cross-collection reference. Review collisions and all references when moving resources into collections. The optional source-root `version` header now accepts `2` or `"2"`; headerless sources remain valid. A collection's `release_version` remains an optional label. Prompt-version labels have been removed: choose one definition per ID and store any application-specific release label outside Promptkit. In a standalone imported prompt item, root `version` is a source header, not a label. For example, change a version-keyed definition: ```yaml prompts: report: "2.0": messages: - role: user content: Review this report. output: format: text validation_mode: none ``` to one identified definition: ```yaml prompts: - id: report messages: - role: user content: Review this report. output: format: text validation_mode: none ``` The same conversion applies to backends and profiles. Sibling inheritance uses identity references, and a later same-ID record replaces the whole lower record: ```yaml profiles: - id: base endpoint: https://example.invalid/v1 model: example-model - id: fast extends: {id: base} timeout_seconds: 30 ``` To customize a lower resource's fields, add a distinct inherited variant as above; when replacing the same ID, supply the complete intended record. Generic append, replace, imports, and inheritance are described by the [ConfigKit v1 configuration contract](https://forge.maximumdirect.net/base-layer/configkit/src/tag/v1.0.0/docs/config.md). Source-root controls are now `config:`, not `configkit:`. Imports are optional unless the selected import declares `required: true`. Update ConfigKit imports to `go.maximumdirect.net/configkit` at v1.0.0: its Go types are incompatible with the old module path. Promptkit now requires Go 1.27.0 or newer. Source builders take ordered slices with explicit IDs: ```go endpoint, model := "https://example.invalid/v1", "example-model" base := "base" source := promptkit.ProfileSource("application", []promptkit.ProfileConfig{ {ID: "base", Endpoint: &endpoint, Model: &model}, {ID: "fast", Extends: &base}, }) ``` Replace former maps passed to `BackendSource` in the same way, setting each `BackendConfig.ID`. Duplicates are retained for loading to reject. Resource inspection paths now address list indexes, for example `configkit.Keys("profiles").Index(0).Key("model")`. Configuration inspection and diffs expose composed values and provenance, while `InspectProfile` and other interpreted views expose Promptkit normalization and defaults; the views are not promised to be identical. Remove `PromptVersion` and `PromptIdentity.Version` uses and the corresponding `prompt_version` JSON members. Prompt hashes are opaque equality values and may change when the removed field no longer participates in hashing. ## Identity Mapping The reviewed catalog identities have slash-free profile keys. Their documented mapping is: | Previous identity | Namespaced identity or action | | --- | --- | | Backend `openrouter` | `openrouter/default` | | Backend `rakestrawhome` | `rakestrawhome/default` | | Each OpenRouter catalog profile `p` | `openrouter/p`, retaining the exact local key `p` | | Profile `rakestrawhome-gemma-4-31b` | `rakestrawhome/rakestrawhome-gemma-4-31b` | | Built-in `promptkit-openrouter-standard` | No automatic replacement; optionally define caller profile `openrouter/standard` | | Built-in `promptkit-openrouter-auto` | No automatic replacement; optionally define caller profile `openrouter/auto` | These are conversion examples, not aliases or bundled resources. Mounting old `/v3` assets does not update backend references, profile inheritance, prompt defaults, or diagnostic defaults inside them. Edit those values to the exact qualified IDs you chose. For example, an optional caller-owned standard profile may extend a selected Gemini profile in the same `openrouter` collection: ```yaml collections: openrouter: profiles: - id: standard extends: {id: gemini-flash-latest} ``` An optional auto profile may instead select the exact backend and model values: ```yaml collections: openrouter: profiles: - id: auto backend: openrouter/default model: openrouter/auto ``` Neither optional profile name is a Promptkit contract. Keep provider model strings and settings as selected by the application, including any meaningful prefixes. If a backend declares diagnostic defaults, update them to exact qualified IDs; an unselected diagnostic default is not automatically made resolvable by migration. ## Prompt Selection API Prompt selection is ID-only. Remove version selectors from calls to `Run`, `Prepare`, `PrepareExecution`, `ValidateRequest`, `InspectRequirements`, and `SmokeTest`. Remove the `PromptVersion` field from `RunRequest`, `RequirementInspectionRequest`, and `SmokeTestRequest`; `InspectPrompt` now has the form `InspectPrompt(ctx, promptID)`. For example, select the prompt explicitly in the request rather than setting a version selector: ```go request := promptkit.RunRequest{ PromptID: "support/report", ProfileID: "support/standard", } _, err = engine.Run(ctx, request) if err != nil { return err } ``` If the former format contained multiple versions under one ID, choose the one definition the application should install. Promptkit no longer retains or returns its former descriptive label. The public inventory APIs can help an operator inspect a captured effective configuration: `ListProfiles`, `ListPrompts`, and `ListBackends` return exact identities, while `ListNamespaces` and `ListCollections` expose resource-bearing namespaces and effective collection declarations. Inventory does not select which configuration version the application should deploy. ## Deployment Selection Remains With The Application Applications decide which checked-in, embedded, operator-supplied, or programmatic inputs to compose for each deployment. They also decide when to construct a replacement engine after changing those sources. Promptkit does not fetch catalog updates, select provider availability, validate upstream catalog release status, or automatically migrate arbitrary consumer files. The maintained [offline collection example](../../examples/go-library/prepare/main.go) shows explicit source selection, local imports, layering, a scoped view, and operator inventory without a provider call.