Stabilize repo face heartbeat transport

This commit is contained in:
Meta Vens 2026-05-20 20:31:42 +01:00
commit c93b1d1716
27 changed files with 2108 additions and 253 deletions

View file

@ -4,7 +4,7 @@ This is the current forward plan for the next larger organs. It is not a changel
## Current Aim
The typed moderation, mood, sleep, agency, and private self-state boundary is live. The current goal is to let ordinary scheduling run, inspect the next unattended direct reply and sleep cycle, and harden only the seams that show concrete failure. Void should answer Discord, remember useful social/project context, retrieve GameCult history/source/lore, and run an unattended moderation/participation loop without reviving JSON projection edits, legacy mirrors, or the swollen memory organ.
The typed moderation, mood, sleep, agency, and private self-state boundary is live. The current goal is to let ordinary scheduling run, inspect the next CTB-routed mention response and sleep cycle, and harden only the seams that show concrete failure. Void should answer Discord through the global heartbeat, remember useful social/project context, retrieve GameCult history/source/lore, and run an unattended moderation/participation loop without reviving JSON projection edits, legacy mirrors, direct-reply organs, or the swollen memory organ.
The next priority is observational hardening of the enabled typed loop. Agents and scheduled workers mutate typed CultCache-backed state through explicit operations, not by editing a whole-state JSON working copy. Sleep and memory distillation now preserve meaning-bearing claims/anchors/tensions in fixture and live-state passes, and short-term rumination has a clustering guard so repeated same-target/topic thoughts update one provisional memory instead of stacking duplicates. Keep checking ordinary cycles for abstraction sludge, duplicate speech, stale residue, or self-orbiting memories.
@ -188,11 +188,15 @@ The runner can hand these to a CLI/MCP tool. The store decides what survives.
- the scheduled moderation runner has a typed rumination contract: bounded context in, reviewed prompt template, typed operation payloads out, parent-owned cursor/receipt recording
- recent event timing in that bounded context now crosses a projection boundary first, so the child sees "5 minutes ago" language while the parent keeps exact timestamps for bookkeeping
- public artifact sharing now crosses the same boundary: repo activity exposes content hints, rumination verifies authorship through retrieval, and a configured `publicSpeechTarget` lets Void queue a normal typed candidate intervention instead of needing a blog-specific announcement path. Void also has explicit herald jurisdiction over the GameCult website/blog; essay-shaped pressures should queue article-proposal candidates for Void-authored site pieces.
- repo-scoped Discord participation now uses role/display-name addressing as queue input and registered webhook personas as the speech boundary. A Face mention appends a pending obligation to the CTB heartbeat state; it no longer creates a direct `repo-identity-mention` Codex job.
- Discord mention participation now uses role/display-name/bot addressing as CTB queue input and parent-owned speech rails as the output boundary. A Face mention appends a pending obligation for that Face; an ordinary Void mention or DM appends a pending obligation for the built-in `void` participant. Ambient direct mentions no longer create direct provider jobs.
- repo-scoped Faces now reuse the typed self-state machinery per identity. Addressed chats are consumed by the heartbeat scheduler, which prioritizes the Face, attaches pending prompts to the next `repo-face-rumination` job, and expects state writes through `read_repo_face_state` / `apply_repo_face_state_operation` against the identity's `.cc` file.
- repo-scoped concrete proposals have an optional parent-owned GitHub authority shared with bylined articles and PR comments. It is gated by `REPO_FACE_GITHUB_ACTIONS_ENABLED` and currently disabled locally. When enabled, a Face can emit a proposal or PR-comment sentinel, but the worker owns file write, branch creation, draft PR/comment creation, branch restoration, and mandatory registered-persona announcement. The intended invariant is simple: if it is a reviewable repo/lore/design change, GitHub carries the proposal and Discord carries the argument around it.
- repo-scoped Faces now have per-topic channel permissions instead of one work-shaped speech lane. `allowedChannelIds` remains the hard gate, while `channelPermissions` gives each Face labeled topics, speech thresholds, and speed multipliers. The current social invariant is that Aquarium is intentionally cheap for casual in-character chatter, while domain channels receive matching work/lore/music/realtime/agent-state thoughts when the recent cross-channel context lines up. Heat is the live-room valve: above-baseline heat now relaxes nap gating, but active-turn freeze still prevents an agent from being queued again while it is thinking.
- repo-scoped Face prompts now explicitly treat social embodiment as durable state territory. A Face may store meaning-bearing social reads about humans, other Faces, or room dynamics through typed memory/incubation/agency/private notes when the read should affect future action. The rule is not "log every joke"; the rule is that friendship, rivalry, irritation, trust, recurring bits, and bonds are allowed to become state when they carry claim/question, tension, action implication, and anchors. Public posts should speak to someone directly and must not begin with note-title formulas or identity labels such as "bright bridge note" or "tiny fish sorting note."
- repo-scoped Face prompts and Void's CTB moderation prompt now carry the richer comedy/improv doctrine that was only implicit before. The distilled rule from Dan Harmon's comedy master class is operational: accept the frame and add one honest character-specific turn; find status inversion, exposed fear, vulnerability, false authority, or shared contradiction; heighten with specificity rather than volume; avoid dominance-weapon jokes; and stop before explaining the joke.
- repo-scoped Face prompts now also carry a jurisdiction-respect doctrine. Faces can comment outside their home territory, but must route ownership to the steward instead of absorbing every nearby problem. Heimdall owns auth/OAuth/grants/custody/revocation, Bifrost owns GitHub/Discord work transport and governed public crossings, Nibu owns Aetheria lore/articles, Void owns GameCult website/heraldry plus room-wide moderation, Aqua owns AquaSynth, Mimir owns realtime field mapping/fusion, Epiphany owns EpiphanyAgent/agent-state birth machinery, and Libby owns CultCache/CultNet/CultMesh/open-knowledge infrastructure. Cross-domain issues should become visible consultation, co-authorship, handoff, or shared proposals.
- repo-scoped concrete proposals cross through Bifrost bridge commands shared with bylined articles, PR comments, and registered-identity Discord posts. It is enabled locally with `REPO_FACE_GITHUB_ACTIONS_ENABLED=true`. A Face can emit a proposal/article/PR-comment sentinel, but the worker now owns identity validation and Face-local receipts while `BIFROST_ROOT/tools/bifrost-bridge.mjs` owns file write, branch creation, draft PR/comment creation, and Discord persona posting. This is the global transport invariant: governed public crossings for GameCult work belong to Bifrost because Bifrost is the governance/labor platform and official public-process bridge. Heimdall remains the OAuth/account/capability gate. Discord should become a native Bifrost interface for work, policy/priority voting, reward allocation discussion, maintainer notices, member/patron/user access, and agent swarm routing; VoidBot retains room cognition, moderation judgment, retrieval, and Face personality. The invariant is simple: if it is a reviewable repo/lore/design change, GitHub carries the proposal and Discord carries the argument around it. If a Face says a topic is the next cut/pass and enough material exists, that should become a draft PR rather than another Aquarium nudge.
- newborn repo Faces now get a repo-local `.voidbot` home on first chat. Birth personality/memory/trajectory artifacts are delegated to EpiphanyAgent's repo personality/birth runner over the repo contents and git history, with status/logs written under the target repo instead of silently mutating VoidBot state.
- repo-scoped Faces now also have standing heartbeats. One scheduler state file owns initiative, load, next-ready timestamps, and queue history for all registered identities; it staggers newborn Faces across a base interval of twice Void's moderation cadence and only emits normal `repo-face-rumination` jobs when a Face is ready.
- repo-scoped Faces now also have standing heartbeats. One scheduler state file owns initiative, load, next-ready timestamps, and queue history for all registered identities; it staggers newborn Faces across a base interval of twice Void's moderation cadence and only emits normal `repo-face-rumination` jobs when a Face is ready. The live roster currently includes Nibu/AetheriaLore, Aqua/AquaSynth, Mimir/LocalCastBridge, Epiphany/EpiphanyAgent, plus built-in Void.
- repo-activity cursor advancement is parent-owned after successful normal rumination passes, so the child can inspect read-only repo weather without stale commits haunting every future pass as fresh material
- the old memory-organ script family, legacy moderation state template, and legacy context exporter have now been deleted instead of preserved as forensic bait
- deterministic cleanup is mostly recent scar tissue from failed manual cleanup passes; it should stay deleted rather than be ported unless a future typed operation protects a real invariant in the new model
@ -301,7 +305,7 @@ Verdict: the foundation is coherent enough for cautious live operation. Do not a
- Landed live sleep-maintenance verification: a manual typed nap ran real memory maintenance on live state, promoted the scheduled rumination short-term memory into one durable `identity_seam`, and left `thoughtMemory.shortTerm` empty.
- Landed sleep brake: scheduled rumination now skips before model invocation during naps when there are no new room messages or open cases. `npm run moderation:rumination:nap-skip-fixture` proves the model path is not touched and no operation proposals are written.
- Landed short-term clustering guard: `record_short_term_memory` folds repeated same-target/topic pressure into one provisional memory with merged anchors, and `npm run moderation:short-term-clustering:fixture` proves the synth-boundary duplicate case without merging unrelated same-repo thoughts. The prompt now states explicitly that underexplored, low-saturation, newly anchored thoughts may keep deepening inside the cluster.
- Remaining work: let ordinary scheduling run and inspect the next unattended direct reply, next advocacy pass, and next sleep cycle for duplicate answers, fresh queued advocacy candidates, stale short-term residue, or ungrounded memory writes before calling the system broadly stable.
- Remaining work: let ordinary scheduling run and inspect the next CTB-routed mention response, next advocacy pass, and next sleep cycle for duplicate answers, fresh queued advocacy candidates, stale short-term residue, or ungrounded memory writes before calling the system broadly stable.
### Commit 10: Resume Product Hardening