Finalize v0.18.0 notes and retire completed plans

This commit is contained in:
2026-11-04 00:33:44 +00:00
parent 2b3d165ce2
commit fda0338134
4 changed files with 28 additions and 554 deletions

View File

@@ -45,9 +45,10 @@ boundary and constraints that framework work must preserve.
## Release Guidance
The [v0.18.0 release notes](docs/releases/v0.18.0.md) cover recorded field
normalization, derived defaults in configuration inspection, and ConfigKit v1.1.
Execution behavior and the Go 1.27 minimum remain unchanged.
The [v0.18.0 release notes](docs/releases/v0.18.0.md) cover the default-on
OpenRouter backend and profiles, recorded configuration normalization, and
ConfigKit v1.1. The notes explain inventory changes and the bundle opt-out;
the Go 1.27 minimum remains unchanged.
The [v0.17.0 release notes](docs/releases/v0.17.0.md) cover the vanity module
path, ConfigKit v1, identified resource lists, removal of prompt-version

View File

@@ -5,6 +5,29 @@ and derived queue-capacity defaults through ConfigKit v1.1.0. Engines also
include a default-on OpenRouter configuration. The minimum supported Go
version remains 1.27.0.
## Bundled OpenRouter Backend And Profiles
New engines include an embedded OpenRouter backend and seventeen root profiles:
ten latest-family aliases, the auto and free routers, and five auto-router
cost-tier variants. Select a profile explicitly in a prompt or request; the
bundle does not supply an implicit execution profile or contact providers
during construction. The backend uses `OPENROUTER_API_KEY` when available under
the existing optional-credential rules.
The bundle is the lowest-priority underlay. Applications can replace its records
or derive named variants through ordinary configuration, and external collections
remain supported. Cost-tier variants inherit the effective `auto` profile, so
replacing that parent changes their inherited target while retaining plugins.
The [bundle reference](../formats.md#bundled-openrouter-configuration) owns the
inventory and composition details.
Explicit smoke diagnostics now have OpenRouter authentication metadata and an
inference fallback profile. They remain opt-in and may incur provider costs.
Latest aliases and routers can change upstream; configured slugs do not pin
the concrete model, pricing, or availability. See the
[consumer guide](../consumers/pkg-promptkit.md#construct-an-engine) for selection
and opt-out examples.
## Recorded Configuration Normalization
Inspection shows normalized backend and profile settings, prompt metadata, and
@@ -24,7 +47,7 @@ Inventory listings and inspection sources therefore change, and references to
bundled IDs that previously failed may now resolve. Pass
`promptkit.WithBundledOpenRouter(false)` to retain application-only behavior.
Caller records can replace bundled definitions through ordinary composition;
see the [bundle inventory and precedence](../formats.md#bundled-openrouter-configuration).
same-ID replacements replace complete records rather than merging selected fields.
No configuration-format migration is required from v0.17.0.
Consumers that display or compare configuration inspection results should account
for normalized values and derived defaults replacing their earlier authored

View File

@@ -1,246 +0,0 @@
# Bundled OpenRouter Backend And Profiles
## Status And Purpose
Implemented: engine construction installs the embedded OpenRouter underlay by
default, with an option to disable it and ordinary caller composition.
Ship a small OpenRouter configuration bundle with PromptKit so consumers
can begin using named profiles without installing a separate catalog. Include
the backend definition those profiles require. Keep separately maintained
operator collections fully supported through the existing configuration path.
The bundle should favor provider-maintained latest aliases and routers, reducing
the need for PromptKit releases just to refresh individual model versions.
This is a convenience catalog, not an exhaustive model inventory or a promise
of stable upstream model behavior.
## Historical Baseline
PromptKit depends on ConfigKit v1.1.0 and records field normalization and derived
defaults during resolution. At that baseline it installed no backend or profile
definitions. Consumers supply configuration inputs, which ConfigKit composes
before PromptKit validates and materializes effective resources.
The existing [configuration format](../formats.md) supports root and namespaced
resource lists, explicit IDs, sibling inheritance, and ordered underlays.
A higher-layer same-ID resource replaces the lower record in full. Inputs in
the same underlay group are strictly composed; file order is not precedence.
The bundle can use these mechanisms without introducing another catalog loader
or restoring the former dependency on provider-specific Go modules.
ConfigKit v1.1.0's normalization and inspection support will apply to bundled
configuration just as it does to caller configuration. Layering itself predates
that release; no further upstream enhancement is required for this feature.
## Target Behavior
### Ordinary Embedded Configuration
Embed a small YAML bundle in PromptKit and load it through the existing
ConfigKit adapter. Place it in its own lowest-priority underlay, before every
caller underlay and the main input. Preserve the existing order and grouping
of caller inputs.
Enable the bundle by default, with `WithBundledOpenRouter(bool)` to disable or
enable it explicitly.
This follows the agreed convenience-oriented direction while preserving the
ability to supply an application's complete catalog.
Bundling a profile makes it available for explicit selection by a prompt or
request. It does not establish an implicit execution profile, change profile
selection precedence, or send a network request during engine construction.
Credentials remain runtime inputs under the existing credential rules.
Use ordinary configuration identities and expose the bundle through existing
listing and inspection APIs. Source explanations should identify embedded
configuration meaningfully. There is no need for a parallel built-in catalog
API or special provenance model.
### Root Resource Layout
Use root entries for both the backend and all built-in profiles. The backend
ID is `openrouter`; each bundled profile supplies or inherits
`backend: openrouter` and is selected using its unqualified ID. No built-in `openrouter` collection is
created, so an externally supplied collection can expose names such as
`openrouter/gpt-sol-latest` alongside the root `gpt-sol-latest` profile.
Built-ins at the root and external libraries under `collections` is a
convention, not an enforced distinction. Applications may supply root entries,
override built-ins, and organize external configuration using either form.
Root names favor convenient selection; their backend remains explicit in the
definition and inspection even though it is absent from the profile ID.
### OpenRouter Backend
Include the root `openrouter` backend with OpenRouter's API base endpoint,
`https://openrouter.ai/api/v1`, and the conventional environment-variable name
`OPENROUTER_API_KEY`. Store the name only; no credential value belongs in the
bundle. Reuse the existing OpenAI-compatible client and credential resolution.
Keep the backend minimal. Leave concurrency limits, queue policy, and provider
request parameters to existing defaults or application configuration.
### Smoke-Test Defaults
Include the following metadata on the root `openrouter` backend:
```yaml
smoke_tests:
default_profile: gpt-luna-latest
authentication:
kind: openrouter_key
```
Omit the reachability endpoint to use the existing backend-endpoint fallback.
Omit the authentication endpoint to use the adapter's backend-relative `/key`
destination. OpenRouter documents the authenticated
[current-key endpoint](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key).
Use `gpt-luna-latest` as the inference diagnostic default when the caller supplies
neither a prompt nor a profile. Explicit prompt/profile selection continues to
follow existing smoke-test selection rules. The default names the effective
root profile, so an application replacement of that profile also affects this
fallback. Applications can change the backend metadata through ordinary
configuration composition.
These defaults make explicit diagnostics usable without additional setup; they
do not run tests automatically or establish a default for ordinary prompt
execution. Results describe the selected diagnostic path, not backend-wide
readiness. The inference smoke test makes a small request with potentially
non-zero cost; no fixed cost or model-availability guarantee is introduced.
### Small Profile Set
The initial set contains seventeen root profiles:
| Profile ID | Intended model selection |
| --- | --- |
| `gpt-astra-latest` | OpenAI GPT Astra latest-family alias through OpenRouter. |
| `gpt-sol-latest` | OpenAI GPT Sol latest-family alias (`~openai/gpt-sol-latest`). |
| `gpt-terra-latest` | OpenAI GPT Terra latest-family alias through OpenRouter. |
| `gpt-luna-latest` | OpenAI GPT Luna latest-family alias through OpenRouter. |
| `claude-fable-latest` | Anthropic Claude Fable latest-family alias through OpenRouter. |
| `claude-opus-latest` | Anthropic Claude Opus latest-family alias through OpenRouter. |
| `claude-sonnet-latest` | Anthropic Claude Sonnet latest-family alias through OpenRouter. |
| `claude-haiku-latest` | Anthropic Claude Haiku latest-family alias through OpenRouter. |
| `gemini-pro-latest` | Google Gemini Pro latest-family alias through OpenRouter. |
| `gemini-flash-latest` | Google Gemini Flash latest-family alias through OpenRouter. |
| `auto` | OpenRouter auto router (`openrouter/auto`). |
| `auto-low` | Inherits `auto`; sets cost tier `low`. |
| `auto-medium` | Inherits `auto`; sets cost tier `medium`. |
| `auto-high` | Inherits `auto`; sets cost tier `high`. |
| `auto-xhigh` | Inherits `auto`; sets cost tier `xhigh`. |
| `auto-max` | Inherits `auto`; sets cost tier `max`. |
| `free` | OpenRouter free-model router (`openrouter/free`). |
These profile IDs are selected. The companion [implementation plan](implementation.md)
records the exact provider `model` slugs checked against the public alias pages.
Keep those mappings explicit rather than deriving them mechanically from IDs.
If a requested alias becomes unavailable, surface that mismatch
instead of silently substituting a pinned model or dropping the profile.
The tilde and slash in a provider model slug remain part of that value; they
do not change the root placement of the PromptKit profile.
Define each cost-tier profile using `extends: {id: auto}` and the matching
`cost_tier` inside an `auto-router` plugin entry under `extra_params.plugins`:
```yaml
profiles:
- id: auto
backend: openrouter
model: openrouter/auto
- id: auto-medium
extends: {id: auto}
extra_params:
plugins:
- id: auto-router
cost_tier: medium
```
Keep the base `auto` profile without an explicit cost tier. Link to
[OpenRouter's cost-tier documentation](https://openrouter.ai/docs/guides/routing/routers/auto-router#cost-tier)
for routing semantics rather than duplicating that explanation here.
Each profile should primarily specify or inherit its backend and model. Avoid
baking in temperature, reasoning, token-budget, timeout, or capability assumptions merely
to make profiles appear more complete. Operator profiles remain the place for
application-specific tuning and fixed model versions.
OpenRouter documents the
[GPT Sol latest alias](https://openrouter.ai/~openai/gpt-sol-latest),
[auto router](https://openrouter.ai/docs/guides/routing/routers/auto-router), and
[free router](https://openrouter.ai/docs/guides/routing/routers/free-router).
Stable selectors reduce maintenance but do not freeze model selection, price,
availability, supported parameters, or output behavior. Describe the free router
as the provider's offering rather than adding PromptKit guarantees about future
pricing or availability.
### Application Control And Compatibility
Applications may replace bundled records through higher configuration layers or
disable the bundle and supply their own definitions. No namespace is reserved
against operator use. A same-ID replacement is a complete replacement, so an
application supplying only a new model value does not inherit the replaced
profile's backend. A distinct sibling using `extends` remains the ordinary way
to create a variant while retaining base fields.
These replacement semantics describe ordinary identified-list upsert behavior.
Honor explicit ConfigKit sequence modes as well: `append` rejects duplicate
identities, while `replace` replaces the complete lower list. The bundle adds no
special conflict handling or exception to those composition rules.
Loading definitions by default changes inventory and inspection results, and
previously unresolved references matching bundled IDs may become resolvable.
Document these effects. Higher-layer application records take precedence under
the applicable ConfigKit composition mode. Changing a bundled backend may
also affect surviving bundled profiles that reference it; that is ordinary
backend completion, not a special override exception.
The five cost-tier profiles inherit from the effective `auto` profile. An
application replacement of `auto` can therefore change their inherited backend
or model while their OpenRouter plugin settings remain present. Cover this
interaction in a focused test and a short example note; it does not require a
new restriction on replacing the parent.
Bundled profile and backend IDs are consumer-facing names. Review future removal
or repurposing through the ordinary compatibility process, since application
configuration may reference them. This does not introduce a separate catalog
lifecycle or a guarantee that upstream aliases retain fixed behavior.
The embedded data ships with the PromptKit release. No catalog download or
automatic refresh mechanism is planned. Provider aliases and routers may change
their targets independently of that release; the inspected configured slug
does not identify or pin the concrete model selected upstream.
## Acceptance And Documentation
The companion implementation plan owns the staged work. The integrated result
should demonstrate:
- Default availability and full disabling through the ordinary configuration
lifecycle, without construction-time provider or credential access.
- Caller precedence, whole-record replacement, inherited variants, explicit
append/replace modes, and coexistence with an external OpenRouter collection.
- All five cost-tier profiles inheriting the effective `auto` backend/model,
retaining their plugin settings even after parent replacement, and producing
the expected top-level `plugins` array through the built-in HTTP client.
- Listing and inspection of effective definitions with meaningful source evidence.
- Explicit smoke diagnostics using backend endpoint fallbacks, authentication,
inference defaults, explicit selection precedence, and effective application
replacements of the default profile or backend metadata.
Offline HTTP tests establish payload construction, not provider acceptance.
Credential-dependent live checks are not recurring test requirements. Existing
credential behavior remains authoritative; coverage should focus on new
integration risks rather than duplicate that suite.
The format reference, consumer guide, relevant GoDoc, and maintained examples
should explain disabling, replacement, and inheritance. Release notes should
identify inventory and inspection changes. Provider latest aliases and routers
remain distinct from fixed models and carry no PromptKit upstream guarantees.
Keep current-state documentation unchanged until implementation lands. Retire
this roadmap after the implemented behavior reaches its durable owners. No new
configuration syntax or collection specification version is needed solely to
distribute this data.

View File

@@ -1,304 +0,0 @@
# Bundled OpenRouter Implementation Plan
Implement [bundled-openrouter.md](bundled-openrouter.md) in the sequential stages
below. Each stage is one Luna-sized assignment. The feature roadmap owns scope
and consumer policy; this document owns the implementation sequence and choices.
## Baseline And Working Rules
The baseline is `9e05c3a`: Go 1.27.0, ConfigKit v1.1.0, recorded field
normalization, and no installed backend/profile catalog. The facade in
`engine.go` applies options; `internal/engine.New` passes caller configuration
to `internal/configuration.Load` before assembling execution collaborators.
Read `docs/development.md` and applicable agent, architecture, testing,
documentation, OSS, and release policies. Follow
[ADR 0001](../adr/0001-configuration-boundary.md). Reuse current source-loading,
generation, and smoke-diagnostic contracts. Preserve unrelated changes.
This is one end-to-end sprint: intermediate stages need not compile or form a
deployable state. Do not introduce compatibility scaffolding or intermediate
human-review/publication gates. Record incomplete checks honestly and reuse
successful checks for unchanged content. Do not publish a release or make paid
provider requests. No dependency upgrade, configuration-version change, or
provider-specific catalog module is required.
## Implementation Choices
- Add `internal/configuration/bundled/openrouter.yaml` and embed it from a small
`bundled.go` in that package. Provide an internal exported
`BundledOpenRouterUnderlay() configkit.Underlay` for engine assembly. It returns
one input created through `configkit.NewFilesystem` and its `File` method,
with a meaningful label such as `Promptkit bundled OpenRouter`.
- Use the existing source loader once. Do not independently parse, validate,
normalize, or cache a separate bundle registry before final composition.
Tests inspect the assembled effective configuration, not raw-source validity.
- Prepend the bundle as its own underlay in `internal/engine.New`. Allocate a
new outer slice and copy caller groups so spare slice capacity cannot let
assembly mutate caller-owned input. Preserve every caller group's contents,
order, main input, imports, and source context.
- Add `WithBundledOpenRouter(enabled bool) Option` in the facade. Add
`disableBundledOpenRouter bool` to internal engine options and a setter
`SetBundledOpenRouter(bool)` following existing setter style. The zero internal
options value enables the bundle; the setter stores `!enabled`. Apply options
in the existing order, so the last supplied bundle option wins. The facade
only delegates; embedding and composition stay internal.
- Disabled means no bundle source or definitions are installed. It does not
reserve names, remove caller definitions, or disable the OpenAI-compatible
client. Scoped views share the engine's captured configuration; they do not
reload the bundle.
- Keep the root backend and profiles described below. No built-in collection,
prompts, implicit execution profile, tuning defaults, catalog download, or
constructor-time provider/credential access is added.
## Exact Data To Install
The root backend is `openrouter`, with endpoint `https://openrouter.ai/api/v1`,
`api_key_env: OPENROUTER_API_KEY`, and:
```yaml
smoke_tests:
default_profile: gpt-luna-latest
authentication:
kind: openrouter_key
```
Leave concurrency, queue, provider parameters, and diagnostic endpoint overrides
unset. Existing reachability and authentication endpoint fallback applies.
Use these exact root profile IDs and model values. Each non-cost-tier profile
sets `backend: openrouter`. The ten family mappings were checked against the
linked provider pages on 2026-11-03; this is authoring evidence, not a guarantee
of future availability or a recurring release check.
| Profile ID | Model | Provider reference |
| --- | --- | --- |
| `gpt-astra-latest` | `~openai/gpt-astra-latest` | [Alias](https://openrouter.ai/~openai/gpt-astra-latest) |
| `gpt-sol-latest` | `~openai/gpt-sol-latest` | [Alias](https://openrouter.ai/~openai/gpt-sol-latest) |
| `gpt-terra-latest` | `~openai/gpt-terra-latest` | [Alias](https://openrouter.ai/~openai/gpt-terra-latest) |
| `gpt-luna-latest` | `~openai/gpt-luna-latest` | [Alias](https://openrouter.ai/~openai/gpt-luna-latest) |
| `claude-fable-latest` | `~anthropic/claude-fable-latest` | [Alias](https://openrouter.ai/~anthropic/claude-fable-latest) |
| `claude-opus-latest` | `~anthropic/claude-opus-latest` | [Alias](https://openrouter.ai/~anthropic/claude-opus-latest) |
| `claude-sonnet-latest` | `~anthropic/claude-sonnet-latest` | [Alias](https://openrouter.ai/~anthropic/claude-sonnet-latest) |
| `claude-haiku-latest` | `~anthropic/claude-haiku-latest` | [Alias](https://openrouter.ai/~anthropic/claude-haiku-latest) |
| `gemini-pro-latest` | `~google/gemini-pro-latest` | [Alias](https://openrouter.ai/~google/gemini-pro-latest) |
| `gemini-flash-latest` | `~google/gemini-flash-latest` | [Alias](https://openrouter.ai/~google/gemini-flash-latest) |
| `auto` | `openrouter/auto` | [Router](https://openrouter.ai/docs/guides/routing/routers/auto-router) |
| `free` | `openrouter/free` | [Router](https://openrouter.ai/docs/guides/routing/routers/free-router) |
The five remaining profiles are `auto-low`, `auto-medium`, `auto-high`,
`auto-xhigh`, and `auto-max`. Each uses `extends: {id: auto}` and only adds
`extra_params.plugins: [{id: auto-router, cost_tier: TIER}]`, where TIER is its
suffix. Do not duplicate backend/model in these children: they inherit the
effective parent, including an application replacement. Base `auto` sets no
cost tier. OpenRouter documents these five values and plugin spelling in its
[cost-tier contract](https://openrouter.ai/docs/guides/routing/routers/auto-router#cost-tier).
The [current-key endpoint](https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key)
documents the existing authentication adapter's destination.
Preserve `~` and `/` in model values; neither makes the profile namespaced.
Do not add sampling, reasoning, timeout, token, or capability settings. If
contradictory provider evidence appears, report it rather than silently selecting
a fixed model or dropping a requested profile. A credentialed generation probe
is not needed to implement this data-backed plan.
## Stage 1: Add The Embedded Configuration Source
Scope: new YAML and small helper in `internal/configuration`.
1. Define one root backend and seventeen root profiles exactly as above. Use
ordinary identified lists and ConfigKit sibling inheritance for the five
cost-tier children. No collection wrapper or prompt definitions are needed.
2. Embed the file with `embed.FS`; expose only the internal underlay helper.
Use a fresh public ConfigKit source/context for loading, without mutable
package-level decoded data or filesystem discovery.
3. Add a focused loader-level test composing that underlay through `Load`.
Check the effective backend, the selected profile/model mapping, cost-tier
inheritance, smoke metadata, and meaningful source evidence. These assertions
protect the chosen catalog contents, not upstream model availability.
4. Do not create raw-YAML validation or live-provider tests. No public catalog
export, custom parser, catalog dependency, or parallel registry is needed.
Validation: `go test ./internal/configuration` after the helper is wired.
Completion: the embedded OpenRouter underlay and loader-level catalog test are
in place; the focused configuration suite passed with Go 1.27.0.
## Stage 2: Enable The Bundle Through Engine Construction
Scope: facade/internal options, assembly, and default/disabled contract tests.
1. Implement the option and default-on internal flag as specified. Prepend the
underlay only when enabled, using a new outer slice. Keep schema/client/
artifact options and main-source handling unchanged.
2. Add external-package facade tests showing `NewEngine(Config{})` exposes the
root backend and all seventeen profiles, but creates no prompts or synthetic
`openrouter` collection. Exercise representative `InspectProfile` values and
`InspectConfiguration` source explanations.
3. Test false disables installation, true retains it, and option ordering follows
ordinary last-option behavior. With false, caller-owned `openrouter` records
remain available. Construction succeeds with the API-key variable unset and
an HTTP transport that rejects unexpected calls.
4. Verify assembly leaves caller underlay slice/backing-array contents unchanged.
5. Adapt preexisting tests whose intended fixture is an application-only or empty
catalog by explicitly disabling the bundle in their local helpers. Update
default-inventory expectations where that is the behavior under test. Do not
globally hide default-on behavior or weaken not-found/validation assertions.
Internal direct configuration-loader tests do not need to install the bundle.
Validation: focused construction/listing/inspection tests, then
`go test ./internal/engine ./...` when intermediate wiring is coherent.
Completion: engine construction installs the bundle by default, with an
ordered opt-out option and a copied underlay slice. Facade contracts and the
full Go suite pass with Go 1.27.0.
## Stage 3: Protect Composition And Application Control
Scope: focused real-loader integration tests through the facade.
1. Verify a caller underlay and then the main input can replace a bundled ID in
order, and caller strict groups remain strict. Demonstrate complete record
replacement: a model-only replacement does not recover the old backend.
Preserve partial-profile support rather than demanding construction readiness.
2. Verify a distinct profile extending a bundled profile retains inherited
fields and applies selected overrides. Add an application-provided OpenRouter
collection with qualified references; root and collection profiles coexist.
3. Replace root backend `openrouter` with a complete local endpoint definition.
Confirm surviving bundled profiles use the replacement backend's settings.
No reserved-ID checks or special merge semantics are added.
4. Replace root `auto` with a profile selecting a different caller backend and
model. All five cost-tier children must inherit that target and retain their
plugin entries. Do not reject this customization or strip plugin settings.
5. Exercise explicit sequence modes using ConfigKit's existing controls:
`config.sequences: [{destination: [profiles], mode: append}]` with a duplicate
bundled ID fails normally; `mode: replace` with an application profile list
replaces all lower profiles. Include a nonconflicting append case. Keep
backend/profile references valid where testing successful replacement.
6. Show that clearing/replacing backend definitions without maintaining surviving
profile references follows existing validation, not a hidden fallback.
Disabling the bundle remains the simple application-only configuration path.
Validation: targeted new composition tests plus existing source, inheritance,
namespace, and profile-completion tests. Avoid reproducing ConfigKit's generic
sequence implementation suite.
Completion: facade integration tests cover caller precedence, whole-record
replacement, inheritance, scoped resources, sequence modes, strict conflicts,
and missing backend rejection. Targeted tests pass on Go 1.27.0.
## Stage 4: Verify Preparation And HTTP Request Construction
Scope: bundled-profile execution integration with existing runner/client paths.
1. With a minimal caller prompt and an injected deterministic client, prepare
and run using an explicit bundled profile. Check selected profile/backend,
model slug, and ordinary defaults/overrides. A prompt with no default and
no request profile must still produce the existing profile-required error.
2. For every cost tier, use the built-in HTTP client and an offline recording
RoundTripper or local server to inspect the outbound JSON. Assert the model
is `openrouter/auto` and `plugins` is a top-level array with the matching
`auto-router`/`cost_tier` entry, not nested under an `extra_params` member.
3. Verify base `auto` sends no explicit cost-tier plugin and `free` preserves
`openrouter/free`. Check at least one `~`-prefixed model reaches the request
unchanged. Return a minimal valid synthetic chat response.
4. Reuse existing runtime credential tests and override tests. Add only missing
bundle integration assertions, such as selecting `OPENROUTER_API_KEY` from
the installed backend. No real credentials, calls, provider capability
assumptions, hardcoded prices, or changes to optional-key behavior are needed.
Validation: new request cases and existing generation/profile/override tests.
Offline HTTP assertions prove payload construction, not provider acceptance.
Completion: offline preparation, injected-client execution, and HTTP payload
tests verify profile selection, overrides, credentials, router plugins, and model
slugs. Focused execution tests pass on Go 1.27.0.
## Stage 5: Verify Bundled Smoke-Test Defaults
Scope: facade-level smoke integration with a synthetic HTTP boundary.
1. On a default engine, explicitly request reachability with
`BackendID: openrouter`. Verify the existing backend-endpoint fallback.
Authentication should select the `openrouter_key` adapter and
`https://openrouter.ai/api/v1/key`, using an isolated synthetic key and a
recording transport. Return the existing adapter's minimal success fixture.
2. For text and structured inference, specify the backend without prompt/profile.
Assert fallback to `gpt-luna-latest` and its exact model slug. Return suitable
private-case responses using the existing smoke-test fixtures. Preserve
factual reports and nil-error concluded-failure semantics.
3. Show explicit profile selection wins over prompt default and backend metadata,
and a prompt default wins over backend metadata when no profile is supplied.
Smoke tests must still use their private cases, not execute caller prompt
content or output contracts.
4. Replace `gpt-luna-latest` through application configuration and verify fallback
uses the effective replacement. Replace backend smoke metadata to select a
different caller profile and confirm the ordinary selection path follows it.
5. Verify listing/inspection are not modified by diagnostics. Keep the existing
rule that diagnostics run only on explicit invocation; no new constructor,
ordinary-run, CI, or release probe is introduced.
Validation: targeted bundled smoke tests and existing smoke contract/integration
tests. Reuse existing endpoint/auth fixtures instead of adding an adapter or
duplicating the full diagnostic suite.
Completion: offline smoke tests verify reachability, authentication, both
inference cases, fallback and override selection, replacement behavior, and
unchanged inspection. Targeted smoke tests pass on Go 1.27.0.
## Stage 6: Update Documentation And Verify The Sprint
Scope: public GoDoc, current guidance/examples, and end-to-end verification.
1. Update `ConfigurationSources`, `Config`/`NewEngine`, and new-option GoDoc to
describe the dedicated lower underlay, default-on behavior, disabling, and
changed inventories. Keep exact option semantics in GoDoc.
2. Update `docs/formats.md` and `docs/consumers/pkg-promptkit.md` with the bundle,
root layout, explicit selection, optional credentials, smoke fallback, and
disabling/whole-record replacement/inherited-variant examples. Make one
canonical bundle inventory in the format reference; link rather than repeat
it throughout guidance. Link provider docs for alias/router behavior.
3. Remove stale claims of no installed catalogs from current migration guidance
and internal source/assembly documentation. Explain that an external
collection is still supported, and replacing `auto` changes inherited child
targets while retaining plugins. Do not add a rule that external catalogs
must be namespaced or upstream aliases must have fixed capabilities.
4. Keep the three maintained examples offline. Where their caller-only inventories
are intentional, pass `WithBundledOpenRouter(false)` and explain that choice;
retain useful fixture assertions rather than expanding them with unrelated
default inventory. Add a short consumer-guide bundled-profile example instead
of another live example program. Recheck README quickstart claims.
5. Add the feature and compatibility effects to the currently untagged
`docs/releases/v0.18.0.md`, including how to retain application-only behavior.
Explain that previously unresolved references matching bundled IDs can now
resolve, alongside the changed default inventories and inspection sources.
If that release has been published by implementation time, use the next
unreleased minor note instead; preserve published notes/tags. Follow the
release procedure for the note/footer. No release operation is part of this
sprint.
6. Format changes, prepare dependency caches, and run with the compatible local
Go toolchain:
```sh
go test -race -vet=off ./...
go vet ./...
go run ./examples/go-library/prepare
go run ./examples/go-library/run
go run ./examples/go-library/observe
git diff --check
```
7. Review the complete diff for unexpected API changes, caller mutation, new
source/history validation, implicit selection, network access, credential
values, and stale links. Confirm only intended documentation and inventories
changed. Follow the focused commit policy and record completion in the
feature roadmap; retire completed plans during release preparation.
Completion requires default availability, full disabling, ordinary caller
composition and provenance, correct cost-tier payloads and explicit diagnostic
fallbacks, and current documentation. There are no unresolved product choices,
external publication prerequisites, or new recurring release gates.
Completion: public guidance, GoDoc, offline examples, and the unreleased v0.18.0
note describe the bundle and opt-out. The race-enabled suite, vet, three example
commands, and diff checks passed on Go 1.27.0; no release was published.