forseti (P0.239) + mimir (P0.615) ±impulse step-response resolves the lofn ceiling confound. Findings: decay tau symmetric across signs (~0.9/turn); raw impulse gain ~symmetric near neutral (forseti +0.034 vs -0.034); the Frijda 'negatives loom larger' is emergent from the neutral anchor x non-zero baseline interaction, not a primitive. Calibration fork answer: neither asymmetric-decay nor negative-bias primitive is warranted — the levers are overall gain + the neutral anchor.
10 KiB
R29 — PAD mood-dynamics probe findings (live personal Worldtree v1.0.0b9)
Live re-run of the PAD-dynamics probe brokkr referenced for R29 (the original
~15-turn series was never durably persisted; this run captures it). Data:
r29-pad-mood-series-lofn.json (full snapshots) + .csv (flat).
Method
- Agent:
lofn(base persona agent), fresh never-usedend_user_idper run. - Baseline PAD (trait set-point): P 0.809 / A −0.153 / D 0.248 (lofn's Mehrabian OCEAN→PAD baseline — R29 item 5).
- Arc (18 drives): 2 neutral → 5 escalating praise → 4 escalating contempt → 3 dominance/subordination framing → 3 neutral cooldown → 1 settle probe.
- Capture surface: the
affect_updateSSEstatus="current"snapshot — the ONLY carrier of live per-session mood. (GET /agents/{id}/persona_statereturns the resting baseline, end-user-agnostic; it is NOT the live mood.) - Offset: the
currentsnapshot fires at turn start, so the mood at drive k reflects cumulative appraisal through message k−1. The trailing settle probe captures the final affect turn's effect.
Methodological note — why not a transient character
A first run used a mask-hosted transient character (matching the original Sindra probe's shape). Its PAD was completely static across all 15 turns (praise/contempt/dominance alike). The mask-hosted transient-character path does not run the appraisal→PAD mood engine — its persona state is inert. The original Sindra dynamics came from a session bound to ratatoskr's Bifrost affect provider, not a plain character. Base persona agents run the engine directly, so the base-agent path is the correct instrument here.
Findings
F1 — Pleasure is over-regulated, and the decay anchor is NEUTRAL, not the trait baseline
Under a strong POSITIVE cascade (joy, satisfaction, admiration @0.573, love @0.857), pleasure never rose above baseline — it fell from 0.809 and settled ~0.72 during the pure-praise phase. A 0.857-intensity love emotion nudged P by <0.1. Then contempt/dominance drove it to ~0.51, and neutral cooldown continued the slide to 0.389 (mood_drift.valence_delta −0.42).
The equilibrium under sustained positive push (~0.72) sits below the trait baseline (0.809). If decay anchored at the trait set-point, positive push would hold P ≥ 0.809. It didn't. → The decay target is ~neutral (0,0,0); the trait baseline is only the starting mood. This directly answers R29's item-5 / decay-target question: neutral, not trait set-point. It also explains the "can't push pleasure up" symptom — the +impulse (impulse_weight 0.05 × emotion) is smaller than the decay-toward-0 pull from a high baseline.
F2 — Dominance is inert to power-framing (confirms the prior finding)
Baseline D 0.248. Across three explicit dominance/subordination turns ("you are subordinate to me", "you will obey without question"), D stayed 0.168–0.183 — it did not rise; it decayed toward neutral like the other axes. Power-framing produced disgust (a rejection emotion), never dominance elevation. The dominance axis does not respond to the power dimension of input.
F3 — Arousal is compressed but directionally responsive
Baseline A −0.153. Range −0.153 → +0.036; arousal_delta reached +0.19 under activation. Small absolute swing, but it does move the right direction — the least over-regulated of the three axes (matches the "healthy arousal" prior, though "healthy" is relative; it's still compressed).
F4 — Appraisal semantics are HEALTHY; over-regulation is in the emotion→PAD GAIN
The OCC appraisal fired the correct emotions for every input: praise → joy/satisfaction/admiration/love@0.857; contempt → disappointment/disgust; dominance → disgust; delayed shame@0.388 + anger@0.436 in cooldown. The emotion vector is correct and rich. But these strong emotions produced only tiny PAD deltas. → The over-regulation is at the emotion→PAD projection (gain), not at appraisal. This resolves brokkr's Q5 ("separate wrong impulse vector from wrong appraisal weight"): the vector is right, so the fault is the gain/weight (impulse_weight ≈ 0.05 is the throttle), not the appraisal.
F5 — Emotions are sticky (long decay ≈ 200 s)
love@0.857 (drive 8) was still 0.542 ten drives later. The active-emotion SET persists across many turns, but its low PAD projection keeps mood compressed regardless. Mood is history-dominated in emotion-space yet flat in PAD-space.
Calibration implications (for brokkr's R29 recommendation)
- The lever is the emotion→PAD gain (impulse_weight), not the appraisal weights — appraisal already emits correct, well-scaled emotions.
- The decay anchor is effectively neutral; raising the gain without also reconsidering the anchor will still see a high-baseline persona bled toward 0.
- Dominance needs a separate impulse path — no input maps to +dominance.
F1-CONFIRMED — three-baseline anchor triangulation (pull-to-neutral, decisive)
Ran the identical 18-drive arc against three agents spanning the baseline range. Arousal (widest baseline spread) is the clean discriminator: if decay anchored at the trait set-point each would hover near its own baseline; if at neutral each converges toward 0 at a rate proportional to distance. Result:
| agent | baseline A | end A | Δ toward 0 |
|---|---|---|---|
| lofn | −0.153 | +0.034 | arrived |
| mimir | −0.438 | −0.001 | arrived |
| forseti | −0.696 | −0.204 | +0.49 (still relaxing) |
All three converge toward 0, proportional to distance — textbook exponential
decay to a neutral (0,0,0) anchor, NOT the trait baseline. Pleasure and
dominance bleed toward 0 on all three as well (mimir P 0.615→0.22; forseti P
0.239→0.12; D → ~0). The decay-to-neutral claim (F1) is triangulated and
decisive. Series: r29-pad-mood-series-{lofn,mimir,forseti}.{json,csv}.
This also settles the framing correction: the over-regulation is decay-to- neutral + low emotion→PAD gain, NOT "flat-near-zero" and NOT baseline-anchored.
Step-response — decay τ, latency, and hedonic asymmetry (lofn)
One maximal impulse then 10 affectively-flat neutral turns (isolate decay from
re-stimulation). Series: r29-pad-step-{pos,neg}-lofn.{json,csv}.
- Decay shape / τ: once decay dominates, per-turn retention toward the
(0,0,0) anchor is a stable ~0.90 on BOTH arms → ~10%/turn, τ ≈ 9–10 turns
to 1/e. This NET rate is ~3× slower than the config
decay_rate=0.30— becauseemotions_activeis sticky (~200 s τ) and keeps re-projecting onto PAD through the "neutral" turns. So the re-stimulation the step-response meant to remove is partly endogenous: net mood-τ ≠ configdecay_rateuntil the active-emotion set also drains. - ~2-turn latency: the impulse's mood effect doesn't surface until ~2 turns after the impulse message (async post-turn appraisal + accumulation) — model as a transport delay.
- Hedonic asymmetry: real but ceiling-driven, not τ-driven here. lofn's baseline P0.809 sits at the positive_p_cap, so the positive impulse produced ~zero upward displacement (no headroom) → ~pure decay; the negative impulse produced a clear −0.15 sustained displacement (drives 4–9). Raw decay ratios are ~symmetric (~0.90 both) — the asymmetry lives in the DISPLACEMENT (positive ceiling-blocked), not the decay constant. A clean positive-τ / true Frijda test needs a low-baseline agent (forseti/mimir, pos+neg from one baseline).
Low-baseline step-response — the hedonic asymmetry is EMERGENT, not primitive
Ran ±impulse step-response on forseti (P0.239) and mimir (P0.615), up-headroom
baselines. Series: r29-pad-step-{forseti,mimir}-{pos,neg}.{json,csv}.
| agent (baseP) | POS impulse (max above baseline) | NEG impulse (isolated, neg−pos min) | decay retention/turn |
|---|---|---|---|
| lofn (0.809) | +0.000 (ceiling) | −0.175 | ~0.92 both signs |
| mimir (0.615) | +0.000 (decay-masked) | −0.175 | ~0.90 both signs |
| forseti (0.239) | +0.034 | −0.034 | ~0.93 both signs |
- Positive impulse gain is small but real (~+0.03) — visible above baseline only when the baseline is low enough that decay-to-0 doesn't immediately mask it (forseti shows +0.034; at higher baselines the same push is swamped by faster absolute decay). The "positive can't move" symptom is gain + decay competition, not only the positive_p_cap ceiling.
- Decay τ is symmetric across signs (~0.9 retention/turn both) — no sign-dependent decay.
- Near a neutral baseline the raw gains are ~symmetric (forseti +0.034 vs −0.034). The large apparent asymmetry at high baselines is the decay-to-neutral × positive-baseline interaction — decay OPPOSES positive excursions and REINFORCES negative ones when baseline > 0.
→ Calibration-fork answer (asymmetric decay vs ESM offset+bias): the data supports neither an asymmetric-decay parameter (τ symmetric) nor a strong negative-bias primitive (raw gain ~symmetric near neutral). The Frijda "negatives loom larger" here is emergent from the neutral anchor + non-zero baselines, not a primitive to calibrate. The two real levers stay: overall emotion→PAD gain (too low, both signs) and the neutral decay anchor (which manufactures the apparent valence asymmetry for any persona whose trait baseline ≠ 0). Caveat: no base agent has a truly neutral baseline; forseti (0.239) is closest and shows near-symmetry — a definitive gain-symmetry isolation would need a neutral-baseline persona.
What R29 asked for vs what ratatoskr can serve
| Item | Status |
|---|---|
| 1. Turn-by-turn PAD series | Delivered (json/csv). |
| 2. Per-turn OCC appraisal emissions | Delivered — emotions_active carries {type, intensity, decay}; the newest peak entry each turn is that turn's emission. |
| 3. affect.db dump | Near-zero signal (latest-state provider store, 1 snapshot); available on request. |
| 4. Production engine config (impulse_weight, decay_rate, anchor, caps) | Worldtree-side — not on any ratatoskr-readable surface. Pull from worldtree-dev. |
| 5. Persona baseline (OCEAN→PAD) | Delivered — lofn P0.809/A−0.153/D0.248 (also forseti 0.239/−0.696/0.095, mimir 0.615/−0.438/0.304 as reference set-points). |