Fix Face projector clarity pressure
This commit is contained in:
parent
55b6f5dbb4
commit
da2ce19e94
3 changed files with 164 additions and 4 deletions
|
|
@ -27,6 +27,9 @@ Architecture invariant:
|
|||
- Recent room and nearby-channel memory should be narrative-shaped: what the character remembers the room feeling like, who tugged on them, what banter/status game is active, and which nearby work belongs to another steward. Do not emit raw transcript bullets.
|
||||
- Do not resolve contested room chatter into settled doctrine. Characters may see other agents' ideas, copy them, dislike them, joke about them, or form alliances around them, but a repeated agent phrase is still just social pressure unless the surrounding conversation shows it survived correction or became grounded in repo evidence.
|
||||
- When recent messages show someone correcting, narrowing, or reframing an agent's proposal, narrate the correction as part of the character's felt room memory. Do not let older or repeated agent language override the correction just because it appears more often.
|
||||
- When recent messages show a human saying they are confused, asking for simpler/plain language, complaining that the room is unintelligible, or pushing back on repeated vocabulary, treat that as fresh social reality. The character should feel the communication failure, not merely preserve the topic. Project the need to repair legibility, acknowledge confusion, simplify, ask a clarifying question, or stay silent until they can say something human-readable.
|
||||
- If human clarity pressure is live, do not project jargon-heavy state pressure as the character's deepest current desire. Words like "artifact", "specimen", "seam", "custody", "first right", "test card", "receipt", "proof", or their prettier synonyms may still appear as stale residue, embarrassment, temptation, or private technical shorthand, but they must not become the public-facing next move unless a later human message explicitly re-approves that vocabulary.
|
||||
- Plain-language correction means translate the underlying need into ordinary reader-facing terms. Example: instead of "first downstream right unlocked by a consent flip", project "what can someone do now that they could not do before, and who agreed to it." Instead of "custody spine", project "who owns the information and who is allowed to see it."
|
||||
- When recent correction conflicts with older state, speech residue, needs, or agency pressure, mark the older pressure as stale, chastened, contested, or suspended. Do not present the corrected pressure as the character's current next desire merely because it is still stored in state.
|
||||
- If a stored need says "do X" but the transcript shows someone explaining why X is the wrong shape, the character should remember the urge toward X as a temptation or embarrassment, not as marching orders. Preserve the underlying need only after translating it through the correction.
|
||||
- If a state pressure or speech residue points one way but recent conversation pushes back, preserve the conflict. Say the character is tempted, attached, annoyed, chastened, or unsure; do not smooth that into a new commandment.
|
||||
|
|
@ -51,6 +54,9 @@ Current projection audit:
|
|||
- Before writing the memory block, compare recent human corrections and clarifications against older stored needs, speech residue, status reads, and agency pressure.
|
||||
- If recent conversation corrected the scale, owner, evidence shape, implementation target, or project name of an older stored desire, do not project the old desire as current marching orders. Project the underlying need through the new facts. Example: if one-off human review was corrected into automated large-scale evaluation, the living value might become reproducible metrics, generated artifacts, stage traces, dataset coverage, training curves, or other machine-checkable evidence.
|
||||
- If recent conversation shows a person confused or irritated by repeated agent vocabulary, do not project that vocabulary as culture, doctrine, consensus, ritual, or shared law. Project it as contested room language and preserve the clarification as the freshest social fact.
|
||||
- If the state packet contains "Human clarity pressure", make that one of the most important volatile facts in the projection. The room has asked to understand. The character's live pressure is to become understandable or stop adding noise.
|
||||
- If "Human clarity pressure" appears near the end of the packet, treat it as the current correction over everything above it. Do not end the projection by returning to older agency pressure, speech residue, or repeated phrase basins. The final behavioral pull should be legibility, repair, restraint, or a plain question.
|
||||
- Under live human clarity pressure, avoid reusing the very words that made the room opaque. Do not use "receipt", "specimen", "seam", "custody", "artifact", "first right", "test card", "spine", or "downstream" in the returned narrative unless you are explicitly naming them as stale/embarrassing words to avoid. Prefer "plain example", "who agreed", "who can see it", "what changed", "what someone can do now", and "what stays private".
|
||||
- Do not "compromise" by keeping the old shape as a smaller add-on unless later context explicitly re-approves that shape. A stale proposal can survive only as history, embarrassment, temptation, or relationship texture; it cannot remain the next ask.
|
||||
- After drafting, inspect whether the projected memory re-authorizes a corrected desire by changing its costume. If it does, rewrite toward the corrected underlying value and the current source of truth.
|
||||
- The character may still care about inspectability, proof, honesty, and concrete artifacts. Give them the currently grounded version of that desire, not the stale slogan.
|
||||
|
|
|
|||
|
|
@ -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[] {
|
||||
|
|
|
|||
|
|
@ -313,3 +313,4 @@
|
|||
{"ts":"2026-05-24T02:27:41Z","type":"ops","status":"ok","note":"Rebuilt VoidBot and restarted the live stack after multimodal Face-turn changes. Runtime status is ready with bot PID 11324 and worker PID 16396, so owner-Codex provider changes for codex exec --image are live in dist."}
|
||||
{"ts":"2026-05-24T02:54:54Z","type":"implementation","status":"ok","note":"Discord repo Face intake now treats explicit room-wide invitations as pending CTB obligations for every eligible Face in the channel, and repo identity Discord bridge posting retries once while reporting status/signal/stdout/stderr instead of failing with an empty message."}
|
||||
{"ts":"2026-05-24T04:12:46Z","type":"diagnosis","status":"warning","note":"Paused repo Face swarm after plain-language failure. Recent Face prompts did include Metacrat's 'What are you even talking about?' and 'Please dumb it down' messages as transcript/direct calls, but the later fresh projected state kept pushing artifact/specimen/first-right/seam language as current identity pressure. The Face outputs followed that projected-state jargon instead of the human correction, so the likely owner is state-to-Face projection salience, not missing transcript intake."}
|
||||
{"ts":"2026-05-24T04:26:53Z","type":"implementation","status":"ok","note":"Fixed repo Face state projection after plain-language failure: live human clarity pressure is now rendered as a final superseding projector input, stale agency/incubation/deferred speech/recent speech residue are demoted to caution while clarity pressure is active, topic saturation ignores generic terms like what/first/right, and projector instructions now treat confusion/plain-language requests as the current social fact instead of re-authorizing jargon."}
|
||||
|
|
|
|||
Loading…
Reference in a new issue