From d79f1e956282f1da1e283a94d0af48daad1f05c8 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Tue, 22 Sep 2026 14:06:35 +0000 Subject: [PATCH] Prepare the v0.10.0 release --- README.md | 2 +- docs/consumers/pkg-promptkit.md | 2 +- docs/formats.md | 2 +- docs/releases/v0.10.0.md | 21 +- docs/roadmap/implementation.md | 284 --------------------- docs/roadmap/profile-policy.md | 359 --------------------------- docs/roadmap/public-facade.md | 217 ---------------- docs/roadmap/remediation.md | 86 ------- go.mod | 2 +- go.sum | 4 +- profile_inheritance_contract_test.go | 6 +- 11 files changed, 25 insertions(+), 960 deletions(-) delete mode 100644 docs/roadmap/implementation.md delete mode 100644 docs/roadmap/profile-policy.md delete mode 100644 docs/roadmap/public-facade.md delete mode 100644 docs/roadmap/remediation.md diff --git a/README.md b/README.md index c3c5271..2593f4a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ boundary and constraints that framework work must preserve. ## Release Guidance -Consumers preparing for the unreleased `v0.10.0` profile-policy transition +Consumers upgrading to the `v0.10.0` profile-policy transition should read the [v0.10.0 transition guide](docs/releases/v0.10.0.md). Consumers upgrading from `v0.8.0` to `v0.9.0` should read the diff --git a/docs/consumers/pkg-promptkit.md b/docs/consumers/pkg-promptkit.md index a13219f..07754f9 100644 --- a/docs/consumers/pkg-promptkit.md +++ b/docs/consumers/pkg-promptkit.md @@ -264,7 +264,7 @@ only the setting it owns: ```go promptkit.WithProfiles(promptkit.Profile{ ID: "weather-light", - BaseProfileID: "deepseek-4-flash", + BaseProfileID: "promptkit-openrouter-standard", ReasoningEffort: "high", }) ``` diff --git a/docs/formats.md b/docs/formats.md index 160852c..6fc07d9 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -346,7 +346,7 @@ cross-version guarantee for these names. The external profile inventory is defined by the selected catalog modules, not duplicated here. Browse the exact data selected by this Promptkit version: -- [OpenRouter catalog v2.20260922.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-openrouter/src/tag/v2.20260922.0/catalog/profiles) +- [OpenRouter catalog v2.20260922.1 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-openrouter/src/tag/v2.20260922.1/catalog/profiles) - [Rakestrawhome catalog v2.20260922.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/src/tag/v2.20260922.0/catalog/profiles) External profile entries are volatile across catalog releases. The diff --git a/docs/releases/v0.10.0.md b/docs/releases/v0.10.0.md index 532e5ad..08cbb68 100644 --- a/docs/releases/v0.10.0.md +++ b/docs/releases/v0.10.0.md @@ -1,9 +1,7 @@ -# Promptkit v0.10.0 (Unreleased) +# Promptkit v0.10.0 -This supplemental transition guide describes the planned `v0.10.0` catalog -profile-policy change. It is not a release record and does not claim that the -version has been published. The annotated tag, when created, remains the -authoritative release record. +This supplemental guide summarizes the `v0.10.0` changes and migration needs. +The annotated tag remains the authoritative release record. ## Transition Summary @@ -12,6 +10,13 @@ modules whose external profile data can change between catalog releases. It also introduces the maintained literal names `promptkit-openrouter-standard` and `promptkit-openrouter-auto`. +The public package now delegates assembly to an internal engine while retaining +the existing Go API. This refactor requires no consumer code changes. + +This release selects OpenRouter `v2.20260922.1` and Rakestrawhome +`v2.20260922.0`; their exact inventories are linked from the +[format reference](../formats.md#external-profile-inventories). + The maintained names provide continuity only within the catalog versions selected and tested by a Promptkit release and when consumers do not override the name or its base. Their current selections may change. External catalog @@ -26,6 +31,12 @@ catalog profile's volatility, or define a complete application-owned profile when the application must control its target and settings. An alias that inherits from an external base is not a frozen copy. +In particular, the selected OpenRouter catalog removes `deepseek-3-2`, +`deepseek-4-flash`, and `deepseek-4-pro`. Consumers using those IDs must choose +an available profile or supply their own complete definition; the new +`deepseek-flash-latest` and `deepseek-pro-latest` profiles are not automatic +aliases and need not preserve the previous settings. + See the [release policy](../release.md#catalog-profile-compatibility) for the compatibility boundary, the [format reference](../formats.md#built-in-profile-catalog) for current Promptkit-owned definitions and selected external inventories, and diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md deleted file mode 100644 index 79bd912..0000000 --- a/docs/roadmap/implementation.md +++ /dev/null @@ -1,284 +0,0 @@ -# Profile Policy Implementation Plan - -## Scope And Starting Point - -Implement the [profile-policy roadmap](profile-policy.md): volatile external -profile catalogs, dated `/v2` catalog modules, and two Promptkit-owned stable -profile names. This replaces the completed public-facade implementation plan. -The facade refactor and its review remediation are complete; composition work -belongs in `internal/engine`, not the public package. - -The feature roadmap still labels its policy provisional. Before executing -Stage 1, confirm maintainer acceptance of this plan and update that roadmap's -status to accepted for implementation, linking here for sequencing. Remove -superseded procedural language there without changing its intended end state. -Until implementation lands, existing durable contracts remain authoritative. - -Execute stages in numerical order, one coding-agent prompt per stage. Stage 2 -is a release handoff requiring explicit publication authority. This plan does -not itself authorize releases or pushes. Do not carry forward completion marks -or API snapshots from the previous implementation plan. - -Read `AGENTS.md`, [development](../development.md), all policies under -`docs/policy/`, [formats](../formats.md), [internal sources](../internal/sources.md), -and [release procedure](../release.md). Read each catalog repository's own -instructions and release procedure before editing it. Preserve unrelated -changes. For every implementation stage, run focused tests and the affected -repository's complete validation workflow before acceptance. Report results -and blockers; do not treat an unrun check as successful. - -## Implementation Decisions - -- Both catalog modules move to `/v2` paths and `v2.YYYYMMDD.N` releases. Use the - actual UTC publication date and the next unused revision starting at zero; - no placeholder tag or preliminary `v2.0.0` is needed. Modules release - independently. Preserve published tags and their historical contracts. -- Only external profile data becomes volatile. Go APIs, manifest/format - semantics, backend IDs and definitions, and Promptkit runtime behavior remain - outside the exception. Promptkit adds no live model or endpoint checks. - Catalog owners remain responsible for upstream mapping accuracy. -- The only profile-specific continuity guarantees are the literal names - `promptkit-openrouter-standard` and `promptkit-openrouter-auto`, within the - selected-and-tested dependency scope and absent consumer overrides. Models, - backends, routing, defaults, and other selection characteristics are not - permanent promises. Do not add notice or approval gates for later selections. -- Initially, standard inherits `gemini-flash-latest`; auto directly selects - backend `openrouter` and model `openrouter/auto`. Add no generation overrides, - connection metadata, implicit default selection, public API, or fallback loop. -- Construct the two raw definitions as internal Go values through - `profile.NewMemoryRepository`, owned by a focused `internal/engine` helper. - Two definitions do not justify another embedded asset tree or package. -- Compose raw sources in this order: consumer memory, ordinary consumer source, - consumer fallback source, Promptkit-owned profiles, external catalogs. Keep - one runtime resolver over the complete hierarchy. Separately validate the - maintained-only composition at construction without freezing its resolved - values into the runtime source. -- Reject the exact `promptkit-` prefix on normalized external catalog IDs in - `internal/catalog.Load`. Do not impose that reservation on consumer sources, - fold case beyond existing ID rules, or alter generic repositories. -- Replace the old external-catalog extraction snapshot with structural and - maintained-name tests. Do not create another full-profile inventory snapshot: - module versions/checksums identify selected data, while repeated snapshots - recreate catalog churn. Preserve backend-contract coverage separately. -- The transition targets a new Promptkit minor release, currently `v0.10.0`. - Later catalog-only updates and maintained-selection adjustments may ship as - patches if other contracts remain intact. Promptkit retains semantic versioning. - -## Stage 1: Prepare Both Catalog Modules For The New Contract - -**Completed:** 2026-09-22 - -Repositories: `../promptkit-backend-openrouter` and -`../promptkit-backend-rakestrawhome`. Their small data-only packages make this -one bounded prompt; keep changes in their respective repositories. - -1. Inspect both worktrees, module files, tags, assets, tests, README files, and - `docs/release.md`. Preserve maintainer changes. The current OpenRouter - checkout already contains a profile refresh; retain it rather than reverting - to Promptkit's selected v1 catalog. Additional model curation is out of scope. -2. Change each module declaration to its existing path plus `/v2`, and update - self-imports and examples. Preserve package names, `FS()`, `Root`, embedded - layout, manifest schema, and backend definitions. Do not introduce a - dependency on Promptkit or duplicate its runtime validation. -3. Revise compatibility documentation: profiles may be added, removed, renamed, - or modified without deprecation or notice; backend definitions, public Go - API, and schema compatibility do not gain that exception. Describe dated - versions and explain that dates do not certify live availability. Do not - pretend a README change retroactively changes the v1 contract. -4. Update each release procedure for `/v2`, dated tags, immutable versions, - independent release dates, and normal module-resolution checks. Retain its - existing validation and annotated source-tag publication requirements. -5. Keep proportionate data-package tests for the exported filesystem and asset - shape. No network calls, credentials, provider SDKs, runtime dependencies, - or cross-version profile-continuity assertions. Run both full workflows. - -Acceptance: both source trees are ready for dated v2 releases; their asset APIs -and backend manifests are unchanged apart from module identity. Report the -candidate commits and validation. Do not publish without authority. - -## Stage 2: Publish And Verify The Catalog Releases - -**Completed:** 2026-09-22 - -**Publication record:** - -- OpenRouter: `gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2` - `v2.20260922.0` from `ad0b16f77035d8acbe38a6ae1e278eaf7eeb0dc8`. -- Rakestrawhome: - `gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/v2` - `v2.20260922.0` from `d664696142bf7c2d93db2a6b2e07f3deb55f2226`. - -This is a maintainer-authorized publication stage, not a coding workaround for -unavailable dependencies. If authority or remote access is missing, report the -handoff and stop before adopting unpublished dependencies. - -1. Follow each catalog's updated release procedure. Select an unused - `v2.YYYYMMDD.N` tag using the publication date, validate the clean candidate, - publish its source commit and only the selected annotated tag, and verify - the remote tag and peeled commit. Never move a published tag. -2. From a temporary module outside these repositories, resolve each exact - `/v2@version` with `GOWORK=off`, without replacements or vendoring. Verify - module identity and version. Downloads are not inference-provider probes - and are separate from offline test execution. -3. Record the two actual module versions and source commits in execution notes - in this plan for Stage 5. They need not share dates or revision numbers. - -Acceptance: both published dependencies resolve normally without sibling -checkouts, workspaces, or replacements. - -## Stage 3: Enforce The External Catalog Namespace - -**Completed:** 2026-09-22 - -Repository: Promptkit. Keep current v1 dependencies during this stage; -dependency adoption remains atomic in Stage 5. - -1. In `internal/catalog.Load`, reject normalized profile IDs starting with - `promptkit-` while inspecting eager-loaded catalog metadata. Use the existing - descriptive catalog-construction error style with source context. Public - construction continues to classify failures as `ErrInvalidConfig`. -2. Preserve catalog-local inheritance, owning-backend validation, duplicate - detection, secret/connection-field rules, strict decoding, and value checks. - Do not relax these because profiles are volatile or add upstream validation. -3. Extend synthetic catalog tests with a reserved maintained name and an - otherwise unused `promptkit-` name. Confirm ordinary IDs still load. Keep - the rule out of generic parsing so consumer definitions can use the prefix. -4. Update internal source documentation for the implemented catalog-only - reservation. Do not yet claim the maintained profiles exist. - -Acceptance: catalogs cannot occupy the namespace; existing protections and -consumer source behavior are unchanged. - -## Stage 4: Add And Compose Promptkit-Owned Profiles - -**Completed:** 2026-09-22 - -1. Add a maintained-profile helper in `internal/engine` with the two raw - definitions specified above. Build its memory repository, overlay it above - the raw external catalog repository, and supply that raw composition to the - existing consumer-source assembly. -2. During construction, resolve each Promptkit-owned definition through a - maintained-only resolver and check that its effective backend exists in the - maintained backend set. Reuse existing resolver and backend lookup owners; - do not implement another inheritance walker or target-policy validator. - External profiles retain catalog-local validation in `catalog.Load`. - Together these checks cover the maintained set without consumer definitions - or network access. -3. If a maintained definition fails to resolve, fail construction through the - existing `ErrInvalidConfig` boundary. Consumer overrides must not mask broken - bundled definitions. Keep raw definitions for runtime resolution so consumer - overrides of a maintained profile or its base still work. No resolved-profile - cache or global mutable repository is needed. -4. Use minimal synthetic composition tests for inherited selection, direct - selection, missing-base failure, and invalid backend reference. Expected - selections should follow the supplied definitions, not become permanent - literal model promises. -5. Add representative public inspection/preparation coverage proving both - literal names resolve, consumers can replace maintained profiles or their - bases, and default-profile selection is unchanged. Reuse source-precedence - and prepared-execution coverage rather than duplicating full matrices. -6. Update formats with the two current definitions, opt-in selection, and - precedence. Update internal ownership and source-validation documentation. - Scope intermediate compatibility claims to policy actually adopted so far. - -Acceptance: both names work through existing APIs, consumer precedence remains -effective, and no public exports or provider routing logic have been added. - -## Stage 5: Adopt Published V2 Catalogs And Replace Snapshot Tests - -**Completed:** 2026-09-22 - -1. Update catalog imports in production and tests to `/v2`. Select the exact - Stage 2 versions through normal Go tooling, tidy module metadata, and review - `go.mod`/`go.sum`. No `latest`, unpublished revisions, unrelated upgrades, - or local replacements. Remove unused v1 requirements. -2. Replace `TestLoadPublishedCatalogsMatchCompatibilityFixture` with an offline - integration test loading both selected catalogs for structural acceptance. - Remove snapshot-only helpers and `testdata/builtin-catalog-v1.json` once no - callers remain. Retain malformed-input tests and backend metadata contract - coverage; add focused backend assertions if deleting the snapshot removes - their only protection. Backend definitions are not volatile profile data. -3. Run maintained-profile tests against the new modules. Verify standard's base - exists locally; if absent, change the maintained selection in this same - dependency update and document the current definition. This is not a new - permanent selection-approval gate. The inspected catalog currently contains - `gemini-flash-latest`, so no replacement is planned. -4. Convert tests that use removed external profiles for unrelated runtime - behavior to consumer-owned fixtures. Keep small real-catalog integration - coverage without coupling every runtime test to external inventories. -5. Review the catalog diff for local compatibility consequences, not provider - health. Do not restore removed IDs or add migration aliases just to preserve - the old snapshot. Confirm backend manifests and public/runtime contracts - did not change as a side effect. - -Acceptance: Promptkit passes its full workflow using published v2 dependencies; -tests protect structural validity and maintained names without promising an -external inventory across releases. - -## Stage 6: Publish Durable Policy And Consumer Guidance - -**Completed:** 2026-09-22 - -1. Update `docs/release.md`, the release-policy owner: narrow external-profile - exception, two-name continuity scope, initial minor transition, and later - patch eligibility. Replace its blanket catalog-update instruction to claim - no consumer migration is needed: removals may require consumer action. - Preserve ordinary compatibility and release records; do not require model - change announcements or additional selection gates. -2. Replace the exhaustive external profile table in `docs/formats.md` with links - to inventories at the selected catalog versions. Keep the small Promptkit - inventory here, label selections current rather than permanent, and link to - release policy for cross-version guarantees. -3. Explain consumer choices in the consumer guide: use a maintained name, - accept a volatile external profile, or define a complete application-owned - profile. Inheritance still follows base changes and can fail if the base - disappears; an application alias is not a frozen copy. -4. Explain selected-and-tested dependency scope and the resolved module graph: - independently upgrading a transitive catalog can break an inherited base. - Pinned data does not preserve upstream availability; running binaries neither - download updates nor automatically replace withdrawn models. -5. Update architecture, internal source/overview, and contributor documentation - only where ownership or workflow changed. Avoid duplicate inventories and - exact contracts. No live endpoint/model-list check belongs in adoption, - tests, or release validation. -6. Prepare `docs/releases/v0.10.0.md` as supplemental transition guidance linking - canonical policy/formats and describing potential profile migration. Add a - README link labeled unreleased until publication. Do not claim release - completion or require individual model-change notices. - -Acceptance: durable documentation distinguishes stable literal names from -volatile selections and agrees across repositories without weakening unrelated -contracts. - -## Stage 7: Final Integration Review And Release Handoff - -**Completed:** 2026-09-22 - -1. Run the complete Promptkit maintainer workflow: ordinary/race tests, vet, - build, both offline examples, formatting, local links, and hygiene. Verify - normal module resolution independent of sibling checkouts. -2. Compare public declarations against the completed facade baseline: no new - API, internal type leak, default-selection change, or consumer restriction - is intended. Confirm existing error, injection, override, inheritance, repair, - prepared-execution, and capacity tests still pass. -3. Check recorded dependency versions, maintained-name resolution without - consumer help, consumer overrides, and absence of cross-version external - inventory promises in tests or documentation. -4. Review for stronger promises than authorized: permanent backend/routing - implied by a profile name, change announcements, deprecation periods, or - live-service checks. Remove accidental guarantees rather than adding gates. -5. Report completion and the minor-release candidate. Retire completed roadmaps - only when requested or approved during release preparation. Promptkit - publication follows its release procedure under separate authority; do not - tag or push it merely because this stage passes. - -Acceptance: ready for independent review and subsequent release preparation, -with validation results and any blockers reported. - -## Open Questions - -No unresolved product or architecture decision is needed for this proposed -implementation. Maintainer acceptance of the still-provisional policy and -authority to publish catalog releases are execution prerequisites, not assumed -permissions. Exact version strings are selected at publication using the -agreed date convention and recorded before Promptkit adoption. diff --git a/docs/roadmap/profile-policy.md b/docs/roadmap/profile-policy.md deleted file mode 100644 index 2d98a33..0000000 --- a/docs/roadmap/profile-policy.md +++ /dev/null @@ -1,359 +0,0 @@ -# Built-In Profile Compatibility Policy - -## Status - -Accepted for implementation on 2026-09-22. The implementation sequence and -completion status are maintained in the -[profile-policy implementation plan](implementation.md). Current code, GoDoc, -durable documentation, published module contracts, and release tags remain -authoritative until each corresponding implementation change lands. - -## Prerequisite And Sequencing - -Implementation of this roadmap must begin only after the -[public facade refactor](public-facade.md) is complete and its compatibility -and validation criteria have passed. The refactor preserves existing behavior; -this subsequent work introduces the deliberate profile-policy changes. - -Profile-source composition, maintained-profile construction, and catalog -dependency assembly must use the internal owners established by that refactor. -Both scopes may ship in `v0.10.0`, but they remain separately reviewable changes. -This prerequisite has been satisfied. The remaining work proceeds through the -[profile-policy implementation plan](implementation.md). - -## Purpose - -Define a truthful compatibility and release boundary for Promptkit's -maintained built-in profiles. The intended direction is to permit exceptionally -rapid catalog updates without weakening Promptkit's stability commitments for -its engine, public Go API, configuration semantics, backend registry, or other -non-profile behavior. - -Model catalogs change faster than the Promptkit runtime. Providers control -their own model catalogs and service lifecycles. Promptkit cannot -reasonably guarantee that a maintained profile's upstream model or endpoint -will remain available, and retaining obsolete profiles can be actively -misleading when their targets no longer provide the expected service. - -The release model should treat external catalog profiles as volatile data, -while providing a small set of Promptkit-owned aliases with stable IDs for -applications that prefer a maintained general-purpose selection. - -## Proposed Compatibility Boundary - -The provisional policy would exclude external catalog profile data from -Promptkit's cross-version compatibility surface. A catalog or Promptkit -release could, without deprecation or advance notice: - -- add or remove an external catalog profile; -- rename a profile, represented as removing one ID and adding another; -- change the upstream model selected by a profile; -- change profile defaults such as reasoning effort, timeout, service tier, - sampling controls, token limits, or extra parameters; and -- correct or otherwise revise profile metadata in response to upstream - behavior. - -Promptkit would make no cross-version promise about the continued presence, -identity, settings, suitability, or upstream availability of an external -catalog profile. The separately defined Promptkit-owned alias IDs would have -the continuity guarantee below. Promptkit would make no claim that an upstream -provider will continue to serve a cataloged model or endpoint for the lifetime -of a Promptkit or catalog release. - -This volatility exception should apply only to external catalog profile -data. It should not silently weaken the ordinary compatibility rules for: - -- Promptkit's exported Go API and GoDoc contracts; -- prompt, profile, and schema format semantics; -- request preparation, execution, validation, repair, cancellation, error, - credential, ownership, and concurrency behavior; -- public built-in backend IDs and registry behavior; -- the external catalog packages' exported Go API; -- the catalog manifest and asset schema understood by Promptkit; or -- consumer-defined profiles and backends. - -Backend definitions, including endpoint, credential-environment, and capacity -metadata, remain outside the profile-volatility exception and subject to the -ordinary compatibility policy. - -## Proposed Stable Promptkit Profiles - -Promptkit would maintain a small, explicitly documented set of built-in -profiles using existing profile definitions and inheritance: - -| Stable profile ID | Initial definition | Initial purpose | -| --- | --- | --- | -| `promptkit-openrouter-standard` | Inherits from external catalog profile `gemini-flash-latest`. | A maintained selection for general-purpose text generation. | -| `promptkit-openrouter-auto` | Selects backend `openrouter` and model `openrouter/auto`. | Delegates model selection to OpenRouter's automatic routing. | - -These definitions and purposes describe the initial selections only and are -not continuing model-selection promises. - -The auto profile can initially be a direct profile definition; it does not -require a second catalog alias or a new public API. It inherits connection and credential -metadata from the OpenRouter backend and need not add generation overrides. -Promptkit forwards `openrouter/auto` as the model identifier through its ordinary -client. OpenRouter owns the routing decision, eligible models, and resulting -provider behavior. Promptkit adds no model-selection algorithm or fallback -loop. Its ordinary local validation does not check the upstream availability -of `openrouter/auto`. - -Both profiles receive the stable-ID guarantee below. References to aliases -describe inherited definitions where applicable; the same namespace, -precedence, and structural-validation requirements cover direct definitions. -Only these two profiles are in scope. This roadmap imposes no additional -approval process for future profiles. - -The only profile-specific continuity promise is that the literal names -`promptkit-openrouter-standard` and `promptkit-openrouter-auto` remain -available, subject to the supported dependency and consumer-override scope -below. Their actual models may change at any time, for any reason, without -notice to anyone. No deprecation, approval, or change-announcement gate applies -to model selection. The names do not promise a permanent model, provider, -routing strategy, or set of defaults. Both initially use OpenRouter, but the -profile names themselves are the only continuity guarantee. - -In particular, `promptkit-openrouter-auto` is not required to retain -`openrouter/auto` or automatic routing indefinitely. Neither profile guarantees -unchanged output, cost, latency, capabilities, or upstream availability. While -using upstream automatic routing, the selected model can vary between requests -even with unchanged Promptkit and catalog versions. - -Catalog dependency updates must preserve local resolution of the two maintained -profile names. If a referenced catalog profile disappears or is renamed, -adjust the affected alias together with the dependency update and ship both in -the same Promptkit release. If the catalog retains the referenced ID but -changes its model, inheritance picks up the change automatically; no separate -model-selection approval is required. Ordinary code review and structural -validation apply. Upstream deprecation, retirement, and mapping accuracy remain -the catalog library's responsibility and do not create a Promptkit monitoring -or upstream-verification obligation. - -Release validation must prove that every maintained alias resolves against -the selected catalog versions. This continuity guarantee applies to the -versions selected and tested by Promptkit and assumes consumers have not -overridden the alias or its base with their own definitions. Independently -upgrading a transitive catalog can remove an alias's base without updating -Promptkit; that untested combination is outside the guarantee. - -Aliases would retain the ordinary profile precedence and inheritance -semantics. They would introduce no new public API or automatic model failover. -An already deployed application would retain its compiled alias and catalog -data until upgraded; an upstream withdrawal would not change its selection -automatically. - -Adding these profiles does not change existing default-profile selection. -Consumers opt into them through the existing profile-selection mechanisms. - -### Ownership, Precedence, And Composition - -The maintained alias definitions belong to a small Promptkit-owned profile -source. Profile precedence is consumer sources in their existing order, then -Promptkit-owned aliases, then external catalog profiles. Consumers may override -an alias or its base using the ordinary profile mechanisms. - -Reserve the `promptkit-` profile-ID prefix against definitions in external -catalogs. Reject such catalog definitions even if they do not yet collide with -an existing alias. This namespace rule does not prohibit consumer overrides. - -Retain existing catalog-local inheritance and backend-ownership validation, -and verify that the combined maintained profiles resolve without relying on -consumer overrides. Do not assert a permanent model or routing selection based -on a profile name. Runtime inheritance must continue to observe the complete -source hierarchy, including consumer overrides of aliases and their bases. -Reuse the existing resolver; exact private assembly and validation sequencing -belongs in the implementation plan. Do not introduce a second inheritance -implementation or freeze alias values in a way that bypasses consumer overrides. - -## Local Validation And Existing Safeguards - -Profile volatility does not remove existing structural validation or library -safeguards. Preserve the following implemented responsibilities without making -them additional profile-availability or permanent implementation promises: - -- catalog assets are immutable build inputs rather than runtime downloads; -- manifests and profiles satisfy the supported schemas; -- IDs are unique and profiles select their owning backend; -- external catalogs do not define IDs in the reserved `promptkit-` namespace; -- secret-bearing fields and prohibited connection metadata are rejected; -- profile values are normalized, copied, resolved, and overlaid through the - existing Promptkit architecture; -- the selected catalogs pass Promptkit's integration suite before a Promptkit - release adopts them; and -- the module graph and checksums provide a reproducible identity for the data - that was tested. - -These checks establish local integrity for selected data, together with the -maintained-profile resolution requirement above. They do not establish external -catalog profile continuity across versions or live upstream availability. - -Promptkit's checks cover local syntax and structural semantics: supported -fields, duplicate IDs, namespace conflicts, inheritance resolution, backend -references, endpoint URL format, and existing security and value constraints. -They expressly exclude attempts to verify that an endpoint exists, a model ID -is recognized upstream, or a provider serves that model. Catalog libraries own -the accuracy of upstream model and endpoint mappings. Promptkit must not add -network probes, model-list lookups, or paid inference checks to catalog adoption -or release validation. Ordinary execution continues to report upstream errors -through the existing generation-error contract. - -## Provisional Release Model - -The first release adopting this policy should be a new Promptkit minor release -because it changes a previously documented consumer expectation and may remove -profile IDs on which deployed configuration depends. `v0.10.0` is the current -candidate. - -The OpenRouter catalog's published `v1.0.0` contract promised stable profile -IDs and advance handling before removal. A later README cannot retroactively -weaken that promise. The current recommendation is therefore to establish the -new boundary in `promptkit-backend-openrouter` major version 2, using the dated -release convention below, even if its exported Go declarations and manifest -schema do not change. - -After that boundary is established, maintained catalog releases could publish -profile additions, deletions, and modifications rapidly under their documented -volatile-data policy. Promptkit could select a reviewed catalog update without -treating profile churn as a compatibility break in its otherwise stable core. -Later catalog updates and corresponding alias adjustments may ship in a -Promptkit patch release, such as `v0.10.1` after `v0.10.0`, provided unrelated -compatibility contracts remain intact. Profile churn alone does not require -`v0.11.0` or another minor release. - -Promptkit's integration validation covers the catalog versions it selected -and tested. It does not guarantee upstream correctness for those versions. -Go module version selection may cause an advanced consumer's build -to select a newer compatible catalog module than Promptkit's own requirement; -the resolved module graph, rather than Promptkit's `go.mod` alone, determines -the actual embedded data. - -Release notes may identify selected catalog updates and summarize changes for -convenience, but no notice of model-selection changes is required, in advance -or afterward. Ordinary release records and validation still apply; they must -not introduce a profile-change announcement gate. - -### Proposed Date-Based Catalog Versions - -The proposed catalog version convention is `vMAJOR.YYYYMMDD.N`. This is a -calendar-based convention encoded in Go-compatible semantic-version syntax: - -- `MAJOR` identifies the compatibility generation of the exported Go package - and catalog asset format. Profile additions, deletions, renames, and setting - changes do not require a major-version increase under the proposed policy. -- `YYYYMMDD` is the release publication date in UTC. It occupies the numeric - minor-version component and communicates snapshot freshness, not the scale - or compatibility of a profile change. -- `N` starts at zero for each UTC date and increments for every additional - release that day, regardless of the kind of profile change. It occupies the - numeric patch-version component and carries no profile-continuity promise. - -For example, `v2.20260922.0` and `v2.20260922.1` would be successive releases -on September 22, 2026, followed by `v2.20260923.0` on the next day. These are -illustrative dates, not scheduled releases. Use the actual publication date; -published versions remain immutable, and corrections receive new versions. -Within a major generation, these versions sort chronologically under Go's -ordinary module-version ordering. - -Go requires a matching major-version suffix in module paths for version 2 and -later. The OpenRouter transition would therefore use -`gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2` in the catalog's -module declaration and Promptkit's imports and dependency requirement. A first -release on the example date would be `v2.20260922.0`; a preliminary `v2.0.0` -release is not required. Promptkit consumers would continue importing -Promptkit through its existing module path. See the -[Go module version rules](https://go.dev/ref/mod#versions) and -[major-version suffix rules](https://go.dev/ref/mod#major-version-suffixes). - -Both maintained catalog libraries, OpenRouter and Rakestrawhome, would -transition to this policy and dated major-version-2 convention as part of this -work, with matching `/v2` module paths. Thereafter each would release -independently; releases need not share dates or revision numbers. -Promptkit itself would retain its existing version-number -convention and explicitly select and test individual catalog versions. - -This proposal replaces the earlier idea of classifying catalog refreshes as -ordinary minor releases and metadata corrections as patches. The date records -when a snapshot was published; release notes may summarize what changed. -Neither establishes live upstream availability or cross-version profile -continuity. The convention remains provisional along with this roadmap. - -## Consumer Guidance - -The eventual durable documentation should make the tradeoff explicit: - -- external catalog profiles optimize for convenient access to a maintained - current model catalog; -- selecting or inheriting directly from an external catalog profile accepts - its volatility; -- selecting either `promptkit-openrouter-standard` or - `promptkit-openrouter-auto` guarantees only continued availability of that - literal profile name within the supported dependency scope; models and - settings may change for any reason without notice; -- `promptkit-openrouter-auto` initially delegates model selection to OpenRouter; - its initial routing behavior is not a permanent contract, and upstream - routing can change independently of a library upgrade; -- pinning the complete resolved Go module graph preserves the exact catalog - assets used by that build, but cannot preserve live upstream availability; -- applications that require their own fixed model selection or settings should - define a complete application-owned profile with an explicit backend, model, - and defaults; and -- an application-owned alias that inherits from an external catalog profile - isolates application configuration from the catalog ID only while that base - exists; it deliberately continues to inherit changes to the base profile. - -Promptkit should not promise automatic migration or replacement aliases for -every removed external catalog ID, deprecation windows for catalog profiles, -or runtime fallback from a removed or unavailable model. Its small maintained -alias set provides continuity through coordinated library releases. - -## Expected Documentation And Repository Changes - -If accepted, implementation would likely require coordinated changes in -Promptkit and each maintained catalog repository: - -- revise catalog compatibility and release documentation to distinguish the - stable Go/schema boundary from volatile profile data and document the - `vMAJOR.YYYYMMDD.N` convention; -- update Promptkit's release policy with a narrowly scoped built-in-profile - volatility exception for external catalogs and an explicit continuity - guarantee for Promptkit-owned alias IDs, while retaining its other pre-`v1` - compatibility rules; -- add `promptkit-openrouter-standard` through existing profile inheritance and - `promptkit-openrouter-auto` as a direct `openrouter/auto` profile; document - their distinct purposes and opt-in selection; -- require coordinated catalog and alias updates, with release checks proving - every maintained alias resolves against the selected catalog versions; -- update the architecture, format, source, development, and consumer - documentation at their existing ownership boundaries; -- keep exact external profile inventories in the catalog repositories, linking - to the selected versions from Promptkit rather than duplicating their tables; - keep Promptkit's small alias inventory and runtime semantics in its own - canonical documentation; -- revise tests and compatibility-fixture terminology so they protect local - structural validity and maintained-profile resolution, without asserting - cross-version stability of external profiles; retain an exact selected-version - snapshot only where its review value justifies its maintenance cost; -- publish both revised catalog contracts as dated major-version-2 releases - with matching `/v2` module paths; -- update Promptkit's catalog imports and requirement, current selected-profile - documentation, and release guidance; and -- publish the policy transition and its consumer impact in the eventual - Promptkit minor release note and annotated tag. - -Implementation is sequenced and tracked in the -[profile-policy implementation plan](implementation.md). - -## Non-Goals - -This proposal does not introduce: - -- runtime catalog downloads, discovery, or mutable global registration; -- any upstream endpoint or model-existence verification by Promptkit, or - guarantees based on current provider health; -- automatic replacement aliases or migration tables for every removed catalog - profile, or runtime fallback models; -- weakened validation of catalog structure or content; -- weaker compatibility for Promptkit's public engine or consumer-defined - configuration; or -- a general exception allowing arbitrary dependency updates to break stable - Promptkit behavior. diff --git a/docs/roadmap/public-facade.md b/docs/roadmap/public-facade.md deleted file mode 100644 index 4f758f4..0000000 --- a/docs/roadmap/public-facade.md +++ /dev/null @@ -1,217 +0,0 @@ -# Public Facade Refactor - -## Status - -Accepted direction; implementation has not begun. This feature roadmap defines -the intended end state and compatibility requirements. The companion -[implementation plan](implementation.md) defines the work sequence. Current -GoDoc and durable documentation remain authoritative until implementation lands. - -## Purpose - -Make Promptkit's root package a deliberately maintained consumer facade while -placing engine implementation and assembly behind Go's `internal/` boundary. -Consumers should depend only on intentional public contracts, and maintainers -should be able to refactor internal behavior without changing those contracts. - -The aim is a clearer ownership boundary, not the smallest possible root package -or a reduction in consumer capabilities. Private root functions are already -inaccessible to consumers; relocating them improves separation but does not by -itself control the exported API. The refactor must also protect public type -ownership, signatures, fields, and method sets against accidental exposure of -implementation details. - -## Current Position - -Promptkit already places execution, repair, capacity management, rendering, -source loading, transport, and validation in specialized internal packages. -Its [architecture policy](../policy/architecture.md) already identifies the -root package as the supported public facade. - -The remaining root implementation includes engine construction and collaborator -assembly, source selection, profile overlay construction, filesystem source -setup, and an in-memory profile repository. These responsibilities can move -inward while the root retains public declarations and explicit adapters. - -ConfigKit's completed facade refactor is a design reference: root-owned public -types wrap private engine state and expose explicitly selected methods. Its -implementation should inform this work without introducing a dependency on -ConfigKit or copying mechanisms that Promptkit does not need. - -## Target End State - -### Root-Owned Public Contract - -The root `promptkit` package remains the consumer import path and owns: - -- public named types, interfaces, constants, and error identities; -- public configuration, request, result, inspection, and profile values; -- constructors, options, and deliberate forwarding methods; -- opaque public handles backed by private internal state; -- public GoDoc and supported serialization and formatting behavior; and -- explicit value conversion, injected-collaborator adaptation, and public - error translation where they cross the facade boundary. - -Public types must remain root-defined. Do not alias them to internal types, -anonymously embed internal implementations to promote methods, expose internal -types in public fields or signatures, or add public bridge methods for wiring. -Private fields may refer to internal implementations. - -Straightforward convenience constructors and boundary code may remain in the -root. A forwarding layer or additional record type should have a concrete -ownership or compatibility purpose; moving every helper is not an objective. - -### Internal Engine Assembly - -A cohesive internal assembly owner constructs an operational engine from -internal configuration and supplied collaborators. `internal/engine` is the -proposed home; exact private package and helper layout belongs in the -implementation plan. Its responsibilities -include source selection and defaults, maintained catalog loading, profile -overlay assembly, backend registration assembly, capacity-manager construction, -default client and validator selection, and runner/repairer wiring. - -The public `Engine` delegates through private state to internal implementation. -Root options express consumer choices and translate public values; internal -construction owns how those choices assemble components. Preserve established -contracts for option capture, application, validation, and source access. -Incidental private ordering is not a new compatibility requirement. - -Build on the existing specialized internal responsibilities. Internal assembly -is the composition owner, not a replacement for the runner, -catalog adapter, profile repositories, transport, or domain packages. It should -not duplicate execution orchestration already owned by `internal/usecase`. - -Move the in-memory profile repository behind the internal boundary; -`internal/profile` is its natural home. Reuse existing definition validation and -copying owners. Other root implementation -helpers should move to their cohesive existing owner or to internal assembly -as appropriate. Avoid generic registries, service locators, or a new extension -framework for this relocation. - -Dependency direction remains root facade to internal components. Internal -production packages must not import the root package. The root can use internal -domain values and narrow collaborator interfaces for explicit conversions; -this proposal does not require all root imports to pass through a single -internal package or require duplicate forwarding APIs to achieve that shape. - -## Compatibility Requirements - -This is a behavior-preserving refactor covering the actual exported surface, -including methods and fields. An exported declaration is -accessible even when it is absent from the consumer guide. Do not infer that -an apparently low-level declaration is safe to remove: injected model clients -and other intentional extension contracts may rely on it. - -Preserve existing public names, signatures, named-type identity, method sets, -interface satisfaction, exported struct fields, and supported value behavior. -Any discovered API removal or redesign requires a separate explicit decision -and consumer migration rationale; the minor release is not blanket permission -to remove accessible declarations. - -The refactor must preserve, in particular: - -- established option order, replacement and accumulation rules, nil behavior, - validation timing, and capture/copy contracts; -- profile-source precedence, lazy consumer source reads, inheritance, and - maintained-catalog validation; -- public error identities and typed errors through `errors.Is` and `errors.As`, - including cancellation propagation and sensitive-detail redaction; -- public JSON representations, formatting, and defensive-copy guarantees; -- injected client and artifact-reader contracts, including caller ownership - of collaborator values; -- preparation and inspection semantics, hash relationships, request overrides, - appended messages, output validation, and bounded repair; -- prepared-execution engine binding, shared lifecycle when handles are copied, - single-use execution, discard behavior, and credential retention; and -- engine-local concurrency, admission, cancellation, usage accounting, and - transport behavior. - -Preserve intentional contracts without elevating incidental private layout, -helper names, operation ordering, diagnostic wording, or opaque hash encodings -into new promises. The baseline inventory identifies accessible API; it is -not authority to turn every observed implementation behavior into a contract. - -## Verification And Test Ownership - -Follow the [testing policy](../policy/testing.md). Existing external-package -contract tests and maintained offline examples should continue to exercise the -same consumer API. Tests coupled to private layout may be adapted or -consolidated under the testing policy without changing their contract-level -expectations. - -Move implementation tests with their owning behavior when package relocation -requires it. Keep focused source, profile, runner, capacity, and transport -coverage at the existing internal owners. Root tests should focus on public -compatibility, boundary conversion, error adaptation, and representative -assembled workflows. Do not duplicate internal test matrices at the facade or -add one test per trivial forwarding method. - -Add a focused public-boundary check that detects internal types escaping -through exported types, signatures, fields, or promoted methods, and rejects -public aliases to internal implementations. Use Go's type information where -needed to inspect the actual exported method sets. The check must permit -private internal state and the established sealed option mechanism. Protect -the no-internal-production-imports-of-root dependency rule without freezing an -incidental file layout or exact internal package inventory. - -Compatibility evidence includes an unchanged exported surface and behavioral -coverage of consequential boundary risks: option timing, conversion ownership, -typed errors, and prepared-execution lifecycle. Acceptance requires the complete -[maintainer validation workflow](../development.md#maintainer-validation), -including race checks and both offline examples. No live provider calls or -sibling repository are required for validation. - -## Relationship To The Profile Policy Work - -This refactor and the [profile-policy proposal](profile-policy.md) are separate -scopes that may ship together in the planned `v0.10.0` release. Establish the -facade boundary with current behavior preserved before implementing the -catalog-policy and standard-profile changes. Their assembly logic can then -land in its intended internal owner. - -This roadmap does not itself change catalog versions, introduce standard -profiles, or adopt the provisional profile compatibility policy. Release -guidance should distinguish the internal refactor from the deliberate consumer -policy changes accompanying it. A completed facade refactor should require no -consumer migration on its own. - -## Documentation End State - -Update the [architecture policy](../policy/architecture.md) to describe the -implemented facade and assembly boundary, and the -[component overview](../internal/overview.md) to identify the new owner and -relocated responsibilities. Update affected internal source and runner -documentation and links when implementation moves. - -Go declarations and GoDoc remain the canonical public contract. Consumer and -format documentation should not acquire new requirements from a private -relocation. Record the durable facade decision in an ADR if needed to preserve -its rationale; ConfigKit is a reference, not an ongoing normative dependency. -Remove this temporary roadmap after completion and durable documentation -updates according to the [documentation policy](../policy/documentation.md). - -## Completion Criteria - -- The root exposes deliberate, root-owned consumer contracts and explicit - adapters without leaking internal types or promoted implementation methods. -- Internal assembly and repositories own the relocated implementation, with - one production path and no parallel legacy engine. -- Specialized internal components retain clear ownership and do not import - the public facade. -- Public API comparison and behavioral tests establish compatibility, - including ownership, errors, option timing, and prepared execution. -- Boundary checks protect accidental API exposure without preventing ordinary - internal refactoring or consumer extension. -- Required validation passes, documentation matches the implemented state, - and consumers require no migration for this refactor. - -## Non-Goals - -- Public API expansion, removal, or redesign. -- Changes to provider behavior, formats, defaults, or execution semantics. -- Replacing the existing specialized packages with one large engine package. -- A dependency on ConfigKit or a reusable facade-generation framework. -- A minimum root-package line count, exhaustive wrapper tests, or a blanket - prohibition on private boundary logic in the root. -- Implementing the separate profile-policy roadmap during this refactor. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md deleted file mode 100644 index fec614e..0000000 --- a/docs/roadmap/remediation.md +++ /dev/null @@ -1,86 +0,0 @@ -# Public Facade Review Remediation - -## Scope - -Review of implementation commits after baseline `7a858c2` through `06251e3`, -against the [feature roadmap](public-facade.md) and -[implementation plan](implementation.md). - -The production ownership split is in place. No production behavior regression -or public API change was identified in the reviewed diff. One required -architecture-test gap was identified and has now been addressed; it did not -establish an existing public type leak in Promptkit. - -## Finding 1: Complete Reachable Public Type Inspection (P2) - -Status: addressed. - -Location: [public boundary checker](../../public_boundary_test.go), -`publicSurfaceViolations`, in its named/alias and method-set traversal. - -The original checker inspected method sets only for exported package-scope type -names. It did not inspect methods on an unexported root type reached through an -exported function or field. Such methods are still callable by consumers. It -also walked generic parameter constraints but not instantiated type arguments; -an internal argument can escape without appearing in the underlying fields. - -Both examples below were type-checked through the existing fixture helper and -incorrectly produced zero violations: - -```go -// Example 1: a caller can invoke New().Leak(). -type result struct{} -func (result) Leak() hidden.Value { return hidden.Value{} } -func New() result { return result{} } -``` - -```go -// Example 2: an internal type appears in an exported result signature even -// though Box has no field using its type parameter. -type Box[T any] struct{} -func New() Box[hidden.Value] { return Box[hidden.Value]{} } -``` - -Here `hidden` is the fixture's own-module internal package. These are separate -fixture packages, not additions to Promptkit's API. Temporary diagnostic tests -confirmed both false negatives and were removed after review. - -### Resolution - -The recursive named-type traversal now checks reachable root types' value and -pointer method sets, using instantiated selections for their signatures. Named -types and aliases have their concrete type arguments inspected before their -underlying representation is considered. The separate package-scope method -loop was removed. Regression fixtures cover returned private types, private -field types with public pointer methods, generic arguments, aliases that erase -their arguments, and allowed public arguments with recursive method signatures. - -### Acceptance Criteria - -Extend the existing recursive traversal rather than adding a second checker: - -- Inspect accessible methods of reachable root named types, including - unexported types, with the existing cycle protection and promoted-method - checks. Cover pointer and value method sets where applicable. -- Inspect concrete generic type arguments on named types and aliases before - losing them through unaliasing or skipping an external named type's internals. - Continue checking constraints. Do not recursively police unrelated dependency - implementation details. -- Add the two reproductions to the compact fixture table and exercise an - allowed public type argument as a control. Preserve acceptance of private - internal fields and sealed options. Avoid duplicated method traversal. - -Acceptance: both examples are rejected, legitimate private state still passes, -and the full maintainer workflow succeeds. No production API changes are needed. - -## Review Validation - -The existing full maintainer workflow passed: ordinary and race tests, vet, -build, both offline examples, formatting, Markdown links, and repository -hygiene. The targeted diagnostic tests failed as expected, demonstrating the -checker gap rather than a runtime failure. No production or permanent test -files were changed during this review. - -After remediation, the focused checker tests and full maintainer workflow also -passed. The changes are confined to the architecture test and this review log; -production code and public contracts remain unchanged. diff --git a/go.mod b/go.mod index b48c20a..890c5b2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gitea.maximumdirect.net/eric/promptkit go 1.25.5 require ( - gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.0 + gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.1 gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/v2 v2.20260922.0 github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 06fda89..8106e87 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.0 h1:uxvVFOylxXrzcg0jJLXcRBIj73BGNjvnsRuMoOeoYKw= -gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.0/go.mod h1:a3VBbh9oaGXD6ruxhtwHj+AWW6DY/SSyby1QtMmYSUo= +gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.1 h1:S2/Q/JDE+m8Ca3pDhAjVbfYrdlEhs9blj0STgNopHo0= +gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v2 v2.20260922.1/go.mod h1:a3VBbh9oaGXD6ruxhtwHj+AWW6DY/SSyby1QtMmYSUo= gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/v2 v2.20260922.0 h1:Y0EXc3eh12eKW2NrOviVqdk3oBo6UUjopt1YAa1B3Oc= gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/v2 v2.20260922.0/go.mod h1:mtgD1E0SGm0e/I8Ffhz+AYX7GN7RKUWJXehNFIKHs4Y= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= diff --git a/profile_inheritance_contract_test.go b/profile_inheritance_contract_test.go index 7417506..6191953 100644 --- a/profile_inheritance_contract_test.go +++ b/profile_inheritance_contract_test.go @@ -18,7 +18,7 @@ func TestProfileInheritanceBuiltInAliasWorkflow(t *testing.T) { SchemaDir: frameworkSchemaDir, }, promptkit.WithProfiles(promptkit.Profile{ ID: "weather-light", - BaseProfileID: "deepseek-4-flash", + BaseProfileID: "promptkit-openrouter-standard", ReasoningEffort: "high", TimeoutSeconds: 120, })) @@ -26,7 +26,7 @@ func TestProfileInheritanceBuiltInAliasWorkflow(t *testing.T) { t.Fatalf("construct alias engine: %v", err) } - base, err := engine.InspectProfile(context.Background(), "deepseek-4-flash") + base, err := engine.InspectProfile(context.Background(), "promptkit-openrouter-standard") if err != nil { t.Fatalf("inspect base: %v", err) } @@ -84,7 +84,7 @@ func TestProfileInheritanceYAMLAliasOfBuiltIn(t *testing.T) { engine, err := promptkit.NewEngine(promptkit.Config{}, promptkit.WithPromptFS(fstest.MapFS{}, "."), promptkit.WithProfileFS(fstest.MapFS{ - "alias.yaml": &fstest.MapFile{Data: []byte("id: yaml-alias\nbase_profile: deepseek-4-flash\n")}, + "alias.yaml": &fstest.MapFile{Data: []byte("id: yaml-alias\nbase_profile: promptkit-openrouter-standard\n")}, }, "."), ) if err != nil {