V7 — codename Mawu — is a creator republic, and a republic needs two
things a single-operator game does not: a way for communities to govern
themselves without being able to vote away the platform's safety floor, and a
way for a player's identity to persist beyond any one realm or product
version. Those are the two halves of the "Governance & Continuity" group.
Eunomia is the multi-tier governance data model — five sovereign rule spaces
from platform down to guild, six plural voting models, a strict proposal
lifecycle, and a non-negotiable safety floor that no vote can override. The
Ori Passport is the cross-version bridge — the seam that lets a V7
character, which is fundamentally a V6 Ori identity record, incarnate into
V2–V6 destinations (and now realm-to-realm) carrying only a minimal, scoped
claim set, while the Ori itself remains the single source of truth no realm ever
holds. The two are connected by one idea: sovereignty bounded by an inviolable
core. A guild governs its charter but not child-safety; a realm renders your
character but never owns it. This page grounds both halves in the code that
exists today and is explicit about which seams are compiled and which are still
mocked. The full section index lives at
../V7_ARCHITECTURE.md.
What ships, honestly#
Eunomia is a real, test-backed decision kernel — but a kernel, not yet a live
service. apps/v7/eunomia-governance-service/src/service.ts (~1,575 lines) is
a library of pure, deterministic functions: tier/parent-override validation,
safety-floor evaluation, the proposal state machine, six plural-voting tally
formulas, Themis appeal routing, localized-proposal rendering, and the Maya
Variants/Crucible governance surface. Its service.test.ts carries 12 test
cases, and the eunomiaGovernanceServiceDescriptor declares port 47302
and 16 capabilities. The honest qualification: the deployable binary
(src/main.ts) is a Node http server that answers exactly one route —
/health — returning the descriptor as JSON. There is no Postgres, no live
proposal API, and no event bus wired in yet; the governance logic decides, but
nothing yet persists or serves it over the wire. Treat Eunomia as a verified
rule engine awaiting its transport, not a running governance plane.
The Ori Passport bridge is real, compiled Rust — and it genuinely links the V6
Ori store. libs/v7/substrate-bridge/src/lib.rs (2,462 lines, 8 #[test]
blocks) mints passports, runs the cross-version round-trip eval, and opens the
realm-federation corridor. Crucially, its Cargo.toml carries real path
dependencies —
egbe-ori-service = { path = "../../../apps/v6/egbe-ori-service" } and
ori-model = { path = "../../v6/ori-model/rust" } — so the V6 Ori event
store, projection materializer, and operator-read audit path are compiled in and
exercised, not stubbed. default_substrate_bindings() labels exactly the V6
Ori/Aye-Bridge and the Maya engine-core Reused; everything else — V1 identity
(libs/shared/auth-primitives), Aje, Lilith, Kuanyin, Themis, Iris, Psyche,
Isis, Sophia, Yemaya, and the V6 Egbe gateway — is Mock. Two consequences to
keep honest below: (1) the Aye Bridge is reused as the contract owner of
the passport envelope (generated_by = "@oshun/aye-bridge",
v6_aye_bridge_package_ref = "libs/v6/aye-bridge"), while the minting logic is
re-implemented natively in V7 Rust; and (2) Themis treaty signing remains a
reference string plus a boolean flag. Proposal appeals now have a separately
configured live HTTP dispatch boundary, but no live dispatch receipt was
captured in this repository slice.
Eunomia — the multi-tier governance data model#
Five sovereign tiers, and the parent-override consent rule#
Governance is partitioned into five tiers, ordered by scope:
EUNOMIA_GOVERNANCE_TIERS = ['platform', 'game', 'realm', 'server', 'guild'].
Each tier holds a sovereign rule space a parent cannot silently override.
The parent chain is explicit in EUNOMIA_PARENT_TIER — game→platform,
realm→game, server→realm, guild→server — and platform deliberately has
no parent. The sovereignty is enforced in executeGovernanceRuleChange(): a
rule change with no parentOverride is marked sovereignRuleSpace: true, and a
parent may only reach into a child tier when validateParentOverride() passes
all three conditions — the override names the correct parent tier for the
target (parent_override_wrong_tier:* otherwise), the target tier has actually
consented (consentedByTargetTier, else
parent_override_requires_target_tier_consent), and a non-empty reason is
given. An attempt to override at the platform tier fails with
platform_tier_has_no_parent_override. This is the "a parent cannot override
without consent" invariant rendered as code, not prose.
The safety floor no vote can cross#
Sovereignty stops at the platform safety floor. EunomiaSafetyFloorPolicy
enumerates the five non-negotiables — minor_protection, harassment_abuse,
csam_blocking, identity_privacy, and real_money_firewall — and every rule
change must ship a non-empty safetyFloorChecks array (absence yields
safety_floor_checks_required). evaluateEunomiaSafetyFloor() filters for any
check where compliant === false; a single violation pushes both
safety_floor_violation and a policy-scoped safety_floor_violation:<policy>
reason, and accepted flips to false. No quorum, no token weight, and no
parent-consent path can execute a change that fails the floor — the
Lilith/Kuanyin safety posture is structurally above the most powerful vote.
The trust-and-safety machinery that backs these policies is described in
./sekhmet-safety-and-anti-cheat.md, and
the real_money_firewall policy is the governance face of the economy
separation in
./abundantia-economy-firewall-and-anti-fraud.md.
The proposal lifecycle as a strict state machine#
EUNOMIA_PROPOSAL_LIFECYCLE_ORDER fixes the legal path:
draft → deliberation → vote → execution → appeal. runProposalLifecycle()
replays a submitted transition list against this order. Each transition must
carry a non-empty actor, timestamp, and reason (transition_actor_required:*
etc.); its from must equal the machine's current state
(transition_from_state_mismatch:*); and its to must be exactly the next
state returned by nextProposalLifecycleState() (transition_not_allowed:*
otherwise). A proposal is complete only when the walk reaches appeal with no
accumulated reasons. The state machine is therefore append-only and
skip-proof: you cannot jump from draft straight to execution, and the
report exposes the full statesVisited trail for audit.
Plural voting — six models, six real formulas#
Eunomia does not hard-code one democratic theory. EunomiaPluralVotingModel
offers six, and pluralVotingBallotWeight() gives each a distinct, real weight
function (mirrored as human-readable strings in pluralVotingFormula()):
token→tokenWeight(stake-weighted).reputation→reputationScore.quadratic→Math.sqrt(quadraticCredits)— the Weyl/Posner quadratic- voting square-root, which taxes concentration of influence.conviction→convictionStake × convictionAgeHours— time-locked conviction voting, where a long-held position carries more weight.delegated→baseWeight + Σ delegatedWeights— liquid-democracy delegation.time_weighted→baseWeight × min(membershipAgeDays, 365)— tenure- weighted, capped at one year so longevity cannot become unbounded capture.
tallyPluralVotingModel() does the honest bookkeeping around those formulas: it
keeps only the latest ballot per voter (latestPluralVotingBallots(), dedup
by castAt), rejects any ballot whose computed weight is non-positive
(ballot_weight_must_be_positive), rounds to six decimal places to avoid
floating-point drift, tallies for/against/abstain, and computes
passed = quorumMet && winningChoice === 'for' && totals.for > totals.against.
Rejected ballots are surfaced with reasons rather than silently dropped.
Appeals route to Themis#
A proposal that reaches the appeal state can be escalated by
routeProposalAppealToThemis(). It refuses anything not in the appeal
lifecycle state (proposal_not_in_appeal_state) and, on success, emits a typed
route naming themisModule: '@themis/arbitration', a deterministic
themisCaseId (themis:eunomia:<proposalId>:<appealId>), and an appealRef
URI (themis://arbitration/eunomia/<proposalId>/<appealId>). Honest seam: this
function only constructs the routing contract. The asynchronous
dispatchProposalAppealToThemis() path invokes a configured Themis HTTP
endpoint. Non-loopback endpoints require HTTPS and bearer authentication;
redirects are forbidden, response bytes are bounded before JSON parsing, and the
returned schema, service, case, appeal reference, receipt, and timestamp must
bind exactly to the request. Rejected lifecycle input never dispatches;
HTTP/network/schema failures remain explicit dispatch-failed results. The
gateway is executable and contract-tested, but there is no credentialed live
receipt in this slice.
Game-tier governance: Maya Variants and the Crucible#
The richest governance surface is at the game tier, where communities steward
forkable game variants. publishMayaVariantFork() produces a standalone
MayaVariantPublication with a full attribution chain and typed
MayaVariantRevenueLinks (parent-fork, marketplace-asset,
inherited-dependency), so revenue flows back along the fork lineage —
basis-points-validated against MAX_REVENUE_SHARE_BASIS_POINTS = 10_000.
resolveCanonicalVariantVote() runs the canonical-variant-vote proposal kind:
eligible variants are tallied by latest weighted vote, and the canonical "main"
branch is reassigned only when a challenger both wins and strictly
out-weighs the incumbent past quorum.
Before a realm can earn Verified status, it must survive the Maya Crucible
— an adversarial economic balance check. runMayaCrucibleBalanceVerification()
simulates two agent strategies against a realm's economy mods: a
baseline-worker that takes honest job payouts, and an exploit-seeker that
greedily chains the highest-net-yield mods. detectCrucibleFindings() then
flags three blocker classes — excessive-mint (net minted beyond the cap),
runaway-growth (balance growth past the bps ceiling), and
infinite-currency-cycle (a refund-multiplier loop whose per-tick yield grows
≥4×). evaluateMayaRealmVerifiedGate() finally gates the Verified registry
status on all three signals being clean: no blocking Crucible findings, a
clean Sekhmet scan, and clean moderation standing. This is governance enforcing
economic soundness, and it interlocks directly with the anti-fraud machinery in
./abundantia-economy-firewall-and-anti-fraud.md.
Proposals themselves are launch-localized: EUNOMIA_LAUNCH_LOCALES covers eight
locales including RTL ar and he, and
renderLocalizedGovernanceProposalForRegion() maps five
EunomiaGovernanceRegions to default locales, requiring an approved
moderation status before a translated proposal renders (else it falls back).
The Ori Passport — cross-version incarnation bridge#
The principle: the Ori is the truth, a realm is a stage#
A V7 character is not a realm's property. It is a NanaCharacterRecord
(libs/v7/nana) — ori_id, realm_id, display_name, optional employment,
and realm-scoped NanaBalances (cash_minor, bank_minor, society_minor as
i64 minor units whose validate() refuses to go negative) — and the ori_id
keys a V6 Ori identity record that is the genuine source of truth. The
bridge's job is to let that identity be rendered into other Oshun product
versions while the Ori root stays singular and intact. As the architecture puts
it: the Ori remains the truth; a realm, like any destination, is a stage it is
rendered into.
Five incarnation destinations through the reused Aye Bridge#
V7AyeIncarnationDestination enumerates the five V-destinations a character may
incarnate into: V2Maya, V3Lilith, V4Odysee, V5Oshun, and V6OriNative
(the native Ori return path). Each carries a stable adapter_ref (v2-fighter,
v3-citizen, v4-operator, v5-companion, v6-ori-service-native) and a
versioned capability_mapping_ref (e.g.
capability-mapping:v3-lilith:citizen:v1), so a character's abilities are
re-mapped per destination rather than copied verbatim — a fighter in V2 is
not the same capability surface as a citizen in V3.
default_v7_aye_incarnation_destinations() returns the full inventory, which is
the V6 Aye Bridge incarnation model carried into V7 with one new corridor added
(federation, below).
Minting a scoped passport: data minimisation by construction#
mint_v7_character_incarnation_passport() produces a
V7CharacterIncarnationPassport. Two design choices matter. First, the passport
carries only what the destination needs: scoped_claims_for_character() emits a
minimal claim set — identity.display, identity.characterKey, and
capabilities.mappingRef — not the character's balances, record, or
relationships. Second, integrity is hashed: ori_root_integrity_hash() binds
the ori_id, the stable character key, and the scoped claims into an
ori_integrity_hash that must survive every subsequent lease, fault, and
concurrent claim. The envelope is stamped generated_by: "@oshun/aye-bridge"
and v6_aye_bridge_package_ref: "libs/v6/aye-bridge", naming the V6 Aye Bridge
as the reused contract authority even though the mint runs in V7 Rust.
The round-trip eval: integrity under fault and concurrency#
round_trip_v7_character_into_destination() exercises the full journey:
departure → destination actor → return → incarnation-journal write-back. It is
adversarial by design. It injects a disconnection during return and recovers
via a return_replay_buffer_ref; it fires a concurrent duplicate departure
against the same Ori and asserts concurrent_departure_blocked; and it checks
that after the dust settles there is exactly one authoritative Ori copy
(active_ori_copy_count == 1) and zero lingering destination copies. The
receipt's round_trip_ok() returns true only when the copy counts hold, the
duplicate was blocked, ori_integrity_hash_before == ori_integrity_hash_after,
and the evidence proves both round-trip-integrity and
incarnation-journal-writeback — i.e. the journey is recorded back into the Ori
biography. This is the same "no window with two writers or zero owners"
discipline the mesh uses for authority handoff, applied to identity.
The new V7 corridor: realm-to-realm federation under treaty#
V7 adds one corridor the prior versions did not have: realm-to-realm
federation. V7RealmFederationTreaty::themis_signed() defines a corridor
between two realms with an explicit allowed_state_keys set and a
lease_ttl_seconds; the default treaty (default_v7_realm_federation_treaty())
permits only presence.status, position.cell, party.intent, and
realm.quest_state for 900 seconds. open_v7_realm_federation_corridor() then
filters the source realm's state down to exactly those keys, hashes the
negotiated subset, and sets out_of_scope_state_rejected true only when there
genuinely was state outside the treaty that was excluded. Its round_trip_ok()
requires a non-empty Themis terms reference, a stable subset hash across the
round-trip, a preserved Ori integrity hash, resolved concurrent claims, and
out-of-scope rejection. Honest seam: themis_signed is a constructor that sets
the boolean and copies a terms reference — the corridor's governance contract
is real and validated, but no live Themis call signs it yet (Themis is Mock).
run_v7_passport_eval — the combined continuity gate#
run_v7_passport_eval() is the single gate that composes both legs. It
round-trips a character into a V-destination with disconnection, opens a
federation corridor with disconnection, and then asserts four properties:
v_destination_round_trip_ok, federated_realm_round_trip_ok,
ori_integrity_preserved_under_disconnection (both legs' before/after hashes
match despite injected faults), and concurrency_preserved_ori_integrity (the
duplicate departure was blocked, concurrent corridor claims were resolved, and
the two legs agree on the Ori hash). The test
passport_eval_round_trips_v_destination_and_federated_realms_with_ori_integrity
runs this end-to-end. Because the V6 Ori store is compiled in, the underlying
character write (EgbeOriFacade::write_character_record) really appends a
MemoryFormed event to PartitionedPostgresOriEventStore and reads it back
through the audited operator_read_ori_projection path — the bridge does
not fake the identity store it claims to use.
How the bridge composes shared identity#
The passport's authority chain begins at the platform principal. A
V7AuthenticatedPrincipal carries user_id, tenant_id, session_id, scopes,
and a residency scope — the same claim shape an @oshun/identity
(libs/shared/identity) JWT issues for every other Oshun product. V7's binding
to that identity layer is currently the Mock StaticIdentityProvider
(V7Substrate::V1Identity → libs/shared/auth-primitives), so the shape is the
shared one while the wire is still a local stand-in. The continuity guarantee
sits on top of it: the V7IdentityFirewall projects the platform principal into
a V7RealmScopedIdentity whose opaque_handle is an HMAC of
(pepper, principal, realm_id) — so a realm sees a per-realm pseudonym, never
the platform account, and the same player in two realms gets two un-linkable
handles. The Ori passport then carries the platform-authoritative ori_id
across version boundaries while each realm only ever touches the pseudonymous
projection. That is the through-line: one shared identity at the core, many
scoped renderings at the edges. The platform-side identity foundation this
composes is documented in
../../platform/auth-identity.html.
Where to read next#
- ./sekhmet-safety-and-anti-cheat.md — the trust-and-safety plane that backs Eunomia's non-negotiable safety floor, and the client-integrity/anti-cheat stack.
- ./abundantia-economy-firewall-and-anti-fraud.md
— the real-money/play-currency firewall the
real_money_firewallpolicy governs, plus the payout-fraud and Crucible-gatedVerifiedinterlock. - ../../platform/auth-identity.html — the
shared
@oshun/identityfoundation whose JWT claim shape the Ori passport composes across versions.
Related#
- Section hub: ../V7_ARCHITECTURE.md
- Real code cited here:
apps/v7/eunomia-governance-service/src/service.ts,apps/v7/eunomia-governance-service/src/main.ts,libs/v7/substrate-bridge/src/lib.rs,libs/v7/substrate-bridge/Cargo.toml,libs/v7/nana/src/lib.rs, andlibs/v7/contracts/src/schemas.ts(theV7GovernanceContractSchemaandV7CharacterContractSchemaZod contracts).