Add Face social bias affect state

This commit is contained in:
Meta Vens 2026-05-24 20:38:51 +01:00
commit aa2485dff4
13 changed files with 131 additions and 10 deletions

View file

@ -750,6 +750,13 @@ function buildRepoFaceSpeakingPressure(
: 0.025;
return sum + entry.value * expressiveWeight;
}, 0);
const socialBiasPressure = (typedState.faceAffect.socialBiases ?? [])
.reduce((sum, entry) => {
const pressureWeight = ["neuroticism", "threat_sensitivity", "hostile_attribution_bias", "reassurance_need", "grievance_retention", "status_vigilance"].includes(entry.name)
? 0.055
: -0.025;
return sum + entry.value * pressureWeight;
}, 0);
const agencyPressure = typedState.agencyPressure.pressures
.filter((entry) => entry.status === "active" || entry.status === "ready_to_act")
.reduce((sum, entry) => sum + entry.intensity * (entry.kind.includes("advocacy") ? 0.22 : 0.11), 0);
@ -759,7 +766,7 @@ function buildRepoFaceSpeakingPressure(
const silencePressure = clamp(hoursSinceSpeech / 8, 0, 1);
const sleepiness = sleepCycle.isNapping ? 0.22 : 0;
const targetNeed = clamp(
0.12 + silencePressure * 0.18 + affectNeedPressure + statusReadPressure + socialBondPressure + moodPressure + agencyPressure + candidatePressure - recentSpeechDamping * 0.24 - sleepiness,
0.12 + silencePressure * 0.18 + affectNeedPressure + statusReadPressure + socialBondPressure + moodPressure + socialBiasPressure + agencyPressure + candidatePressure - recentSpeechDamping * 0.24 - sleepiness,
0,
1,
);
@ -767,8 +774,8 @@ function buildRepoFaceSpeakingPressure(
return {
needToSpeak,
confessionPressure: round3(clamp((previous.confessionPressure ?? 0.2) * 0.7 + moodPressure * 0.42 + socialBondPressure * 0.18, 0, 1)),
noveltyPressure: round3(clamp((previous.noveltyPressure ?? 0.25) * 0.62 + affectNeedPressure * 0.35 + statusReadPressure * 0.24 + candidatePressure * 0.28, 0, 1)),
confessionPressure: round3(clamp((previous.confessionPressure ?? 0.2) * 0.7 + moodPressure * 0.42 + socialBondPressure * 0.18 + socialBiasPressure * 0.2, 0, 1)),
noveltyPressure: round3(clamp((previous.noveltyPressure ?? 0.25) * 0.62 + affectNeedPressure * 0.35 + statusReadPressure * 0.24 + socialBiasPressure * 0.18 + candidatePressure * 0.28, 0, 1)),
recentSpeechDamping: round3(recentSpeechDamping),
lastSpokeAt,
};
@ -2042,6 +2049,8 @@ function renderRepoFaceStatePacket(
.sort(sortAffectByStatusAndIntensity);
const moodDimensions = [...state.faceAffect.moodDimensions]
.sort((left, right) => right.value - left.value);
const socialBiases = [...state.faceAffect.socialBiases]
.sort((left, right) => right.value - left.value);
const agencyPressures = [...state.agencyPressure.pressures]
.filter((pressure) => pressure.status !== "retired")
.sort(sortAffectByStatusAndIntensity);
@ -2148,6 +2157,15 @@ function renderRepoFaceStatePacket(
].join("\n"));
}
if (socialBiases.length > 0) {
lines.push([
"Social interpretation biases that shape ambiguous signals:",
...socialBiases.map((bias) =>
`- ${bias.name}=${bias.value.toFixed(2)}: ${asSentence(bias.summary)} Behavioral pull: ${asSentence(bias.behavioralPull)}`,
),
].join("\n"));
}
if (durableMemories.length > 0) {
lines.push([
"Durable memories that should still bias judgment:",

View file

@ -66,7 +66,7 @@ try {
throw new Error(`read_repo_face_state did not expose typedState.faceAffect for ${identity}.`);
}
for (const field of ["needs", "socialBonds", "statusReads", "moodDimensions"]) {
for (const field of ["needs", "socialBonds", "statusReads", "moodDimensions", "socialBiases"]) {
if (!Array.isArray(faceAffect[field])) {
throw new Error(`typedState.faceAffect.${field} is not an array for ${identity}.`);
}
@ -86,6 +86,7 @@ try {
socialBonds: faceAffect.socialBonds.length,
statusReads: faceAffect.statusReads.length,
moodDimensions: faceAffect.moodDimensions.length,
socialBiases: faceAffect.socialBiases.length,
},
}, null, 2)}\n`);
} finally {