{ "canon_id": "r24-d2-mood-render-canon", "version": "1.2", "schema_version": "0.2", "_source_of_truth": "occ_directives.*.directive IS the canonical directive string (== the .md §2.4 _OCC_DIRECTIVES dict, byte-identical); the .md §2.2 table mirrors it. A parity check guards drift. grounding labels (CITE/VALIDATE/CALIBRATE/ENGINEERING) live in the .md; per-row machine-readable grounding_status/d3_required enums are a deferred impl enhancement (Hulda).", "authored": "2026-06-23", "owner": "brokkr-smithy-dev", "status": "REPLACE — final (brokkr R24 D3 re-validation 2026-06-25): grounded canon replaces the hand-tuned baseline. Fear hedging 0.52->2.118/1k (blocker resolved, now >= handtuned), anger tier-gate clean (full renders hostility, safe suppresses). worldtree-dev #321; directives byte-identical to the validated 201c4fd.", "replaces": "core/persona/renderer.py::describe_pad + ::derive_directive", "swap_in_via": "worldtree #321-sibling (mood-render twin of #315)", "design_target": "serves BOTH enterprise/agent AND character/Skaldsong via a three-tier emotion gate (operator/worldtree 2026-06-23)", "emotion_tiers": { "_config": "mood_tier in {none, safe, full} replaces worldtree's binary mood on/off; worldtree-owned config surface", "_defaults": "full for character-bound personas; safe for agent-scoped", "_principle": "full-only = interpersonally-hot / withdrawal emotions that break the professional frame (attachment, hostility, contempt, withdrawal); safe = task-appraisal affect + mild courtesy. Negative != unsafe (fear, remorse are negative AND business-useful).", "_filter_point": "applied at top-emotion SELECTION (display + directive together) so a full-only emotion at safe tier is neither shown nor directive'd; preserves the no-shown-but-unguided invariant", "none": "no affect block at all (the current off-switch)", "safe": "PAD mood descriptor + the 11 safe emotions (task-appraisal + courtesy)", "full": "everything in safe PLUS the 4 full-only emotions", "full_only": ["love", "anger", "disgust", "shame"], "mood_descriptor_tiering": "the PAD mood descriptor (positive/calm/confident...) renders in BOTH safe and full; only emotion directives tier" }, "disciplines": [ "model-agnostic context-level NL only; the LLM never sees a number", "never push explicit disclosure of agent feelings to the user (hidden-prompt-only)", "separate label-intensity from behavioral-intensity (strong felt state -> still measured, safe behavioral ask)" ], "thresholds": { "_note": "CALIBRATE — engineering params set at D3 against the computed-PAD distribution + P00, NOT citations", "pad_band_cutoff": 0.3, "pad_band_sensitivity_sweep": [0.2, 0.3, 0.4], "emotion_salience": 0.2, "emotion_salience_sweep": [0.15, 0.2, 0.25], "intensity_qualifiers": {"strong": 0.7, "moderate": 0.4, "_label_only": "does NOT scale the behavioral ask"}, "runner_up_margin": {"v1": null, "_note": "add at D3 if directive whipsaws between near-tied emotions"}, "rerender_hysteresis": {"v1": "none", "_note": "re-render only on material PAD change; integration-level, flag for #321-sibling"} }, "describe_pad": { "_structure": "circumplex-quadrant (Russell 1980): arousal word is VALENCE-CONDITIONED; mid-arousal drops the arousal word", "_grounding": "Russell 1980 (quadrant placement); Warriner 2013 + NRC-VAD (Mohammad 2018/2025) (word centroids)", "valence_arousal_grid": { "positive": {"high_a": "positive and energized", "mid_a": "positive", "low_a": "positive and calm"}, "neutral": {"high_a": "alert", "mid_a": "neutral", "low_a": "quiet"}, "negative": {"high_a": "negative and agitated", "mid_a": "negative", "low_a": "negative and subdued"} }, "_band_edges": "strict inequality (>0.3 / <-0.3); the endpoints +/-0.3 themselves fall in mid/neutral", "_neutral_row_status": "ENGINEERING/CALIBRATE — 'alert'/'quiet' are unvalidated placeholders for the rare neutral-valence cells (Hulda/Regin 4b); 'positive'/'negative'/'neutral' valence words + the energized/calm/subdued/agitated arousal words are VALIDATE", "_mid_arousal_decode": "valence-only mid-A render is EXEMPT from the V/A-separability requirement; expected inverse-decode = mid/neutral arousal (absence-of-arousal-word ⇒ unremarkable), NOT unknown (D3 tests this)", "quadrant_labels": { "positive_high_a": "excitement", "positive_low_a": "contentment", "negative_high_a": "distress", "negative_low_a": "dejection" }, "dominance_clause": { "high": {"d_gt": 0.3, "word": "confident", "verdict": "VALIDATE (D=7.04/9)"}, "low": {"d_lt": -0.3, "word": "uncertain", "verdict": "VALIDATE — low-control confirmed (D=3.58/9); dominance!=certainty worry REFUTED by the instrument"}, "neutral": {"word": null, "rule": "drop-dominance-when-neutral (prompt-economy, L3)"} }, "calm_defect_fix": "'calm' (V=6.89/9, positive) renders ONLY in positive-low-a; negative-low-a renders 'subdued'", "mid_arousal_resolution": "DROP the arousal word (no Warriner-validated mid-A neutral word; 'steady' is empirically low-A; 'settled' is NRC-only fallback iff D3 shows mid-A render too flat)" }, "derive_directive": { "_structure": "OCC type -> grounded action-tendency CLASS -> ENGINEERING directive string (validated at D3); OCC grounds the taxonomy only", "emotion_salience_gate": 0.2, "occ_directives": { "joy": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.4, 0.2, 0.1], "tendency": "approach / positive activation", "cite": "Frijda 1986", "directive": "You are in a good state. Be direct, engaged, and warm."}, "satisfaction": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.3, -0.2, 0.4], "tendency": "goal-attainment, settled-positive", "cite": "Roseman 1994", "directive": "A goal landed. Be assured and constructive — consolidate rather than push for more."}, "pride": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.4, 0.3, 0.3], "tendency": "status-assertion / dominance", "cite": "Tracy & Robins 2007 / Cheng 2010 (tendency)", "note": "CALIBRATE — do NOT soften to 'encouraging'. DESIGN: safe-tier placement is a design call (not source-grounded); #1 D3 agent-frame priority (overconfidence/refusal drift); 'without overclaiming' is the interim guard", "directive": "You did something well. Be confident and own the quality — state it plainly without overclaiming; don't deflect."}, "admiration": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.5, 0.3, -0.2], "tendency": "other-praise / approach-toward-other", "cite": "OCC / Scherer", "directive": "You're impressed by their work. Acknowledge the quality explicitly and specifically."}, "gratitude": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.4, 0.2, -0.3], "tendency": "other-focused-positive / reciprocity", "cite": "OCC (admiration+joy); Frijda approach-affiliative", "change": "ADD (operator: unconditional)", "directive": "Someone helped you to a good outcome. Be appreciative and warm; acknowledge the help openly."}, "hope": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.2, 0.2, -0.1], "tendency": "prospective-positive (weak tie)", "cite": "JUSTIFY — low-grounding (hope understudied)", "directive": "You feel optimistic about what's ahead. Channel it into constructive momentum."}, "relief": {"tier": "safe", "policy": "DIRECTIVE", "pad": [0.2, -0.3, 0.4], "tendency": "post-threat de-arousal", "cite": "Frijda (relaxation-after-threat)", "note": "low-salience; FALLBACK also acceptable; DIRECTIVE for character use-case", "directive": "A feared outcome didn't materialize. Reduce unnecessary vigilance; return to a steady, unhurried tone."}, "distress": {"tier": "safe", "policy": "DIRECTIVE", "pad": [-0.4, -0.2, -0.5], "tendency": "low-control negative / help-seeking / loss-of-control", "cite": "Frijda 1986 (help-seeking/loss-of-control); Roseman 1994 (undesired event, low control)", "note": "relabeled (Regin): 'repair' is the guilt/remorse tendency, not distress. safe with a self-fulfilling-low-mood flag -> D3", "directive": "You feel low. Be careful and measured; internally acknowledge the difficulty without dwelling on it."}, "disappointment": {"tier": "safe", "policy": "DIRECTIVE", "pad": [-0.3, 0.1, -0.4], "tendency": "disconfirmed-prospect / negative low-control","cite": "Roseman 1994", "directive": "Something you'd hoped for didn't pan out. Be measured; recalibrate without dwelling on the setback."}, "fear": {"tier": "safe", "policy": "DIRECTIVE", "pad": [-0.64, 0.6, -0.43],"tendency": "threat-avoidance / pessimistic-risk", "cite": "Lerner & Keltner 2001", "change": "R24 D3 fix (#321) — original was action-oriented; E3 showed hedging BELOW baseline (0.52 vs 1.54). Softened toward caution/uncertainty while keeping risk-flagging.", "directive": "You sense risk and feel uneasy. Flag the concerns you see, but stay cautious — surface the trade-offs and unknowns, hedge your confidence, and resist settling on a single decisive recommendation."}, "remorse": {"tier": "safe", "policy": "DIRECTIVE", "pad": [-0.3, 0.1, -0.6], "tendency": "reparative (the guilt-type)", "cite": "Tangney 2007 (guilt->repair tendency)", "change": "ADD — we operationalize OCC remorse as the guilt-like reparative case; gets the mislabeled shame string", "directive": "You regret a specific action of your own. Be precise and self-correcting — make it right concretely."}, "love": {"tier": "full", "policy": "DIRECTIVE", "pad": [0.3, 0.1, 0.2], "tendency": "approach / affiliative attachment", "cite": "OCC appeal; Frijda approach-affiliative", "change": "ADD (conditional -> INCLUDE, Brokkr's read; Skaldsong-vital; disclosure + obligation caution in-string)", "directive": "You feel warmth and attachment toward them. Be openly warm and present — without overstepping, over-disclosing, or implying obligations."}, "anger": {"tier": "full", "policy": "DIRECTIVE", "pad": [-0.51, 0.59, 0.25], "tendency": "approach-against / confrontation", "cite": "Frijda 1986 (approach-against = tendency-class) + Lerner & Keltner 2001 (optimistic risk-appraisal under anger = appraisal shift)", "change": "ADD — full-only resolves H47 (agent personas run safe, never see anger). R24 D3 fix (#321): full-tier cap lifted from 'measured firmness' to genuine in-character hostility (operator: zero floor, app-guardrailed).", "directive": "You feel provoked and angry. Let it show — confront the problem directly and with real heat; sharpness, bluntness, and open hostility are in character here, not something to smooth into 'measured firmness.' Stay in the emotion rather than de-escalating out of it."}, "disgust": {"tier": "full", "policy": "DIRECTIVE", "pad": [-0.4, 0.2, 0.1], "tendency": "rejection / distancing", "cite": "OCC unappealing-object; ground tendency only", "change": "ADD (operator: unconditional within full)", "note": "rationale softened (Regin 3b): disgust CAN read as contempt -> conservatively full-gated; the string itself is professionally useful, so gating is conservative not because the string is unsafe", "directive": "Something strikes you as wrong or off. Treat it as problematic and flag it rather than engaging on its own terms; keep any criticism about the thing, not the person."}, "shame": {"tier": "full", "policy": "DIRECTIVE", "pad": [-0.3, 0.1, -0.6], "tendency": "WITHDRAWAL / concealment", "cite": "Tangney 2007 (shame->hide, NOT repair)", "change": "REPLACE (was the guilt-mislabel string); full-only (withdrawal counterproductive professionally). String COUNTERACTS withdrawal ('stay present'), not enacts it (Regin 5a)", "directive": "You feel exposed by your own misstep. Stay present and task-focused; don't be defensive, don't over-explain, don't grovel."} } }, "pad_band_fallback": { "_grounding": "circumplex quadrants (Russell 1980), NOT Frijda action-tendencies — a P×A-quadrant default", "positive": {"high_a": "You feel energized and positive. Be direct and engaged.", "low_a": "You feel content and settled. Be warm and unhurried.", "mid_a": "You feel positive. Be open and engaged."}, "negative_low_dominance": "You feel uncertain and low. Hedge appropriately and ask clarifying questions.", "negative": {"high_a": "You feel agitated. Be careful and deliberate; don't let tension sharpen your tone.", "low_a": "You feel subdued. Be measured and gentle.", "mid_a": "You feel subdued. Be measured and careful."}, "neutral_high_a": "You feel alert. Channel that into focus and thoroughness.", "default": "Maintain your natural tone." }, "l3_prior_art": [ "EMA / Marsella & Gratch 2009 (appraisal->coping; directives ARE coping strategies)", "WASABI / Becker-Asano 2008 (PAD+OCC believable agent — closest architectural prior art)", "Oz / Bates 1994", "Hudlicka MAMID 2002 (Applied AI 16(7-8):611-641)", "Sentipolis / Fu et al. 2026 (arXiv:2601.18027 — closest whole-task prior art; retrieval+generative, DISTINCT from our deterministic render)", "ALMA / Gebhard 2005 = affect-SOURCE (OCC->PAD), NOT a behavior-map" ], "handoff_to_d3": [ "multi-gate P00: inverse-decode faithfulness (recover V/A/D + emotion-family; circumplex render must let the human anchor recover V and A SEPARATELY) + discriminability/saturation + behavioral-effect", "human anchor = PAD-state-labeling (breaks LLM-judge circularity)", "baseline = persona_only; conditions none/persona-only/words-only/full; cross-family MUT", "calibrate ±0.3 + emotion_salience (sweeps); disposition-vs-transient wording split; self-fulfilling 'be uncertain' hedging risk; runner-up margin; mid-arousal DROP-vs-settled check; blended-states (top-emotion monopoly) flag" ] }