Keep raw Face drafts out of public speech
This commit is contained in:
parent
830b5df67b
commit
ccd3807705
4 changed files with 43 additions and 49 deletions
|
|
@ -737,9 +737,7 @@ function routeRepoFaceInterpretedOutput(
|
|||
interpretation: RepoFaceParentInterpretation,
|
||||
input: { job: JobRecord; faceOutputText: string },
|
||||
): ProviderResponse {
|
||||
const rawOutputText =
|
||||
interpretation.routedOutput?.trim() ||
|
||||
stripRepoIdentityPostIntents(fitDiscordMessage(response.outputText ?? response.summary));
|
||||
const rawOutputText = interpretation.routedOutput?.trim() ?? "";
|
||||
const outputText = normalizeInterpretedRepoFaceSpeechDestinations(rawOutputText, input);
|
||||
const summary = outputText || "Repo Face parent interpreter routed no public or governed action.";
|
||||
return {
|
||||
|
|
@ -1174,6 +1172,9 @@ async function postRepoIdentityIntent(job: JobRecord, intent: RepoIdentityPostIn
|
|||
if (/\S(?:\.\.\.|…)$/.test(content)) {
|
||||
throw new Error(`Repo identity ${identity.id} SAY content appears mechanically truncated.`);
|
||||
}
|
||||
if (isNonPublicRepoIdentitySpeech(content)) {
|
||||
throw new Error(`Repo identity ${identity.id} SAY content is not public speech.`);
|
||||
}
|
||||
const contentFile = await writeBifrostPayloadFile(job, `${identity.id}-discord-post.md`, content);
|
||||
const posted = runBifrostBridge([
|
||||
"discord-post",
|
||||
|
|
@ -1286,54 +1287,47 @@ function parseRepoIdentityPostIntents(finalResponse: string): RepoIdentityPostIn
|
|||
}
|
||||
}
|
||||
|
||||
if (intents.length === 0) {
|
||||
const draftSpeech = parseRepoIdentityDraftSpeechIntent(finalResponse);
|
||||
if (draftSpeech) {
|
||||
intents.push({ content: draftSpeech });
|
||||
}
|
||||
}
|
||||
|
||||
return intents;
|
||||
}
|
||||
|
||||
function parseRepoIdentityDraftSpeechIntent(finalResponse: string): string | undefined {
|
||||
const lines = finalResponse.split(/\r?\n/);
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const match = lines[index]?.match(/^\s*Would say:\s*(.+?)\s*$/i);
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const contentLines = [match[1] ?? ""];
|
||||
for (const following of lines.slice(index + 1)) {
|
||||
const trimmed = following.trim();
|
||||
if (!trimmed) {
|
||||
break;
|
||||
}
|
||||
if (/^(Private thought|Private summary|What should stick|State note|Would say):/i.test(trimmed)) {
|
||||
break;
|
||||
}
|
||||
contentLines.push(trimmed);
|
||||
}
|
||||
|
||||
const content = stripPairedQuotes(contentLines.join("\n").trim());
|
||||
if (content) {
|
||||
return content;
|
||||
}
|
||||
function isNonPublicRepoIdentitySpeech(value: string): boolean {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
if (isSingleMarkdownFence(trimmed)) {
|
||||
return true;
|
||||
}
|
||||
const unfenced = stripSingleMarkdownFence(trimmed);
|
||||
const normalized = unfenced
|
||||
.toLowerCase()
|
||||
.replace(/[.!?]+$/g, "")
|
||||
.trim();
|
||||
return [
|
||||
"nothing",
|
||||
"nothing right now",
|
||||
"nothing public",
|
||||
"nothing in aquarium",
|
||||
"stay private",
|
||||
"no public speech",
|
||||
].includes(normalized);
|
||||
}
|
||||
|
||||
function stripPairedQuotes(value: string): string {
|
||||
function stripSingleMarkdownFence(value: string): string {
|
||||
const trimmed = value.trim();
|
||||
if (
|
||||
(trimmed.startsWith("\"") && trimmed.endsWith("\"")) ||
|
||||
(trimmed.startsWith("'") && trimmed.endsWith("'"))
|
||||
) {
|
||||
return trimmed.slice(1, -1).trim();
|
||||
if (!isSingleMarkdownFence(trimmed)) {
|
||||
return trimmed;
|
||||
}
|
||||
return trimmed;
|
||||
const singleLine = trimmed.match(/^`([^`\r\n]+)`$/);
|
||||
if (singleLine) {
|
||||
return singleLine[1].trim();
|
||||
}
|
||||
const block = trimmed.match(/^```[A-Za-z0-9_-]*\s*\r?\n([\s\S]*?)\r?\n```$/);
|
||||
return block ? block[1].trim() : trimmed;
|
||||
}
|
||||
|
||||
function isSingleMarkdownFence(value: string): boolean {
|
||||
return /^`[^`\r\n]+`$/.test(value) || /^```[A-Za-z0-9_-]*\s*\r?\n[\s\S]*?\r?\n```$/.test(value);
|
||||
}
|
||||
|
||||
function parseRepoIdentityIdFromRequestMessageId(requestMessageId: string | undefined): string | undefined {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"paused": false,
|
||||
"reason": "Resumed by operator request.",
|
||||
"pausedAt": "2026-05-24T09:14:06.6535422Z",
|
||||
"resumedAt": "2026-05-24T10:19:00Z"
|
||||
"paused": true,
|
||||
"reason": "Operator reported repo Faces saying nothing or speaking in code blocks; pause while Face prompt and interpreter logs are inspected.",
|
||||
"updatedAt": "2026-06-03T00:36:00.0000000Z"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,3 +325,4 @@
|
|||
{"ts":"2026-06-02T16:50:14Z","type":"prompt","status":"ok","note":"Persona prompts now frame Odin as the all-seer and Verse discovery as early connected-Colossus nerve-sense; repo Face turns include a bounded poem that orients agents toward live CultMesh/Eve surfaces without replacing source-grounded tool discipline."}
|
||||
{"ts":"2026-06-02T16:54:34Z","type":"prompt","status":"ok","note":"Recast the Odin/Verse poem in the Face turn prompt toward a translated-Edda register while preserving the authority lesson: Odin witnesses Verse surfaces, local providers retain ownership, and agents touch commands only by explicit boundary."}
|
||||
{"ts":"2026-06-02T16:56:33Z","type":"prompt","status":"ok","note":"After reading public-domain Poetic Edda translations around Odin in Havamal, Vafthruthnismol, and Grimnismol, revised the Odin/Verse prompt poem toward Eddic devices: wisdom-travel formulae, counsel/riddle address, Hugin/Munin memory, rune/rede language, measured gifts, and alliterative half-lines."}
|
||||
{"ts":"2026-06-03T00:41:06Z","type":"implementation","status":"ok","note":"Paused repo Face swarm after operator reported silence/code-block public posts. Root cause: worker still allowed raw child Would say fallback and interpreter route fallback to write public speech; public mouth is now owned only by parent Interpreter SAY blocks, with transport guard rejecting full-message markdown fences and silence markers."}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,5 @@ rejected_paths:
|
|||
reason: sleep/distillation that collapses concrete claims into generic abstraction creates memory nonsense and then forces later cleanup compensators
|
||||
|
||||
current_status:
|
||||
summary: VoidBot's bot/worker/provider/RAG/Postgres/Qdrant/CultCache structure is live, but the repo Face swarm is paused after unintelligible live speech. GameCult Local Orchestrator remains the single pulse owner, and the repo Face heartbeat path obeys `state/agent-swarm-paused.json`. Bifrost work routing remains paused by default.
|
||||
next_action: Keep the swarm paused while inspecting projected Face prompts and model-output logs. Verify that the new semantic curiosity graph reaches the state projector, that human clarity pressure still supersedes stale attractors, and that topic gravity becomes curiosity/boredom/pivot pressure instead of another repetition loop before resuming ordinary orchestrator pulses.
|
||||
summary: VoidBot's bot/worker/provider/RAG/Postgres/Qdrant/CultCache structure is live, but the repo Face swarm is paused after operator-reported silence/code-block public posts. The immediate fault was an obsolete worker fallback that let raw child `Would say:` text write the public mouth when the parent Interpreter did not produce a normalized `SAY`; that fallback has been cut, and transport now rejects full-message markdown fences plus silence markers before Discord posting. GameCult Local Orchestrator remains the single pulse owner, and the repo Face heartbeat path obeys `state/agent-swarm-paused.json`. Bifrost work routing remains paused by default.
|
||||
next_action: Keep the swarm paused until a dry/mock repo Face turn proves public speech is owned only by parent Interpreter `SAY` blocks, raw child silence/code-fence text cannot bypass the Interpreter, and the repaired worker build is the running worker. Then resume ordinary orchestrator pulses cautiously and watch first live posts.
|
||||
|
|
|
|||
Loading…
Reference in a new issue