Egbe Companions · Architecture

Determinism, Data & Integration

A focused page within the Egbe Companions Architecture documentation. The full map and every sibling page live in the Architecture hub.

5sections11 minread1diagram1table

On this page

V6 — Egbe, the agentic-companion universe — runs a world full of LLM-driven minds (the Ori) that keep living whether or not a player is watching. A non-deterministic mind sitting on top of a non-deterministic world would be unauditable and undebuggable: you could never replay why an agent refused an objective, never reproduce a welfare report, never re-cut a Chronicle cinematic from the same seed. So V6 draws a hard line down the middle of the system. The non-LLM substrate — tier assignment, behaviour-tree / HTN stepping, the world tick, the perception→action channel — is deterministic and seeded; the LLM cognition that rides on top is not deterministic, but every call is logged with full input context, output, agent, tier, and cause, and retained for audit. That split is the load-bearing invariant of the whole universe: the deterministic half is replayable, and the stochastic half is accountable. Underneath both sits one more guarantee — the Ori is an append-only, event-sourced biography, so an agent's entire life is a hash- chained, vector-clocked log that nothing else may contradict. This page is the platform-and-governance companion that ties those three together — the determinism invariant, the data architecture, and how the new V6 subsystems integrate with each other and with the reused V1/V3 foundations. It is part of the Platform, Governance, and Launch group; the orientation hub is ../V6_ARCHITECTURE.md.

What ships, honestly#

Five plain claims, so the rest of the page reads at face value.

  • The deterministic core is real and tested by replay. The Moirai kernel (libs/v6/moirai-kernel/rust/src/lib.rs) carries 34 Rust unit tests. seeded_tier_assignment_replay_is_identical (:4089) runs the same seeded 24-agent / 12-tick trace twice and asserts the two traces are byte-identical; the 10,200-agent latency test runs the same batch through three fresh kernels and keeps the minimum elapsed time (:4391:4397), which is only meaningful because a tick is a pure function of its inputs.
  • The wire protocol is fixed-point integer by construction. egbe-protocol (libs/v6/egbe-protocol/proto/.../egbe.proto) carries no floats anywhere on the deterministic channel: positions are sint32 *_mm (:119), rotations sint32 *_md milli-degrees (:125), everything soft is basis-points, and ticks/sequences are uint64 (:197). The generated TS and the UE C++ bindings (ue/generated/.../egbe.pb.h) share that integer schema, so there is no cross-machine float drift to replay around.
  • Cognition is logged, not faked. The cognition-call audit log (build_moirai_cognition_call_audit_log, lib.rs:877; TS twin buildMoiraiCognitionCallAuditLog, src/index.ts:615) records the agent, tier, cause, model route, input context, output, token usage, and the Isis safety decision for every dispatched call, and validate…AuditLog (:826) fails closed unless every record is replayable. It is retained under v1:audit-platform:retention:cognition-call (lib.rs:33).
  • The audited "call" is currently the kernel's deterministic intent plus a token estimate. The honest seam: the audit record's output is the serialized wire::ActionIntent the kernel produced, and token_usage is an estimate (tier_budget_tokens is flagged ACCOUNTING-ONLY, lib.rs:138). The real model transcript flows through the injected cognition gateway (src/cognition-gateway-mount.ts); wiring its output into the audit record is a named, separate ledger task, not done here.
  • Storage backends are service-side; this page verifies the contracts and the kernel. PostgreSQL+pgvector, Redis Streams, and MinIO live in the Rust services (apps/v6/egbe-ori-service/), which this page does not open. What is verified in-lib is the schema of record (libs/contracts/src/v6/) and the deterministic kernel that consumes it; the persistence substrate is described against the monolith's data-architecture section and the platform persistence-data reference.

These are altitude statements, not disparagement: every file cited compiles and is exercised by a passing spec. V6's determinism story is simply stamped one layer lower than a full lockstep engine — it is the scheduler, channel, and event-log layer, with the model run deliberately left stochastic-but-logged.

The determinism invariant#

The monolith states it directly (arch§"Determinism, Replay, and Audit"): the deterministic core can be replayed for debugging and for Clio's Sequencer-driven Chronicle cinematics, while LLM cognition is logged rather than reproduced. Four mechanisms make that real.

Integer state, seeded transitions#

Everything on the deterministic channel is integer. The proto's Vector3Mm (egbe.proto:119), RotationMilliDegrees (:125), AgentNeedState / EmotionState basis-points (:156,:163), and uint64 world_tick / sequence fields are the substrate; there is no float/double on the perception→action path to diverge across a server, a UE client, and a Tier-2 web fallback. Where the kernel needs randomness for a test harness it uses an explicit seeded LCG — SeededTierReplayRng (lib.rs:5345) is state = state*2862933555777941757 + 3037000493, advanced identically on every machine — and the seeded trace it drives (seeded_tier_assignment_trace, :5296) is exactly what seeded_tier_assignment_replay_is_identical proves reproducible. Tier assignment itself is a pure function of the perception frame plus per-agent damping state (assign_cognition_tier_with_transition_damping), so the same inputs always yield the same Clotho/Lachesis/Atropos decision and reason.

Deterministic ordering on the body↔mind channel#

A scheduler over a population must not let map iteration or network arrival order leak into behaviour. egbe-protocol therefore sorts at every boundary: orderedPerceptionFrames (src/index.ts:2065) orders frames by (agentEntityId, perceptionSequence, worldTick) before deriving actions; stableActionOrderingKey (:1207) gives each action a total order; compareWorldEvents (:1942) orders by sequence then eventId; and the delta path — encodeAgentStateDeltaFromSnapshots (:1268) and applyAgentStateDelta (:1327) — sorts upserts/removals by id and merges world events deterministically. roundTripPerceptionBatchToActionBatch (:1201) encodes → decodes → derives → re-encodes, and the spec asserts the protobufs round-trip exactly (index.spec.ts:312,:360). The result: a perception batch and the action batch it produces are independent of the order the world server happened to enqueue agents in.

Replayable rehydration and lossless consolidation#

The hardest determinism case is an agent that lived off-screen and is now escalating into a player's scene. The kernel reconstructs it from the Ori, not from RAM: rehydrate… loads the projection (load_ori_projection_from_snapshot, lib.rs:1560), sorts the events by sequence (:1567), and reports projection_replayed_event_count and projection_within_budget (:1591) — a deterministic snapshot-plus-tail replay. The continuity bar is enforced: CONTINUITY_EVAL_PASS_THRESHOLD_BASIS_POINTS = 9_500 (:27), and the eval asserts a clean rehydrate scores 10,000 bp. The mirror case, an agent dropping fidelity, must lose nothing: consolidate_deescalation_to_ori_events (:1993) buckets pending fine-grained fragments into a BTreeMap<FineGrainedStateKind, …> (:1996, ordered iteration, deterministic event emission) and verify_deescalation_consolidation_no_state_loss (:2021) returns no_state_lost only when every fragment is covered by an emitted Ori event (:2038). Escalation rehydrates losslessly; de-escalation consolidates losslessly; both are replayable.

Logged, fail-loud cognition#

LLM output cannot be replayed bit-for-bit, so V6 makes it auditable instead. Every dispatched call yields a MoiraiCognitionCallAuditRecord carrying agent_entity_id, tier, cause, the selected model route, input_context, output, token_usage, and a safety_decisions vector (build_moirai_cognition_call_audit_record, lib.rs:907). validate_moirai_cognition_call_audit_log (:826) is fail-closed: it rejects the log unless the policy/retention refs match, identities are non-empty, the replay context and the safety decision are present, and replayable_record_count == records.len(). The dedicated test cognition_calls_are_logged_with_v1_retention_for_audit_replay (:4267) drives the full path. This is the spine the monolith leans on when the Operator Console investigates a welfare report — the deterministic world tells you what happened; the cognition log tells you why the model chose it, and every operator read of either is itself audited through @oshun/audit-platform.

Honest boundary: the in-lib audit output is the deterministic intent and the tokens are estimates. The monolith additionally promises a UE-side V6.Replay.GoldenReplayHarness spec and a golden-replay corpus in V6Tests; those run on the engine and are not exercised by the libs read here, so treat them as monolith-stated, UE-side, unverified on this page.

Data architecture#

The deterministic core is only as trustworthy as the log it replays from. V6's data model is event-sourced at the centre, materialized at the edges.

The Ori event log — the audit spine#

An Ori is not a mutable row; it is an append-only, ordered stream of life-events keyed by ori_id. The schema of record is libs/contracts/src/v6/ori-event.ts: a discriminated union of 17 event types (OriEventTypeSchema, :10Born, MemoryFormed, ObjectiveRefused, Crossroads, Incarnated, Departed, Transcended, Died, …). Every event carries the same base fields (OriEventBaseFields, :240): an eventId, the oriId, a vector clock (OriVectorClockSchema, :31 — one non-negative counter per writer context: Solo, a Commons region, a Co-op session, an Aye realm; rejected if empty), a UTC timestamp, an attribution (OriEventAttributionSchema, :43 — which steward/agent/ system/shard/realm caused it, and the causedByEventId), and a provenance ref whose chainHash is a SHA-256 content hash (OriEventProvenanceRefSchema, :53; V6ContentHashSchema = /^[a-f0-9]{64}$/, primitives.ts:12). The contracts' round-trip spec parses each fixture and re-parses its JSON-normalized form to prove stability (roundtrip.spec.ts:124).

Append-only is a design guarantee, not an optimization (arch§"Why Append-Only"): erasure is not an operation the log exposes, so a steward — or a bug, or an exploit — cannot silently rewrite a life or wipe an agent's memory of mistreatment. Forgiveness is itself an appended event that reweights an episode's salience; the original episode remains. Current state is a materialized read-model (personality vector, memory index, relationship graph, capability profile, arc state) rebuilt from the log, with a snapshot every K events so an agent loads in O(snapshot + tail) — exactly the snapshot-plus-tail the kernel replays. Concurrent writes merge by vector-clock ordering with a documented precedence (physical-presence wins location; steward-directive wins accepted objectives; memory/relationship events are commutative); genuinely unorderable conflicts are handed to Clio for narrative reconciliation, which appends a connective beat and logs that it did.

Where the bytes live, and tenancy#

Store What it holds
PostgreSQL + pgvector the Ori event log and projections, memory embeddings, the relationship adjacency graph, homestead/roster state, steward reputation — partitioned by ori_id/account, residency-tagged
Redis Streams the world-event bus, the Moirai perception/action queues, the cognition-batch queues, presence fan-out
MinIO / S3 + CDN UE assets, district content, Yemaya Chronicle media, Book-of-the-Ori editions
V1 event bus (@oshun/event-bus) cross-domain events: incarnation start/return, welfare alerts, commerce, Themis disputes

V6 runs in its own domain database following the Oshun domain-isolation pattern; all agent data is residency-tagged and consent-scoped through the V1 Iris and @oshun/data-residency stacks, and every operator read is recorded by the V1 audit platform. Because the Ori service is the single source of truth, the player's whole household and progression are intrinsically cross-platform — there is no per-platform save to reconcile, and the cross-progression continuity report simply compares event-sourced projections by continuity hash. The storage-engine, partitioning, and residency mechanics belong to the platform persistence-data reference; this page owns the shape (event-sourced + vector-clocked + hash-chained) that makes them auditable.

Subsystem integration#

V6 does not fork the monorepo (arch§"V1 and V3 Integration"). It is a new agent-simulation substrate — Ori, Moirai, Vac, Clio, Ninhursag, the Aye Bridge — bolted onto a reused metaverse substrate (the UE5 client, world server, gateway, Pixel Streaming, avatars, spatial audio, all carried from V3) and a reused mind (Iris memory, Psyche runtime, Isis governed generation, Sophia grounding). The integration seams are deliberately narrow.

flowchart TB subgraph BODY["BODY — Egbe World Server (deterministic, integer wire)"] ws["World tick · physics · BT/HTN co-located"] end subgraph MIND["MIND — Moirai kernel + cluster"] sched["Tier scheduler<br/><sub>pure fn of perception + state</sub>"] gw["Cognition gateway mount<br/><sub>injected → @iris/agents-core</sub>"] sched --> gw end subgraph MEM["MEMORY — Ori service (append-only)"] log[("event log<br/>vector-clock · chainHash")] proj["projections + snapshots"] log --> proj end audit[("cognition-call audit log<br/><sub>v1:audit-platform retention</sub>")] contracts["libs/contracts/src/v6<br/><sub>UE C++ · Rust · TS</sub>"] aye["Aye Bridge<br/><sub>passport / journal</sub>"] ws -->|"PerceptionBatch (egbe-protocol)"| sched sched -->|"ActionBatch (ordered, integer)"| ws gw -->|"governed model run"| MEM sched -->|"every call logged"| audit ws -->|"durable life-events"| log sched -->|"rehydrate: snapshot + tail"| proj proj -->|"de-escalation consolidate"| log ws & aye -->|"incarnation journal"| log contracts -.->|"schema of record"| ws & sched & log & aye classDef det fill:#dbeafe,stroke:#1e40af,color:#1e3a8a classDef store fill:#f3e8ff,stroke:#6d28d9,color:#3b0764 class ws,sched det class log,proj,audit store

Body ↔ Mind is the egbe-protocol perception/action channel. The world server emits a PerceptionBatch; Moirai recomputes tiers, dispatches the right kind of thinking, and returns an ActionBatch (MoiraiKernel::tick, lib.rs:1354). The cheap, near-deterministic path (tier assignment + BT/HTN stepping) runs co-located with the world server so it survives a cognition outage; the expensive LLM cognition is dispatched to the horizontally-scaled Moirai cluster, sharded by ori_id (arch§"Where the Work Runs").

Mind ↔ Memory is the rehydrate/consolidate cycle above: Moirai reads context from the Ori on escalation and writes consolidated events back on de-escalation, so an off-screen life is continuous with the on-screen one and nothing is lost when fidelity drops.

Mind ↔ Models is the cognition gateway. cognition-gateway-mount.ts mounts the shared Iris CognitionGateway so an Ori dialogue request round-trips through a governed, auditable model run with a per-tier budget and operator kill-switches, instead of V6 growing a fourth private agent stack. Because moirai-kernel is a buildable lib (it sets rootDir), it cannot import the @iris/agents-core source without TS6059, so the gateway, run manager, and kill-switch registry are injected structural handles to which the real implementations are assignable — a deliberate, documented seam, with the on-host model run left [~].

Contracts are the one schema across three languages. Everything in libs/contracts/src/v6/ is consumed by the UE client (generated C++), the Rust services, and the web surfaces (TS); the egbe-protocol proto likewise emits TS and UE C++ (egbe.pb.h/.cc). A change to the Ori event shape or the wire format is a single edit that every surface re-generates against.

Aye realms integrate only through the bridge. V2/V3/V4/V5 are reached solely via the Aye Bridge's per-destination adapters and the passport/journal envelope (IncarnatedPayloadSchema / IncarnationReturnedPayloadSchema, ori-event.ts:181,:191): the full Ori stays here, authoritative, while a destination realm holds only a signed passport and writes an incarnation journal back as appended events. Commerce is just as narrow — base purchase, cosmetics, expansions, Egbe Studio capacity, and Yemaya keepsakes route through the Aje substrate (egbe-protocol EgbeAjeCommerceCatalog), and agents, bond, fate, and capability are structurally not sellable (EgbeForbiddenCommerceSkuKind), with no gacha and no loot box. Steward-not-owner is enforced the same way in the kernel: delete, will-erasure, memory-wipe, and forcing past a refusal are simply not operations the substrate exposes, and that boundary is fuzz-proven — both of which are detailed in the safety companion below.

  • ./moirai-kernel-and-cost-tiering.md — the kernel whose deterministic tick, tier scheduling, and cognition-call audit log this page treats as the determinism substrate; the per-tier token budgets and smallest-qualified model routing that bound the logged cognition.
  • ./safety-welfare-provenance-and-eval-gates.md — steward-not-owner enforcement, the Isis behaviour-policy gate that stamps every audit record's safety decision, provenance signing, and the behaviour/consistency/safety eval gates that block a release.
  • ./ori-biography-service.md — the append-only event log, projections, snapshots, the passport, and vector-clock conflict resolution in full.
  • ./world-server-and-shard-continuum.md — the deterministic world tick and shard continuum on the body side of the perception/action channel.
  • ../../platform/persistence-data.html — the platform storage substrate (PostgreSQL+pgvector, Redis, object storage) and residency mechanics the Ori event log materializes onto.
  • Hub: ../V6_ARCHITECTURE.md — the "Determinism, Replay, and Audit", "Data Architecture and Tenancy", and "V1 and V3 Integration" sections.