docs: spec limit semantics, pricing caveats, manifest hedge

I2 (controller ruling): docs/superpowers/specs/2026-08-19-traefik-llmgateway-design.md
described limits as "user overrides group" / "user limit if set, else
group limit, else unlimited" — stale relative to the actual, already-correct
implementation (buildLimitScopes/checkAndCount evaluate every configured
scope and return the first violation). Amended §2 and §7 to state both
scopes are enforced together and the tighter bound wins.

I4 (manifest hedge): .traefik.yml's groups.default was a bare "{}",
the shape empirically reproduced as a decode failure outside this
repo's own (necessarily simplified) yaegi-check harness. Changed to
"providers: []" — same zero semantics, no longer a bare empty object.
manifest_test.go's JSON mirror and drift-check token updated to match;
make yaegi-check still passes (its YAML-subset parser already handles
an inline "[]" under a nested map key).

M9 (pricing provenance): pricing.go's built-in table comment replaced
"verify before release" with a real source note (each provider's own
published list prices, recorded 2026-08, approximate). README's limits
section gained the matching caveat and points to the "pricing" config
override for billing-grade accuracy.

Doc nits: README's Kubernetes section now says the example manifest
applies cleanly once Traefik's CRDs (Middleware, IngressRoute) are
installed, rather than claiming kubectl apply -f works unconditionally.
README's Security notes section no longer claims "no auth-event logging
at all" (see the paired fix: commit) — it now describes what is logged
and that key material never appears.

This commit and its sibling fix: commit are the final wave closing out
the whole-branch review findings for docs/superpowers/sdd/2026-08-20-
traefik-llmgateway.

Gates: go test ./... -count=1 (-race) green, gofmt -l . empty, go vet
clean, make yaegi-check OK, golangci-lint 0 issues.
This commit is contained in:
2026-08-20 14:59:57 +01:00
parent 4b849fd6c7
commit c9ae14adf7
5 changed files with 32 additions and 19 deletions
+2 -1
View File
@@ -34,6 +34,7 @@ func testDataConfig(t *testing.T) *Config {
"providers", "groups", "users", // top-level testData keys
"openai", "type: openai", "test-key", "gpt-test", // providers.openai
"default", // groups.default and users.inline[0].group
"providers: []", // groups.default.providers — zero-semantic hedge, not bare {}
"tester", // users.inline[0].name
"test-user-key", // users.inline[0].apiKey
}
@@ -50,7 +51,7 @@ func testDataConfig(t *testing.T) *Config {
cfg := CreateConfig()
// mirror of testData, kept in sync by this test living next to the manifest
blob := `{"providers":{"openai":{"type":"openai","apiKey":"test-key","models":["gpt-test"]}},
"groups":{"default":{}},
"groups":{"default":{"providers":[]}},
"users":{"inline":[{"name":"tester","group":"default","apiKey":"test-user-key"}]}}`
if err := json.Unmarshal([]byte(blob), cfg); err != nil {
t.Fatal(err)