textmachine/backend/internal/config/lowereffort_shipping_test.go

58 lines
3.1 KiB
Go

package config
import (
"path/filepath"
"testing"
)
// lowereffort_shipping_test.go pins the OTHER half of the same data decision its neighbour pins: every
// shipping pipeline leaves `retries.lower_effort_on_empty` OFF.
//
// WHY A TEST AND NOT THE GO DEFAULT. The Go zero value is already false, and that is exactly why the
// files need a gate: turning the remedy on is a one-word edit to a YAML that nothing would notice. The
// report of the pack that built it says «the landing is inert»; without this test that sentence is a
// promise, not a property — and the sibling's doc comment states the rule in as many words: an un-pinned
// data decision is one a later config edit reverts silently, on the money path, without anything going
// red.
//
// WHAT THE OFF STATE IS PROTECTING, in numbers rather than caution:
//
// - The one stage the knob can actually move is the EDITOR. The draft already rides `low`, the lowest
// emitting step, so ReducedEffort returns no step for it; the editor rides the vendor default and
// steps to `low`.
// - The editor role's echo safety at `low` on dense CJK is NOT MEASURED. The published echo numbers
// are the TRANSLATOR's (00-provider-quirks: one raw-Chinese output in sixteen on flash; zero in five
// on deepseek-v4-pro through escalation hops), and the quirks doc names the gap itself and requires
// an echo control in the editor role before the step. Backlog row 433 carries the condition.
// - Flipping it mid-book is not free either: effort and max_tokens are both in the request hash, so
// every unit that already holds a stored regeneration buys one more call. Measured across this
// machine: 58 such units on 24 books.
//
// Mutation this catches: set the key true in any shipping pipeline → RED, naming the file.
func TestShippingPipelinesDoNotLowerEffortOnEmpty(t *testing.T) {
m, err := LoadModels(filepath.Join("..", "..", "configs", "models.yaml"))
if err != nil {
t.Fatalf("load the shipping models.yaml: %v", err)
}
// The same four files the sibling gate walks, and for the same reason: an arm exists to isolate the
// EDITOR, so a retry policy that differed between an arm and its baseline would put a second
// variable into the comparison the arm is for.
for _, pf := range []string{
"pipeline-c1.yaml", "pipeline-c2.yaml",
"pipeline-arm-glm.yaml", "pipeline-arm-mistral.yaml",
} {
p, err := LoadPipeline(filepath.Join("..", "..", "configs", pf), m, "zh-ru", nil)
if err != nil {
t.Fatalf("load %s: %v", pf, err)
}
if p.Retries.LowerEffortOnEmpty {
t.Errorf("%s: retries.lower_effort_on_empty is ON. The remedy is built and deliberately "+
"INERT: the only stage it moves is the editor, whose echo safety at a lowered effort on "+
"dense CJK has never been measured (the published numbers are the translator's), and "+
"flipping it mid-book re-buys one call per unit that already holds a regeneration — 58 "+
"units on 24 books when that was last counted. Turning it on is a decision backlog row "+
"433 carries, and it needs the editor-role echo control the quirks doc asks for, not a "+
"config edit", pf)
}
}
}