Plan the built-in Rakestrawhome backend

This commit is contained in:
2026-08-23 17:00:01 +00:00
parent 4ca3be2c14
commit d783b687a5
2 changed files with 436 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
# Rakestrawhome Built-In Backend Implementation Plan
## Purpose
Implement the target state defined in the
[Rakestrawhome built-in backend roadmap](rakestrawhome-backend.md): make the
maintainer's OpenAI-compatible inference service a reserved built-in backend,
publish its first built-in model profile, and document the resulting consumer
surface.
This is an execution plan, not an additional source of feature policy. When a
detail in this plan requires interpretation, preserve the decisions and scope
boundaries in the feature roadmap and the ownership rules under
[`docs/policy/`](../policy/).
## Fixed Decisions
- The internal and wire-facing backend ID is `rakestrawhome`; its exported root
constant is `BackendRakestrawHome`.
- Its base endpoint is `https://inference.ai.rakestrawhome.com/v1`. The existing
OpenAI-compatible client composes the final request URL as
`https://inference.ai.rakestrawhome.com/v1/chat/completions`.
- Its API-key environment variable is
`RAKESTRAWHOME_INFERENCE_API_KEY`.
- Each engine permits four active generation calls for this backend. The
existing default bounded waiting capacity of 1024 applies.
- The embedded profile ID is `rakestrawhome-gemma-4-31b`, its backend is
`rakestrawhome`, and its model is `google/gemma-4-31b-it`.
- The new profile contains no optional generation settings. The existing
OpenRouter `gemma-4-31b` profile remains unchanged.
- Built-in registration is inert: engine construction does not read a
credential or contact the service. Existing selection-time credential,
endpoint-override, profile-precedence, and error behavior remains in force.
- Consumer backend additions cannot replace either built-in ID. Consumer
profile sources may continue to override an embedded profile by profile ID.
- Verification is deterministic and offline. Do not add a live service test,
provider-specific client, duplicate concurrency stress matrix, or duplicate
endpoint-composition matrix.
## Execution Rules
- Implement the stages in numerical order. Treat each stage as one bounded
coding-agent prompt, and complete its focused and regression verification
before beginning the next stage.
- At the start of each stage, review the feature roadmap and the policy files
relevant to that stage. Follow the task-specific reading guide in
[`docs/development.md`](../development.md).
- Preserve unrelated working-tree changes. Do not commit, tag, push, or modify
release documentation unless a separate instruction authorizes it.
- Keep tests at their narrowest owner. Extend existing tests where they already
own the contract instead of creating parallel test matrices.
- Update current-state documentation only in Stage 3, after the implemented
behavior exists.
## Stage 1: Generalize Built-In Backend Registration
### Objective
Add the exact Rakestrawhome definition to the immutable backend registry and
expose its reserved ID through the public facade without changing the generic
backend, capacity, or client mechanisms.
### Implementation
1. In `internal/backend/registry.go`, add the stable exported internal ID
`RakestrawHomeID = "rakestrawhome"` and private constants for:
- endpoint `https://inference.ai.rakestrawhome.com/v1`;
- API-key environment variable `RAKESTRAWHOME_INFERENCE_API_KEY`; and
- concurrency limit `4`.
2. Replace the inline OpenRouter construction in `NewRegistry` with a private
`builtInBackends() []domain.Backend` factory that returns fresh definitions
for OpenRouter and Rakestrawhome on every call. Do not use a mutable package-
level slice or map. The Rakestrawhome definition must leave
`QueueCapacitySet` false so the existing normalization path assigns the
shared default queue capacity of 1024.
3. Have `NewRegistry` allocate from `len(builtIns) + len(additions)`, process
built-ins before consumer additions, and pass every definition through the
existing `normalizeBackend` and duplicate-ID logic. Preserve defensive-copy
behavior and all validation and error contracts.
4. In the root `backends.go`, expose
`BackendRakestrawHome = backend.RakestrawHomeID`. Update the `Backend` and
`WithBackend` GoDoc so their reservation language applies to all built-ins,
not only OpenRouter. Do not expose endpoint, credential, or capacity
constants in the root package.
5. Make no changes to `NewEngine`, the capacity manager, or the OpenAI-
compatible client. They must consume the new definition through their
existing registry and policy interfaces.
### Tests
1. In `internal/backend/registry_test.go`, generalize the exact built-in test
to assert both definitions. For Rakestrawhome, assert the exact ID, base
endpoint, API-key environment-variable name, concurrency limit `4`,
normalized queue capacity `1024`, `QueueCapacitySet == true`, and absence of
extra parameters. Preserve the corresponding exact OpenRouter assertions.
2. Assert that `CapacityPolicies` contains exactly both built-in policies in a
registry with no additions, including the exact concurrency and queue
values. Retain lookup-isolation coverage rather than exposing registry-
owned data to mutation.
3. Update addition-related expected counts to include two built-ins. Ensure the
custom-addition mutation test still proves registry isolation and does not
accidentally replace either built-in.
4. Table-drive the existing built-in collision coverage over whitespace-
normalized `openrouter` and `rakestrawhome` additions. Each must return the
existing duplicate-ID configuration error.
5. At the root public-contract owner, extend the existing reserved-backend
registration test to cover both `BackendOpenRouter` and
`BackendRakestrawHome`. Do not duplicate the internal registry's full
validation matrix.
### Verification
Run the focused backend and root tests first, then the ordinary regression
suite:
```sh
go test ./internal/backend
go test .
go test ./...
```
The stage is complete when both exact built-ins are published through the same
immutable registry path, both IDs are reserved, and existing custom-backend and
OpenRouter behavior remains green.
## Stage 2: Add the Built-In Profile and Prove Assembly
### Objective
Embed the minimal Gemma profile, generalize built-in catalog assumptions from
one backend to the maintained built-in set, and prove ordinary engine assembly
without adding provider-specific execution logic.
### Implementation
1. Add `internal/profile/builtin/assets/google/rakestrawhome-gemma-4-31b.yml`
with exactly these semantic fields and no optional settings:
```yaml
id: rakestrawhome-gemma-4-31b
backend: rakestrawhome
model: google/gemma-4-31b-it
```
Keep the asset under `google` because the existing directory hierarchy
groups profiles by model provider; the profile ID and `backend` field carry
the inference-backend distinction.
2. Do not change the embedded repository implementation: its existing recursive
`assets/**/*.yml` pattern must discover the new asset. Do not alter
`internal/profile/builtin/assets/google/gemma-4-31b.yml`.
3. In the built-in repository tests, replace the assumption that every asset
selects OpenRouter with an explicit allowed built-in set containing
`backend.OpenRouterID` and `backend.RakestrawHomeID`. Continue to reject a
blank or duplicate profile ID, an unapproved backend ID, raw `api_key`,
`endpoint`, or `api_key_env` fields, and any asset that fails ordinary
repository parsing and validation.
4. Add a focused assertion that loading `rakestrawhome-gemma-4-31b` returns the
exact backend and model and leaves every optional generation setting,
timeout, service tier, endpoint, credential field, and extra-parameter map
absent or at its zero value. This protects the deliberate native-default
policy rather than merely proving that the YAML parses.
5. Generalize the existing root test that prepares a built-in profile without
a profile directory into a small table covering its current OpenRouter case
and the new Rakestrawhome case. Supply a synthetic credential with
`t.Setenv`; call preparation only; and assert the selected profile ID,
backend ID, base endpoint, credential environment-variable name, and model.
Capacity policy has no public inspection seam and is intentionally covered
by the registry and existing generic capacity-contract owners instead.
### Test Boundaries
- Rely on the registry test for the literal Rakestrawhome capacity values and
on the existing generic capacity-contract tests for semaphore and queue
behavior. Do not add another four-way goroutine test.
- Rely on the exact registered base endpoint plus the existing generic client
endpoint-composition test. Do not make a live request or add a second copy of
the transport matrix.
- Preserve existing profile-source precedence tests. The new asset uses the
same repository and resolution path, so do not duplicate the complete
precedence matrix.
### Verification
Run the focused catalog and root tests, then the ordinary regression suite:
```sh
go test ./internal/profile/builtin
go test .
go test ./...
```
The stage is complete when the new ID resolves through the embedded catalog and
ordinary engine assembly, contains no unintended request defaults, and does
not alter the existing OpenRouter Gemma profile.
## Stage 3: Update Canonical Documentation and Complete Validation
### Objective
Bring each canonical documentation owner into line with the implemented public
and internal state, give manual registrants an explicit migration path, and
run the complete maintainer workflow.
### Documentation
1. Update `docs/policy/architecture.md` and `docs/internal/overview.md` so the
backend registry is described as owning multiple maintained built-ins rather
than a single inline OpenRouter definition. Keep architectural policy at the
ownership level; do not turn it into a catalog of duplicated literal values.
2. Update `docs/internal/sources.md` to remove the assertion that every
built-in profile selects OpenRouter. Explain that embedded profiles inherit
connection and credential metadata from whichever maintained built-in
backend they select.
3. Update `docs/formats.md` as the canonical owner of backend definitions and
the embedded profile catalog:
- list OpenRouter and Rakestrawhome with their exact stable IDs, endpoints,
API-key environment variables, concurrency limits, and default queue
capacity;
- add a `Backend` column to the built-in profile table so a mixed-backend
catalog is unambiguous; and
- add `rakestrawhome-gemma-4-31b` with backend `rakestrawhome` and model
`google/gemma-4-31b-it`, while preserving every existing catalog row.
4. Update `docs/consumers/pkg-promptkit.md` with the shortest supported use of
the built-in profile and `BackendRakestrawHome`. State that consumers set
`RAKESTRAWHOME_INFERENCE_API_KEY`, do not register the built-in manually,
and must remove an existing `WithBackend` registration under the exact
`rakestrawhome` ID to avoid the intentional duplicate-ID error. Preserve the
documented direct credential and runtime endpoint overrides.
5. Ensure root GoDoc added in Stage 1 documents the exported constant and the
plural built-in reservation rule. Leave
`docs/integrations/openai-compatible-chat.md` as the canonical owner of
generic endpoint composition and wire behavior; change it only if it
contains an inaccurate single-built-in statement. Do not duplicate its
transport details in consumer guidance.
6. Do not add release notes in this feature pass. Release documentation and
tagging are separate maintainer actions.
### Final Verification
Run the complete offline workflow in
[`docs/development.md#maintainer-validation`](../development.md#maintainer-validation),
including:
```sh
go test ./...
go test -race ./...
go vet ./...
go build ./...
go run ./examples/go-library/prepare
go run ./examples/go-library/run
```
Also perform the documented Go-formatting, local Markdown-link, and repository-
hygiene checks. Review the examples' deterministic output as instructed. No
command may require a real Rakestrawhome credential or contact either provider.
Finally, inspect the diff against the feature roadmap and confirm all of the
following:
- only the new public constant and embedded profile ID enlarge the consumer
surface;
- OpenRouter's definition and existing `gemma-4-31b` profile are unchanged;
- both built-in backend IDs are reserved and consumer-added IDs remain
extensible;
- no API key value, mutable global registry, provider-specific transport, live
test, or hidden generation default was introduced; and
- current-state documentation and GoDoc agree with the implemented behavior.
## Open Questions
None. The feature roadmap and this plan fix every implementation-relevant
choice required for the three stages.

View File

@@ -0,0 +1,164 @@
# Rakestrawhome Built-In Inference Backend
## Purpose
Promptkit should provide the maintainer's Rakestrawhome inference service as a
second built-in OpenAI-compatible backend, alongside OpenRouter. This removes
the repeated backend and profile registration currently required in every
downstream application that uses the service.
The feature is intentionally a built-in registration rather than another
convenience constructor. Engines should receive the same immutable backend
definition, credential convention, concurrency policy, and initial model
profile without consumer assembly code.
## Target End State
Every newly constructed engine contains two reserved built-in backend IDs:
- `openrouter`, with its existing definition and behavior unchanged; and
- `rakestrawhome`, configured with the OpenAI-compatible base endpoint
`https://inference.ai.rakestrawhome.com/v1`, API-key environment variable
`RAKESTRAWHOME_INFERENCE_API_KEY`, and a concurrency limit of four active
model-generation calls per engine.
The Rakestrawhome backend uses Promptkit's existing default bounded waiting
capacity of 1024. The capacity manager therefore permits no more than four
simultaneous generation calls for this backend while retaining the existing
high, bounded backlog policy. Ordinary backend, profile, runtime endpoint,
credential, and request-setting precedence remains unchanged.
Promptkit also embeds this profile:
```yaml
id: rakestrawhome-gemma-4-31b
backend: rakestrawhome
model: google/gemma-4-31b-it
```
The profile deliberately omits optional generation controls so the inference
service and model apply their native defaults. It does not repeat the backend
endpoint or credential environment-variable name. The existing
`gemma-4-31b` OpenRouter profile and its current model spelling and settings
remain unchanged.
Consumers can select `rakestrawhome-gemma-4-31b` anywhere an ordinary profile
ID is accepted. Higher-precedence in-memory, configured, or application
fallback profile sources may continue to replace the embedded profile by ID.
Consumers can refer to the built-in backend through a new exported constant,
`BackendRakestrawHome`, while the exact backend definition remains internal.
## Backend Registry End State
Built-in registry construction owns a small maintained collection rather than
an inline OpenRouter special case. Both built-ins enter the same normalization,
validation, immutable storage, defensive-copy, and capacity-policy paths.
The internal backend package owns stable IDs and connection and capacity
policy. The root facade exposes only the stable Rakestrawhome ID through
`BackendRakestrawHome`. Public uniqueness and reservation rules apply equally
to every built-in.
Consumer additions must remain unable to replace either reserved built-in ID.
Registrations under all other valid IDs retain their current behavior. Engine
construction must not contact the Rakestrawhome endpoint, read the API-key
environment variable, or require credentials merely because the backend is
registered. Credential resolution occurs only when a selected execution target
uses it, under the existing precedence and error contracts.
The built-in OpenAI-compatible client will append `chat/completions` to the
registered base path, producing
`https://inference.ai.rakestrawhome.com/v1/chat/completions`. No provider-
specific transport implementation is required.
## Built-In Profile Catalog End State
The Rakestrawhome Gemma profile is an embedded YAML asset in the existing
built-in profile repository. No additional repository layer or provider-
specific profile loader exists.
Catalog validation permits the maintained built-in backend IDs and establishes
that:
- every embedded profile has a unique, nonblank ID;
- every embedded profile selects an approved built-in backend;
- no embedded profile contains a raw API key or repeats an endpoint or API-key
environment-variable name owned by its backend; and
- the new profile resolves to the exact intended backend and model through the
ordinary repository and engine assembly.
Retain the existing source precedence: consumer profile sources may override
the new built-in profile, but a malformed authoritative override remains an
error rather than silently falling through.
## Public Compatibility And Migration
This feature adds one public constant and one embedded profile ID. It does not
remove or change an existing public declaration or profile.
The backend ID `rakestrawhome` becomes reserved. A downstream application that
currently registers that ID manually must remove its `WithBackend`
registration when adopting this feature; otherwise construction will correctly
report a duplicate built-in ID. It may also remove any equivalent manually
supplied profile and select `rakestrawhome-gemma-4-31b` directly. A consumer
profile with the same profile ID remains a supported higher-precedence
override rather than a registry collision.
Direct API-key and runtime endpoint overrides continue to work. Promptkit must
never embed, inspect, log, or document an actual credential value; only the
environment-variable name belongs in the built-in definition.
## Documentation End State
Canonical current-state documentation:
- describes the backend registry as containing multiple built-ins in the
architecture policy and internal component overview;
- describes both built-in backend definitions and the mixed-backend profile
catalog in the framework format reference and internal source overview;
- lists `rakestrawhome-gemma-4-31b` in the built-in profile catalog;
- documents `BackendRakestrawHome`, the removal of redundant downstream
registration, the credential variable, and the four-call concurrency policy
in public GoDoc and consumer guidance; and
- retains the OpenAI-compatible integration document as the canonical owner of
endpoint composition and outbound wire behavior.
## Acceptance Criteria
The completed feature is protected at the narrowest stable owners:
- registry tests should cover both exact built-in definitions, default queue
normalization, capacity-policy publication, lookup ownership, and duplicate
rejection for both reserved IDs;
- built-in profile tests should validate the generalized catalog invariants and
exact Rakestrawhome profile;
- a representative root integration test proves that selecting the new
profile resolves the expected backend ID, endpoint, model, and credential
environment-variable name without making a live network request or
requiring a real credential;
- the registry's exact capacity-policy tests and the existing generic engine
capacity tests together protect the engine-local four-call limit without a
duplicate provider-specific concurrency matrix; and
- existing OpenRouter, custom-backend, profile-precedence, endpoint-override,
credential, capacity, and injected-client tests should remain green without
duplicating their full behavioral matrices for the new built-in.
## Non-Goals
This feature does not add:
- provider discovery, health checking, model enumeration, or live integration
tests;
- automatic fallback, retry, or routing between OpenRouter and Rakestrawhome;
- global mutable registry state or consumer replacement of built-in IDs;
- a second model-client protocol or non-OpenAI-compatible transport;
- provider-specific generation defaults that have not been deliberately
selected; or
- any embedded API-key value.
## Open Questions
None. The backend ID, public constant direction, endpoint base path,
credential environment-variable name, concurrency and queue policy, profile
ID, model name, optional-setting policy, compatibility behavior, and scope
boundaries are fixed by this roadmap.