Migrate profile fixtures to keyed documents

This commit is contained in:
2026-10-04 00:23:04 +00:00
parent b1b0fc7455
commit 43a68e97ee
23 changed files with 71 additions and 56 deletions

View File

@@ -237,7 +237,7 @@ func newProcessFixture(t *testing.T, mode, modules string) processFixture {
t.Fatal(err)
}
for _, id := range []string{"proposal", "validation"} {
profile := fmt.Sprintf("id: %s\nbackend: local\nmodel: local\ntimeout_seconds: 5\n", id)
profile := fmt.Sprintf("profiles:\n %s:\n backend: local\n model: local\n timeout_seconds: 5\n", id)
if err := os.WriteFile(filepath.Join(dir, "profiles", id+".yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err)
}

View File

@@ -1,7 +1,7 @@
# Implementation Plan: PromptKit v0.12.0 Adoption
**Last updated:** 2026-10-03
**Status:** In progress; Stage 1 completed.
**Status:** In progress; Stages 1–2 completed.
**Audience:** Luna coding agent.
## Scope and Execution
@@ -148,6 +148,12 @@ selections, and changed fixture text; run `git diff --check` and format touched
Go test files. These formats become consumable in Stage 3. Commit this unit.
Current documentation links and recipes are updated together in Stage 8.
**Completion marker:** Stage 2 complete. Six maintained profile documents are
keyed and split into separately selected local/service roots; the listed Go
fixtures use keyed definitions. Touched Go files were formatted and
`git diff --check` passed. Runtime tests are deferred until Stage 3 replaces
the current consumer, as the plan allows intermediate commits not to run.
## Stage 3 — Adopt the Released Source API and Selected-Role Checks
**Primary files:** `go.mod`, `go.sum`,

View File

@@ -1,4 +1,5 @@
version: 2
profiles_dir: profiles/local
backends:
local-base:
endpoint: http://127.0.0.1:11434/v1

View File

@@ -1,4 +1,5 @@
version: 2
profiles_dir: profiles/local
backends:
local:
endpoint: http://127.0.0.1:11434/v1

View File

@@ -1,4 +1,5 @@
version: 2
profiles_dir: profiles/service
backends:
service:
endpoint: https://openrouter.ai/api/v1

View File

@@ -1,7 +0,0 @@
id: local-proposal
backend: local
model: replace-with-local-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -1,7 +0,0 @@
id: local-validation
backend: local
model: replace-with-local-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
local-proposal:
backend: local
model: replace-with-local-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
local-validation:
backend: local
model: replace-with-local-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -1,7 +0,0 @@
id: service-proposal-testing
backend: service
model: replace-with-testing-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -1,7 +0,0 @@
id: service-proposal
backend: service
model: replace-with-provider-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -1,7 +0,0 @@
id: service-validation-testing
backend: service
model: replace-with-testing-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -1,7 +0,0 @@
id: service-validation
backend: service
model: replace-with-provider-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
service-proposal-testing:
backend: service
model: replace-with-testing-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
service-proposal:
backend: service
model: replace-with-provider-model
temperature: 0
max_tokens: 2048
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
service-validation-testing:
backend: service
model: replace-with-testing-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -0,0 +1,8 @@
profiles:
service-validation:
backend: service
model: replace-with-provider-model
temperature: 0
max_tokens: 1024
top_p: 1
timeout_seconds: 120

View File

@@ -46,7 +46,7 @@ func TestRolesShareBackendCapacityAndReleaseAfterCancellation(t *testing.T) {
t.Fatal(err)
}
for _, name := range []string{"proposal", "validation"} {
profile := "id: " + name + "\nbackend: shared\nmodel: local\n"
profile := "profiles:\n " + name + ":\n backend: shared\n model: local\n"
if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err)
}
@@ -175,7 +175,7 @@ func TestDistinctBackendsHaveIndependentCapacity(t *testing.T) {
t.Fatal(err)
}
for name, backend := range map[string]string{"proposal": "first", "validation": "second"} {
if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte("id: "+name+"\nbackend: "+backend+"\nmodel: local\n"), 0600); err != nil {
if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte("profiles:\n "+name+":\n backend: "+backend+"\n model: local\n"), 0600); err != nil {
t.Fatal(err)
}
}

View File

@@ -68,7 +68,7 @@ func adapterFixture(t *testing.T, replies []reply, retries, repairs int, hook fu
base := fmt.Sprintf("version: 2\nbackends:\n offline:\n endpoint: %s/v1\n credential: ADAPTER_KEY\nllm:\n proposal_profile: base\n transient_retries: %d\n repair_attempts: %d\n", server.URL, retries, repairs)
dir := profileLayout(t, base, "")
main := filepath.Join(dir, "config.yml")
profile := "id: base\nbackend: offline\nmodel: full-model\n"
profile := "profiles:\n base:\n backend: offline\n model: full-model\n"
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err)
}
@@ -301,7 +301,7 @@ func TestPreparedAdapterRejectsTargetDriftAndPreparationErrors(t *testing.T) {
t.Fatalf("preparation failure dispatched: %v, %d", err, count.Load())
}
// PrepareExecution reloads the profile, so a changed target must be blocked.
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("id: base\nbackend: offline\nendpoint: http://127.0.0.1:1/v1\nmodel: full-model\n"), 0600); err != nil {
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("profiles:\n base:\n backend: offline\n endpoint: http://127.0.0.1:1/v1\n model: full-model\n"), 0600); err != nil {
t.Fatal(err)
}
req = adapterRequest(responseschema.CorrectionSetKey)

View File

@@ -30,8 +30,8 @@ func profileLayout(t *testing.T, base, overlay string) string {
}
}
for name, content := range map[string]string{
"base": "id: base\nbackend: offline\nmodel: full-model\ntemperature: 0.3\nmax_tokens: 500\ntop_p: 0.8\ntimeout_seconds: 12\nservice_tier: priority\nreasoning_effort: medium\n",
"testing": "id: testing\nbackend: offline\nmodel: economy-model\n",
"base": "profiles:\n base:\n backend: offline\n model: full-model\n temperature: 0.3\n max_tokens: 500\n top_p: 0.8\n timeout_seconds: 12\n service_tier: priority\n reasoning_effort: medium\n",
"testing": "profiles:\n testing:\n backend: offline\n model: economy-model\n",
} {
if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte(content), 0600); err != nil {
t.Fatal(err)
@@ -188,9 +188,9 @@ func TestProfileAssemblyRejectsUnsafeSelections(t *testing.T) {
dir := profileLayout(t, profileBase, "")
main := filepath.Join(dir, "config.yml")
for _, tc := range []struct{ name, profile string }{
{"endpoint only", "id: custom\nendpoint: https://offline.invalid/v1\nmodel: model\n"},
{"mismatched endpoint", "id: custom\nbackend: offline\nendpoint: https://elsewhere.invalid/v1\nmodel: model\n"},
{"profile credential", "id: custom\nbackend: offline\nmodel: model\napi_key_env: OTHER_KEY\n"},
{"endpoint only", "profiles:\n custom:\n endpoint: https://offline.invalid/v1\n model: model\n"},
{"mismatched endpoint", "profiles:\n custom:\n backend: offline\n endpoint: https://elsewhere.invalid/v1\n model: model\n"},
{"profile credential", "profiles:\n custom:\n backend: offline\n model: model\n api_key_env: OTHER_KEY\n"},
} {
t.Run(tc.name, func(t *testing.T) {
if err := os.WriteFile(filepath.Join(dir, "profiles", "custom.yaml"), []byte(tc.profile), 0600); err != nil {

View File

@@ -41,7 +41,7 @@ func TestRepairedProposalStillFacesDomainChecks(t *testing.T) {
if err := os.WriteFile(main, []byte(content), 0600); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("id: base\nbackend: offline\nmodel: local-model\n"), 0600); err != nil {
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("profiles:\n base:\n backend: offline\n model: local-model\n"), 0600); err != nil {
t.Fatal(err)
}
loaded, err := config.Load(ck.File(main), "")

View File

@@ -55,7 +55,7 @@ func TestValidatorFailureCancelsActiveAndPendingProviderWork(t *testing.T) {
if err := os.WriteFile(main, []byte(body), 0600); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "profiles/base.yaml"), []byte("id: base\nbackend: shared\nmodel: local\ntimeout_seconds: 30\n"), 0600); err != nil {
if err := os.WriteFile(filepath.Join(dir, "profiles/base.yaml"), []byte("profiles:\n base:\n backend: shared\n model: local\n timeout_seconds: 30\n"), 0600); err != nil {
t.Fatal(err)
}
loaded, err := config.Load(ck.File(main), "")

View File

@@ -55,7 +55,7 @@ func TestValidationRepairAndRuntimeFailuresThroughDomainBoundary(t *testing.T) {
if err := os.WriteFile(main, []byte(content), 0600); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("id: base\nbackend: offline\nmodel: local-model\n"), 0600); err != nil {
if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte("profiles:\n base:\n backend: offline\n model: local-model\n"), 0600); err != nil {
t.Fatal(err)
}
loaded, err := config.Load(ck.File(main), "")