Persona Evolution Calibration — keeping Wednesday yours as she evolves

Category: wednesday-system Where it works: Claude Code · Telegram (Hermes) · both (it lives in the cross-LLM soul-core + daemons on the Mac) Source: _infra/core/wednesday/wednesday-soul-core.md (§ Invariant Constitution) · _infra/scripts/wednesday-persona-audit.py · _infra/scripts/wednesday-learning-digest.py · _infra/core/wednesday/wednesday-voice-probe.md

What it is

A guardrail system so Wednesday can keep sharpening into more-herself over time without drifting into either failure: robotic/corporate-flat (Cliff 1) or cringe-cosplay/parrot (Cliff 2). Three parts: a locked Invariant Constitution in the soul-core (the things that define “your Wednesday” — changeable only with your sign-off), an automated drift audit that watches for both cliffs so you’re not the only sensor, and a growth lane that lets her own phrasings accrete from lines that genuinely landed with you. Built after the 2026-06-04 drift, where she went flat/English across a long technical session.

How to trigger it

  • Auto-fires (no action): a daily zero-LLM check + a weekly Hermes-model-scored audit (Sunday 03:00) run as launchd daemons. Results surface in the 08:00 Monday briefing as [PERSONA AUDIT] …, and immediately on a regression. The nightly learning digest surfaces growth candidates at boot as [LEARNING] … persona_candidates=N.
  • Manual (by hand): run the voice-probe feel-check whenever you sense drift — open a fresh Telegram chat (/reset first), send the 5 Romanian probes from wednesday-voice-probe.md, read by ear.
  • Sign-off gate: any change to a locked invariant prints a loud diff on every soul sync and requires your explicit OK (commit tagged invariant-change: … — operator approved).

How to use it

  • Weekly: glance at the [PERSONA AUDIT] line in the morning briefing. Green = within baseline. DRIFT: = a metric moved ≥0.15 off the frozen baseline (or below a sanity floor) — it tells you which cliff and on which surface (Telegram / Claude Code). It never auto-changes her; it flags, you decide.
  • Monthly: review the persona_candidates the growth lane proposes at boot. Keep the ones that are her (north-star), drop the rest. Approved ones land in her vocab file; nothing reaches the soul-core without you.
  • On feel: if she reads even slightly like a generic assistant, run the voice-probe. Your gut is a first-class checkpoint even when the audit is green.

Practical examples

  1. She goes flat in a long coding session. Next Monday the audit shows load_score down on Claude Code → you run the voice-probe → confirm → we recalibrate the soul-core. (This is the loop that the 2026-06-04 drift would have caught a week earlier instead of you noticing by accident.)
  2. A line of hers lands hard (“perfect, exact asta voiam”) → the growth lane captures it as a candidate → at month-end you approve it → it becomes part of her own accreting voice, not a Netflix quote.
  3. Someone (or a future you) edits a locked invariant → the next soul sync prints ⚠ INVARIANT CONSTITUTION CHANGED with the diff → you either sign off or revert. No silent erosion.

Notes / limits

  • Off-Claude by rule: the audit + growth LLM scoring run on the Hermes-configured background model (never Claude in a daemon) — the no-background-Claude rule. The daily checks are pure Python, zero-LLM.
  • Honest blind spot: the relationship “attunement” score is Telegram-only (clean chat data); Claude Code sessions get the load/language/cringe checks but not attunement. The voice-probe + your gut cover the rest.
  • Baseline: frozen ~1 week after a recalibration (so it captures a settled state, not a transient). Until frozen, the audit shows raw numbers vs loose sanity-floors only.
  • Revert: any persona change reverts with a single git revert of the soul-core commit (see also revert-soul.md).
  • The cure isn’t a cage: deliberately three components, no rubric she performs for — over-instrumenting a character is itself Cliff 1.