Aetheria/Aetheria.State/README.md

30 KiB

Aetheria.State

Aetheria.State is the replacement owner for durable Aetheria game state.

It uses modern GameCult.Caching, GameCult.Caching.MessagePack, and GameCult.Mesh. It does not reference the old Assets/Scripts/ServerShared tree, RethinkDB, JsonKnownTypes, or Newtonsoft.Json.

The first live state files are GameData/aetheria-world.cc for daemon-owned Verse state and GameData/aetheria-client.cc for the client-owned active Verse target. Aetheria.State.Import generates the daemon-owned world file from checked-in legacy catalog inputs without embedding machine-local absolute paths. A full import emits one self-contained monolithic .cc suitable for a fresh clone or released package. Runtime-created .cc.records directories are mutable materializations, not part of the release contract. Legacy files such as GameData/AetherDB.msgpack are migration inputs only.

The typed runtime state model is split into player settings, loadout templates, run state, zone state, entity snapshots, item slots, weapon groups, action-bar bindings, stat grids, and runtime session documents. Runtime checkpoints include current action-bar bindings as stable typed targets: input control path, binding kind, item key, equipment index, behavior index, or weapon-group index. They also include current faction relationship rows as typed corporation references plus relationship tokens and numeric standings. Zone checkpoints include typed orbit and body rows for generated celestial state: orbit IDs, parent IDs, distance, phase, fixed positions, body kind, typed resource item keys, gravity/body multipliers, asteroid entries, and gas/sun visual parameters. Entity checkpoints include typed simulation stat grids for temperature, thermal mass, armor, max armor, and hull-conductivity axes. Player settings include player name, tutorial flag, story-file hash cursors, gameplay formatting, graphics preferences, input binding overrides, and action-bar inputs. Do not preserve SavedGame, Unity runtime settings projections, or runtime entity blueprints as opaque payloads in the new store; they are source shapes for projection, not portable state authority.

The Unity client no longer writes PlayerSettings.msgpack, .loadout, or .zone files. AetheriaPlayerSettings is the typed Verse replacement for PlayerSettings.msgpack, and AetheriaLoadoutTemplate is the typed Verse replacement for bespoke loadout files, with structured hull/equipment/cargo/ docking item slots, nested child-entity loadouts, and weapon groups. RuntimePlayerSettings is the Unity session projection for menus, formatting, and input binding display. Menu and input-screen changes send typed Eve request documents to the provider-owned Aetheria Verse service; they are not portable state authority and must not mutate daemon-owned state inside Unity. The old .cc.pending runtime commit document lane is deleted. Gameplay state, loadout templates, and run checkpoints are accepted by the daemon/Verse owner through typed state operations and daemon command documents, not by renderer-side commit authority. AetheriaRuntimeSession is the typed Verse signal for the running daemon. Aetheria.State.Daemon owns the long-running aetheria-daemon heartbeat and publishes starting, running, and stopping states through Aetheria.State; legacy outbox status remains operation telemetry, not daemon-session ownership. The daemon has one combat writer in AetheriaRuntimeDaemonSimulation. Projectile movement and contact are computed by Ymir through the injected physics port and committed by that same daemon writer. Combat state remains in the native run/zone/entity snapshot graph; there is no separate abstract combat save model or optional second writer. Unity Eve surfaces construct typed gamecult.eve.command.v1 command documents. AetheriaRuntimeVerseClient is the shared CultMesh client boundary for headless, Unity, and non-Unity runtimes. Typed command clients submit directly to the same Verse records; there is no command-port facade or cached submitter between client code and the Aetheria state graph. AetheriaEveCommandBridge is the provider-owned command acceptor for those records: it validates the provider, surface, and command template before running the narrow refresh handlers for the catalog and operations surfaces plus the typed player-settings mutation handlers for gameplay/graphics Eve controls and typed Verse-host visibility commands. Renderer callbacks do not accept commands or mutate game state locally. AetheriaEveRuntimeBootstrap mounts the aetheria.operations surface through a runtime-created UIDocument after scene load, with environment and command-line switches for diagnostics. UI Toolkit is now a live runtime lowering path, not only a package sample. The old SavedGame/SavedZone DTOs and Galaxy loader constructor have also been deleted; the new document family is live Verse run/zone state, not a bespoke save-file format. Daemon run frames project into Unity through the explicit EntityConstructionBlueprintProjector.ProjectObservedFromBlueprint lowering path; authoritative blueprint construction remains named separately as a migration target for code that still has to move into the daemon. Main-menu gameplay boot also projects the daemon run through Galaxy.ProjectObservedDaemonRun rather than constructing or generating a Unity-owned run. The Unity handle for this shell is ActionGameManager.ObservedGalaxy to keep the client-side object named as an observation. The dead SavedStory JSON DTO is gone. ZoneConstructionBlueprint and RuntimeEntityBlueprint remain in-memory construction/loadout projections for Unity runtime code, with RuntimeEntityBlueprintProjector capturing and instantiating those projections. They no longer carry save-file or serializer vocabulary, and they do not declare MessagePack persistence attributes.

Keyboard layout rendering now builds the static ANSI-104 display as typed InputLayout rows and columns. It no longer reads a checked-in JSON text asset or uses SimpleJson for display geometry. The generated AetheriaInput wrapper still calls Unity's InputActionAsset.FromJson; that is an engine-owned lowering boundary under Aetheria's remapping layer, not a save format or state owner. The old generated GameData/KeyboardLayouts/*.msgpack cache and the checked-in ansi104.json display file are deleted. Remapping and action-bar edits are owned by typed AetheriaPlayerSettings commits, and the live input screen now lowers through Eve/UI Toolkit instead of the old drag/drop uGUI shell. Keyboard display layout edits remain runtime-only until Verse owns a typed layout document. The unused Unity Localization package and imported Google Sheets localization sample have been removed; the old transitive Unity Newtonsoft package is no longer in the manifest or package lock.

The old IMGUI CultCache database editor has been deleted, and NameTools no longer exports NameFile/*.msgpack. AetherDB.msgpack and existing name files remain legacy catalog inputs only; typed catalog records are the durable owner. Dead legacy catalog roots for user records and galaxy map-layer resources have been deleted from live Unity source. Surviving runtime DTOs no longer carry legacy catalog group/table annotations; their remaining metadata is projection and inspection metadata for the typed runtime bridge. Item instances now carry AetheriaRuntimeItemReference, a typed item-key facade. ItemInstance.ItemKey is the identity surface; the old ItemId legacy-GUID projection has been deleted from item instances. Cargo inventory indexes, consumable activation lookup, action-bar consumable quantity/fill, transfer lookup, trade owned counts, weapon ammo references, and item-use behavior references now use item keys. The old cargo/consumable GUID lookup overloads and the derived behavior AmmoType/Item GUID properties have been deleted. Action-bar consumable bindings now read the target ItemKey directly from typed runtime catalog rows instead of reconstructing it from legacy item IDs. Daemon snapshot DTOs carry typed ItemKey/HullItemKey fields only for loadout items, action-bar targets, body resources, entity hulls, and active consumables; daemon command application no longer reconstructs item keys from legacy item GUID fields. Daemon snapshot DTOs now carry typed FactionKey only for loadout entities, run entity snapshots, and faction relationship state. The old command-document CorporationLegacyId fallback fields are deleted. EntityConstructionBlueprint also carries FactionKey only. Loadout restore, entity construction, run entity snapshots, and faction relationship commits no longer rebuild corporation references from legacy Faction.ID GUIDs. Galaxy faction relationship projection is also typed-key-only: the old Faction.Allegiance GUID dictionary, GUID containment helper, and GUID faction resolver are deleted from the simulation shell. The remaining temporary Faction shell also uses GeonameFileKey and BossHullItemKey; it no longer parses name-file or boss-hull legacy IDs into GUID link fields. Faction equality, hashing, narrative constraints, sector display filtering, sector-map link/influence rendering, zone security ownership checks, and runtime faction-relationship ordering now use FactionKey. The legacy Faction.ID projection field is deleted from the temporary simulation shell. Run checkpoint snapshot DTOs carry typed OrbitKey, ParentOrbitKey, and BodyKey only for zone orbit/body snapshots. The old command-document OrbitLegacyId, ParentLegacyId, and BodyLegacyId fallback fields are deleted. Behavior-state daemon snapshots and readback snapshots carry typed body-key fields for resource scanner targets and mining tool asteroid belts; the old raw body ID commit/readback field names are deleted. ResourceScanner and MiningTool now retain typed body-key runtime state directly, while Zone owns parsing and resolution at the current Unity body runtime boundary. Zone, Planet, AsteroidBelt, and Orbit now own the runtime body/orbit key surfaces used for projection, and ActionGameManager no longer formats or resolves body/orbit keys locally while checkpointing or restoring state. Typed AetheriaZoneState orbit/body snapshot rows now use OrbitKey, ParentOrbitKey, and BodyKey property names all the way through the typed document and runtime catalog readback surface; the old ...Id names were only legacy-shaped aliases for those key strings and are gone. Orbit-targeting agent runtime also now retains typed orbit keys directly: PatrolOrbitsTask, MoveToOrbitState, and StationTowing no longer own raw orbit GUID targets, and Zone resolves orbit keys for agent orbit movement. Orbital runtime entities and their construction blueprints now follow the same rule: OrbitalEntity and OrbitalEntityConstructionBlueprint retain OrbitKey, runtime loadout generation seeds the empty value as "", and Zone resolves orbit keys for orbital entity movement and dock camera parent lookup. Renderer and gameplay orbit consumers now stay on that keyed edge too: intro-cutscene planet selection, zone planet/belt loading, gas-giant parent lighting, asteroid-belt UI setup, and ResourceScanner planet range checks all read OrbitKey from runtime wrappers and ask Zone to resolve it instead of reading wrapper GUID orbit fields directly. Planet and AsteroidBelt runtime wrappers no longer publish separate wrapper orbit GUID fields either: they keep OrbitKey plus their Orbit runtime object, and Zone lowers asteroid transforms through belt.Orbit.ParentOrbitKey instead of reading a raw wrapper orbit GUID. Zone's own public key-facing lookup surface is also now natively keyed: body and orbit lookups resolve through key-indexed runtime dictionaries rather than reparsing GUIDs from BodyKey or OrbitKey strings before touching the Guid-indexed substrate. The live asteroid helper surface follows the same rule: nearest-asteroid, asteroid-exists, transform-update, and mining paths now use typed body keys or runtime AsteroidBelt objects directly instead of Guid asteroid-belt helper overloads. The package runtime catalog snapshot indexes items by canonical item key; Unity gameplay, HUD, inventory, trade, ship, and zone helper lookups use ItemKey directly instead of deriving ItemId and searching by legacy GUID. The Unity runtime package snapshot also no longer exposes item, corporation, or name-file lookup by legacy ID, and its item/corporation/name-file DTOs no longer publish legacy relationship fields. Canonical legacy-ID lookup remains only in Aetheria.State migration/catalog inspection APIs. The shared runtime item catalog reader is also item-key-only now: its GUID index, GetRuntimeItem(Guid) entry point, raw GUID string fallback, AetheriaRuntimeItemReference(Guid) constructor, FromLegacyId, and reverse legacy-GUID projections have been deleted. ItemManager now reads typed item rows directly from the shared AetheriaRuntimeCatalogSnapshot; the redundant AetheriaRuntimeItemCatalog adapter layer has been deleted. The old generic RuntimeCatalogLink<T> abstraction, ItemManager.GetData hydration path, vague ItemInstance.Data identity field, and old RuntimeItemReference.Projection cache have been deleted; runtime item facts come from typed catalog rows. ItemManager's behavior construction no longer exposes a generic GUID reader or item GUID projection helper. Migrated legacy-id behavior payload fields carry LegacyIdValue as provenance/backfill only; gameplay item behavior reads the typed ItemKeyValue emitted by import/runtime projection. Loadout generation now applies typed catalog prefilters for item category, hardpoint type, shape fit, hull type, and behavior kind, then instantiates generated equipment directly from typed runtime rows. Typed item definition Category values are stable Aetheria tokens such as hull, weapon, gear, cargo-bay, and docking-bay; legacy union class names remain migration provenance, not live category predicates. The surviving trade menu also applies typed catalog prefilters for row size, hardpoint type, and behavior kind before legacy buy actions. The old ItemData/EquippableItemData/HullData/WeaponItemData DTO hierarchy has been deleted from live Unity source. Shared runtime geometry and stat primitives now live in RuntimeGeometry.cs; item facts come from typed runtime rows. The old RuntimeCatalogEntry and RuntimeItemProjectionEntry base names no longer appear in live source. The dead InspectableRuntimeCatalogLinkAttribute inspector metadata is gone; live Unity source no longer carries LegacyPayloadKeyAttribute either. Catalog import and migration readers own deterministic legacy field layout through explicit key maps, while runtime behavior construction uses an explicit typed behavior-kind mapper. Agent task DTOs no longer inherit the item projection base; they are local runtime AI work orders until a typed Verse task document exists.

Aetheria.State.Import captures the legacy catalog files into typed quarantine state: path, size, and SHA-256 fingerprint for AetherDB.msgpack plus NameFile/*.msgpack, and a migration ledger update. It also performs a bounded raw MessagePack union pass that maps stable catalog fields into typed item/faction/name-file documents without compiling Unity's legacy domain model into Aetheria.State. The current checked-in catalog maps to 115 item definitions, 12 factions, and 12 name files. Typed item definitions include legacy manufacturer IDs, price, shape dimensions, occupied cell counts, full shape-cell masks, interior shape masks for hull/cargo equipment, hull hardpoint definitions, behavior kind fingerprints, typed recursive behavior payloads, and stable equipment facets: hardpoint type, hull type, stack size, durability, and weapon range/caliber/type/fire/modifier classifications. Typed corporation documents include the legacy short name, the true description field from key 3, name-file and boss-hull legacy IDs, influence distance, allegiance count, full allegiance edges, and music bank IDs. Corporation documents are aetheria.corporation.v2 records because runtime generation needs actual allegiance weights, not only display counts. Runtime checkpoints now persist session faction relationships into typed run state, and runtime sessions publish typed state-host liveness. Zone checkpoints persist generated orbit/body rows into AetheriaZoneState, so ZoneConstructionBlueprint is a one-shot construction input carrying typed orbit/body keys rather than the retained surface carrying celestial graph facts. Entity checkpoints persist hull simulation grids into AetheriaEntitySnapshot, so EntityConstructionBlueprint is no longer the only surface carrying those live values. Run checkpoints project the flattened live entity graph, including docked children, into exact typed entity snapshot records. Continue restore lowers the current zone entity graph from those records, including position, velocity, target/contact state, child/docking relationships, shutdown/heatsink state, thermal exposure, active consumable timers, and typed stat grids for temperature, thermal mass, armor, max armor, and hull conductivity. Continue also lowers typed weapon and behavior runtime rows back into live equipped-item and active-consumable behavior instances through behavior-owned restore methods; construction/loadout blueprints do not own behavior replay. Broader runtime object graphs without typed rows remain legacy until dedicated typed runtime documents exist. Live behavior instances expose typed behavior kind and group through Behavior.Kind and Behavior.Group; behavior construction now reads typed payload fields through RuntimeBehaviorDefinition instead of projecting through config DTOs. Stat modifiers ask live behavior instances for target stats instead of reading behavior config objects directly; base Behavior captures a runtime stat table at construction without config reflection. Heat, EnergyDraw, and Cooldown behavior instances now copy their constructor stat/scalar inputs into explicit runtime fields and no longer retain their config subclasses after construction. Wear, Visibility, Reflector, VelocityLimit, VelocityConversion, and ItemUsage also copy their constructor stat/key/scalar inputs into explicit runtime fields instead of retaining config subclasses. Capacitor, Shield, Thruster, MiningTool, ResourceScanner, Thermotoggle, Switch, HeatStorage, and Cockpit have also dropped runtime config retention. Thermotoggle adjustability is exposed on the live behavior instance, not through its config. Reactor, Radiator, Sensor, and StatModifier now copy their constructor performance stats, curves, flags, and target strings into explicit runtime fields; those live behaviors no longer retain their config subclasses. AetherDrive now follows the same rule for rotor geometry, performance stats, torque curve, audio parameters, and prefab path. Weapon, InstantWeapon, ConstantWeapon, ChargedWeapon, and LockWeapon now copy constructor stats, curves, ammo/reload fields, guided projectile profile fields, burst/cooldown fields, charge multipliers, and lock parameters into runtime-owned fields. Behavior instances no longer retain construction config DTOs after construction. Cockpit, HeatStorage, Switch, Trigger, and TurretController read directly from typed runtime behavior definitions. Heat, EnergyDraw, Cooldown, Wear, Visibility, Reflector, VelocityLimit, VelocityConversion, and ItemUsage also bypass the temporary config bridge and read typed behavior fields through RuntimeBehaviorDefinition, registering runtime performance stats explicitly for StatModifier. Capacitor, Shield, MiningTool, ResourceScanner, Thermotoggle, and Thruster now follow the same direct-definition path. Reactor, Radiator, Sensor, StatModifier, and AetherDrive also read typed payload fields through RuntimeBehaviorDefinition; AetherDrive registers its live performance-stat names explicitly for StatModifier. Weapon, InstantWeapon, AutoWeapon, ConstantWeapon, ChargedWeapon, LockWeapon, Launcher, and GuidedWeapon payloads also construct directly from RuntimeBehaviorDefinition. The old RuntimeBehaviorConfig bridge, BehaviorPayloadReader, and weapon config hierarchy are deleted. Typed name-file documents are aetheria.name_file.v2 records. They carry the legacy ID, display name, count, compact sample names for surfaces, and the full name array used by Galaxy/Markov name generation through typed name-file keys rather than legacy NameFile.Names. Legacy GUID references that are Guid.Empty are imported as absent references, not as resolvable catalog links. Before materializing state, the importer clears the generated .cc, .cc.records, and .cultmesh outputs for the selected state path. Legacy catalog inputs are captured first and are not deleted. Full import writes the result through the monolithic CultCache store; no ignored directory record may be required to open the artifact. This lets schema changes rebuild the typed artifact instead of failing on a stale embedded schema catalog.

AetheriaCatalogSnapshot is the typed read surface over materialized catalog documents. It exposes trade items, legacy-ID migration lookup, typed manufacturer/corporation/name-file key lookup, corporation prefix lookup, equipment items, behavior lookup, and hardpoint lookup without reading runtime projection DTOs.

AetheriaCatalogSurfaceProjector publishes the first Eve-compatible provider surface from typed catalog state. The importer materializes gamecult.eve.surface.v1 at eve:surface:aetheria.catalog.operator with summary, trade-catalog, and corporation views. This is a typed CultCache provider document and a local mirror of the Eve contract until the shared Eve Unity UI Toolkit lowering package exists.

Aetheria.State.Unity is the Unity-facing runtime read facade over typed state. It resolves the active Verse through the client-owned aetheria-client.cc target document, then opens the selected typed state source. Today that source is still a local .cc file transport, so the facade emits immutable catalog read models for trade, equipment, behavior, hardpoint, manufacturer, corporation, and name-file queries, exposes typed item shape masks for layout and fitting consumers, exposes typed interior masks and hardpoints for equipment/cargo layout consumers, exposes typed behavior payload read models, can read typed player settings for Unity boot, and can read the published Eve catalog surface. It does not deserialize legacy runtime projection objects and does not write daemon-owned Verse state. Unity can use this as the first package boundary once CultLib/Eve runtime packaging is available. Unity MainMenu now lowers a typed Verse settings shell over that split: client-target edits persist locally in aetheria-client.cc, while Verse-host visibility changes append provider-owned Eve request documents against the selected local Verse state file. Galaxy now consumes this package-owned runtime catalog for faction selection and name generation, so generated sectors use typed corporation v2 and aetheria.name_file.v2 records instead of legacy Faction/NameFile catalog documents. Loadout manufacturer-distance weighting also resolves manufacturers through typed corporation keys rather than parsing manufacturer legacy IDs. Galaxy still projects typed corporations into temporary Faction DTOs, including local GUID equality for the surviving simulation surface, because the surrounding simulation has not yet been rebuilt around typed corporation records. The DTOs now carry typed faction/name-file keys and typed allegiance edges so they cannot reclaim catalog lookup authority.

Aetheria.State.Smoke writes and reopens full typed player settings plus a typed loadout template in addition to world, catalog, run state, zone state, and an entity snapshot. It also writes and reopens AetheriaRuntimeSession, the provider-owned aetheria.player_settings Eve surface, and player-settings Eve commands that mutate typed significant-digit and minimap-asteroid settings through the provider bridge. The smoke checks that the Eve provider advertises the runtime-session schema and player-settings command surface. The run smoke proves a typed run can reference a typed zone, the zone can preserve orbit/body rows and reference typed entity snapshots, and entity snapshots can preserve equipment slots, weapon groups, and simulation stat grids without reviving PlayerSettings.msgpack, .loadout, or .zone serialization. Unity MainMenu now lowers that same player-settings Eve document contract locally through UI Toolkit instead of hand-authoring separate gameplay/graphics widgets; the menu shell keeps name entry and back-navigation while gameplay still owns command semantics through ActionGameManager.RequestRuntimePlayerSettingsCommand. The run document also carries CurrentEntityKey, so Continue restore binds the saved player entity by exact typed record identity instead of reconstructing it from a transient entity-slot index. Canonical typed run state no longer stores CurrentZoneEntityIndex; older stored runs are translated through the package reader into CurrentEntityKey. The older runtime commit importer has been removed from the first-party state host and Unity package.

Aetheria.State.Verify opens a materialized state file and checks that the typed migration ledger matches the actual item, corporation, and name-file records in the .cc store. It also verifies the canonical legacy-ID lookup API for one migrated record of each catalog kind, checks that name-file v2 records carry their full name arrays, and checks that expanded item and corporation catalog facts survived materialization. The verifier also exercises the typed catalog snapshot query surface, shape-mask invariants, the typed behavior payload tree, and the published Eve catalog surface. The current catalog materializes 65 behavior payloads, 661 behavior fields, and 18 behavior-side legacy-ID references. Legacy content currently includes at least one overhanging hardpoint; the verifier preserves the payload and checks hardpoint local masks rather than silently converting content repair into migration. The verifier also fails if live Assets/Scripts source grows back serializer or legacy database symbols such as MessagePack, Newtonsoft, JsonKnownTypes, RethinkDB, or old DatabaseEntry/DatabaseLink references; the remaining MessagePack usage is a named package/import CultCache transport boundary, not gameplay state authority. The package boundary is also fenced: MessagePack symbols may only appear in the runtime catalog reader, CultCache document store, and typed runtime/Eve command document files until generated CultCache serializers replace that temporary Unity-side codec. The verifier also checks that the Eve runtime bootstrap exists, mounts the operations surface through the UI Toolkit presenter, and keeps renderer commands routed through the typed Eve command inbox. Use it after import when GameData/aetheria-world.cc changes.

Aetheria.State.Unity.Smoke opens the materialized state through the runtime facade and proves read-only Unity-facing catalog access without the legacy catalog reader. Live Unity code uses typed Eve or daemon request documents instead of runtime commit outboxes. Runtime and Eve requests are typed .cc records with embedded schema catalogs; their current record payload codec is still temporary package code until Unity consumes generated CultCache serializers directly.

Aetheria.State.Daemon opens the CultMesh Verse daemon, publishes daemon-owned Verse identity/health/game/editor surfaces, accepts observed Eve command documents on startup, and executes observed daemon command records each tick. For a bounded one-shot daemon tick:

dotnet run --project .\Aetheria.State.Daemon\Aetheria.State.Daemon.csproj -- --once

The daemon publishes AetheriaEveCommandAcceptanceStatus, the aetheria.operations Eve surface, and the typed aetheria.player_settings Eve surface after request acceptance attempts, so observed depth, accepted/applied/rejected counts, failures, timestamps, and player settings controls are typed state rather than console-only status. It also persists daemon-owned aetheria.verse_host_settings.v1, with boot-time defaults or overrides for service id, Verse id, visibility, and CultMesh address. When visibility is public, the daemon also serves a derived CultMesh Verse catalog from that same typed host document, using the located service name as the discoverable cultnet://...:3075 endpoint. The operations surface and provider advertisement project from that typed host document instead of hardcoded daemon identity strings. The provider advertisement still publishes gamecult.eve.provider_advertisement.v1 for the aetheria provider, advertising the catalog, operations, and player-settings surfaces plus the typed schemas witnessed by the local .cc state file.

Remote Unity clients should not pretend a public Verse is local authority. Use Aetheria.State.Replica to pull a cache-only local witness from the daemon:

dotnet run --project .\Aetheria.State.Replica\Aetheria.State.Replica.csproj -- sync --endpoint cultnet://host:3075 --game-data-root .\GameData --verse-id aetheria.public

That writes GameData\Verses\<verse>.cc as a replica projection of daemon truth. The selected remote client target resolves to that replica path. The daemon still owns accepted state; the replica is only the local read surface Unity lowers from.

The Unity Verse-settings shell can also trigger the same one-shot sync through the Aetheria.State.Replica bridge when the repo-local tool is available. That keeps target selection local while the replica organ owns daemon transport.

The old standalone Aetheria.State.DrainCommands applicator is deleted. Command acceptance is daemon behavior now; bounded operation uses Aetheria.State.Daemon --once so the same Verse member publishes the same provider, health, command boundary, and Eve surfaces.

Current rebuild notes:

  • MessagePack 3.1.4 is pulled transitively through CultLib and is currently flagged by NuGet advisory GHSA-hv8m-jj95-wg3x; update CultLib's GameCult.Caching.MessagePack package ownership rather than adding a local Aetheria override.
  • CultRecordRef<T> should become the persisted reference shape once the MessagePack source-generator path handles the GameCult formatter cleanly. Until then, v1 profile documents store explicit record-key strings at the persistence boundary.