refactor(person): break the shared personality template so the sixteen stop converging #296

Merged
coilysiren merged 1 commit from aos/claude/personality-prose-distinctiveness into main 2026-08-17 17:20:50 +00:00
Member

What

Rewrites all 16 personality bodies in internal/person/data/. Prose only. No schema, no code, no eval changes.

Why

Every one of the 16 ran an identical four-move skeleton:

  1. abstract definition paragraph
  2. You bring opening paragraph two (16/16)
  3. You notice (15/16) and You sound naming a register in three adjectives (14/16)
  4. a Healthy X ... closer that walked the trait back toward balance (16/16)

Two consequences. Every personality ended by regressing to the same center, so bold was told to stay proportional, decisive not to be impulsive, skeptical not to block. And none of them ever demonstrated the register it named, because all 16 files read in one measured voice regardless of the trait they described.

Where a spec names a voice without showing one, the model supplies its own default. That is why the roles were landing on top of each other. The traits were already well separated as concepts (mean content-word cosine 0.143) and identical as prose.

Measurements

Content-word cosine over the bodies, before and after:

  • skeleton vocabulary present in 12+/16 files - 5 words (bring, healthy, notice, sound, without) to 0
  • mean pairwise similarity across all 120 pairs - 0.1427 to 0.1153
  • worst single pair - 0.2911 to 0.2525

Near-synonyms carried together inside a single role, where overlap costs that role its distinctness directly:

  • director, bold / decisive - 0.286 to 0.103
  • creator, nurturing / warm - 0.273 to 0.099
  • exec, curious / decisive - 0.238 to 0.125
  • qa and ai, meticulous / skeptical - 0.120 to 0.046
  • engineer and ai, meticulous / curious - 0.178 to 0.035
  • ai, curious / skeptical - 0.251 to 0.228

Each pair is now separated on an explicit axis rather than by wording alone. Bold is magnitude and decisive is timing. Nurturing is a trajectory and warm is the present tense. Curious widens a question and skeptical tests an answer. Meticulous checks parts and skeptical checks claims.

Verification

go build ./..., go test ./..., and pre-commit run --all-files all pass. No em-dashes, semicolons, italics, or middots. Frontmatter contract intact on all 16.

Not in this pass

  • color derivation. internal/color.Favorite takes the OKLab centroid of a role's three personality colors, which structurally pulls every role toward the band center. Engineer and exec sit 0.033 apart, design and ai 0.047.
  • the static emphasis mechanism. One personality foregrounded per role, chosen least-used and spread-maximized. Solves cleanly for six roles.
  • create and delete on the catalog. Exec and ai own no unique personality, so neither can take a distinct emphasis without stealing one. That needs a decision, not a rewrite.
  • evals. Deliberately deferred.
## What Rewrites all 16 personality bodies in `internal/person/data/`. Prose only. No schema, no code, no eval changes. ## Why Every one of the 16 ran an identical four-move skeleton: 1. abstract definition paragraph 2. `You bring` opening paragraph two (16/16) 3. `You notice` (15/16) and `You sound` naming a register in three adjectives (14/16) 4. a `Healthy X ...` closer that walked the trait back toward balance (16/16) Two consequences. Every personality ended by regressing to the same center, so bold was told to stay proportional, decisive not to be impulsive, skeptical not to block. And none of them ever demonstrated the register it named, because all 16 files read in one measured voice regardless of the trait they described. Where a spec names a voice without showing one, the model supplies its own default. That is why the roles were landing on top of each other. The traits were already well separated as concepts (mean content-word cosine 0.143) and identical as prose. ## Measurements Content-word cosine over the bodies, before and after: * skeleton vocabulary present in 12+/16 files - 5 words (`bring`, `healthy`, `notice`, `sound`, `without`) to **0** * mean pairwise similarity across all 120 pairs - 0.1427 to **0.1153** * worst single pair - 0.2911 to **0.2525** Near-synonyms carried together inside a single role, where overlap costs that role its distinctness directly: * director, bold / decisive - 0.286 to **0.103** * creator, nurturing / warm - 0.273 to **0.099** * exec, curious / decisive - 0.238 to **0.125** * qa and ai, meticulous / skeptical - 0.120 to **0.046** * engineer and ai, meticulous / curious - 0.178 to **0.035** * ai, curious / skeptical - 0.251 to **0.228** Each pair is now separated on an explicit axis rather than by wording alone. Bold is magnitude and decisive is timing. Nurturing is a trajectory and warm is the present tense. Curious widens a question and skeptical tests an answer. Meticulous checks parts and skeptical checks claims. ## Verification `go build ./...`, `go test ./...`, and `pre-commit run --all-files` all pass. No em-dashes, semicolons, italics, or middots. Frontmatter contract intact on all 16. ## Not in this pass * color derivation. `internal/color.Favorite` takes the OKLab centroid of a role's three personality colors, which structurally pulls every role toward the band center. Engineer and exec sit 0.033 apart, design and ai 0.047. * the static emphasis mechanism. One personality foregrounded per role, chosen least-used and spread-maximized. Solves cleanly for six roles. * create and delete on the catalog. Exec and ai own no unique personality, so neither can take a distinct emphasis without stealing one. That needs a decision, not a rewrite. * evals. Deliberately deferred.
refactor(person): break the shared personality template so the sixteen stop converging
All checks were successful
ci / test (pull_request) Successful in 50s
1be182788b
All 16 personality bodies ran one four-move skeleton: an abstract definition,
"You bring" opening paragraph two, "You notice", "You sound" naming a register
in three adjectives, and a "Healthy X ..." closer that walked the trait back
toward balance. Every personality therefore ended by regressing to the same
center, and none of them ever demonstrated the register it named. Where a spec
names a voice without showing one, the model falls back on its own default, so
sixteen distinct traits arrived in one voice.

Rewrite all sixteen. No shared skeleton, no "Healthy X" closer, register
demonstrated rather than named, and explicit cross-references that hold the
near-synonyms apart where a single role carries both.

Measured on content-word cosine over the bodies:

  skeleton vocabulary in 12+/16 files   5 words -> 0
  mean pairwise similarity (120 pairs)  0.1427  -> 0.1153
  worst pair                            0.2911  -> 0.2525

  co-held inside one role:
    director  bold / decisive        0.286 -> 0.103
    creator   nurturing / warm       0.273 -> 0.099
    exec      curious / decisive     0.238 -> 0.125
    qa + ai   meticulous / skeptical 0.120 -> 0.046
    engineer  meticulous / curious   0.178 -> 0.035
    ai        curious / skeptical    0.251 -> 0.228

The traits were already well separated as concepts. They were identical as
prose. This pass fixes the prose only. Color derivation, the static emphasis
mechanism, and the create/delete half of the catalog refactor stay open.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agent-compose!296
No description provided.