A creator republic is not just a renderer and a netcode — it is the place where a character persists, where money has to stay sound across thousands of community-run economies, where two people standing in the same square can hear each other, and where a crew that earned its reputation in one realm carries it into the next. V7 ("Mawu") names those three planes Nàná (the character and economy data model), Pheme (the proximity-and-radio voice architecture), and Hera (the social-graph data model — crews, guilds, organizations). This page is the engineering companion to the "Nàná — Character and Economy Data Model," "Pheme — Voice Architecture," and "Hera — Social Graph Data Model" summaries in the orientation hub, and it sits beside the realm-server deep dive that owns the authority these models are written through.
The grounding is real Rust and real Unreal C++, and it is dual-located the way
V7 always is: the canonical character primitive is the v7-nana crate
(libs/v7/nana/src/lib.rs); the economy, property, civic, and deletion-limit
machinery that surrounds it is in the realm server
(apps/v7/moremi-realm-server/src/lib.rs); the social graph is its own
hera-social-service crate (apps/v7/hera-social-service/src/lib.rs); voice is
both a Blueprint mix library in UE (V7/ue/Source/MawuVoice) and a wire channel
in libs/v7/realm-protocol; and the bridge that writes a character into durable
storage is libs/v7/substrate-bridge. Read the realm-server page for how
authority and netcode work; read this for what they carry. The section hub is
../V7_ARCHITECTURE.md.
What ships, honestly#
These three planes are real, test-driven code — but they ship at three different levels of assembly, and the monolith's prose runs slightly ahead of the structs in two places. The honest picture:
- Real and test-covered. The Nàná character record + validation
(
libs/v7/nana, 2 tests), the double-entry economy ledger that refuses to post an unbalanced entry, the inflation auto-balancer with a sinkless-config gate, the Iris-consent-gated character store with steward-not-owner deletion limits, property ACLs with a Danu interior-handoff probe, and the civic-records model are all genuine algorithms inside the realm server's 69#[test]cases. Hera is a real 1,085-line social graph with role-gated treasury withdrawals, an audit ledger, a cross-realm reputation whitelist gate, an Ori group-presence passport, and a device-attestation ban-evasion eval (7 tests). The MawuVoice proximity/radio mix is real UE C++ math. - Library-grade, not a running service. Both
moremi-realm-serverandhera-social-serviceexpose their behaviour as libraries plus a health-only daemon —hera-social-service'smain()callsrun_service(), which binds the sharedservice_contracthealth server (owner "Hera", port47206). The social graph is exercised by tests and eval functions, not by a live socket serving group mutations. - Spec-level where the monolith over-claims. Pheme's codec and SFU (Opus
over WebRTC) are reused V6 Egbe-Gateway infrastructure, not re-implemented
here; the
MawuVoicemodule depends onCore/CoreUObject/Engineonly and is a per-emitter gain/pan evaluator, not the server-side SFU mix path, and the "≤40 audible streams per listener" AoI budget is a written target, not implemented culling. And two field names drift: Hera group kinds areCrew | Guild | Organization(the monolith's "gang"/"org" are not in the enum), and the richCharacter { aliases, appearance_ref, licenses[], relationships[] }aggregate is split — the core crate holds only identity, employment, and balances; property/civic/job aggregates live in the realm server; appearance and free-form relationships are not yet structs.
Nàná — the character and economy data model#
The character record#
A Nàná character is the smallest stable thing a realm owns about a player.
NanaCharacterRecord (libs/v7/nana/src/lib.rs) is deliberately minimal: an
ori_id (the platform identity), a realm_id (the owning realm — characters
are realm-scoped aggregates), a display_name, an optional NanaEmployment
(job_id, grade: u16, on_duty), and NanaBalances (cash_minor,
bank_minor, society_minor, all i64 minor currency units). The crate has an
empty [dependencies] block on purpose — it is the contract Moremi,
Nephthys, and future TS bindings agree on before anything richer is built. Two
methods carry weight: stable_key() returns the realm-local key
nana:{realm_id}:{ori_id}, and validate() returns a typed
NanaValidationError for a missing Ori id, missing realm, empty display name,
or any negative balance — the last is the load-bearing invariant a
server-authoritative economy depends on, and rejects_negative_balances proves
a cash_minor = -1 is refused. Everything that follows treats this record as
the unit it persists, employs, taxes, and (carefully) deletes.
The double-entry economy ledger#
The economy is a realm-scoped, server-authoritative double-entry ledger, and
"double-entry" is enforced, not decorative. MoremiNanaEconomyLedger
(apps/v7/moremi-realm-server/src/lib.rs:4379) holds typed accounts — Cash,
Bank, Society, Faucet, Sink (:4267) — and a list of
MoremiNanaLedgerEntrys. Each entry's balanced() (:4360) requires the entry
be non-empty, every line be a debit xor a credit (never both, never negative),
and total debits equal total credits; post_entry (:4393) rejects an
ImbalancedEntry or an entry touching an UnknownAccount before it appends,
and account_balance_minor (:4411) folds a balance as Σ(debit − credit).
Entry kinds are the real economic events — OpeningBalance, Payroll, Fine,
Purchase (:4322) — and MoremiNanaEconomyPolicy (:4440) computes a
purchase's purchase_tax_minor from purchase_tax_basis_points so a sale
splits into seller revenue and a tax sink. The gate
run_moremi_nana_economy_ledger_eval (:5585) only passes
(MoremiNanaEconomyLedgerEvalReport::passed, :4491) when the authoritative
writer is literally "moremi:server-authority", payroll and fine and
purchase entries posted, and the whole ledger's debits equal its credits with
imbalance_minor == 0. Two tests pin it:
nana_economy_ledger_eval_balances_double_entry_to_the_cent (:14100) and
nana_economy_ledger_eval_runs_payroll_fine_and_purchase (:14127).
Inflation health and the sinkless-config gate#
A realm owner tunes faucets and sinks, but the platform refuses to let them
build a sink-less hyperinflationary economy by accident. The sink primitives are
first-class — RepairDegradation, PropertyUpkeep, TransactionTax,
ServiceFee (MoremiNanaSinkPrimitiveKind, :4505) — and
MoremiNanaInflationBalancerConfig::total_enabled_sink_basis_points (:4559)
sums the active drains. A MoremiNanaInflationBand (:4538) declares a target
inflation corridor (contains, :4543), and the auto-balancer nudges the
transaction-tax rate toward it, capped by max_adjustment_basis_points — the
Alter-Aeon dynamic-control model. The interesting violation is
SinklessConfigNotFlagged (:4596): run_moremi_nana_inflation_balancer_eval
(:5945) is required to detect a sink-less configuration, proven by
nana_inflation_balancer_eval_flags_sinkless_config (:14161), while
nana_inflation_balancer_eval_holds_fixture_within_target_band (:14185) shows
a healthy fixture stays in band. Inflation rate, sink coverage, and money supply
are emitted as a MoremiNanaEconomyHealthSnapshot (:4577) — per-realm health
metrics, not afterthoughts.
Property, civic institutions, and the steward-not-owner deletion limit#
Beyond money, the realm server models the FiveM-class RP surface as Nàná
aggregates. MoremiNanaPropertyAsset (:4678) is
Housing | Business | Vehicle (:4629) with a per-subject ACL of rights —
Enter, Manage, StoreInventory, OperateBusiness, DriveVehicle (:4636)
— and an optional MoremiNanaPersistentInterior whose state survives via a
persistent_state_hash. Crucially the interior is a Danu handoff target, not
a loading-screen instance: run_moremi_nana_property_eval (:6174) only
passes (:4742) when a stranger is denied entry, and the
MoremiNanaDanuInteriorHandoffProbe (:4698) shows authority moving between
mesh nodes with the client set unchanged and zero reconnects — the seamless
interiors the meshing page makes possible. Civic life is modelled too:
MoremiNanaCivicInstitutionKind is Law | EmsFire | Government (:4764), and
MoremiNanaCivicRecordKind (:4771) enumerates the real records —
CadMdtRecord, Warrant, ChargeBooking, Downed, Revive, Treatment,
License, Permit, BusinessRegistration — sealed by the civic resource that
owns them.
The deletion posture is the most consent-shaped piece.
MoremiNanaCharacterStore::persist_character (:3899) refuses to store a
record without a MoremiNanaIrisConsentGrant that
permits(... CharacterPersistence), and request_deletion (:3954) makes the
steward-not-owner rule literal: a RealmOwner actor with no deletion
consent is denied with RealmOwnerDeletionRequiresIrisConsent and an audit line
reading denied:iris-consent-required — a realm owner cannot silently erase a
player's character. A permitted deletion tombstones (deleted_at, :3997)
rather than hard-deleting, and every persist/load/delete appends a
MoremiNanaCharacterAuditEntry. run_moremi_nana_character_deletion_limit_eval
(:5162) gates the whole policy.
Where Nàná state lives#
Moremi is the authority; it is not the store. libs/v7/substrate-bridge is how
a character reaches durable platform storage without re-implementing it. Its
EgbeOriFacade (:1248) implements V7OriRecordFacade::write_character_record
(:1277), turning a NanaCharacterRecord into a nana_character_memory_event
(:1760) written through the reused V6 Ori event store, stamped with an
Isis provenance bundle (provenance:isis:v7:substrate-bridge:nana), and read
back via the V6 operator-read projection path. authenticate_and_sync_character
(:1343) guards the write behind
V7_ORI_WRITE_REQUIRED_SCOPE = "v7:ori:write", and
rejects_authenticated_principal_without_ori_write_scope (:2284) proves an
authenticated-but-unscoped principal is refused. Durable realm and character
state is event-sourced in Nephthys and made seamless across nodes by Danu — see
./danu-meshing-and-nephthys-persistence.md.
Pheme — proximity and radio voice#
The proximity + radio mix#
Pheme's most concrete code is the UE mix evaluator.
UMawuVoiceMixLibrary::EvaluateVoiceEmitter
(V7/ue/Source/MawuVoice/Private/MawuVoiceMix.cpp) takes an
FMawuVoiceListener (location, forward vector, HearingRadiusCm default 3200,
the set of RadioChannels it monitors) and an FMawuVoiceEmitter (location,
VoiceRadiusCm default 2400, SpokenLevelDb default −12, bRadioTransmitting,
RadioChannel) and returns an FMawuVoiceMixResult (bAudible,
bRadioRouted, DistanceCm, GainLinear, Pan). The proximity math is real:
the effective radius is min(HearingRadiusCm, VoiceRadiusCm), the distance
alpha is clamp(distance / radius, 0, 1), the falloff is (1 − alpha)² (a
smooth inverse-square-shaped curve), and the speech level converts from decibels
with 10^(clamp(SpokenLevelDb, −80, 12) / 20). Radio is a parallel,
distance-independent path: when the emitter is transmitting on a non-empty
channel the listener monitors, the gain is floored at 0.18 regardless of
distance. Panning is equal-power-shaped — the listener's right vector is
cross(Up, Forward) and the pan is dot(directionToEmitter, right) clamped to
[−1, 1] — and a radio-routed voice is pulled toward center (Pan *= 0.25), the
familiar "in your head" radio feel. bAudible trips only above a 0.001
linear-gain floor.
Voice on the wire#
Voice negotiation is a first-class citizen of the realm protocol.
RealmWireMessageKind::VoiceSignal (libs/v7/realm-protocol/src/lib.rs:966)
routes onto the dedicated RealmWireChannel::Voice (:1525) and is
reliable-ordered (:1537) — SDP offers and answers cannot be dropped the
way an AuthoritativeDelta can — with the wire label "voice-signal" (:1549)
and a distinct authority scope, "realm.voice.signal", separate from the
state-mutation scope (:4378). It is one of the six required kinds the wire
conformance harness drives through reordering and loss, so the voice signalling
path is held to the same framing contract as movement and state. The substrate
boundary names this seam explicitly: substrate-bridge tags a "V6 realtime
gateway and Pheme transport boundary." The actual media — Opus packets across
the WebRTC SFU — rides the reused V6 gateway, which is why no codec lives in the
V7 crates.
Accessibility parity and child-safety screening#
Two platform-owned guarantees wrap the mix. Accessibility parity is linted in
contracts: V7MawuVoiceRadioParitySpec
(libs/v7/contracts/src/accessibility-eval.ts) and lintVoiceRadioParity
require captions, transcript, and speaker/range/channel/mute-state visual
indicators for both proximity and radio voice, emitting
voice_radio_parity_missing:live_captions when a surface omits them — the
voice-radio-text-visual-parity rule. Child-safety is never realm-delegated:
the Sekhmet scanner makes ProximityVoice a MinorProtectionFeature
(apps/v7/sekhmet-scanner/src/lib.rs:1117) and screens for a
VoiceGroomingSignal endangerment kind on a tight (2,400 ms) SLA. The mix
evaluator decides what you hear; Sekhmet and the parity linter decide what
the platform must guarantee around it — detailed in the trust-boundary page.
Hera — the social-graph data model#
Groups, roles, and role-gated treasury#
A Hera group is a real aggregate, not a join table. HeraGroup
(apps/v7/hera-social-service/src/lib.rs:259) carries a kind
(Crew | Guild | Organization, :164), a home_realm_id, a map of
HeraGroupRoles (each a permission set drawn from TreasuryDeposit,
TreasuryWithdraw, SharedAssetManage, ReputationRead, :170), members with
their assigned role_ids, a HeraTreasuryAccount (an aje_account_id plus a
balance_cents), shared assets, and a cross_realm_reputation_score. The
treasury is role-gated and audited: withdraw_from_treasury (:439) checks
actor_has_permission(... TreasuryWithdraw) (:574) and either denies with
missing_treasury_withdraw_permission / insufficient_treasury_funds or debits
the balance — and every attempt, permitted or not, appends a sequenced
HeraGroupAuditEntry recording the actor, decision, reason, amount, and
post-balance. publish_shared_asset (:479) is gated the same way on
SharedAssetManage. The gate run_hera_groups_eval (:828) only passes
(:675) when a permissionless member's withdrawal is denied, a treasurer's
succeeds, a shared-asset publish succeeds, and the audit ledger shows at least
two permitted and one denied entry — proven by
groups_eval_grants_role_gated_treasury_and_cross_realm_reputation (:990).
Cross-realm reputation and the whitelist gate#
Reputation is the thing a group earns that another realm reads at its door.
evaluate_cross_realm_whitelist_gate (:521) compares a group's
cross_realm_reputation_score against a target realm's required_minimum_score
and returns a HeraGroupWhitelistDecision (:346) — the mechanism by which a
whitelisted RP realm admits an established crew without re-vetting every member.
A group is also a governance tier: the Eunomia service
(apps/v7/eunomia-governance-service/src/service.ts) makes 'guild' a
first-class EunomiaGovernanceTier (parent tier 'server') with treasury-spend
and reputation-weighted voting models, so a guild's charter and treasury
decisions run through the same governance plane as the realm above it.
Group presence travels: the Ori passport#
The "a group travels into V2–V6" claim is implemented as a passport mint plus a
bridge. mint_ori_group_presence_passport (:538) snapshots each member's
role_ids into a HeraOriGroupPresencePassport and stamps a continuity
hash — a deterministic FNV-1a fold over the group id and the per-account role
assignments (stable_group_presence_hash, :619).
bridge_group_presence_passport_to_v2_match (:603) then projects that
passport into a HeraV2MatchGroupRoster, recomputing the same hash so a tamper
is detectable. run_hera_cross_version_group_presence_eval (:751) passes
(:701) only when the V2 roster preserves the member count, every role
assignment, and a matching continuity hash — group identity that survives
the version boundary, the Hera analogue of the Ori passport the substrate bridge
mints for individual characters.
Ban propagation and device-attestation evasion#
Hera also closes the smurf/ban-evasion loop FiveM left open. PlatformBanLedger
(:113) records a PlatformBan keyed on both a platform_account_id and a
device_attestation_id, and evaluate_realm_join (:130) returns a
RealmJoinDecision that blocks not only the banned account but a fresh
account joining from the same attested device. A ban also drives the group's
cross_realm_reputation_score negative. run_ban_evasion_eval (:711) passes
(:652) only when both the original account and a fresh same-device account are
blocked, propagation lands within V7_BAN_PROPAGATION_SLA_MS (5,000 ms), and
the reputation score is negative — pinned by
device_attestation_blocks_fresh_account_realm_hop (:1056) and
ban_evasion_eval_blocks_platform_ban_and_device_hop (:1069). This is the
trust-boundary's "platform owns identity and bans, realms cannot launder them"
posture made concrete in the social graph.
How it connects#
These three planes are the payload the realm backbone carries. Every Nàná
balance mutation and Hera treasury debit is a server-authoritative write that
only happens after the cross-trust envelope validates — the authority path,
netcode, and the determinism contract are owned by
./moremi-realm-server-and-netcode.md,
and the VoiceSignal wire kind described above is part of that same conformance
matrix. Character records, persistent property interiors, and group rosters are
made durable and seamless by
./danu-meshing-and-nephthys-persistence.md
— the Danu interior-handoff probe in the property eval is exactly the meshing
guarantee in miniature. And the economy these models settle — payouts to the
crews and creators who run a realm, plus the anti-fraud spine that keeps a
double-entry ledger honest at platform scale — is the subject of
./abundantia-economy-firewall-and-anti-fraud.md.
Related#
- Moremi: Realm Server & Netcode — the authority that validates every Nàná and Hera mutation, and the wire matrix the voice channel rides
- Danu Meshing and Nephthys Persistence — where character, property, and group state become durable and seamless
- Abundantia Economy Firewall and Anti-Fraud — payout rails and the anti-fraud spine around the realm economy
- The orientation hub: ../V7_ARCHITECTURE.md