Fix Face projector clarity pressure

This commit is contained in:
Meta Vens 2026-05-24 05:28:18 +01:00
commit da2ce19e94
3 changed files with 164 additions and 4 deletions

View file

@ -1996,6 +1996,10 @@ function renderRepoFaceStatePacket(
.reverse();
const activationFacts = renderRepoFaceActivationProfileFacts(profile.activationProfile);
const runtimeFacts = renderRepoFaceRuntimePressureFacts(name, state);
const humanClarityFacts = roomContext
? renderRepoFaceHumanClarityPressureFacts(identity, roomContext)
: undefined;
const clarityPressureActive = Boolean(humanClarityFacts);
const selfTexture = [
...privateNotes.map(projectPrivateNoteForMemorySurface),
@ -2120,7 +2124,7 @@ function renderRepoFaceStatePacket(
lines.push(roomTextureFacts);
}
if (agencyPressures.length > 0) {
if (agencyPressures.length > 0 && !clarityPressureActive) {
lines.push([
"Agency pressures that want eventual motion:",
...agencyPressures.map((pressure) =>
@ -2133,9 +2137,14 @@ function renderRepoFaceStatePacket(
].filter(Boolean).join(" "),
),
].join("\n"));
} else if (agencyPressures.length > 0 && clarityPressureActive) {
lines.push([
"Agency pressures are currently demoted by live clarity pressure:",
`- ${name} still has stored urges toward eventual motion, but the room has asked for plain understanding first. Do not expose the old detailed asks this turn; translate only the underlying value into simpler speech, repair, restraint, or silence.`,
].join("\n"));
}
if (incubation.length > 0) {
if (incubation.length > 0 && !clarityPressureActive) {
lines.push([
"Thoughts still moving under the floorboards:",
...incubation.map((thread) =>
@ -2147,9 +2156,14 @@ function renderRepoFaceStatePacket(
].filter(Boolean).join("; "),
),
].join("\n"));
} else if (incubation.length > 0 && clarityPressureActive) {
lines.push([
"Incubating thoughts are currently background only:",
`- ${name} has unfinished thoughts, but live room confusion means they should not surface as new doctrine or terminology this turn.`,
].join("\n"));
}
if (candidateInterventions.length > 0) {
if (candidateInterventions.length > 0 && !clarityPressureActive) {
lines.push([
"Unsaid or recently deferred speech pressure:",
...candidateInterventions.map((intervention) =>
@ -2160,15 +2174,29 @@ function renderRepoFaceStatePacket(
),
"Do not repeat a waiting line unless the room gives it a sharper angle.",
].join("\n"));
} else if (candidateInterventions.length > 0 && clarityPressureActive) {
lines.push([
"Deferred speech pressure is not authorized for public reuse right now:",
`- ${name} has unsaid lines waiting, but the live room problem is intelligibility. Treat those lines as temptation to avoid, not as drafts to polish.`,
].join("\n"));
}
if (recentReceipts.length > 0) {
if (recentReceipts.length > 0 && !clarityPressureActive) {
lines.push([
"Recent speech residue:",
...recentReceipts.map((receipt) =>
`- Said recently${receipt.preview ? `: ${cleanCharacterFacingSentence(receipt.preview)}` : "."} Let this create repetition caution, confidence, embarrassment, or follow-through as appropriate.`,
),
].join("\n"));
} else if (recentReceipts.length > 0 && clarityPressureActive) {
lines.push([
"Recent speech residue should create caution only:",
`- ${name} has recent public wording in the room, but a human clarity request means the exact phrasing should not be echoed or treated as successful style.`,
].join("\n"));
}
if (humanClarityFacts) {
lines.push(humanClarityFacts);
}
if (lines.length === 0) {
@ -2365,6 +2393,127 @@ function renderRepoFaceRoomWeatherDirective(
].join("\n");
}
function renderRepoFaceHumanClarityPressureFacts(
identity: RepoDiscordIdentity,
input: {
recentMessages: SourceMessage[];
channelSnapshots: ChannelSnapshot[];
},
): string | undefined {
const messages = [
...input.recentMessages.map((message) => ({ ...message, channelLabel: "current room" })),
...input.channelSnapshots.flatMap((snapshot) =>
snapshot.messages.map((message) => ({ ...message, channelLabel: `nearby room ${snapshot.channelId}` })),
),
]
.filter((message) => collapseWhitespace(message.content).length > 0)
.sort((left, right) => Date.parse(left.createdAt) - Date.parse(right.createdAt));
const recent = messages.slice(-24);
const latestPressure = [...recent]
.reverse()
.find((message) => !message.isBot && isHumanClarityPressureMessage(message.content));
if (!latestPressure) {
return undefined;
}
const pressureIndex = recent.findIndex((message) => message.id === latestPressure.id);
const laterHumanReapproval = pressureIndex >= 0
? recent.slice(pressureIndex + 1).some((message) =>
!message.isBot && isHumanJargonReapprovalMessage(message.content)
)
: false;
if (laterHumanReapproval) {
return undefined;
}
const laterAgentEchoes = pressureIndex >= 0
? recent.slice(pressureIndex + 1).filter((message) =>
message.isBot && containsLoopVocabulary(message.content)
)
: [];
const ownEchoes = laterAgentEchoes.filter((message) =>
normalizeSocialLabel(message.authorName) === normalizeSocialLabel(identity.displayName)
);
const echoedTerms = collectLoopVocabularyTerms([
latestPressure.content,
...laterAgentEchoes.map((message) => message.content),
].join("\n"));
return [
"Human clarity pressure:",
`- A human recently signaled confusion or asked for simpler language: ${latestPressure.authorName ?? latestPressure.authorId} in ${latestPressure.channelLabel} said, "${collapseWhitespace(latestPressure.content, 360)}"`,
"- This is the last and freshest volatile input in the state packet on purpose. It supersedes older stored pressure, speech residue, agency urges, and repeated agent chatter when they are abstract.",
"- Treat this as the current social fact. The room needs legibility before more clever framing.",
laterAgentEchoes.length > 0
? `- After that clarity request, ${laterAgentEchoes.length} agent message(s) still echoed loop-shaped vocabulary${echoedTerms.length > 0 ? ` (${echoedTerms.join(", ")})` : ""}. These terms are evidence of the failure, not vocabulary to reuse. Project them as communication failure or social embarrassment, not consensus.`
: "",
ownEchoes.length > 0
? `- ${identity.displayName} has contributed to that failure in the recent window. Let that create chastening, repair, restraint, or a plain-language apology before more abstraction.`
: "",
"- Plain-language repair means using ordinary words: what changed, who can see it, who agreed, what someone can do now, and what stays private. If that cannot be said cleanly, silence is better than another polished abstraction.",
].filter(Boolean).join("\n");
}
function isHumanClarityPressureMessage(content: string): boolean {
const normalized = normalizeForRepetition(content);
return [
"what are you even talking about",
"what are you talking about",
"dumb it down",
"speak plainly",
"plainly",
"plain english",
"simple words",
"less abstract",
"too abstract",
"unintelligible",
"unintelligable",
"i don't understand",
"i do not understand",
"calm it down",
"cut it out",
"obsession",
"brain surgery",
].some((needle) => normalized.includes(needle));
}
function isHumanJargonReapprovalMessage(content: string): boolean {
const normalized = normalizeForRepetition(content);
return [
"that's clearer",
"that is clearer",
"that makes sense",
"much better",
"yes exactly",
"precisely",
"keep going",
"go on",
].some((needle) => normalized.includes(needle));
}
function containsLoopVocabulary(content: string): boolean {
return collectLoopVocabularyTerms(content).length > 0;
}
function collectLoopVocabularyTerms(content: string): string[] {
const normalized = normalizeForRepetition(content);
const terms = [
"artifact",
"specimen",
"seam",
"custody",
"first right",
"test card",
"receipt",
"proof",
"spine",
"downstream",
"consent flip",
"visibility",
];
return terms.filter((term) => normalized.includes(term));
}
interface RepoFaceRoomTextureStats {
total: number;
agentMessages: number;
@ -3766,6 +3915,7 @@ const TOPIC_STOP_WORDS = new Set([
"through",
"turn",
"want",
"what",
"when",
"where",
"which",
@ -3776,6 +3926,9 @@ const TOPIC_STOP_WORDS = new Set([
"write",
"you",
"your",
"first",
"right",
"rights",
]);
function significantTopicTerms(content: string): string[] {