diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc
index 436232b86..e5d0be56a 100644
Binary files a/.voidbot/state/aetheria.cc and b/.voidbot/state/aetheria.cc differ
diff --git a/Aetheria.State.Smoke/Aetheria.State.Smoke.csproj b/Aetheria.State.Smoke/Aetheria.State.Smoke.csproj
index ca788873d..e9e2dc0f7 100644
--- a/Aetheria.State.Smoke/Aetheria.State.Smoke.csproj
+++ b/Aetheria.State.Smoke/Aetheria.State.Smoke.csproj
@@ -9,5 +9,6 @@
+
diff --git a/Aetheria.State.Smoke/Program.cs b/Aetheria.State.Smoke/Program.cs
index ca402191b..ade754924 100644
--- a/Aetheria.State.Smoke/Program.cs
+++ b/Aetheria.State.Smoke/Program.cs
@@ -2,6 +2,8 @@ using Aetheria.State;
using Aetheria.State.Documents;
using Aetheria.State.Migration;
using GameCult.Caching;
+using GameCult.Aetheria.State.Unity;
+using GameCult.Eve.Surface;
var root = args.Length > 0 ? args[0] : Directory.GetCurrentDirectory();
var statePath = AetheriaStatePaths.ResolveDefaultStatePath(root);
@@ -105,20 +107,24 @@ await using (var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-s
await node.PutOperationsSurfaceAsync(AetheriaOperationsSurfaceProjector.Build(drainStatus));
await node.PutProviderAdvertisementAsync(AetheriaProviderAdvertisementProjector.Build(statePath, now));
- AetheriaEveCommandBridge.QueueCommand(
+ AetheriaRuntimeEveCommandLog.QueueCommand(
statePath,
- AetheriaProviderAdvertisementProjector.ProviderId,
- AetheriaCatalogSurfaceProjector.SurfaceId,
- "aetheria.catalog.refresh",
- new Dictionary { ["source"] = "state-smoke" },
- "aetheria-state-smoke");
- AetheriaEveCommandBridge.QueueCommand(
+ new EveSurfaceCommandRequest(
+ AetheriaProviderAdvertisementProjector.ProviderId,
+ AetheriaCatalogSurfaceProjector.SurfaceId,
+ "aetheria.catalog.refresh",
+ new Dictionary { ["source"] = "state-smoke" },
+ DateTimeOffset.UtcNow,
+ "aetheria-state-smoke"));
+ AetheriaRuntimeEveCommandLog.QueueCommand(
statePath,
- AetheriaProviderAdvertisementProjector.ProviderId,
- AetheriaCatalogSurfaceProjector.SurfaceId,
- "aetheria.catalog.unknown",
- new Dictionary { ["source"] = "state-smoke" },
- "aetheria-state-smoke");
+ new EveSurfaceCommandRequest(
+ AetheriaProviderAdvertisementProjector.ProviderId,
+ AetheriaCatalogSurfaceProjector.SurfaceId,
+ "aetheria.catalog.unknown",
+ new Dictionary { ["source"] = "state-smoke" },
+ DateTimeOffset.UtcNow,
+ "aetheria-state-smoke"));
var eveCommandReport = await AetheriaEveCommandBridge.ApplyPendingAsync(node);
var eveCommandStatus = new AetheriaEveCommandDrainStatus
{
diff --git a/Aetheria.State/AetheriaEveCommandBridge.cs b/Aetheria.State/AetheriaEveCommandBridge.cs
index 8af91ac55..bf3d81610 100644
--- a/Aetheria.State/AetheriaEveCommandBridge.cs
+++ b/Aetheria.State/AetheriaEveCommandBridge.cs
@@ -1,4 +1,3 @@
-using System.Buffers;
using Aetheria.State.Documents;
using MessagePack;
@@ -80,43 +79,6 @@ public static class AetheriaEveCommandBridge
return report;
}
- public static void QueueCommand(
- string stateFilePath,
- string providerId,
- string surfaceId,
- string command,
- IReadOnlyDictionary? payload = null,
- string clientId = "aetheria-state")
- {
- var issuedAtUtc = DateTimeOffset.UtcNow.UtcDateTime.ToString("O");
- var commandId = Guid.NewGuid().ToString("N");
- var pendingDirectory = GetPendingDirectory(stateFilePath);
- Directory.CreateDirectory(pendingDirectory);
-
- var finalPath = Path.Combine(
- pendingDirectory,
- $"{issuedAtUtc.Replace(':', '-')}.{StableToken(surfaceId)}.{StableToken(command)}.{commandId}.cc");
- var tempPath = finalPath + ".tmp";
-
- var buffer = new ArrayBufferWriter();
- var writer = new MessagePackWriter(buffer);
- writer.WriteArrayHeader(8);
- writer.Write(CommandSchema);
- writer.Write(commandId);
- writer.Write(providerId ?? "");
- writer.Write(surfaceId ?? "");
- writer.Write(command ?? "");
- writer.Write(issuedAtUtc);
- writer.Write(clientId ?? "");
- WritePayload(ref writer, payload);
- writer.Flush();
-
- File.WriteAllBytes(tempPath, buffer.WrittenSpan.ToArray());
- if (File.Exists(finalPath))
- File.Delete(finalPath);
- File.Move(tempPath, finalPath);
- }
-
private static AetheriaPendingEveCommand ReadCommand(string path)
{
var reader = new MessagePackReader(File.ReadAllBytes(path));
@@ -199,17 +161,6 @@ public static class AetheriaEveCommandBridge
};
}
- private static void WritePayload(ref MessagePackWriter writer, IReadOnlyDictionary? payload)
- {
- payload ??= new Dictionary(0, StringComparer.Ordinal);
- writer.WriteMapHeader(payload.Count);
- foreach (var entry in payload.OrderBy(entry => entry.Key, StringComparer.Ordinal))
- {
- writer.Write(entry.Key ?? "");
- writer.Write(entry.Value ?? "");
- }
- }
-
private static IReadOnlyDictionary ReadPayload(ref MessagePackReader reader)
{
var count = reader.ReadMapHeader();
@@ -225,20 +176,6 @@ public static class AetheriaEveCommandBridge
return payload;
}
- private static string StableToken(string value)
- {
- if (string.IsNullOrWhiteSpace(value))
- return "empty";
-
- var chars = value
- .Select(character => char.IsLetterOrDigit(character) ? character : '-')
- .ToArray();
- var token = new string(chars).Trim('-').ToLowerInvariant();
- while (token.Contains("--", StringComparison.Ordinal))
- token = token.Replace("--", "-", StringComparison.Ordinal);
- return string.IsNullOrWhiteSpace(token) ? "empty" : token;
- }
-
private static string ReadString(ref MessagePackReader reader)
{
return reader.ReadString() ?? "";
diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md
index 76ce87dac..f10855484 100644
--- a/docs/aetheria-perfect-machine-map.md
+++ b/docs/aetheria-perfect-machine-map.md
@@ -900,6 +900,10 @@ First Aetheria surfaces to publish:
validates provider/surface/command templates, invokes the current refresh
handlers, republishes accepted surfaces, rejects unknown commands, and
records typed command-drain status.
+ - Done: delete provider-side Eve command emission from
+ `AetheriaEveCommandBridge`; renderer/runtime command files are queued
+ through `AetheriaRuntimeEveCommandLog`, while the provider bridge only
+ validates, applies, reports, and deletes accounted commands.
- Extend the command bridge beyond refresh commands as gameplay/editor Eve
surfaces acquire provider-owned handlers.
- Wire the presenter into a Unity scene/prefab for the first runtime surface