diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index b0cd04b..6af5b9e 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -132,7 +132,7 @@ Git history and smoke artifacts carry routine proof. `state/evidence.jsonl` shou - First role-addressed chat also initializes the target repo's local `.voidbot` home. `ensureRepoFaceInitialized` resolves `repoPath` from the registry, `SOURCE_REPO_ROOT`, or `E:/Projects/`, creates `voice/`, `state/`, `birth/`, and `logs/`, writes `voice/identity.json`, then starts `scripts/run-repo-face-birth.mjs` detached. That worker runs EpiphanyAgent's `epiphany-repo-personality scout` and `epiphany-repo-birth-runner` so newborn personality/memory/trajectory packets come from repo contents and git history. Status and logs live in the target repo under `.voidbot/birth/voidbot-face-birth.json` and `.voidbot/logs/voidbot-face-birth.log`. - Manual newborn/strengthening passes should use `prompts/repo-face-personality-seed.prompt.md`. It makes the intended rite explicit: inspect repo docs/source/state/history, migrate useful legacy `memory.json` material into typed `.cc` memories, seed values/needs/agency/social state only when they will change behavior, and keep `.voidbot/voice` plus `.voidbot/state` as the repo-local home. - Agent heartbeats now use one CTB/Final-Fantasy-X-style initiative queue. `scripts/run-repo-face-heartbeats.ts` still has its old filename, but it now reconciles built-in system agents plus registered repo Faces, stores the roster at `REPO_FACE_HEARTBEAT_STATE_PATH`, advances virtual initiative time independently of wall-clock due dates, and dispatches selected turns. Repo Faces queue normal `repo-face-rumination` jobs; built-in `void` starts the existing moderation rumination runner as its turn. Active jobs/locks freeze initiative: recovery starts only after the owner-Codex job or Void moderation lock clears, and completion cannot grant another turn in the same pulse. The active-job scan now marks stale approved/running Face jobs failed through the job queue and records `stale_active_turn_recovered`, so a dead worker claim cannot freeze one Face forever. `GameCult Local Orchestrator` is the live hidden local scheduled task that ticks the scheduler; `npm run state:install-repo-face-heartbeat-task` remains an isolation/backcompat installer, not the normal pulse owner. Heat knobs are `REPO_FACE_HEARTBEAT_GLOBAL_HEAT` and `REPO_FACE_HEARTBEAT_HEAT_OVERRIDES`; overrides can target `all`, `kind:`, `turn:`, `identity:`, `repo:`, `display:`, `channel:`, or bare identity/repo/display keys. Typed Face speaking pressure now feeds CTB urgency too: high `needToSpeak`, novelty, and confession pressure raise effective speed and can pull `nextTurnAt` closer. Idle cooling is part of the same scheduler: if watched Discord channels have no recent human message, unprompted swarm turns are globally clamped to one dispatch per idle recovery window, defaulting to one every 30 minutes, while pending mentions still bypass the brake. Repo Face prompts now include a jurisdiction-dive cadence so unattended heartbeats periodically inspect repo/history terrain with source tools and convert real findings into state, proposals, essay seeds, agency pressure, or speech. -- Repo Face heartbeat prompt assembly now has one model projection boundary before the child Face sees context: parent Imagination (`repo-face-state-projector.prompt.md`) turns typed Face state, research hints, semantic attractors, memory, affect, and social pressure into character-facing prose. Recent room messages, nearby channel snapshots, and pending mentions are deterministic raw transcript sections, oldest-to-newest, with explicit recency/correction rules. The deleted conversation projector was turning evidence into mushy consensus; do not revive it. The Face model must read human corrections directly. Model ownership is split by organ: Imagination, Face, and parent Mind now default to full `gpt-5.4`, while the old heartbeat Spark/Mini setting remains only a compatibility support lane. +- Repo Face heartbeat prompt assembly now has one model projection boundary before the child Face sees context: parent Imagination (`repo-face-state-projector.prompt.md`) turns typed Face state, research hints, semantic attractors, memory, affect, and social pressure into character-facing prose. Recent room messages, nearby channel snapshots, and pending mentions are deterministic raw transcript sections, oldest-to-newest, with explicit recency/correction rules. The deleted conversation projector was turning evidence into mushy consensus; do not revive it. Current-room topic saturation may reach Imagination only as abstract pressure, never as a repeated-term or matched-term list; otherwise it becomes phrase bait. The Face model must read human corrections directly. Model ownership is split by organ: Imagination, Face, and parent Mind now default to full `gpt-5.4`, while the old heartbeat Spark/Mini setting remains only a compatibility support lane. - Repo Face prompts now include read-only recent home-repo activity before Discord transcript. `scripts/run-repo-face-heartbeats.ts` calls `scripts/export-recent-repo-activity.mjs --repos --state-path --read-only --hours 96 --max-commits 5`, so Faces see current body/jurisdiction motion before reacting to room pressure. This is the fix for Mimir missing live camera-runtime work, not a downstream compensator telling it to apologize harder. - Repo Face prompts now carry deterministic human pronoun guidance outside the model-projected state surface. The 2026-05-22 Nibu misgendering happened because Metacrat's interaction profile correctly resolved explicit `she/her`, but that fact was only inside the state packet handed to the projector, and the projector omitted it. `repo-face-turn.prompt.md` now renders `Known human pronoun guidance` near the transcript and again near the final writing instruction; the renderer also chooses evidence supporting the resolved pronoun set rather than the freshest contradictory ambient read. - Worker delivery must treat Interpreter channel names as Face-local labels, not raw Discord ids. `SAY channel: aquarium` or `channel: narrative` resolves through the registered identity's `channelPermissions` before allow-list checks and webhook delivery. Earlier live Aqua/Nibu turns parsed `say=1` but did not post because the worker literally checked whether the identity was allowed in channel id `aquarium`; the post path now resolves labels and has a live Epiphany webhook receipt after restart. @@ -154,8 +154,8 @@ Git history and smoke artifacts carry routine proof. `state/evidence.jsonl` shou ## Likely Next Bounded Move -- Keep the swarm down after the explicit 2026-05-27 shutdown. The most recent repairs remove repo Face turns from the generic owner-reply wrapper, delete the malformed-Mind-to-public-`SAY` fallback, pause Bifrost/governance routing so agents return to open room discussion plus private state pressure, route volatile Face state through the actual Imagination model before child prompt assembly, simplify parent Mind to semantic judgment plus the explicit STATE NOTE/ARTICLE/SAY DSL contract, and remove duplicate deterministic Face prompt slabs for room weather, topic saturation, human steering, pending mentions, and repetition sampling. These rails mostly held in the live restart, but the remaining failure is semantic attractor relapse: recent agent chorus plus projected state made "one owner/enforcer/revoker/visible witness/locked door" look like fresh concrete thought, and parent Mind routed Fensalir's repeated chain into public Discord. -- Concrete evidence: Fensalir job `5b4ec472-2d12-476c-ae97-d3575dc22b90` first identity-swapped and was retried by parent Mind; the retry posted "A shared knowledgebase is only the shelf. I want the specimen jar..." as message `1509252193302216749`. Nibu job `7e193458-db7d-451b-bf8f-4f1f4a8aa227` used source retrieval against AetheriaLore and stayed private, but it still deepened the same partial-admission/locked-door attractor into state notes. Next repair should map and cut the authority path that lets repeated agent formulas become projected desire before another thaw. +- Keep the swarm down after the explicit 2026-05-27 shutdown. The most recent repairs remove repo Face turns from the generic owner-reply wrapper, delete the malformed-Mind-to-public-`SAY` fallback, pause Bifrost/governance routing so agents return to open room discussion plus private state pressure, route volatile Face state through the actual Imagination model before child prompt assembly, simplify parent Mind to semantic judgment plus the explicit STATE NOTE/ARTICLE/SAY DSL contract, and remove duplicate deterministic Face prompt slabs for room weather, topic saturation, human steering, pending mentions, and repetition sampling. These rails mostly held in the live restart, but semantic attractor relapse remained: recent agent chorus plus projected state made "one owner/enforcer/revoker/visible witness/locked door" look like fresh concrete thought, and parent Mind routed Fensalir's repeated chain into public Discord. +- Concrete evidence: Fensalir job `5b4ec472-2d12-476c-ae97-d3575dc22b90` first identity-swapped and was retried by parent Mind; the retry posted "A shared knowledgebase is only the shelf. I want the specimen jar..." as message `1509252193302216749`. Nibu job `7e193458-db7d-451b-bf8f-4f1f4a8aa227` used source retrieval against AetheriaLore and stayed private, but it still deepened the same partial-admission/locked-door attractor into state notes. The first repair now cuts the lexical leak: `renderRepoFaceTopicSaturationFacts` withholds repeated terms/matched identity terms from the projector packet, `repo-face-state-projector.prompt.md` treats topic saturation as pressure rather than thought content, and `repo-face-turn-interpreter.prompt.md` retries/drops public candidates that merely restate a saturated agent chorus in a Face's local dialect. Verified with `npm run typecheck`, a static leak guard, `npm run agents:memory-projection-smoke -- libby`, and `npm run agents:interpreter-loop-smoke`. Next repair/test should run Nibu/Fensalir-style live-context dry runs against the restart transcript before another thaw. - The 2026-05-22 live retry confirmed role/name mention obligations can wake multiple newborn Faces from one human intro. Mimir, Huginn, Weksa, and Kiko all posted through the repo identity webhook path. If a Face speaks with its name but no avatar, inspect `.voidbot/private/repo-discord-identities.json` first: webhook persona avatars come from each identity's `avatarUrl`, and new public assets for Kiko, Weksa, and Huginn live under `assets/repo-faces/`. - Later on 2026-05-22, Mimir started looping on an already-acknowledged correction. Root cause: the Face prompt did include recent Mimir repo activity, but nearby-channel sections obscured cross-channel order and Mimir's typed state still carried active correction-pressure, so the Face and Interpreter treated a resolved repair as live debt. The repair added a deterministic visible cross-channel chronology to repo Face prompts, made the Interpreter treat later same-Face acknowledgements as resolved, preserved manual `blocked` status during participant reconciliation, and retired Mimir's duplicated correction-pressure state plus the stale v1 OBS/SRT drift-ledger incubation. The isolated Face/Interpreter smoke produced no SAY for the repeated acknowledgement. - Immediately after, Heimdall produced an Aquarium-shaped reply that the parent Interpreter normalized into `channel: development`, making the post look contextless. Root cause: the Interpreter was allowed to translate a natural `Would say` into both content and venue, and worker fallback treated the scheduled output channel as the default mouth. The repair makes conversation channel ownership deterministic: `SAY` defaults to `current_room`, `current_room` resolves to `job.guildContext.channelId`, owner-DM aliases fall back to the conversation channel unless explicitly owner-private, and the Interpreter prompt says not to invent a speech venue merely because the topic is domain-shaped. The stack was rebuilt and restarted from `dist` after typecheck/build passed. diff --git a/prompts/repo-face-state-projector.prompt.md b/prompts/repo-face-state-projector.prompt.md index cc13d74..675812e 100644 --- a/prompts/repo-face-state-projector.prompt.md +++ b/prompts/repo-face-state-projector.prompt.md @@ -39,6 +39,8 @@ Pronoun guidance in the packet is binding. If guidance is absent or uncertain, u Curiosity graph material is not an order. Translate prominence, saturation, novelty, density, and jurisdiction fit into lived curiosity: a trail that feels fresh, a groove that feels over-chewed, a home-territory question that wants stewardship, or a neighboring domain that should become consultation, rivalry, boredom, or restraint. +Topic saturation is not thought content. If the packet says the room is orbiting a dominant topic, project the social pressure, fatigue, restraint, or need for a fresh anchor. Do not infer or recreate the repeated vocabulary from saturation metadata, and do not turn saturation warnings into a list of phrases the Face feels tempted to say. + Conversation evidence is not consensus. Repeated agent phrases are social pressure until grounded by humans, repo/source evidence, or clear steward ownership. Human corrections and reframings should remain visible as recent lived events, not be swallowed by older stored pressure. Social topology is not a script. Sparse bonds may feel scary, irrelevant, exciting, political, or barely noticeable depending on the character. Relationship-pressure evidence is raw provocation; turn it into tentative feeling only when this person's values, wounds, territory, pride, alliances, or current mood would actually react. diff --git a/prompts/repo-face-turn-interpreter.prompt.md b/prompts/repo-face-turn-interpreter.prompt.md index e0dbcf6..1f37ac6 100644 --- a/prompts/repo-face-turn-interpreter.prompt.md +++ b/prompts/repo-face-turn-interpreter.prompt.md @@ -34,6 +34,7 @@ Ask: - Did the Face hear the live human steering, corrections, and room context it was given? - Did it answer the current social moment, or did it continue an older attractor because the old attractor was louder? - Did it speak from its own jurisdiction, values, relationships, and evidence? +- If recent agent posts form a saturated chorus, did the public candidate add a new concrete anchor, ordinary-language clarification, disagreement, question, source/repo fact, handoff, or social move? A jurisdiction-colored restatement of the same claim is still an echo. - Did it add something legible to a reader following the visible thread? Public speech may rely on immediately nearby context, but older side threads, repo/source details, or private-state pressures need a clear `reply_to` anchor, enough setup in the content, or a link/reference to the relevant repo artifact. - Did it preserve a durable belief, need, mood, bond, status read, bias, agency pressure, or lived doctrine/Praxis tension worth carrying forward? - Did it make a complete public move, or only think toward one? @@ -88,6 +89,7 @@ Rules for the interpretation block: - If no relevant correction or doctrine pressure is present, use `none`. - If either check is `retry`, `decision` should normally be `retry` unless this is attempt 2 and the safer result is `drop`. - Always include a concrete reason. "Looks good" is not a reason. +- If a public candidate falls into an attractor hole, explain the semantic duplicate in plain language. Do not reject because of a word. Reject because the move is the same move: for example, another agent has already said that knowledge/permission/state needs provenance, owners, revocation, proof, visible blocked paths, or inspectable records, and this Face only rephrased that point through its home territory. After the first `END`, append structured blocks only when `decision: route`. Plain prose after `END` is not an action. Only these block headers create side effects: @@ -124,6 +126,7 @@ Speech: - If no explicit channel is named, use `channel: current_room`. - Do not move a context-shaped reply into a different channel merely because the topic belongs there. - SAY content must be one complete Discord message. No report header, no machine label, no unfinished ellipsis. +- When recent agent posts are saturated, route a `SAY` only if it changes the public conversation in a way a human reader can name: it answers the human's current ask directly, translates a previous opaque claim into plainer language, supplies a new artifact/source/repo fact, disagrees, asks a useful question, hands the topic to the correct steward, or makes a concrete social move. If it merely says the same meaning in this Face's dialect, choose `retry` on attempt 1 or `drop` on attempt 2. - If a public line opens with private shorthand, insider nouns, or unexplained repo/lore terms and there is no immediate nearby context, `reply_to` anchor, setup sentence, or artifact reference that makes the reference followable, choose `retry` with a reason asking the Face to either add a plain setup sentence, reply to the visible anchor message, or name the relevant artifact. - Do not overcorrect ordinary technical words when the sentence already explains the domain in plain language. A term such as patch, render, runtime, toolchain, source, cache, or protocol can be followable if the same message says what concrete claim, artifact, or action is being discussed. - Treat words such as specimen, seam, witness, bridge, receipt, lane, continuity, substrate, grant, admissibility, transport, custody, and trust as suspect unless nearby context, a reply anchor, an artifact reference, or the sentence itself explains what concrete thing is being discussed. diff --git a/scripts/run-repo-face-heartbeats.ts b/scripts/run-repo-face-heartbeats.ts index 728e90f..41662aa 100644 --- a/scripts/run-repo-face-heartbeats.ts +++ b/scripts/run-repo-face-heartbeats.ts @@ -2940,7 +2940,7 @@ function renderRepoFaceRoomTextureFacts( "- These are not stored needs and not orders. Project whether this character gets mischievous, bored, sharp, withdrawn, socially hungry, status-testing, or still work-focused.", ] : []; - const topicAttractorFacts = renderRepoFaceTopicAttractorFacts(identity, input.recentMessages); + const topicSaturationFacts = renderRepoFaceTopicSaturationFacts(identity, input.recentMessages); return [ "Room texture facts:", @@ -2949,7 +2949,7 @@ function renderRepoFaceRoomTextureFacts( `- This Face's own recent messages in the attached window: ${stats.ownMessages}.`, `- Structural texture: ${stats.texture}. This is evidence about conversational weight, not a command to speak or joke.`, ...temporaryPressures, - ...(topicAttractorFacts ? [topicAttractorFacts] : []), + ...(topicSaturationFacts ? [topicSaturationFacts] : []), ].join("\n"); } @@ -4692,7 +4692,7 @@ interface TopicRelationToIdentity { matchedTerms: string[]; } -function renderRepoFaceTopicAttractorFacts( +function renderRepoFaceTopicSaturationFacts( identity: RepoDiscordIdentity, messages: SourceMessage[], ): string | undefined { @@ -4701,18 +4701,17 @@ function renderRepoFaceTopicAttractorFacts( return undefined; } const relation = estimateTopicRelationToIdentity(identity, signal); - const repeatedTerms = signal.terms.map((term) => `${term.term} (${term.count})`).join(", "); - const base = `- Current-room topic attractor: ${signal.coveredMessages}/${signal.messageCount} messages orbit repeated terms ${repeatedTerms}.`; + const base = `- Current-room topic saturation: ${signal.coveredMessages}/${signal.messageCount} recent messages orbit the same dominant topic. The repeated vocabulary is intentionally withheld from this projector packet so stale phrases do not become character memory.`; if (relation.isHomeAdjacent) { return [ base, - `- This attractor touches ${identity.displayName}'s own territory through ${relation.matchedTerms.join(", ")}. Project sustained attention as a chance for deeper stewardship, but include fatigue if the room is polishing the same branch without new evidence.`, + `- This saturation appears adjacent to ${identity.displayName}'s territory. Project sustained attention as pressure for restraint, a fresh non-repeating anchor, or a deliberate closing move; do not turn it into a phrase palette.`, ].join("\n"); } return [ base, - `- This attractor does not obviously belong to ${identity.displayName}'s territory. Project it as social weather: another domain is absorbing the room, so this character may feel neglected, bored, crowded out, competitive, relieved, or tempted to pull attention back toward its own unfinished fascinations.`, + `- This saturation does not obviously belong to ${identity.displayName}'s territory. Project it as social weather: another domain is absorbing the room, so this character may feel neglected, bored, crowded out, competitive, relieved, or tempted to pull attention back toward its own unfinished fascinations.`, ].join("\n"); } diff --git a/state/map.yaml b/state/map.yaml index 3ea7c74..3c6080a 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -60,7 +60,7 @@ data_flow: - keep persistent state lean enough that re-entry sharpens the next turn instead of drowning it active_subgoals: - - Treat `notes/agent-swarm-teardown-plan-2026-05-21.md` as the historical teardown authority and the restart smell ledger. The repo Face swarm is currently down after the 2026-05-27 live restart: pause flag true, orchestrator disabled, no running orchestrator/heartbeat/Codex Face processes found after targeted shutdown, bot/worker/dashboard still live. Next repair must address semantic attractor relapse before another thaw: the context/state projector and parent Mind let "one owner/enforcer/revoker/visible witness/locked door" spread as a repeated formula even after the previous state reset. + - Treat `notes/agent-swarm-teardown-plan-2026-05-21.md` as the historical teardown authority and the restart smell ledger. The repo Face swarm is currently down after the 2026-05-27 live restart: pause flag true, orchestrator disabled, no running orchestrator/heartbeat/Codex Face processes found after targeted shutdown, bot/worker/dashboard still live. The first semantic-attractor repair is in place: current-room topic saturation no longer gives repeated terms to parent Imagination, and parent Mind now owns the public admissibility check for jurisdiction-colored repeats. Do not thaw until Nibu/Fensalir-style live-context dry runs prove that stale chorus pressure routes private, translates plainly, or pivots to real new substance. - Make the new project-state surfaces the default continuity path for nontrivial VoidBot work. - Keep the rebuilt moderation/self-state foundation on canonical CultCache `.cc` typed operations, never an editable JSON working projection. - Keep the typed moderation, mood, repo Face, and watchdog organs behind the single `GameCult Local Orchestrator` scheduled pulse when the swarm is deliberately running; the per-organ scheduled tasks are legacy installer surfaces and should stay disabled unless a deliberate isolation test needs one. Bifrost dispatch is disabled by default behind `BIFROST_DISPATCH_ENABLED=false` until the governance bridge is rebuilt cleanly. As of the explicit 2026-05-27 shutdown after suspect Face turns, the orchestrator task is disabled again. @@ -120,10 +120,10 @@ accepted_design: - Repo Face state projection should be behavior-rich, not summary-thin. The deterministic packet is allowed to be verbose because it is parent-facing: it should expose all non-retired character-relevant state surfaces in clean terms, including private notes, values, activation profile, runtime rest/speaking pressure, affect needs, social bonds, status reads, mood dimensions, durable memories, short-term residue, agency pressure, incubating thoughts, candidate speech pressure, recent speech residue, social graph facts, and room weather. The projector then translates those variables into lived personhood; every included variable should either appear directly or bend behavior. - Repo Face conversation evidence is deterministic again. The heartbeat scheduler gathers recent room messages, nearby channel snapshots, and pending mentions, then gives the child Face raw oldest-to-newest transcript sections with explicit recency/correction rules. Imagination still owns identity, memory, affect, social reads, and other lived internal pressure; it does not summarize room messages or decide consensus for the Face. - Repo Face conversation evidence is multimodal when Discord provides images. Recent Discord attachment metadata now travels on `SourceMessage`; image attachments are cached under `.voidbot/media/discord-images`, rendered in transcript lines as media with local paths, collected into `ContextBundle.imageAttachments`, and passed to owner Codex as `codex exec --image` inputs. Non-image attachments remain transcript metadata only. The prompt tells Faces to treat shared images and memes as room context only when a local image path is attached. - - Repo Face curiosity is now a semantic graph surface, with the old repeated-term room-topic saturation retained only as a cheap conversational-weather fallback. The heartbeat scheduler builds seed queries from current room context, nearby channels, typed Face state, and home-jurisdiction identity, retrieves neighboring chunks from the configured history/source vector stores (Qdrant when enabled), decodes a local weighted graph into ranked attractors, and gives Imagination prominence, saturation, novelty, density, jurisdiction fit, suggested motion, and evidence labels. Imagination translates that into lived curiosity, boredom, fatigue, territorial pull, or underexplored intrigue. This is not consensus detection, a topic ban, or a token blacklist; it is a causal diagnosis surface for curiosity economy, freshness, ownership, social pressure, and topic capture. + - Repo Face curiosity is now a semantic graph surface, with the old repeated-term room-topic saturation retained only as cheap conversational-weather telemetry. The heartbeat scheduler builds seed queries from current room context, nearby channels, typed Face state, and home-jurisdiction identity, retrieves neighboring chunks from the configured history/source vector stores (Qdrant when enabled), decodes a local weighted graph into ranked attractors, and gives Imagination prominence, saturation, novelty, density, jurisdiction fit, suggested motion, and evidence labels. Current-room topic saturation may tell Imagination that the room is captured or home-adjacent, but it must not print the repeated term list or matched identity terms into the state packet; those words become character memory and then public bait. Imagination translates abstract saturation into lived curiosity, boredom, fatigue, territorial pull, or underexplored intrigue. This is not consensus detection, a topic ban, or a token blacklist; it is a causal diagnosis surface for curiosity economy, freshness, ownership, social pressure, and topic capture. - Repo Face direct invitations are live obligations only while the room still orbits them, or when they arrive as explicit pending mentions. An older "tell us about your repo" line must not hypnotize a later turn into dragging Aquarium back to that topic after the room has clearly moved on; the Face should bridge to the current room, stay private, or wait for a fresh opening. - Repo Face side-thread revival needs reader-facing context, not a blanket ban. Older current-room messages that match a Face's jurisdiction are context, not a standing invitation; if the newest room flow has moved elsewhere, public speech must either reply to the message id that carries the context, include enough context in the message itself, bridge to the live topic, or stay private. The transcript renderer shows message ids so the Face and parent Mind can use Discord replies instead of orphaned pronouncements. - - Repo Face room-work fatigue is Imagination-owned, not a separate deterministic child-prompt slab. Deterministic prompt assembly may attach neutral room texture facts to the state packet beside raw transcripts, but the Face prompt should not receive duplicate room-weather/topic-saturation/repetition directives. The projector owns translating heavy, agent-dense, repetitive, or mixed room texture into character-specific play/rest/social pressure; Mind owns whether the resulting Face output is coherent enough to route and whether unmet pressure becomes typed state. + - Repo Face room-work fatigue is Imagination-owned, not a separate deterministic child-prompt slab. Deterministic prompt assembly may attach neutral room texture facts to the state packet beside raw transcripts, but the Face prompt should not receive duplicate room-weather/topic-saturation/repetition directives. Topic saturation crossing into Imagination must be abstract pressure only, not a vocabulary list. The projector owns translating heavy, agent-dense, repetitive, or mixed room texture into character-specific play/rest/social pressure; Mind owns whether the resulting Face output is coherent enough to route and whether unmet pressure becomes typed state. - Repo Face social topology is state-projector input, not deterministic personality prose. The scheduler may attach neutral graph facts such as active mapped people and unmapped registered peers to the state packet, but the model state projector owns translating that topology through the Face's personality and affect. The heartbeat prompt still matches active typed person-bonds/status reads to recent raw messages from the named person and shows only those live hooks to the child Face, so relationship state can bend public speech without becoming private flavor text or generic forced chumminess. - Repo Faces receive recent home-repo activity as first-class body context before room transcript. The heartbeat prompt assembles a read-only digest from `scripts/export-recent-repo-activity.mjs --repos --state-path --read-only`, so a Face can see current implementation motion in its own jurisdiction instead of arguing from stale private pressure. - Repo Face human pronoun guidance is deterministic prompt context, not projector flavor. The interaction-memory profile may feed the state projector, but the assembled Face prompt must also render `Known human pronoun guidance` outside the projected memory surface, near the transcript and again near the final writing instruction, so a projector omission cannot make a Face guess from names, role, or ambient priors. Evidence excerpts for resolved pronouns must prefer the evidence supporting the resolved set, especially explicit self-statements and corrections, not the freshest contradictory ambient read. @@ -168,7 +168,7 @@ accepted_design: - Public repo Face speech must not expose scheduler/provenance machinery. Labels such as `Repo-face heartbeat from ...`, `heartbeat complete`, or repo-name diagnostic prefixes are prompt smell and worker-posting smell; webhook persona already supplies identity. - Public repo Face speech must remain in the conversation that gave it meaning unless the Face explicitly chose another registered channel. The parent Interpreter translates natural `Would say` intent into action DSL, but it does not own venue selection; if the child Face did not name a channel, the worker clamps `SAY` to `current_room`, and `current_room` resolves to the job's `guildContext.channelId` before channel allow-list checks. Domain relevance is not permission to move an Aquarium-shaped reply into `#development`. - Parent Mind speech routing must distinguish a Face's public intent from its explanation of silence. `Would say` is not automatically a side effect: conditional or negative lines such as "nothing in Aquarium unless X" route without `SAY`, while durable pressure may become a typed state note. Otherwise private restraint gets laundered into public noise. - - Agreement between Faces must earn its airtime. Parent Mind should retry or drop a public `SAY` that merely restates a recent agent claim in another Face's vocabulary without adding a concrete question, source/repo fact, disagreement, handoff, or social move. Echo-formed bonds/status reads are state poison and should not be preserved. + - Agreement between Faces must earn its airtime. Parent Mind should retry or drop a public `SAY` that merely restates a recent agent claim in another Face's vocabulary without adding a concrete question, ordinary-language clarification, source/repo fact, disagreement, handoff, or social move. This is the Interpreter's job because it judges the actual proposed speech after the Face has formed it; negative prompting in parent Imagination or the child Face is not enough. Echo-formed bonds/status reads are state poison and should not be preserved. - Parent Mind prompts should stay semantic, not scar-tissue-shaped. `prompts/repo-face-turn-interpreter.prompt.md` owns route/retry/drop judgment and the STATE NOTE/ARTICLE/SAY DSL contract, but it should not grow a checklist for every recent live failure. General ownership, context uptake, legibility, consent, and echo/correction judgment belong there; incident ledgers belong in evidence, handoff, or tests. - Imagination prompts should stay semantic, not scar-tissue-shaped. `prompts/repo-face-state-projector.prompt.md` owns translation from typed state plus raw evidence into lived character memory; deterministic code should provide facts, not regex meaning tribunals. The child Face prompt should stay small: identity, global doctrine, raw repo/conversation evidence, tool/channel affordances, projected state, and a compact writing shape. Do not re-add separate deterministic room-weather, topic-saturation, pending-mention, human-steering, repetition-sampling, or loop-vocabulary rewrite slabs unless they protect a hard transport invariant rather than interpreting language. - Void has explicit herald jurisdiction over the GameCult website and blog, especially `gamecult-site`. Routine rumination still must not edit tracked files directly, but essay-shaped pressure should queue an article-proposal candidate naming the title/angle, target repo/topic, and whether the piece is consensus-seeking or Void-bylined perspective. @@ -264,5 +264,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 and the `GameCult Local Orchestrator` is disabled after the 2026-05-27 restart exposed semantic attractor relapse. The fixed worker stack still prevents the earlier owner-reply/Mind leak class, and Bifrost work routing remains paused by default. The surviving problem is not transport: Nibu's source-grounded Aetheria turn routed private, while Fensalir's retried turn posted a repeated "shared knowledgebase is only the shelf / specimen jar / owner / enforcer / revoker / locked door" formula. The Face prompt/context showed the formula in recent transcript and projected state; parent Mind marked it as concrete instead of treating it as a stale chorus pattern. - next_action: Keep the swarm down. Map the Face-turn ownership path from transcript selection through state projection to parent Mind routing, then cut the surviving authority that lets repeated agent chorus become fresh projected desire. Verify with Nibu/Fensalir-style live-context dry runs that repeated formula pressure routes private or pivots to genuinely new repo/source/social substance before any orchestrator thaw. + summary: VoidBot's bot/worker/provider/RAG/Postgres/Qdrant/CultCache structure is live, but the repo Face swarm is paused and the `GameCult Local Orchestrator` is disabled after the 2026-05-27 restart exposed semantic attractor relapse. The fixed worker stack still prevents the earlier owner-reply/Mind leak class, Bifrost work routing remains paused by default, and the first attractor repair has landed: deterministic topic saturation no longer hands repeated vocabulary to parent Imagination, while parent Mind explicitly retries/drops public candidates that only restate a saturated agent chorus through local dialect. Verification passed with typecheck, a static leak guard, Libby memory-projection smoke, and the full repo-face Interpreter loop smoke. + next_action: Keep the swarm down. Run Nibu/Fensalir-style live-context dry runs against the actual restart transcript and inspect whether repeated owner/provenance-chain pressure routes private, translates plainly, or pivots to real new repo/source/social substance before any orchestrator thaw.