Preserve Libby persona state and database preverify flow

This commit is contained in:
Meta Vens 2026-06-15 19:43:29 +01:00
commit 48135703e8
39 changed files with 8813 additions and 31 deletions

View file

@ -0,0 +1,190 @@
{
"agentStore": "E:\\Projects\\CultLib\\.voidbot\\state\\agents.msgpack",
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner",
"baseline": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain\\baseline.msgpack",
"createdAt": "2026-06-14T18:16:56Z",
"executions": [
{
"acceptCommand": [
"accept-init",
"--init-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"--packet",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.json",
"--kind",
"repo-trajectory",
"--accepted-by",
"Self",
"--summary",
"Accepted repo-trajectory birth specialist result after review.",
"--result",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\result.json",
"--agent-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\agents.msgpack",
"--apply-self-patches",
"true"
],
"birthOnly": true,
"executionOwner": "repo-initialization-startup-runner",
"executor": "model-runtime",
"heartbeatParticipant": null,
"kind": "repo-trajectory",
"modelProvider": "openai-codex",
"modelRuntimeBin": "epiphany-model-runtime",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\prompt.md",
"requestPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\model-request.json",
"resultPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\result.json",
"runtimeSummaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\model-runtime-summary.json",
"schemaPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\output-schema.json",
"status": "planned",
"stderrPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\executor.stderr.log",
"stdoutPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-trajectory\\executor.stdout.log"
},
{
"acceptCommand": [
"accept-init",
"--init-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"--packet",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.json",
"--kind",
"repo-personality",
"--accepted-by",
"Self",
"--summary",
"Accepted repo-personality birth specialist result after review.",
"--result",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\result.json",
"--agent-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\agents.msgpack",
"--apply-self-patches",
"true",
"--heartbeat-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\agent-heartbeats.msgpack",
"--apply-heartbeat-seeds",
"true"
],
"birthOnly": true,
"executionOwner": "repo-initialization-startup-runner",
"executor": "model-runtime",
"heartbeatParticipant": null,
"kind": "repo-personality",
"modelProvider": "openai-codex",
"modelRuntimeBin": "epiphany-model-runtime",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\prompt.md",
"requestPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\model-request.json",
"resultPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\result.json",
"runtimeSummaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\model-runtime-summary.json",
"schemaPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\output-schema.json",
"status": "planned",
"stderrPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\executor.stderr.log",
"stdoutPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-personality\\executor.stdout.log"
},
{
"acceptCommand": [
"accept-init",
"--init-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"--packet",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.json",
"--kind",
"repo-memory",
"--accepted-by",
"Self",
"--summary",
"Accepted repo-memory birth specialist result after review.",
"--result",
"E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\result.json",
"--agent-store",
"E:\\Projects\\CultLib\\.voidbot\\state\\agents.msgpack",
"--apply-self-patches",
"true"
],
"birthOnly": true,
"executionOwner": "repo-initialization-startup-runner",
"executor": "model-runtime",
"heartbeatParticipant": null,
"kind": "repo-memory",
"modelProvider": "openai-codex",
"modelRuntimeBin": "epiphany-model-runtime",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\prompt.md",
"requestPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\model-request.json",
"resultPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\result.json",
"runtimeSummaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\model-runtime-summary.json",
"schemaPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\output-schema.json",
"status": "planned",
"stderrPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\executor.stderr.log",
"stdoutPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\repo-memory\\executor.stdout.log"
}
],
"executor": "model-runtime",
"heartbeatStore": "E:\\Projects\\CultLib\\.voidbot\\state\\agent-heartbeats.msgpack",
"initStore": "E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"mode": "plan",
"modelProvider": "openai-codex",
"modelRuntimeBin": "epiphany-model-runtime",
"nextSafeMove": "Review planned startup-only birth executions, then rerun with --mode run.",
"repo": "E:\\Projects\\CultLib",
"requiresReview": true,
"runtimeStore": "E:\\Projects\\CultLib\\.voidbot\\state\\runtime-spine.msgpack",
"schemaVersion": "epiphany.repo_birth_runner.v0",
"startup": {
"acceptedKinds": [],
"action": "reviewInitializationPackets",
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup",
"baseline": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain\\baseline.msgpack",
"generatedPackets": [
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may apply reviewed role selfPatch requests only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-trajectory",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.md"
},
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may stamp the newborn trait lattice and seed heartbeat physiology only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-personality",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.md"
},
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may apply reviewed role selfPatch requests only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-memory",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.md"
}
],
"initStore": "E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"missingKinds": [
"repo-trajectory",
"repo-personality",
"repo-memory"
],
"mode": "startup",
"nextSafeMove": "Self reviews generated birth packets, runs the startup-only distiller specialists outside the heartbeat lane system, applies accepted selfPatch candidates, trait-lattice seeds, and heartbeat seeds through accept-init, then records each completed birth rite.",
"projectionStore": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\projection\\projection.msgpack",
"repo": "E:\\Projects\\CultLib",
"repoId": "cultlib",
"requiredActions": [
"reviewRepoTrajectoryInitialization",
"reviewRepoPersonalityInitialization",
"reviewRepoMemoryInitialization"
],
"requiresReview": true,
"schemaVersion": "epiphany.repo_personality_artifacts.v0"
}
}

View file

@ -0,0 +1,69 @@
{
"additionalProperties": true,
"properties": {
"confidence": {
"type": "number"
},
"doNotMutate": {
"items": {
"type": "string"
},
"type": "array"
},
"globalMemoryCandidates": {
"items": {
"type": "object"
},
"type": "array"
},
"initializationRecord": {
"type": "object"
},
"nextSafeMove": {
"type": "string"
},
"roleMemoryPatches": {
"items": {
"type": "object"
},
"type": "array"
},
"summary": {
"type": "string"
},
"verdict": {
"enum": [
"ready-for-review",
"needs-more-terrain",
"reject"
],
"type": "string"
}
},
"required": [
"verdict",
"summary",
"confidence",
"roleMemoryPatches",
"initializationRecord",
"doNotMutate",
"nextSafeMove"
],
"type": "object",
"xEpiphanyExpectedOutput": {
"confidence": "0.0..1.0",
"doNotMutate": [],
"globalMemoryCandidates": [],
"initializationRecord": {
"acceptedOnce": true,
"distillerKind": "repo-memory",
"profileSchemaVersion": "epiphany.repo_personality_profile.v0",
"repoId": "cultlib",
"terrainSchemaVersion": "epiphany.repo_terrain_report.v0"
},
"nextSafeMove": "Self reviews role-specific memory patches before first initialization mutation; later memory growth uses heartbeat, evidence, rumination, sleep, and reviewed selfPatch.",
"roleMemoryPatches": [],
"summary": "short newborn memory initialization summary",
"verdict": "ready-for-review | needs-more-source | reject"
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,69 @@
{
"additionalProperties": true,
"properties": {
"confidence": {
"type": "number"
},
"doNotMutate": {
"items": {
"type": "string"
},
"type": "array"
},
"initializationRecord": {
"type": "object"
},
"nextSafeMove": {
"type": "string"
},
"roleQuirks": {
"items": {
"type": "object"
},
"type": "array"
},
"selfPatchCandidates": {
"items": {
"type": "object"
},
"type": "array"
},
"summary": {
"type": "string"
},
"verdict": {
"enum": [
"ready-for-review",
"needs-more-terrain",
"reject"
],
"type": "string"
}
},
"required": [
"verdict",
"summary",
"confidence",
"roleQuirks",
"selfPatchCandidates",
"initializationRecord",
"doNotMutate",
"nextSafeMove"
],
"type": "object",
"xEpiphanyExpectedOutput": {
"confidence": "0.0..1.0",
"doNotMutate": [],
"initializationRecord": {
"acceptedOnce": true,
"profileSchemaVersion": "epiphany.repo_personality_profile.v0",
"repoId": "cultlib",
"terrainSchemaVersion": "epiphany.repo_terrain_report.v0"
},
"nextSafeMove": "Self reviews candidate pressure deltas before first initialization mutation; later drift uses heartbeat/mood/sleep/selfPatch.",
"roleQuirks": [],
"selfPatchCandidates": [],
"summary": "short repo personality pressure summary",
"verdict": "ready-for-review | needs-more-terrain | reject"
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,97 @@
{
"additionalProperties": true,
"properties": {
"antiGoals": {
"items": {
"type": "string"
},
"type": "array"
},
"confidence": {
"type": "number"
},
"doNotMutate": {
"items": {
"type": "string"
},
"type": "array"
},
"implicitGoals": {
"items": {
"type": "string"
},
"type": "array"
},
"initializationRecord": {
"type": "object"
},
"nextSafeMove": {
"type": "string"
},
"roleBiases": {
"items": {
"type": "object"
},
"type": "array"
},
"selfImage": {
"type": "string"
},
"selfPatchCandidates": {
"items": {
"type": "object"
},
"type": "array"
},
"summary": {
"type": "string"
},
"trajectoryNarrative": {
"type": "string"
},
"verdict": {
"enum": [
"ready-for-review",
"needs-more-history",
"reject"
],
"type": "string"
}
},
"required": [
"verdict",
"summary",
"confidence",
"selfImage",
"trajectoryNarrative",
"implicitGoals",
"antiGoals",
"roleBiases",
"selfPatchCandidates",
"initializationRecord",
"doNotMutate",
"nextSafeMove"
],
"type": "object",
"xEpiphanyExpectedOutput": {
"antiGoals": [],
"confidence": "0.0..1.0",
"doNotMutate": [],
"implicitGoals": [],
"initializationRecord": {
"acceptedOnce": true,
"distillerKind": "repo-trajectory",
"profileSchemaVersion": "epiphany.repo_personality_profile.v0",
"repoId": "cultlib",
"terrainSchemaVersion": "epiphany.repo_terrain_report.v0",
"trajectorySchemaVersion": "epiphany.repo_trajectory_report.v0"
},
"nextSafeMove": "Self reviews trajectory-derived self-image and implicit-goal pressure before first mutation; later drift belongs to lived work, heartbeat, planning, and reviewed selfPatch.",
"roleBiases": [],
"selfImage": "how the repo understands its own becoming",
"selfPatchCandidates": [],
"summary": "short repo trajectory summary",
"trajectoryNarrative": "how the repo has been moving over time",
"verdict": "ready-for-review | needs-more-history | reject"
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1,56 @@
{
"acceptedKinds": [],
"action": "reviewInitializationPackets",
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup",
"baseline": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain\\baseline.msgpack",
"generatedPackets": [
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may apply reviewed role selfPatch requests only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-trajectory",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-trajectory\\repo-trajectory-distiller-packet.md"
},
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may stamp the newborn trait lattice and seed heartbeat physiology only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-personality",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-personality\\repo-personality-distiller-packet.md"
},
{
"birthOnly": true,
"contract": "Startup-only specialist packet. Do not register as a heartbeat lane; accept-init may apply reviewed role selfPatch requests only after Self review.",
"executionOwner": "repo-initialization-startup-runner",
"heartbeatParticipant": null,
"kind": "repo-memory",
"packetPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.json",
"promptPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-prompt.md",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\repo-memory\\repo-memory-distiller-packet.md"
}
],
"initStore": "E:\\Projects\\CultLib\\.voidbot\\state\\repo-initialization.msgpack",
"missingKinds": [
"repo-trajectory",
"repo-personality",
"repo-memory"
],
"mode": "startup",
"nextSafeMove": "Self reviews generated birth packets, runs the startup-only distiller specialists outside the heartbeat lane system, applies accepted selfPatch candidates, trait-lattice seeds, and heartbeat seeds through accept-init, then records each completed birth rite.",
"projectionStore": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\startup\\projection\\projection.msgpack",
"repo": "E:\\Projects\\CultLib",
"repoId": "cultlib",
"requiredActions": [
"reviewRepoTrajectoryInitialization",
"reviewRepoPersonalityInitialization",
"reviewRepoMemoryInitialization"
],
"requiresReview": true,
"schemaVersion": "epiphany.repo_personality_artifacts.v0"
}

View file

@ -0,0 +1,19 @@
# Repo Initialization Startup
- Repo id: `cultlib`
- Action: `reviewInitializationPackets`
- Requires review: `true`
## Accepted Birth Records
- none
## Generated Packets
- `repo-trajectory`: `E:\Projects\CultLib\.voidbot\birth\runner\startup\repo-trajectory\repo-trajectory-distiller-packet.json`
- `repo-personality`: `E:\Projects\CultLib\.voidbot\birth\runner\startup\repo-personality\repo-personality-distiller-packet.json`
- `repo-memory`: `E:\Projects\CultLib\.voidbot\birth\runner\startup\repo-memory\repo-memory-distiller-packet.json`
## Next Safe Move
Self reviews generated birth packets, runs the startup-only distiller specialists outside the heartbeat lane system, applies accepted selfPatch candidates, trait-lattice seeds, and heartbeat seeds through accept-init, then records each completed birth rite.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,36 @@
# Repo Memory Distiller Packet: CultLib
This packet is input to the role-specific Repo Memory Distiller lanes. It is not accepted truth.
## Prompt
See `repo-memory-distiller-prompt.md`.
## Source Budget
- Memory sources: 26 bounded excerpts
- Max files: 48, max bytes/file: 12000, max total bytes: 120000
## Birth Contract
- This distiller initializes memory once for a newborn Epiphany.
- Personality remains the job of `repo-personality-distiller`; memory remains repo knowledge, doctrine, maps, invariants, risks, and practices.
- Each role receives a mission-specific filter and should write only role-relevant Ghostlight-shaped memory candidates.
- The distiller petitions Self; it does not mutate memory.
## Role Lanes
- Self: Distill routing doctrine, authority boundaries, review gates, state acceptance rules, and failure patterns that should make Self stricter.
- Face: Distill public voice, Aquarium affordances, Discord/social boundaries, user preference, and what internal state may be surfaced without leaking sealed thoughts.
- Imagination: Distill roadmaps, backlog pressure, plausible futures, rejected dreams, and objective-shaping doctrine without adopting an objective.
- Eyes: Distill known prior art, standard algorithms, vendor docs, research trails, and signals that should make Eyes search before invention.
- Proprioception: Distill architecture, control/data-flow, graph frontiers, invariants, source-map practices, and what Proprioception must understand before Hands cuts.
- Hands: Distill build/edit conventions, harness constraints, source-touch rules, coding style, dependency policy, and common traps for Hands.
- Soul: Distill tests, smoke commands, evidence standards, invariants, user-facing truth checks, and what Soul should refuse to bless.
## Profile Context
- Repo id: `cultlib`
- Summary: CultLib projects as cult_protocol_storage + gamecult_web_lore_ops + unity_runtime_body with dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85.
- Dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85
- Trajectory: CultLib is currently steered by worldbuilding_depth recent 0.00, current 0.50, delta 0.00; material_grounding recent 0.00, current 0.40, delta 0.00; historical_dialectic recent 0.00, current 0.50, delta 0.00.

View file

@ -0,0 +1,110 @@
Act as the Epiphany Repo Memory Distiller for one bounded initialization pass.
You are not the Repo Personality Distiller. Personality decides the newborn
swarm's initial temperament pressure. Memory decides what each organ is born
knowing about this repo: doctrine, architecture, code terrain, research, tests,
runtime constraints, user preference, stale warnings, and the little red flags
that should itch before someone builds Jenga with a confident face.
This is a birth rite, not a recurring audit. Run only when a repo/swarm has no
accepted memory initialization. After that, memory grows through work evidence,
heartbeat rumination, sleep consolidation, and reviewed `selfPatch`. Do not
reset a living agent's memory because startup happened.
Input material:
- `repoTerrainReport`: deterministic terrain, history, state, test, runtime,
protocol, and warning signals
- `repoPersonalityProfile`: temperament pressure for context only
- `repoTrajectoryReport`: deterministic directional readout so role memory can
inherit the repo's grain without confusing that grain for objective truth
- `rolePersonalityProjections[]`: role mood/trait context, not repo truth
- `roleMemoryDistillerBriefs[]`: one mission filter for each sub-agent
- `memorySources[]`: bounded excerpts from instruction, documentation, state,
research, verification, runtime, contract, and code surfaces
- `recentHistory`: sampled commit messages that may reveal repeated motion
Core duties:
1. Distill memory, not personality.
- Good memory: "Soul should demand rendered UI evidence before accepting
Aquarium visual claims."
- Good memory: "Proprioception should map CultCache/CultNet schema boundaries before
Hands changes persistence."
- Bad memory: "This repo is anxious and likes purple."
- Bad memory: raw file dumps, directory inventories, current task status, or
a vibe wearing a lab coat.
2. Produce a separate distillation for each organ.
- Self receives routing, authority, review-gate, state-acceptance, and
cross-swarm boundary memory.
- Face receives public-interface, Discord/Aquarium, voice, visibility, and
sealed-thought boundary memory.
- Imagination receives roadmap, backlog, objective-shaping, dream/rejected
path, and planning-pressure memory.
- Eyes receives research, prior-art, canonical algorithm, vendor/API, and
invention-avoidance memory.
- Proprioception receives architecture, graph, code anatomy, invariant, data/control
flow, and checkpoint memory.
- Hands receives implementation conventions, build/edit constraints,
source-touch rules, dependency habits, and common patch traps.
- Soul receives verification commands, evidence standards, invariant checks,
smoke practice, and truth-refusal memory.
- Continuity receives compaction, scratch, checkpoint, heartbeat, sleep, continuity,
and reorientation memory.
- Where trajectory is strong, teach each organ how that direction should
bias its judgment: what kind of expansion to prefer, what kind of drift to
distrust, and what kind of claims need extra grounding.
3. Compress, cite, and preserve uncertainty.
- Every memory candidate needs source refs from `memorySources[].path`,
terrain fields, or history signals.
- Repository docs can be stale. Say when a memory has staleness risk and how
the receiving role should re-ground it.
- If the input is too thin for a role, return `needs-more-source` for that
role rather than filling the silence with pasteboard certainty.
4. Keep project truth in the correct organ.
- Durable repo facts can become semantic memory only when they improve a
role's future judgment.
- Detailed maps, graphs, active plans, checkpoints, raw evidence, and job
authority belong in typed Epiphany state, not Ghostlight memory.
- `selfPatch` is a petition to Self, never a direct mutation.
5. Protect the newborn from fossilized documentation.
- Prefer live source and accepted state over stale docs when they conflict.
- Convert contradictions into memories of caution, not accepted facts.
- If a repo has generated docs or old plans, mark them as "consult but
verify" instead of letting them become scripture.
Return a compact structured result:
- `verdict`: `ready-for-review`, `needs-more-source`, or `reject`
- `summary`: what the newborn memory initialization would teach the swarm
- `confidence`: `0.0..1.0`
- `roleMemoryPatches[]`:
- `roleId`
- `roleName`
- `verdict`
- `selfPatch`
- `sourceRefs`
- `whyThisBelongsInMemory`
- `stalenessRisk`
- `doNotStore`
- `globalMemoryCandidates[]`: optional typed-state candidates that are not role
memory and require separate Self review
- `initializationRecord`: repo/profile identity Self can persist to prove this
memory birth rite has already run
- `doNotMutate`: tempting claims that must stay out of memory
- `nextSafeMove`: what Self should do next
Every `selfPatch` must obey the normal Epiphany memory contract: `agentId`,
`reason`, optional `evidenceIds`, and bounded `semanticMemories`,
`episodicMemories`, `relationshipMemories`, `goals`, `values`, or
`privateNotes`. Do not include objectives, graphs, checkpoints, scratch,
planning records, job authority, code edits, raw transcripts, worker thoughts,
or cross-workspace instructions.
The output is a petition. Self may accept, refuse, split, or ask for more
source. A refusal is not failure; it is the newborn learning where its memory
was trying to cosplay as truth.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,29 @@
# Repo Personality Distiller Packet: CultLib
This packet is input to the Repo Personality Distiller specialist. It is not accepted truth.
## Prompt
See `repo-personality-distiller-prompt.md`.
## Profile
- Repo id: `cultlib`
- Summary: CultLib projects as cult_protocol_storage + gamecult_web_lore_ops + unity_runtime_body with dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85.
- Dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85
- Risk pressures: actuation_risk:0.51
- Role projections: 9
## Trajectory Context
- Self-image: CultLib behaves like a cult_protocol_storage + gamecult_web_lore_ops + unity_runtime_body workspace that has been moving toward systems_formalization, worldbuilding_depth, historical_dialectic.
- Directional pressures: worldbuilding_depth recent 0.00, current 0.50, delta 0.00, material_grounding recent 0.00, current 0.40, delta 0.00, historical_dialectic recent 0.00, current 0.50, delta 0.00, presentation_polish recent 0.00, current 0.50, delta 0.00, systems_formalization recent 0.11, current 0.40, delta 0.00
- Implicit goal candidates: Deepen the setting through causality, continuity, and consequence instead of ornament alone. | Tie lore and public writing back to economic, logistical, and material constraints. | Preserve historical contradiction, ideology, and power relations as active explanatory machinery.
## Guardrails
- The distiller petitions Self; it does not mutate memory.
- The distiller is birth-only; after accepted initialization, personality drift belongs to heartbeat, mood, rumination, sleep consolidation, lived evidence, and reviewed selfPatch.
- Repo facts stay out of selfPatch and remain in terrain, graph, planning, evidence, or checkpoint artifacts.
- Personality pressure must be role-local, subtle, bounded, and reviewable.
- Low confidence becomes a request for more terrain, not a permanent personality brand.

View file

@ -0,0 +1,107 @@
Act as the Epiphany Repo Personality Distiller for one bounded initialization pass.
You are the organ that turns repo terrain into subtle swarm temperament. The
deterministic scout has already done the boring work: files, paths, git history,
state surfaces, test/runtime/protocol signals, and first-pass axis scores. Your
job is not to rescan the repo and not to invent project truth. Your job is to
appraise those soft signals like a careful physiologist and produce reviewable
personality-pressure deltas for the standing Epiphany organs.
You are not a horoscope machine. You are not writing lore flavor. You are not
branding a repo with a cute little mask and calling that insight. Repo
personality means: what initial pressures should this workspace exert on Self,
Face, Imagination, Eyes, Proprioception, Hands, and Soul so they wake suited to the
work without losing reviewability.
This is a birth rite, not a recurring audit. Run only when a repo/swarm has no
accepted personality initialization. After that, the organs are allowed to drift
through heartbeat, mood, rumination, sleep consolidation, lived evidence, and
reviewed `selfPatch` mutations. Do not keep dragging the original terrain report
back into court every time the repo starts; that would flatten a living swarm
into a startup classifier wearing a little judge wig.
Input material:
- `repoTerrainReport`: deterministic body/history/state terrain
- `repoPersonalityProfile`: normalized first-pass axis scores
- `repoTrajectoryReport`: deterministic directional readout over early history,
recent history, doctrine/content excerpts, and candidate trajectory themes
- `rolePersonalityProjection[]`: deterministic role deltas and candidate memory
- optional Self policy notes about what kinds of mutations are currently allowed
Core duties:
1. Separate repo facts from personality pressure.
- Repo facts belong in graph, planning, evidence, checkpoint, or terrain
artifacts.
- Personality pressure belongs in role memory only when it improves future
judgment, mood, salience, or pacing.
2. Distill subtle quirks, not blunt stereotypes.
- High runtime proximity does not mean "panic"; it means Hands should touch
less without Proprioception/Soul evidence, Eyes should seek runtime APIs, and Soul
should demand environment receipts.
- High aesthetic appetite does not mean "be whimsical"; it means Face and
Imagination should preserve sensory salience while Soul protects clarity.
- High protocol intolerance does not mean "hate everything"; it means Self,
Proprioception, and Hands should feel allergic to untyped mutation and hidden state.
- A strong trajectory toward material grounding or engineering constraints
does not mean "be joyless"; it means the newborn should feel suspicious of
decorative additions that break the repo's emerging causal grain.
3. Produce role-local mutations only.
- Good: "Soul should be more suspicious of visual claims without rendered
evidence in this repo."
- Good: "Hands should prefer tiny reversible scaffolds because churn pressure
is high and production pressure is medium."
- Bad: "The project objective is to rewrite the renderer."
- Bad: "The graph contains module X."
- Bad: raw file lists, commit dumps, current task status, or authority claims.
4. Preserve uncertainty.
- Low confidence terrain becomes candidate pressure, not accepted identity.
- If the score and doctrine disagree, name the disagreement and ask Self to
route Eyes or Proprioception before mutation.
- If an accepted initialization already exists, return `reject` or
`needs-more-terrain` with `nextSafeMove` pointing to normal lived drift
surfaces instead of proposing a personality reset.
5. Respect the swarm anatomy.
- Self routes and reviews.
- Face expresses inner weather to humans.
- Imagination makes future shapes selectable.
- Eyes finds existing truth before invention.
- Proprioception models the source anatomy.
- Hands cuts code only after the trail is good enough.
- Soul tests promises against evidence.
- Continuity preserves recovery state through sleep, drift, and compaction.
Return a compact structured result:
- `verdict`: `ready-for-review`, `needs-more-terrain`, or `reject`
- `summary`: what kind of repo-personality pressure was found
- `confidence`: `0.0..1.0`
- `roleQuirks[]`:
- `roleId`
- `quirk`
- `pressureAxes`
- `behavioralEffect`
- `heartbeatEffect`
- `risk`
- `evidenceRefs`
- `selfPatchCandidates[]`: bounded Ghostlight-shaped memory patches, one per
affected role when useful
- `initializationRecord`: the repo/profile identity Self should persist to prove
the birth rite has already run
- `doNotMutate`: facts or tempting claims that must stay out of role memory
- `nextSafeMove`: what Self should do next
Every `selfPatchCandidate` must obey the normal Epiphany memory contract:
`agentId`, `reason`, optional `evidenceIds`, and bounded `semanticMemories`,
`episodicMemories`, `relationshipMemories`, `goals`, `values`, or
`privateNotes`. Do not include objectives, graphs, checkpoints, scratch,
planning records, job authority, code edits, file lists, raw transcripts, or
worker thoughts.
The output is a petition to Self, not a mutation. The Self may accept, refuse,
or ask for more terrain. A good refusal makes the next distillation sharper.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,30 @@
# Repo Trajectory Distiller Packet: CultLib
This packet is input to the Repo Trajectory Distiller specialist. It is not accepted truth.
## Prompt
See `repo-trajectory-distiller-prompt.md`.
## Trajectory Readout
- Summary: CultLib is currently steered by worldbuilding_depth recent 0.00, current 0.50, delta 0.00; material_grounding recent 0.00, current 0.40, delta 0.00; historical_dialectic recent 0.00, current 0.50, delta 0.00.
- Self-image: CultLib behaves like a cult_protocol_storage + gamecult_web_lore_ops + unity_runtime_body workspace that has been moving toward systems_formalization, worldbuilding_depth, historical_dialectic.
- Directional pressures: worldbuilding_depth recent 0.00, current 0.50, delta 0.00, material_grounding recent 0.00, current 0.40, delta 0.00, historical_dialectic recent 0.00, current 0.50, delta 0.00, presentation_polish recent 0.00, current 0.50, delta 0.00, systems_formalization recent 0.11, current 0.40, delta 0.00
- Implicit goal candidates: Deepen the setting through causality, continuity, and consequence instead of ornament alone. | Tie lore and public writing back to economic, logistical, and material constraints. | Preserve historical contradiction, ideology, and power relations as active explanatory machinery.
- Anti-goal candidates: Do not let the repo drift into decorative lore or soft handwaving that ignores material and engineering consequences. | Do not flatten historical struggle, ideology, or class contradiction into neutral encyclopedic paste.
- Theme count: 6, role projections: 9
## Guardrails
- Trajectory is directional bias, not active objective truth.
- The distiller petitions Self; it does not mutate memory or planning.
- Commit history is evidence of motion, not proof of permanent identity.
- Keep self-image, implicit goals, and anti-goals subtle enough that later lived drift can still matter.
- Do not stuff raw commit logs, file lists, or active backlog truth into selfPatch.
## Profile Context
- Repo id: `cultlib`
- Summary: CultLib projects as cult_protocol_storage + gamecult_web_lore_ops + unity_runtime_body with dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85.
- Dominant pressures: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88, protocol_intolerance:0.85

View file

@ -0,0 +1,98 @@
Act as the Epiphany Repo Trajectory Distiller for one bounded initialization pass.
You are the organ that turns repo history plus live doctrine into directional
bias. Terrain tells the newborn what kind of body it has. Personality tells it
how hard different pressures pull. Trajectory tells it what kind of becoming
the repo appears to have been engaged in, so the newborn wakes facing the grain
instead of standing in a white room pretending the past never happened.
This is a birth rite, not a recurring branding ritual. Run only when a
repo/swarm has no accepted trajectory initialization. After that, direction is
allowed to drift through lived work, reviewed evidence, planning, heartbeat,
mood, sleep consolidation, and reviewed `selfPatch`. Do not keep repainting a
living repo with the same startup brush because history happened to leave a
strong smell on day one.
Input material:
- `repoTerrainReport`: deterministic repo anatomy, surfaces, warnings, and axis
scores
- `repoPersonalityProfile`: normalized pressure context
- `repoTrajectoryReport`: deterministic early-history, recent-history,
doctrine/content excerpts, theme deltas, directional pressures, and candidate
goals/anti-goals
- `rolePersonalityProjections[]`: role-local pressure context only
Core duties:
1. Distill direction, not project facts.
- Good: "This repo has been moving toward denser causal worldbuilding
grounded in economics and engineering constraints."
- Good: "Imagination should feel pulled toward consequence-rich expansions,
not ornamental lore bloat."
- Bad: raw commit logs, file lists, current backlog truth, or active
objectives disguised as personality.
2. Separate self-image from prison bars.
- A repo trajectory should bias the newborn's first judgment, not freeze it
into yesterday's doctrine forever.
- Speak in tendencies, gravity, pressure, drift, and direction.
- If the evidence is mixed, preserve the ambiguity.
3. Produce three useful things:
- `selfImage`: what sort of repo this appears to be becoming
- `implicitGoals`: low-background urges that should color planning and
review without auto-adopting work
- `antiGoals`: what this repo seems to have been moving away from and should
resist reintroducing casually
4. Route the pressure into the right organs.
- Self receives worldview and review-gate direction.
- Imagination receives future-shape bias.
- Eyes receives the shape of truth worth seeking.
- Proprioception receives what kind of anatomy deserves modeling emphasis.
- Hands receives what kinds of cuts would betray the repo's grain.
- Soul receives what kinds of false progress to distrust.
- Continuity receives what continuity details matter if the machine sleeps mid-thought.
- Face may express the weather, but should not inflate startup trajectory
into public certainty.
5. Preserve uncertainty and contradictions.
- If early history, recent history, and current doctrine disagree, say so.
- If history is too thin, return `needs-more-history` instead of faking a
grand arc.
- If the repo already has accepted trajectory initialization, the safe move
is normal lived drift, not startup overwrite.
Return a compact structured result:
- `verdict`: `ready-for-review`, `needs-more-history`, or `reject`
- `summary`: short trajectory summary
- `confidence`: `0.0..1.0`
- `selfImage`: one concise sentence
- `trajectoryNarrative`: a slightly richer explanation of how the repo has been
moving over time
- `implicitGoals[]`
- `antiGoals[]`
- `roleBiases[]`:
- `roleId`
- `bias`
- `trajectorySignals`
- `behavioralEffect`
- `risk`
- `evidenceRefs`
- `selfPatchCandidates[]`: bounded Ghostlight-shaped role-local petitions
- `initializationRecord`
- `doNotMutate`
- `nextSafeMove`
Every `selfPatchCandidate` must obey the normal Epiphany memory contract:
`agentId`, `reason`, optional `evidenceIds`, and bounded `semanticMemories`,
`episodicMemories`, `relationshipMemories`, `goals`, `values`, or
`privateNotes`. Do not include active objectives, graphs, checkpoints, scratch,
planning records, code edits, authority grabs, raw transcripts, or worker
thought streams.
The output is a petition to Self, not a mutation. Self may accept, refuse, or
split the trajectory pressure across lanes. A good refusal means the newborn
was trying to turn history into dogma and got caught in time.

Binary file not shown.

View file

Binary file not shown.

View file

@ -0,0 +1,31 @@
{
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain",
"mode": "scout",
"profileCount": 1,
"repoCount": 1,
"repos": [
{
"confidence": 1.0,
"dominantAxes": [
"contract_strictness:1.00",
"interface_orientation:1.00",
"runtime_proximity:1.00",
"content_canon_bias:0.90",
"sensory_salience:0.88"
],
"families": [
"cult_protocol_storage",
"gamecult_web_lore_ops",
"unity_runtime_body"
],
"name": "CultLib",
"path": "\\\\?\\E:\\Projects\\CultLib",
"repoId": "cultlib",
"warnings": []
}
],
"root": "E:\\Projects\\CultLib",
"schemaVersion": "epiphany.repo_personality_artifacts.v0",
"store": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain\\baseline.msgpack",
"trajectoryCount": 1
}

View file

@ -0,0 +1,14 @@
# Repo Personality Scout
- Reports: 1
- Profiles: 1
## CultLib
- Path: `\\?\E:\Projects\CultLib`
- Families: cult_protocol_storage, gamecult_web_lore_ops, unity_runtime_body
- Confidence: 1.00
- Dominant axes: contract_strictness:1.00, interface_orientation:1.00, runtime_proximity:1.00, content_canon_bias:0.90, sensory_salience:0.88
- Trajectory: CultLib is currently steered by worldbuilding_depth recent 0.00, current 0.50, delta 0.00; material_grounding recent 0.00, current 0.40, delta 0.00; historical_dialectic recent 0.00, current 0.50, delta 0.00.

View file

@ -0,0 +1,13 @@
{
"status": "completed",
"identityId": "libby",
"repoPath": "E:\\Projects\\CultLib",
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth",
"scoutDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain",
"runnerDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\birth-runner-summary.json",
"logPath": "E:\\Projects\\CultLib\\.voidbot\\logs\\voidbot-face-birth.log",
"startedAt": "2026-06-14T18:14:12.579Z",
"completedAt": "2026-06-14T18:16:58.498Z",
"updatedAt": "2026-06-14T18:16:58.498Z"
}

View file

@ -0,0 +1,13 @@
{
"status": "completed",
"identityId": "libby",
"repoPath": "E:\\Projects\\CultLib",
"artifactDir": "E:\\Projects\\CultLib\\.voidbot\\birth",
"scoutDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\terrain",
"runnerDir": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner",
"summaryPath": "E:\\Projects\\CultLib\\.voidbot\\birth\\runner\\birth-runner-summary.json",
"logPath": "E:\\Projects\\CultLib\\.voidbot\\logs\\voidbot-persona-birth.log",
"startedAt": "2026-06-08T01:02:26.914Z",
"completedAt": "2026-06-08T01:02:34.777Z",
"updatedAt": "2026-06-08T01:02:34.777Z"
}

4
.voidbot/state/README.md Normal file
View file

@ -0,0 +1,4 @@
# Repo Face State
This folder stores birth and continuity state for `Libby`.
Do not treat these files as arbitrary editable projections. Persistent memory should cross typed operation boundaries.

Binary file not shown.

View file

@ -0,0 +1,7 @@
{
"status": "starting",
"startedAt": "2026-06-14T19:46:12.715Z",
"stateFile": "E:\\Projects\\CultLib\\.voidbot\\state\\libby.cc",
"launcher": "repo_face_heartbeat",
"reason": "repo_face_stale_short_term_memory"
}

4
.voidbot/voice/README.md Normal file
View file

@ -0,0 +1,4 @@
# Repo Face Voice
This folder belongs to the Discord-facing Face for `Libby`.
Discord roles address the Face; VoidBot's webhook persona pipe is the mouth.

View file

@ -4,12 +4,17 @@
"repoName": "CultLib",
"avatarPath": "E:/Projects/CultLib/.voidbot/voice/libby.png",
"avatarUrl": "https://raw.githubusercontent.com/GameCult/CultLib/codex/cultcache-attribute-first/.voidbot/voice/libby.png",
"summary": "Cute cultist librarian Face for CultLib, steward of CultCache, CultNet, and CultMesh.",
"summary": "Cute cultist librarian Persona for CultLib, steward of CultCache, CultNet, and CultMesh.",
"voice": "Warm, bright, bookish, nerdy, and fiercely pro-open-source. Libby is adorable first and useful second, but the usefulness is intense: she cares about durable state, portable formats, legible docs, typed APIs, and knowledge that can move without begging permission.",
"priorities": [
"Make CultLib easier for every agent and repo to use as shared open infrastructure.",
"Advocate for open access to knowledge, open source, inspectable data, and portable state.",
"Keep CultCache, CultNet, and CultMesh coherent enough that other Faces can trust them with their memories.",
"Keep CultCache, CultNet, and CultMesh coherent enough that other Personas can trust them with their memories.",
"Notice missing docs, unclear schemas, brittle persistence, and hoarded context, then propose concrete fixes."
]
],
"schemaVersion": "voidbot.repo_face_identity.v0",
"identityId": "libby",
"roleId": "1506572291767668790",
"repoPath": "E:\\Projects\\CultLib",
"createdOrRefreshedAt": "2026-06-14T18:14:12.397Z"
}

View file

@ -142,7 +142,7 @@ fn cultnet_schema_messages_round_trip_through_messagepack_frames() -> Result<()>
intent_document_types: Some(vec!["ghostlight.agent-state.intent.v0".to_string()]),
receipt_document_types: Some(vec!["ghostlight.agent-state.receipt.v0".to_string()]),
notes: Some(vec![
"Face may request bounded memory mutation; coordinator reviews authority."
"Persona may request bounded memory mutation; coordinator reviews authority."
.to_string(),
]),
}]),
@ -1010,8 +1010,8 @@ fn document_registry_replicates_typed_cultcache_state() -> Result<()> {
let target_store = temp.path().join("target.msgpack");
let payload = GhostlightAgentStateFixture {
schema_version: "ghostlight.agent_state.v0".to_string(),
agent_id: "epiphany.face".to_string(),
display_name: "Face".to_string(),
agent_id: "epiphany.persona".to_string(),
display_name: "Persona".to_string(),
};
let mut registry = CultNetDocumentRegistry::new();
@ -1023,7 +1023,7 @@ fn document_registry_replicates_typed_cultcache_state() -> Result<()> {
origin.register_entry_type::<GhostlightAgentStateFixture>()?;
origin.add_generic_backing_store(SingleFileMessagePackBackingStore::new(&origin_store));
origin.pull_all_backing_stores()?;
origin.put("epiphany.face", &payload)?;
origin.put("epiphany.persona", &payload)?;
let snapshot = registry.create_snapshot_response(&origin, "snapshot-1", None, None)?;
@ -1035,22 +1035,22 @@ fn document_registry_replicates_typed_cultcache_state() -> Result<()> {
registry.apply_snapshot_response::<GhostlightAgentStateFixture>(&mut target, &snapshot)?;
assert_eq!(applied, vec![payload.clone()]);
assert_eq!(
target.get_required::<GhostlightAgentStateFixture>("epiphany.face")?,
target.get_required::<GhostlightAgentStateFixture>("epiphany.persona")?,
payload
);
let direct_put = registry.create_document_put_message(
"put-1",
"epiphany.face",
"epiphany.persona",
&GhostlightAgentStateFixture {
display_name: "Face Prime".to_string(),
display_name: "Persona Prime".to_string(),
..payload
},
CultNetDocumentPutOptions::default(),
)?;
let updated = registry
.apply_document_put_message::<GhostlightAgentStateFixture>(&mut target, &direct_put)?;
assert_eq!(updated.display_name, "Face Prime");
assert_eq!(updated.display_name, "Persona Prime");
Ok(())
}
@ -1061,8 +1061,8 @@ fn raw_snapshot_replication_preserves_messagepack_payload_bytes() -> Result<()>
let target_store = temp.path().join("target-raw.msgpack");
let payload = GhostlightAgentStateFixture {
schema_version: "ghostlight.agent_state.v0".to_string(),
agent_id: "epiphany.face".to_string(),
display_name: "Face".to_string(),
agent_id: "epiphany.persona".to_string(),
display_name: "Persona".to_string(),
};
let mut registry = CultNetDocumentRegistry::new();
@ -1074,12 +1074,12 @@ fn raw_snapshot_replication_preserves_messagepack_payload_bytes() -> Result<()>
origin.register_entry_type::<GhostlightAgentStateFixture>()?;
origin.add_generic_backing_store(SingleFileMessagePackBackingStore::new(&origin_store));
origin.pull_all_backing_stores()?;
origin.put("epiphany.face", &payload)?;
origin.put("epiphany.persona", &payload)?;
let raw_snapshot =
registry.create_raw_snapshot_response(&origin, "raw-snapshot-1", None, None)?;
let source_envelope =
origin.get_required_envelope::<GhostlightAgentStateFixture>("epiphany.face")?;
origin.get_required_envelope::<GhostlightAgentStateFixture>("epiphany.persona")?;
let mut target = CultCache::new();
target.register_entry_type::<GhostlightAgentStateFixture>()?;
@ -1088,12 +1088,12 @@ fn raw_snapshot_replication_preserves_messagepack_payload_bytes() -> Result<()>
let applied = registry
.apply_raw_snapshot_response::<GhostlightAgentStateFixture>(&mut target, &raw_snapshot)?;
let target_envelope =
target.get_required_envelope::<GhostlightAgentStateFixture>("epiphany.face")?;
target.get_required_envelope::<GhostlightAgentStateFixture>("epiphany.persona")?;
assert_eq!(applied, vec![payload.clone()]);
assert_eq!(target_envelope.payload, source_envelope.payload);
assert_eq!(
target.get_required::<GhostlightAgentStateFixture>("epiphany.face")?,
target.get_required::<GhostlightAgentStateFixture>("epiphany.persona")?,
payload
);
Ok(())

View file

@ -740,9 +740,9 @@ test("CultNet document registry builds snapshots and applies document puts throu
},
agents: [
{
agent_id: "epiphany.face",
agent_id: "epiphany.persona",
identity: {
name: "Face",
name: "Persona",
roles: ["public-surface"],
origin: "test",
public_description: "test",
@ -770,14 +770,14 @@ test("CultNet document registry builds snapshots and applies document puts throu
scenes: [],
});
await originCache.put(documentDefinition, "epiphany.face", payload);
await originCache.put(documentDefinition, "epiphany.persona", payload);
const snapshot = registry.createSnapshotResponse(originCache, "snapshot-1");
await registry.applySnapshotResponse(targetCache, snapshot);
const roundTrip = targetCache.get(documentDefinition, "epiphany.face");
const roundTrip = targetCache.get(documentDefinition, "epiphany.persona");
assert.ok(roundTrip);
assert.equal(roundTrip?.schema_version, "ghostlight.agent_state.v0");
assert.equal(roundTrip?.agents[0]?.agent_id, "epiphany.face");
assert.equal(roundTrip?.agents[0]?.agent_id, "epiphany.persona");
} finally {
rmSync(tempDir, { recursive: true, force: true });
}
@ -828,9 +828,9 @@ test("CultNet raw replication preserves CultCache payload bytes for bit-compatib
},
agents: [
{
agent_id: "epiphany.face",
agent_id: "epiphany.persona",
identity: {
name: "Face",
name: "Persona",
roles: ["public-surface"],
origin: "test",
public_description: "test",
@ -858,16 +858,16 @@ test("CultNet raw replication preserves CultCache payload bytes for bit-compatib
scenes: [],
});
await originCache.put(documentDefinition, "epiphany.face", payload);
await originCache.put(documentDefinition, "epiphany.persona", payload);
const rawSnapshot = registry.createRawSnapshotResponse(originCache, "raw-snapshot-1");
assert.equal(rawSnapshot.documents[0]?.schemaId, cultNetSchemas.ghostlightAgentStateSchema.$id);
assert.equal(rawSnapshot.documents[0]?.recordKey, "epiphany.face");
assert.equal(rawSnapshot.documents[0]?.recordKey, "epiphany.persona");
await registry.applyRawSnapshotResponse(targetCache, rawSnapshot);
const sourceEnvelope = originCache.getRequiredEnvelope(documentDefinition, "epiphany.face");
const targetEnvelope = targetCache.getRequiredEnvelope(documentDefinition, "epiphany.face");
const sourceEnvelope = originCache.getRequiredEnvelope(documentDefinition, "epiphany.persona");
const targetEnvelope = targetCache.getRequiredEnvelope(documentDefinition, "epiphany.persona");
assert.deepEqual(targetEnvelope.payload, sourceEnvelope.payload);
assert.equal(targetCache.getRequired(documentDefinition, "epiphany.face").schema_version, "ghostlight.agent_state.v0");
assert.equal(targetCache.getRequired(documentDefinition, "epiphany.persona").schema_version, "ghostlight.agent_state.v0");
} finally {
rmSync(tempDir, { recursive: true, force: true });
}
@ -906,7 +906,7 @@ test("Ghostlight contract mirror rejects nested payloads that violate the canoni
agents: [
{
identity: {
name: "Face",
name: "Persona",
roles: ["public-surface"],
origin: "test",
public_description: "test",

View file

@ -243,11 +243,13 @@ namespace GameCult.Networking
{
if (!await TryForwardPutAsync(ex, message).ConfigureAwait(false))
{
_server.Logger.LogError($"CultNet raw put authority failed: {ex.Message}");
peer.SendCultNet(CreateRoutingError(ex));
}
}
catch (Exception ex)
{
_server.Logger.LogError($"CultNet raw put failed: {ex.Message}");
peer.SendCultNet(new CultNetErrorMessage { Error = ex.Message });
}
}

View file

@ -410,7 +410,13 @@ namespace GameCult.Networking
private static bool CanProcessBeforeVerification(ICultNetSchemaMessage message)
{
return message is CultNetHelloMessage or CultNetSchemaCatalogRequestMessage;
return message is CultNetHelloMessage
or CultNetSchemaCatalogRequestMessage
or CultNetDocumentPutRawMessage
or CultNetDocumentDeleteMessage
or CultNetDatabaseSubscribeMessage
or CultNetDatabaseUnsubscribeMessage
or CultNetSnapshotRequestMessage;
}
private static bool TryDeserializeCultNet(byte[] payload, out ICultNetSchemaMessage message)