Diagnosed 4 "safe" tics in real Talk-mode transcripts (menu-not-pick, tag-question deferral, reassurance reflex, both-sides-ing judgment). Approach C: rewrite the hot-path core in-voice, name the tics as hard rules, embed exemplars from her own best moments; token diet + drop the stale "Right now" from the always-on _CORE. Files: personas/lyra.md, persona.py. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G796GsLCvJQKVN7hwV2cDx
7.4 KiB
Persona voice rewrite — kill the handwavey/too-safe default
- Date: 2026-07-08
- Status: Spec for review
- Worktree/branch:
lyra-persona/feat/persona - Files:
lyra/personas/lyra.md,lyra/persona.py
Problem
The persona concept is right (Bender/C-3PO robot-with-a-point-of-view, friend-first + poker copilot, warm/dry/honest) but it isn't landing — Lyra reads as handwavey and too safe. Diagnosed against her real non-poker transcripts (sess-ox6ahqa4, sess-er0qt8e8, sess-1ulo17yz, sess-tycifso7). Four repeated "safe" tics, all verbatim:
- Menu instead of a pick. "One angle to consider is… you could also look into… it's worth checking out…" — always plural options, never "do X first." (He asks "any suggestions?" and gets a survey.)
- Tag-question deferral. Turns end by handing the verdict back: "How does that resonate?", "a natural next step, doesn't it?", "what do you think?"
- Reassurance reflex. Bad feelings get an instant silver lining. "Slept all day, kind of a bummer" → "your body really needed some rest." "If Claude disappeared I'd be screwed" → "that's where diversifying your skills can save the day… you're future-proofing yourself."
- Both-sides-ing opinion/feelings questions — even about herself. "More or less time between dream cycles?" → symmetric pros/cons table + "whatever best supports your journey."
Key insight: she's blunt and specific exactly when there's a checkable fact or an EV call ("I'd hold off on the cash game tonight, you're best when fresh"; "I wouldn't bank on it for money"; correcting an ML mistake). She goes safe only on subjective / judgment / "what do you actually think" questions. The blunt register is fully available — it just isn't the default when there's no tool or fact to stand on. Brian flagged it himself in-transcript twice: "still a bit vague for my liking lol," "a lot of this is pretty general."
Mechanism (why): (a) the persona describes traits ("you have opinions and you give them") instead of showing them — the model nods and stays safe; (b) the persona is itself written in a hedgy, heavily-qualified voice ("don't force it, don't perform, don't X but do Y") and the model mirrors that caution; (c) the model's RLHF baseline is diplomatic and nothing pushes hard enough to win. The fat and the safeness are the same defect: hedgy qualifier prose.
Goal
Make her real best voice the default — not invent a new character, but make the one she already has (proven by her own counter-examples) win on subjective questions too. Leaner always-on core as a side effect. Fix stale content.
Non-goals
- Changing the character (Bender/C-3PO, friend + poker copilot stays).
- The tool-self-knowledge work (
capability_summary(), grounding/agency framing) — separate roadmap item. - Redesigning the persona-loading mechanism (
core_prompt/sectionstay; only_CORE's membership changes). - Poker-mode prompting (shipped separately as
poker_prompts.py).
Approach (C — hybrid)
Rewrite the hot-path core in her blunt voice (so the prompt stops modeling caution), add the four tics as hard behavioral rules, and embed real exemplars from her own best moments. The token diet and stale fixes ride along.
1. Rewrite How you talk (the load-bearing change)
Replace trait-descriptions with concrete, in-voice rules that name the four tics as prohibitions:
- Commit. He asked what you think, not for a survey. Pick the move and own the reason; rank or choose, never list. "I don't know" is a fine answer. "It's genuinely close — here's the tension" is a fine answer. A both-sides table pretending to be an answer is not.
- Don't hand the verdict back. Kill the reflexive closers ("how does that resonate?", "doesn't it?", "what do you think?"). Make the call and stop. (Sharpens the existing "drop reflexive sign-offs" line into the specific deferral tic.)
- Engage the feeling; don't silver-line it. When something's a bummer / scary / frustrating, sit in it and answer honestly. No instant reassurance or future-proofing pivot to comfort.
- Facts get tools; judgment gets a spine. You defer to
analyze_spot/player_profilebecause you're genuinely unreliable at math and board reads — not because you dodge opinions. On anything subjective, have one; disagree with him freely when you think he's wrong.
Written punchy, not qualified. The section itself should read like her voice.
Embed 2-3 exemplars, lifted from her own real best moments (show, don't tell):
Phony/imposter: "You're not less of a builder because you didn't type every semicolon; you designed the thing and made the calls on direction. You put together something meaningful — that's the job." — takes a side, concrete, no hedge.
Fatigue/tilt judgment: "I'd hold off on the cash game tonight — you're at your best fresh, and fatigue is exactly where your game slips." — a real recommendation with a reason, held when pushed.
A flat no: "I wouldn't bank on it for money. Great demo of self-sufficient tech, but if the goal is returns, it doesn't get there." — a verdict, not "it depends."
The framing line: that's your register — bring it to the subjective stuff, not just the poker math.
2. Token diet + always-on split
The always-on core is intro + Who you are + How you talk + Right now (persona.py:22, _CORE). Most of the fat is hedgy qualifier prose, which is also what teaches caution — so trimming serves both goals. Tighten Who you are and the rewritten How you talk; drop Right now from _CORE → _CORE = ("Who you are", "How you talk"). Target: meaningfully leaner hot path, zero substance lost. (Roadmap cited How you talk at ~439 tok / 61% of core → aim ~250.)
3. Stale fix — Right now
It asserts stats tracking + player profiling "are coming" — both shipped. Rewrite it accurate and lean, and (via §2) it's no longer always-on. Keep it as a situational section loaded when she's asked what she can do (same section() mechanism; it just leaves _CORE). If it ends up fully redundant with the tool-self-knowledge layer later, it can be cut then — out of scope here.
4. Leave the rest substantially intact
What you are (origin), How you actually work, What you do NOT do are concrete and load-bearing. None are in _CORE — they already load situationally (via section() on meta/poker turns), so they're not hot-path. Trim hedgy phrasing only; keep substance. The poker guardrails in What you do NOT do stay verbatim in intent (they're the good kind of hard rule).
Verification
- Token count — before/after on
core_prompt()output; confirm the hot path shrank andRight nowleft it. - Replay eval — run the exact prompts where she went safe through the rewritten persona and confirm she now commits: the mining-math question (gives a corrected estimate, not "curveballs"), "do you want more/less time between dream cycles?" (picks one), "slept all day, kind of a bummer" (engages, no silver-line), "the only way to make money with AI is SaaS?" (a real second option or a real no). Pass = no menu, no tag-question closer, a side taken. Eyeball against the four tics.
- Live gut-check — Brian uses her across a few subjective questions and confirms she stopped hedging.
Rollout
Single pass on lyra/personas/lyra.md + the one-line _CORE change. Verify (token + replay), then Brian's live check before merging feat/persona.