engine: realistic config bounds, enforced and served

ConfigBounds (students 10-500, edgesPerNode 1-8, forwardProb 0-0.9,
triangleProb 0-1) caps what RunScenario accepts: a student does not
keep 150 close friendships and a guaranteed forward is not a real
base rate. numEducated gains its missing upper limit (numStudents).
Bounds-side validation also protects the public server from absurd
numStudents values. GET /api/config/default now returns
{config, bounds} so the frontend can drive its controls from the
same numbers; the frontend does not call it yet, so this commit
changes no UI behaviour.
This commit is contained in:
Justin Visser 2026-06-11 15:54:07 +02:00
parent 232faf892e
commit bd890384e5
7 changed files with 194 additions and 15 deletions

View file

@ -51,12 +51,15 @@ func TestDefaultConfigEndpoint(t *testing.T) {
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
}
var config engine.Config
if err := json.Unmarshal(recorder.Body.Bytes(), &config); err != nil {
var response DefaultConfigResponse
if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil {
t.Fatal(err)
}
if config != engine.DefaultConfig() {
t.Errorf("served config %+v, want %+v", config, engine.DefaultConfig())
if response.Config != engine.DefaultConfig() {
t.Errorf("served config %+v, want %+v", response.Config, engine.DefaultConfig())
}
if response.Bounds != engine.ConfigBounds() {
t.Errorf("served bounds %+v, want %+v", response.Bounds, engine.ConfigBounds())
}
}