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) t.Fatal(err)
} }
for _, id := range []string{"proposal", "validation"} { 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 { if err := os.WriteFile(filepath.Join(dir, "profiles", id+".yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@@ -1,7 +1,7 @@
# Implementation Plan: PromptKit v0.12.0 Adoption # Implementation Plan: PromptKit v0.12.0 Adoption
**Last updated:** 2026-10-03 **Last updated:** 2026-10-03
**Status:** In progress; Stage 1 completed. **Status:** In progress; Stages 1–2 completed.
**Audience:** Luna coding agent. **Audience:** Luna coding agent.
## Scope and Execution ## 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. Go test files. These formats become consumable in Stage 3. Commit this unit.
Current documentation links and recipes are updated together in Stage 8. 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 ## Stage 3 — Adopt the Released Source API and Selected-Role Checks
**Primary files:** `go.mod`, `go.sum`, **Primary files:** `go.mod`, `go.sum`,

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
version: 2 version: 2
profiles_dir: profiles/service
backends: backends:
service: service:
endpoint: https://openrouter.ai/api/v1 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) t.Fatal(err)
} }
for _, name := range []string{"proposal", "validation"} { 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 { if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -175,7 +175,7 @@ func TestDistinctBackendsHaveIndependentCapacity(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
for name, backend := range map[string]string{"proposal": "first", "validation": "second"} { 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) 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) 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, "") dir := profileLayout(t, base, "")
main := filepath.Join(dir, "config.yml") 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 { if err := os.WriteFile(filepath.Join(dir, "profiles", "base.yaml"), []byte(profile), 0600); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -301,7 +301,7 @@ func TestPreparedAdapterRejectsTargetDriftAndPreparationErrors(t *testing.T) {
t.Fatalf("preparation failure dispatched: %v, %d", err, count.Load()) t.Fatalf("preparation failure dispatched: %v, %d", err, count.Load())
} }
// PrepareExecution reloads the profile, so a changed target must be blocked. // 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) t.Fatal(err)
} }
req = adapterRequest(responseschema.CorrectionSetKey) 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{ 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", "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": "id: testing\nbackend: offline\nmodel: economy-model\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 { if err := os.WriteFile(filepath.Join(dir, "profiles", name+".yaml"), []byte(content), 0600); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -188,9 +188,9 @@ func TestProfileAssemblyRejectsUnsafeSelections(t *testing.T) {
dir := profileLayout(t, profileBase, "") dir := profileLayout(t, profileBase, "")
main := filepath.Join(dir, "config.yml") main := filepath.Join(dir, "config.yml")
for _, tc := range []struct{ name, profile string }{ for _, tc := range []struct{ name, profile string }{
{"endpoint only", "id: custom\nendpoint: https://offline.invalid/v1\nmodel: model\n"}, {"endpoint only", "profiles:\n custom:\n endpoint: https://offline.invalid/v1\n model: model\n"},
{"mismatched endpoint", "id: custom\nbackend: offline\nendpoint: https://elsewhere.invalid/v1\nmodel: model\n"}, {"mismatched endpoint", "profiles:\n custom:\n backend: offline\n endpoint: https://elsewhere.invalid/v1\n model: model\n"},
{"profile credential", "id: custom\nbackend: offline\nmodel: model\napi_key_env: OTHER_KEY\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) { t.Run(tc.name, func(t *testing.T) {
if err := os.WriteFile(filepath.Join(dir, "profiles", "custom.yaml"), []byte(tc.profile), 0600); err != nil { 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 { if err := os.WriteFile(main, []byte(content), 0600); err != nil {
t.Fatal(err) 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) t.Fatal(err)
} }
loaded, err := config.Load(ck.File(main), "") 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 { if err := os.WriteFile(main, []byte(body), 0600); err != nil {
t.Fatal(err) 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) t.Fatal(err)
} }
loaded, err := config.Load(ck.File(main), "") 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 { if err := os.WriteFile(main, []byte(content), 0600); err != nil {
t.Fatal(err) 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) t.Fatal(err)
} }
loaded, err := config.Load(ck.File(main), "") loaded, err := config.Load(ck.File(main), "")