-
Notifications
You must be signed in to change notification settings - Fork 0
Moral Tension
An opt-in overlay that gives an NPC a conscience: guilt, secrets, lies, accusation, suspicion, and betrayal — all as the same kind of coupled-integrator dynamics as the rest of the engine, plus a small bookkeeping ledger of what is hidden and what was lied about.
It is strictly opt-in. With no moral config, a persona is byte-identical to a non-moral build,
and the whole base believability corpus renders identically across the merge. You turn it on by adding a
moral overlay (calibration/moral_overlay.yaml) and moral traits/secrets to a persona.
-
Guilt core — a wrong raises guilt; confessing relieves it, staying silent lets it sit. A litmus
confess↔remain_silentdecision emerges from the state, not a rule. -
Lie loop — lying or deflecting buys short-term relief but accrues
cognitive_load_from_lies(a self-limiting noose): the more you lie, the heavier it gets. -
Repair & rumination —
apologize(empathic repair) and a rumination replay loop. -
Secrets & exposure — a
MoralLedgerofSecrets (each with amoral_weight) andLieRecords. An active secret drips salience/stress; being caught spikes exposure anxiety and guilt. -
Accusation & suspicion — being falsely accused raises a grievance (
perceived_injustice) and routes toblame_other/avoid; being watched with suspicion (innocent) raises asuspicionrelation dimension toward the watcher. - Witness fan-out — built on Architecture (multi-event per tick): one event can be perceived by several NPCs at once.
The engine has one guilt state with one half-life, but a serious wrong should weigh longer than a
minor one. Rather than a second state, an active secret re-injects guilt proportional to its authored
moral_weight × salience. So a serious unconfessed secret keeps guilt alive against decay (it lingers),
a minor one barely does (it fades), and confession/exposure inactivates the secret → the drip stops →
relief. Judge-validated timescales: minor ≈ 18h, serious ≈ 72h.
There is no PASS/FAIL rate for the moral layer — unlike the base corpus, moral behaviour is judged on a fuzzy 1–5 quality scale (believability + curve_plausibility). Testing is three blind-judge surfaces on top of a deterministic pre-filter (no LLM until the hard gates pass):
- Deterministic pre-filter — Jury + litmus gates over an 81-point magnitude grid (18/81 survive).
- Litmus judge — 12 single-situation vignettes: 4.83/5 after calibration.
- Gate-C corpus — 126 observable vignettes (7 personas × situations): weak situations lifted to 4.0/4.0, full sweep mean 3.93.
- Multi-day judge — half-life persistence; serious-guilt 72h scored 5/5, suspicion set to 24h.
All blind judging is paced (single agents over time, never one large parallel burst).
-
eval/MORAL_REPORT.md— the full moral test report (HTML twin:eval/MORAL_REPORT.html). - Plan + spec:
docs/moral_tension_PLAN.md,docs/moral_tension_impl_spec.md,docs/moral_calibration_plan.md; block diagram:docs/diagrams/moral_tension.md.