feat(aieos): validate OCEAN values in [0.0, 1.0] range

Address review feedback from @nikolasdehor on PR #469.
Out-of-range psychology values would produce unexpected natural
language output, so we now reject them at load time.
This commit is contained in:
Edouard CLAUDE 2026-02-20 07:48:31 +04:00
parent bce31a0149
commit 37c120d219
2 changed files with 65 additions and 0 deletions

View file

@ -47,5 +47,27 @@ func validate(p *Profile) error {
if p.Identity.Name == "" {
return fmt.Errorf("aieos: identity.name is required")
}
if p.Psychology != nil {
if err := validateOCEAN(p.Psychology); err != nil {
return err
}
}
return nil
}
// validateOCEAN checks that all OCEAN trait values are in [0.0, 1.0].
func validateOCEAN(psy *Psychology) error {
traits := map[string]float64{
"openness": psy.Openness,
"conscientiousness": psy.Conscientiousness,
"extraversion": psy.Extraversion,
"agreeableness": psy.Agreeableness,
"neuroticism": psy.Neuroticism,
}
for name, val := range traits {
if val < 0.0 || val > 1.0 {
return fmt.Errorf("aieos: psychology.%s must be in [0.0, 1.0], got %v", name, val)
}
}
return nil
}

View file

@ -103,3 +103,46 @@ func TestDefaultProfilePath(t *testing.T) {
got := DefaultProfilePath("/home/user/workspace")
assert.Equal(t, "/home/user/workspace/aieos.json", got)
}
func TestLoadProfileOCEANOutOfRange(t *testing.T) {
tests := []struct {
name string
json string
want string
}{
{
name: "openness too high",
json: `{"version":"1.1","identity":{"name":"A"},"psychology":{"openness":1.5}}`,
want: "psychology.openness must be in [0.0, 1.0]",
},
{
name: "neuroticism negative",
json: `{"version":"1.1","identity":{"name":"A"},"psychology":{"neuroticism":-0.1}}`,
want: "psychology.neuroticism must be in [0.0, 1.0]",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "aieos.json")
require.NoError(t, os.WriteFile(path, []byte(tt.json), 0644))
_, err := LoadProfile(path)
assert.Error(t, err)
assert.Contains(t, err.Error(), tt.want)
})
}
}
func TestLoadProfileOCEANValidBoundary(t *testing.T) {
dir := t.TempDir()
path := filepath.Join(dir, "aieos.json")
data := `{"version":"1.1","identity":{"name":"A"},"psychology":{"openness":0.0,"conscientiousness":1.0,"extraversion":0.5,"agreeableness":0.0,"neuroticism":1.0}}`
require.NoError(t, os.WriteFile(path, []byte(data), 0644))
p, err := LoadProfile(path)
require.NoError(t, err)
assert.Equal(t, 0.0, p.Psychology.Openness)
assert.Equal(t, 1.0, p.Psychology.Conscientiousness)
}