Remove client document forwarding shortcuts

This commit is contained in:
Meta Vens 2026-06-28 05:43:12 +01:00
commit 9b46a745e1
5 changed files with 52 additions and 90 deletions

View file

@ -13491,23 +13491,38 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
string.Join(", ", missingDaemonStateFacadeSymbols));
}
var requiredManagedClientAccessSymbols = new[]
var requiredManagedClientConnectionSymbols = new[]
{
"public AetheriaClientState State => _state;",
"public AetheriaClientState Aetheria() => State;",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public Task<TDocument> LatestAsync<TDocument>()",
"public Observable<TDocument> Watch<TDocument>()",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>("
"public AetheriaClientState Aetheria() => State;"
};
var missingManagedClientAccessSymbols = requiredManagedClientAccessSymbols
var missingManagedClientConnectionSymbols = requiredManagedClientConnectionSymbols
.Where(symbol => !aetheriaClient.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingManagedClientAccessSymbols.Length > 0)
if (missingManagedClientConnectionSymbols.Length > 0)
{
throw new InvalidOperationException(
"AetheriaClient must expose managed typed document access instead of document-specific compatibility readers: " +
string.Join(", ", missingManagedClientAccessSymbols));
"AetheriaClient must expose the managed state object without owning document-catalog shortcuts: " +
string.Join(", ", missingManagedClientConnectionSymbols));
}
var requiredManagedStateAccessSymbols = new[]
{
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public ICultMeshDocumentHandle DocumentBySchema(string schemaVersion)",
"public Task<TDocument> LatestAsync<TDocument>()",
"public Observable<TDocument> Watch<TDocument>()",
"public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>(",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>("
};
var missingManagedStateAccessSymbols = requiredManagedStateAccessSymbols
.Where(symbol => !aetheriaClientState.Contains(symbol, StringComparison.Ordinal))
.ToArray();
if (missingManagedStateAccessSymbols.Length > 0)
{
throw new InvalidOperationException(
"AetheriaClientState must expose managed typed document access instead of AetheriaClient forwarding shortcuts: " +
string.Join(", ", missingManagedStateAccessSymbols));
}
var requiredObservedDaemonStateSymbols = new[]
@ -13576,7 +13591,13 @@ static void RequireRuntimeStateReaderOwnsUnityStateAcquisition(string root)
"public async Task<global::Aetheria.State.Documents.EveSurfaceState?> DaemonEditorSurfaceAsync()",
"public async Task<global::Aetheria.State.Documents.EveSurfaceState?> DaemonEditorTuiSurfaceAsync()",
"public Func<string, string> CreateEveSurfaceStateRefResolver()",
"public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()"
"public CultMeshStateRefResolver CreateEveSurfaceCultMeshStateRefResolver()",
"public CultMeshDocumentHandle<TDocument> Document<TDocument>()",
"public ICultMeshDocumentHandle DocumentBySchema(string schemaVersion)",
"public Task<TDocument> LatestAsync<TDocument>()",
"public Observable<TDocument> Watch<TDocument>()",
"public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>(",
"public CultMeshReactiveDocument<TDocument> Reactive<TDocument>("
};
var daemonClientBypassHits = forbiddenDaemonClientBypassSymbols
.Where(symbol => aetheriaClient.Contains(symbol, StringComparison.Ordinal))

View file

@ -351,7 +351,7 @@ Work:
Gates:
- `InventoryMenu`, `InventoryPanel`, `TradeMenu`, `LocalMenu`, `SchematicDisplay`, `SectorRenderer`, `MapRenderer`, and `ZoneRenderer` do not manually join state projections to obtain domain values.
- Shared projected documents are reachable through `client.Aetheria().Document<TDocument>()`, including same-schema CLR aliases, `client.Aetheria().DocumentBySchema(schemaVersion)`, `client.Aetheria().LatestAsync<TDocument>()`, and `client.Watch<TDocument>()`; the underlying type/schema lookup is delegated to CultMesh rather than an Aetheria-owned schema registry.
- Shared projected documents are reachable through `client.Aetheria().Document<TDocument>()`, including same-schema CLR aliases, `client.Aetheria().DocumentBySchema(schemaVersion)`, `client.Aetheria().LatestAsync<TDocument>()`, and `client.Aetheria().Watch<TDocument>()`; the underlying type/schema lookup is delegated to CultMesh rather than an Aetheria-owned schema registry.
- Client-facing code contains no `_observedFacadeIndex.TryResolve*` outside Unity render adapter internals.
- Client-facing code contains no `ResolveClient().Current*Async().GetAwaiter().GetResult()` or equivalent blocking state reads.
- `TryGetTypedCurrentDockingBayFacade` and similar transitional helpers are deleted rather than renamed.

View file

@ -578,20 +578,13 @@ Assert-Contains $tickRunner "ProjectTradeValuePolicySurfaceDocument(stateFilePat
$client = Read-Text "Packages\org.gamecult.aetheria.state\Runtime\AetheriaClient.cs"
Assert-Contains $client "AetheriaClientState State" "AetheriaClient must expose the semantic typed state facade."
Assert-Contains $client "Aetheria()" "AetheriaClient must expose the canonical domain facade entrypoint."
Assert-Contains $client "Document<TDocument>()" "AetheriaClient must allow callers to retrieve a projected state document by shared document type."
Assert-Contains $client "DocumentBySchema(string schemaVersion)" "AetheriaClient must allow projected state lookup by shared schema identity."
Assert-Contains $client "LatestAsync<TDocument>()" "AetheriaClient must allow one-call typed state reads by shared document type."
Assert-Contains $client "Watch<TDocument>()" "AetheriaClient must allow reactive typed state reads by shared document type."
Assert-Contains $client "ObjectsViewportAsync" "AetheriaClient must expose objects viewport facade."
Assert-Contains $client "GravityViewportAsync" "AetheriaClient must expose gravity viewport facade."
Assert-Contains $client "CurrentZoneAsync" "AetheriaClient must expose current-zone facade."
Assert-Contains $client "CurrentEntityAsync" "AetheriaClient must expose current-entity facade."
Assert-Contains $client "CurrentDockingAsync" "AetheriaClient must expose current-docking facade."
Assert-Contains $client "ZoneContactsAsync" "AetheriaClient must expose zone-contacts facade."
Assert-Contains $client "StationRefitAsync" "AetheriaClient must expose station-refit facade."
Assert-Contains $client "SectorMapAsync" "AetheriaClient must expose sector-map facade."
Assert-Contains $client "ZoneDetailsAsync" "AetheriaClient must expose zone-details facade."
Assert-Contains $client "ZoneRenderAsync" "AetheriaClient must expose zone-render facade."
Assert-Contains $client "AetheriaControl Control" "AetheriaClient must expose command controls separately from managed state documents."
Assert-Contains $client "AetheriaUi Ui" "AetheriaClient must expose UI command submission separately from managed state documents."
Assert-NotContains $client "Document<TDocument>()" "AetheriaClient must not forward typed document lookup; use AetheriaClientState."
Assert-NotContains $client "DocumentBySchema(string schemaVersion)" "AetheriaClient must not forward schema document lookup; use AetheriaClientState."
Assert-NotContains $client "LatestAsync<TDocument>()" "AetheriaClient must not forward one-call typed reads; use AetheriaClientState."
Assert-NotContains $client "Watch<TDocument>()" "AetheriaClient must not forward reactive reads; use AetheriaClientState."
Assert-NotContains $client "ReactiveAsync<TDocument>" "AetheriaClient must not forward reactive document creation; use AetheriaClientState."
$verseClient = Read-Text "Packages\org.gamecult.aetheria.state\Runtime\AetheriaRuntimeVerseClient.cs"
Assert-Contains $verseClient "AetheriaClientState Aetheria()" "AetheriaRuntimeVerseClient must expose the shared domain state facade."

View file

@ -194,11 +194,11 @@ public class DaemonRuntimeDocumentTests
.LatestAsync()
.GetAwaiter()
.GetResult();
var currentEntityFromClientType = client
var currentEntityFromClientType = client.State
.LatestAsync<AetheriaRuntimeCurrentEntityDocument>()
.GetAwaiter()
.GetResult();
using var currentEntityReactive = client
using var currentEntityReactive = client.State
.ReactiveAsync<AetheriaRuntimeCurrentEntityDocument>()
.GetAwaiter()
.GetResult();
@ -222,21 +222,21 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual("aetheria.current.entity", client.State.Current.Entity.DocumentId);
Assert.AreSame(client.State.Current.Entity, client.State.Document<AetheriaRuntimeCurrentEntityDocument>());
Assert.AreSame(client.State.Catalog, client.Document<AetheriaRuntimeCatalogSnapshot>());
Assert.AreSame(client.State.ZoneRender, client.Document<AetheriaRuntimeZoneRenderDocument>());
Assert.AreSame(client.State.LatestFrame, client.Document<AetheriaRuntimeDaemonFrameDocument>());
Assert.AreSame(client.State.Catalog, client.State.Document<AetheriaRuntimeCatalogSnapshot>());
Assert.AreSame(client.State.ZoneRender, client.State.Document<AetheriaRuntimeZoneRenderDocument>());
Assert.AreSame(client.State.LatestFrame, client.State.Document<AetheriaRuntimeDaemonFrameDocument>());
Assert.AreSame(client.State.Daemon.LatestFrame, client.State.LatestFrame);
Assert.AreSame(client.State.Daemon.LatestSoaView, client.State.LatestSoaView);
Assert.AreSame(
client.State.Daemon.ProviderAdvertisement,
client.Document<AetheriaRuntimeDaemonProviderAdvertisementDocument>());
Assert.AreSame(client.State.Daemon.Health, client.Document<AetheriaRuntimeDaemonHealthDocument>());
client.State.Document<AetheriaRuntimeDaemonProviderAdvertisementDocument>());
Assert.AreSame(client.State.Daemon.Health, client.State.Document<AetheriaRuntimeDaemonHealthDocument>());
Assert.AreSame(
client.State.Daemon.CommandBoundary,
client.Document<AetheriaRuntimeDaemonCommandBoundaryDocument>());
client.State.Document<AetheriaRuntimeDaemonCommandBoundaryDocument>());
Assert.AreSame(
client.State.Daemon.AuthorityPolicy,
client.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>());
client.State.Document<AetheriaRuntimeVerseAuthorityPolicyDocument>());
Assert.AreSame(
client.State.Daemon.AuthorityPolicy,
client.State.DocumentBySchema(AetheriaRuntimeVerseAuthoritySchemas.Policy));
@ -244,17 +244,17 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(AetheriaRuntimeDaemonGameSurfaceBuilder.TuiSurfaceId, client.State.Daemon.GameTuiSurface.DocumentId);
Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.SurfaceId, client.State.Daemon.EditorSurface.DocumentId);
Assert.AreEqual(AetheriaRuntimeDaemonEditorSurfaceBuilder.TuiSurfaceId, client.State.Daemon.EditorTuiSurface.DocumentId);
Assert.AreSame(client.State.Settings.Player, client.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.Settings.VerseHost, client.Document<AetheriaRuntimeVerseHostSettingsDocument>());
Assert.AreSame(client.State.Settings.Player, client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.Settings.VerseHost, client.State.Document<AetheriaRuntimeVerseHostSettingsDocument>());
Assert.AreSame(
client.State.Current.Entity,
client.State.DocumentBySchema(AetheriaRuntimeDaemonSchemas.CurrentEntity));
Assert.AreSame(
client.State.ZoneContacts,
client.DocumentBySchema("gamecult.aetheria.zone_contacts"));
client.State.DocumentBySchema("gamecult.aetheria.zone_contacts"));
Assert.AreEqual(
typeof(AetheriaRuntimeCurrentEntityDocument),
client.DocumentBySchema(AetheriaRuntimeDaemonSchemas.CurrentEntity).DocumentType);
client.State.DocumentBySchema(AetheriaRuntimeDaemonSchemas.CurrentEntity).DocumentType);
Assert.IsTrue(client.State.TryGetDocument<AetheriaRuntimeSectorMapDocument>(out var sectorMapDocument));
Assert.AreSame(client.State.SectorMap, sectorMapDocument);
Assert.IsTrue(client.State.TryGetDocumentBySchema(
@ -325,8 +325,8 @@ public class DaemonRuntimeDocumentTests
Assert.AreEqual(AetheriaRuntimeVerseHostSettingsDocument.SchemaId, verseHost.Schema);
Assert.AreEqual("", player.PlayerName);
Assert.AreEqual("", verseHost.VerseId);
Assert.AreSame(client.State.Settings.Player, client.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.Settings.VerseHost, client.Document<AetheriaRuntimeVerseHostSettingsDocument>());
Assert.AreSame(client.State.Settings.Player, client.State.Document<AetheriaRuntimePlayerSettingsDocument>());
Assert.AreSame(client.State.Settings.VerseHost, client.State.Document<AetheriaRuntimeVerseHostSettingsDocument>());
}
[Test]

View file

@ -2,8 +2,6 @@ using System;
using System.IO;
using System.Threading.Tasks;
using GameCult.Eve.Surface;
using GameCult.Mesh;
using R3;
#nullable enable
@ -39,56 +37,6 @@ namespace GameCult.Aetheria.State.Verse
public AetheriaClientState Aetheria() => State;
public CultMeshDocumentHandle<TDocument> Document<TDocument>()
where TDocument : class
{
ThrowIfDisposed();
return State.Document<TDocument>();
}
public ICultMeshDocumentHandle DocumentBySchema(string schemaVersion)
{
ThrowIfDisposed();
return State.DocumentBySchema(schemaVersion);
}
public Task<TDocument> LatestAsync<TDocument>()
where TDocument : class
{
ThrowIfDisposed();
return State.LatestAsync<TDocument>();
}
public Observable<TDocument> Watch<TDocument>()
where TDocument : class
{
ThrowIfDisposed();
return State.Watch<TDocument>();
}
public IDisposable Watch<TDocument>(Action<TDocument> onNext)
where TDocument : class
{
ThrowIfDisposed();
return State.Watch(onNext);
}
public Task<CultMeshReactiveDocument<TDocument>> ReactiveAsync<TDocument>(
CultMeshReactiveDocumentOptions? options = null)
where TDocument : class
{
ThrowIfDisposed();
return State.ReactiveAsync<TDocument>(options);
}
public CultMeshReactiveDocument<TDocument> Reactive<TDocument>(
CultMeshReactiveDocumentOptions? options = null)
where TDocument : class
{
ThrowIfDisposed();
return State.Reactive<TDocument>(options);
}
internal AetheriaRuntimeDaemonOperationsClient Operations => _operations;
public static async Task<AetheriaClient> OpenAsync(