2026-05-06 03:31:46 +01:00
# VoidBot Routine Adoption Plan
VoidBot has grown the reference agent routine Epiphany should steal without
cosplaying as a Discord moderator. The useful organs are:
- heartbeat turns that choose work, rumination, or sleep/consolidation
- cooldown that starts after a heartbeat turn completes, not when it launches
- nap windows for memory consolidation, pruning, dream residue, and incubation
- canonical MessagePack state through a CultCache-style typed document store
2026-05-06 05:00:57 +01:00
- CultCache-native inspection/debug tooling rather than long-lived JSON shadow state
2026-05-06 03:31:46 +01:00
deliberately
- code-owned schemas instead of schema drift hiding in loose files
- semantic memory vectors in Qdrant with source hashes and compact dimensions
- memory resonance, incubation queues, analytic/associative thought lanes, and a
bridge that decides speech, draft, hold, or silence
2026-06-15 16:38:09 +01:00
- repo identities with Persona state, Discord roles, pending mentions, jurisdiction,
2026-05-19 13:42:39 +01:00
proposal authority, and a CTB/Final-Fantasy-style initiative scheduler
2026-06-15 16:38:09 +01:00
## Project-Persona Direction
2026-05-19 13:42:39 +01:00
VoidBot is no longer only a moderator with retrieval. It now has the small
2026-06-15 16:38:09 +01:00
working version of the Epiphany pitch: repos grow Personas.
2026-05-19 13:42:39 +01:00
The live pattern is:
- a repo identity has a Discord role and registered allowed channels
2026-06-15 16:38:09 +01:00
- that identity has repo-local Persona state, not just base Void personality
- first contact can birth the Persona through Epiphany repo terrain/personality
2026-05-19 13:42:39 +01:00
scouting and reviewable startup artifacts
- role/display-name mentions become pending obligations, not direct hidden jobs
2026-06-15 16:38:09 +01:00
- an initiative scheduler chooses which Persona or system agent gets the next turn
2026-05-19 13:42:39 +01:00
- heat can prioritize identities, repos, participant kinds, turns, channels, or
all participants
- active turns freeze initiative until the owner-Codex job or moderation lock
completes
2026-06-15 16:38:09 +01:00
- Personas may advocate for repo needs and propose changes, while implementation
2026-05-19 13:42:39 +01:00
authority still requires the configured human/review path
Epiphany should absorb that as native product direction. The user should talk to
projects: "Aqua, what does AquaSynth need?", "Nibu, what is wrong with this lore
arc?", "Mimir, what seam is drifting?" The project should schedule modeling,
2026-06-15 16:38:09 +01:00
research, verification, memory maintenance, or a Persona response from its own
2026-05-19 13:42:39 +01:00
typed state. The human should not have to deliver a complete implementation
brief just to make the system start thinking.
2026-05-06 03:31:46 +01:00
## Target Shape
Epiphany should treat this as a shared agent routine substrate, not as another
specialist lane. The substrate owns scheduling, persistence, and memory
maintenance; the coordinator owns authority.
```text
coordinator pressure / user objective / swarm messages
-> heartbeat scheduler
-> work turn | rumination turn | sleep turn
-> typed state read through CultCache-compatible store
-> optional Qdrant memory recall / resonance
-> bounded result, selfPatch, statePatch, dream, or callback
-> completion receipt starts cooldown
2026-05-06 05:00:57 +01:00
-> canonical MessagePack write + typed inspection/debug views
2026-05-06 03:31:46 +01:00
```
## Scheduler Contract
Heartbeat state keeps:
- participant identity, role, speed, load, status, readiness, reaction bias, and
pending turn
- pacing policy with work recovery, idle recovery, sleep multiplier, and
completion-gated cooldown
- sleep cycle state: enabled, cadence, nap duration, current nap, next nap,
dream count, active dream themes, and last distillation summary
- history of work, rumination, sleep, completion, and refused-repeat events
Turn kinds:
2026-06-15 16:38:09 +01:00
- `work` : coordinator-approved lane work, specialist result, Persona surface, or
2026-05-06 03:31:46 +01:00
implementation continuation.
- `rumination` : role-local memory hygiene, selfPatch, stale habit detection, or
low-pressure thought incubation.
- `sleep` : inward maintenance. The agent should distill/prune memory, strengthen
resonance clusters, update incubation, write or refresh dreams, and speak only
2026-06-15 16:38:09 +01:00
through Persona if something genuinely needs to surface.
2026-05-06 03:31:46 +01:00
No lane may receive another heartbeat while `pending_turn.status == running` .
The completion receipt is the only normal path that starts cooldown. This is the
part that keeps the heart from turning into a tiny manager with a stopwatch and
no shame.
2026-06-15 16:38:09 +01:00
Repo Personas use the same law. A Persona can be heated because a human mentioned it,
2026-05-19 13:42:39 +01:00
a repo is hot, a stream is live, or a group needs attention; that heat changes
2026-06-15 16:38:09 +01:00
opportunity, not authority. The Persona still freezes while thinking, still returns
2026-05-19 13:42:39 +01:00
through typed receipts, and still needs an explicit grant before crossing from
proposal into canonical repo mutation.
2026-05-06 03:31:46 +01:00
## Persistence Contract
Epiphany needs a Rust version of the CultCache contract because the app-server
and `epiphany-core` are Rust and should not route core state through a Node
helper just to persist its own mind.
Minimum Rust surface:
- `DocumentType<T>` : type id plus serde/schema metadata.
- `CultCacheEnvelope` : `{ key, type, payload, stored_at }` .
- `BackingStore` : `pull_all` , `push` , `delete` , optional `push_all` .
- `SingleFileMessagePackBackingStore` : atomic whole-file MessagePack store with
external lock expectation.
- `CultCache` : register types, load stores, validate payloads through typed
serde structs, get/get_required/get_all/put/update/delete/snapshot.
2026-05-06 05:00:57 +01:00
- Typed inspection/debug views should come from CultLib/CultCache tooling so
all wire-compatible runtimes share the same schema and display assumptions.
Repo-local JSON projections are temporary compatibility shims only.
2026-05-06 03:31:46 +01:00
The schema should live in annotated Rust structs using serde plus generated JSON
Schema where useful. MessagePack is canonical. JSON is the window, not the
house.
2026-05-29 01:23:43 +01:00
## Shared Persona-State Contract
2026-05-06 05:50:42 +01:00
2026-05-29 01:23:43 +01:00
Epiphany should not invent its own rival Persona ontology.
2026-05-06 05:50:42 +01:00
2026-05-29 01:23:43 +01:00
The shared cross-runtime public/person-shaped payload contract is now the
GameCult Persona state shape, with Ghostlight and VoidBot as source lineage:
2026-05-06 05:50:42 +01:00
- payload schema id:
2026-05-29 01:23:43 +01:00
`https://gamecult.dev/cultnet/gamecult.persona_state.v0.schema.json`
2026-05-06 05:50:42 +01:00
- payload schema version:
2026-05-29 01:23:43 +01:00
`gamecult.persona_state.v0`
2026-05-06 05:50:42 +01:00
- intended CultNet document type:
2026-05-29 01:23:43 +01:00
`gamecult.persona_state.v0`
2026-05-06 05:50:42 +01:00
2026-06-15 16:38:09 +01:00
That means Epiphany Persona, VoidBot repo Personas, and Ghostlight characters can
2026-05-29 01:23:43 +01:00
exchange Persona state without turning every Epiphany work organ into a public
personality simulation.
2026-05-06 05:50:42 +01:00
2026-05-29 01:49:54 +01:00
The shared contract uses `candidateActions` for generic forward pressure.
VoidBot can expose the same list as `voidbotProjection.candidateInterventions`
2026-06-15 16:38:09 +01:00
when repo-Persona routine language wants that noun, but the projection does not own
2026-05-29 01:49:54 +01:00
the portable Persona contract. Persona documents also carry provenance and a
public presentation surface so imported state can say where it came from, when
it was exported, whether it is canonical/projection/import data, and how the
public person should be rendered.
Source-specific fields belong in `anchoredThought.extensions` . That bag is
preservation glue, not authority. Consumers may keep it round-tripped, but they
must not let it steer shared Persona behavior unless they explicitly understand
the originating contract.
The affect layer keeps semantic bones where they matter: social bonds name
subject/object/kind/trust/tension, status reads name target/kind/confidence,
and doctrine stances name principle/stance/action implication. Needs remain
anchored thoughts because they behave like pressure records.
2026-05-29 02:00:06 +01:00
The baseline also requires a public `presentation` block, annotates timestamps
as JSON Schema `date-time` , and gives every `custom` enum path a companion
2026-05-29 02:02:42 +01:00
custom-label field. `candidateActions.actions` are typed action records now:
action type, target, optional delivery target, readiness, risk, urgency,
confidence, evidence, timestamps, and expiry. `privateNotes` stay simple for v0
interchange; if they begin carrying provenance or authority, promote them into
typed private-note records instead of letting raw strings grow a steering
wheel.
2026-05-29 02:00:06 +01:00
2026-05-06 05:50:42 +01:00
CultNet is not just ergonomic framing. It also carries CultLib-style auth and
session semantics:
- shared connection key for both peers
- AES-GCM encrypted auth/session payloads
- server-side session-signing secret
- signed verify/reconnect tokens
So the target shape is:
2026-05-29 01:23:43 +01:00
- canonical work-organ state in MessagePack through CultCache-compatible
2026-05-06 05:50:42 +01:00
storage
- typed CultNet document replication for live exchange
2026-05-29 01:23:43 +01:00
- Persona payloads for public/person-shaped agents
2026-05-06 05:50:42 +01:00
2026-05-29 01:23:43 +01:00
Narrow work-organ views stay derived and local. The shared person-state truth is
Persona-shaped.
2026-05-06 05:50:42 +01:00
2026-05-06 03:31:46 +01:00
Initial document types:
- `epiphany.thread_state`
2026-05-29 01:23:43 +01:00
- `epiphany.agent_memory`
2026-05-06 03:31:46 +01:00
- `epiphany.heartbeat_state`
2026-05-29 01:23:43 +01:00
- `gamecult.persona_state.v0`
2026-05-06 03:31:46 +01:00
- `epiphany.swarm_message`
- later: planning, graph checkpoint, memory resonance, incubation, dreams
## Vector Memory Contract
Epiphany already has Qdrant/Ollama retrieval for workspace source. Extend that
pattern to agent memory:
- collection namespace: `epiphany_memory_<instance_id>`
- point id: stable memory id or hash of document type/key/path
- vector model: default `qwen3-embedding:0.6b`
- payload: agent id, role id, memory kind, source hash, schema version, summary,
salience, confidence, updated time, source refs
- canonical MessagePack state stores vector metadata and optionally compact
inline vectors; Qdrant stores the retrieval vector
2026-05-06 05:00:57 +01:00
- CultCache inspection views may strip vector values while preserving metadata
2026-05-06 03:31:46 +01:00
Memory resonance is not proof. It is "these things rhyme" evidence for
2026-06-15 16:38:09 +01:00
rumination, Persona surfacing, and sleep consolidation.
2026-05-06 03:31:46 +01:00
## Migration Slices
1. **Contract extraction **
- Add Rust CultCache-compatible module in `epiphany-core` .
- Add fixtures proving MessagePack round-trip, typed serde/schema validation,
2026-05-06 05:00:57 +01:00
and CultCache inspection compatibility.
2026-05-06 03:31:46 +01:00
2. **Heartbeat state migration **
2026-05-06 05:29:28 +01:00
- Move `state/agent-heartbeats.json` into a typed MessagePack document.
Landed: the tracked JSON state file is retired and heartbeat
init/status/tick/complete now route through the native CultCache store.
2026-05-06 03:31:46 +01:00
- Add `sleep_cycle` , `memory_resonance` , and `incubation` fields.
- Keep the current CLI contract stable while the backing store changes.
2026-05-29 01:23:43 +01:00
3. **Organ and Persona memory migration **
- Store lean Epiphany work-organ memory as `epiphany.agent_memory` .
2026-06-15 16:38:09 +01:00
- Store public/person-shaped Persona state as `gamecult.persona_state.v0` .
2026-05-06 05:00:57 +01:00
- Use CultLib/CultCache inspection tools for human/debug review instead of
preserving per-role JSON as a parallel source of truth.
2026-05-06 03:31:46 +01:00
- Attach semantic vector metadata to episodic, semantic, relationship, goal,
value, musing, and dream entries.
4. **Memory organ **
- Add a bounded memory maintenance command that embeds missing memory vectors,
refreshes Qdrant points, builds resonance edges/clusters, updates
incubation, and writes dream residue during sleep turns.
5. **Coordinator integration **
- Coordinator sees heartbeat sleep state, pending turns, resonance summaries,
and memory maintenance results.
- Coordinator may route work, accept/refuse selfPatch, or let the swarm sleep.
6. **Aquarium visibility **
- Expose sleep state, dreams, resonance clusters, incubating thoughts, and
pending turns as inspectable Aquarium surfaces.
## Non-Goals
- Do not replace CRRC compaction yet.
- Do not make Qdrant canonical truth.
- Do not let sleep turns edit implementation code.
- Do not auto-accept specialist findings because a dream sounded good.
- Do not build a general database shrine before the typed MessagePack seam
proves it deserves to live.