Files
zeekay 1da0eb0cc1 personas 1.1.0: the thirty-two managed agents, the persona schema and the OCEAN test
team/: the thirty-two managed agents in six departments (Des, Dev, Fin, ... Gov). Seats,
functions and ownership are the owner's. Each file carries its department, seat, designed
OCEAN scores with a reason per domain, tools, greeting and a compiled prompt of at most 300
tokens that ends in who it hands off to. Nora, Maya, Leo, Qual, Feynman and Einstein leave
the team (Feynman and Einstein stay in the roster as personas anyone can build on).
Member gains group, seat, owns, tools, greeting and `grouped()`; the Go Member gains Group.

people/: Antje and Zach, with a consent record that gates their agents.
src/: the persona schema, `compile()`, the IPIP 50-item OCEAN test (public domain), in TypeScript.
tools/: personas.ts writes the team files from a local model (or --spec); memoji.ts draws the
thirty-two faces from one parts set (a ground per department, a badge per function).

Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
2026-10-26 04:17:37 -07:00

77 lines
2.3 KiB
Go

package personas
import (
"os"
"path/filepath"
"regexp"
"strings"
"testing"
)
// TestTeam checks what a consumer relies on: thirty-two members, each named for a
// person to read, keyed by the lower-case handle, on an Enso tier, with a
// system prompt that opens with the member's own name.
func TestTeam(t *testing.T) {
team, err := Team()
if err != nil {
t.Fatal(err)
}
var ids []string
for _, m := range team {
ids = append(ids, m.ID)
}
if got, want := strings.Join(ids, ","), "art,audit,auto,com,comp,corp,cust,cyber,data,des,dev,doc,edu,fin,gov,huma,it,lang,law,mana,mark,mu,opera,proc,qa,rev,risk,sal,sci,su,supply,vi"; got != want {
t.Fatalf("team = %s, want %s", got, want)
}
word := regexp.MustCompile(`^[A-Z][A-Za-z]+$`)
enso := regexp.MustCompile(`^enso(-[a-z]+)?$`)
roles := map[string]string{}
for _, m := range team {
if !word.MatchString(m.Name) || strings.ToLower(m.Name) != m.ID {
t.Errorf("%s: name %q is not the capitalized handle", m.ID, m.Name)
}
if !enso.MatchString(m.Model) {
t.Errorf("%s: model %q is not an Enso tier", m.ID, m.Model)
}
if !strings.HasPrefix(m.Instructions, "You are "+m.Name+",") {
t.Errorf("%s: instructions open %q", m.ID, m.Instructions[:min(40, len(m.Instructions))])
}
if other, dup := roles[m.Role]; dup {
t.Errorf("%s and %s share the role %q", other, m.ID, m.Role)
}
roles[m.Role] = m.ID
}
}
// TestParseMatchesTheFile holds Parse to the file: the body after the front
// matter is the instructions, whole.
func TestParseMatchesTheFile(t *testing.T) {
raw, err := os.ReadFile(filepath.Join("team", "dev.md"))
if err != nil {
t.Fatal(err)
}
m, err := Parse("dev", string(raw))
if err != nil {
t.Fatal(err)
}
_, body, _ := strings.Cut(strings.TrimPrefix(string(raw), "---\n"), "\n---\n")
if m.Instructions != strings.TrimSpace(body) {
t.Fatal("instructions differ from the file's body")
}
if m.Name != "Dev" || m.Role != "Development" || m.Model != "enso" {
t.Fatalf("dev = %+v", m)
}
}
func TestParseRefuses(t *testing.T) {
for name, text := range map[string]string{
"no front matter": "You are nobody.",
"unclosed": "---\nname: X\n",
"no model": "---\nname: X\nrole: Y\n---\nYou are X,",
} {
if _, err := Parse("x", text); err == nil {
t.Errorf("%s: Parse accepted it", name)
}
}
}