2026-06-25 18:09:33 +01:00
using Aetheria.State ;
using GameCult.Aetheria.State.Verse ;
using System.Diagnostics ;
using System.Net ;
using System.Net.Sockets ;
using System.Text ;
var checks = new AuthoritySmokeChecks ( ) ;
await checks . RunAsync ( ) ;
Console . WriteLine ( "Authority smoke passed." ) ;
internal sealed class AuthoritySmokeChecks
{
private static readonly object ProcessOutputLock = new ( ) ;
private static readonly Dictionary < int , List < string > > ProcessOutput = new ( ) ;
public async Task RunAsync ( )
{
DefaultTrustedPolicyAcceptsCommand ( ) ;
DelegatedRuntimeAcceptsOnlyListedRuntime ( ) ;
HostAuthoritativeAcceptsOnlyHostRuntime ( ) ;
InterestLeaseAcceptsOnlyActiveMatchingLease ( ) ;
UnsupportedAuthorityModesReject ( ) ;
AuthorizedCommandsReportsRejectedIds ( ) ;
PreRejectedCommandsEnterFrameReceipts ( ) ;
ClientTargetCarriesRuntimeIdentity ( ) ;
TwoLocalRuntimeDelegatedPolicyHarness ( ) ;
2026-07-05 20:57:22 +01:00
GameDocumentsBuildLocalViewportFromFrame ( ) ;
2026-06-25 18:09:33 +01:00
StarbridgeSessionSummaryProjectsScenarioFacts ( ) ;
2026-06-28 06:04:54 +01:00
await AetheriaClientStateDocumentsProjectAndSubmitAsync ( ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
await DaemonOncePublishesStarbridgeSessionFactsAsync ( ) . ConfigureAwait ( false ) ;
await SamePolicyDocumentCanBeLoadedByTwoNodesAsync ( ) . ConfigureAwait ( false ) ;
await TwoDaemonProcessesApplyDelegatedPolicyAsync ( ) . ConfigureAwait ( false ) ;
await ConcurrentDaemonsPublishRemoteFramesToLocalReplicasAsync ( ) . ConfigureAwait ( false ) ;
TrustedCommittedFactsConvergeLocalRuns ( ) ;
}
private static void DefaultTrustedPolicyAcceptsCommand ( )
{
2026-07-05 20:57:22 +01:00
var command = Command ( "pilot-client" , "entity:raven" ) ;
2026-06-25 18:09:33 +01:00
var decision = AetheriaRuntimeAuthorityRouter . Authorize (
command ,
policy : null ,
leases : null ,
localRuntimeId : "aetheria-daemon" ) ;
Require ( decision . Authorized , "default trusted policy should accept trusted local commands" ) ;
RequireEqual ( AetheriaRuntimeAuthorityModes . AnyTrustedRuntime , decision . Mode , "default policy mode" ) ;
RequireEqual ( "entity:raven" , decision . SubjectKey , "default policy subject" ) ;
RequireEqual ( AetheriaRuntimeClaimKinds . Movement , decision . ClaimKind , "default policy claim" ) ;
}
private static void ClientTargetCarriesRuntimeIdentity ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var gameData = Directory . CreateDirectory ( Path . Combine ( Path . GetTempPath ( ) , $"aetheria-client-target-{smokeId}" ) ) ;
try
{
var state = AetheriaState . At ( gameData ) ;
var target = state . ClientTarget . Refresh ( ) ;
2026-07-05 20:57:22 +01:00
RequireEqual ( AetheriaRuntimeStateBoundary . DefaultClientRuntimeId , target . RuntimeId , "client target default runtime id" ) ;
2026-06-25 18:09:33 +01:00
target = state . ClientTarget . RequestRuntimeId ( "raven-test-runtime" ) ;
RequireEqual ( "raven-test-runtime" , target . RuntimeId , "client target should persist requested runtime id" ) ;
var boot = AetheriaRuntimeStateBoot . Inspect ( gameData ) ;
RequireEqual ( "raven-test-runtime" , boot . RuntimeId , "boot report should expose client target runtime id" ) ;
var previousRuntimeOverride = Environment . GetEnvironmentVariable ( AetheriaRuntimeStateBoundary . RuntimeIdOverrideEnvironmentVariable ) ;
try
{
Environment . SetEnvironmentVariable ( AetheriaRuntimeStateBoundary . RuntimeIdOverrideEnvironmentVariable , "raven-env-runtime" ) ;
boot = AetheriaRuntimeStateBoot . Inspect ( gameData ) ;
RequireEqual ( "raven-env-runtime" , boot . RuntimeId , "generic runtime id override should win" ) ;
}
finally
{
Environment . SetEnvironmentVariable ( AetheriaRuntimeStateBoundary . RuntimeIdOverrideEnvironmentVariable , previousRuntimeOverride ) ;
}
}
finally
{
try
{
gameData . Delete ( recursive : true ) ;
}
catch
{
}
}
}
private static void DelegatedRuntimeAcceptsOnlyListedRuntime ( )
{
var policy = Policy (
AetheriaRuntimeAuthorityModes . AnyTrustedRuntime ,
new AetheriaRuntimeAuthorityRule
{
RuleId = "raven.movement" ,
SubjectPrefix = "entity:raven" ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Movement ] ,
Mode = AetheriaRuntimeAuthorityModes . DelegatedRuntime ,
2026-07-05 20:57:22 +01:00
RuntimeIds = [ "pilot-client" ] ,
2026-06-25 18:09:33 +01:00
Priority = 10
} ) ;
var accepted = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "pilot-client" , "entity:raven" ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "commander-client" ) ;
2026-06-25 18:09:33 +01:00
var rejected = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "commander-client" , "entity:raven" ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "commander-client" ) ;
2026-06-25 18:09:33 +01:00
Require ( accepted . Authorized , "delegated runtime should accept listed runtime id" ) ;
Require ( ! rejected . Authorized , "delegated runtime should reject unlisted runtime id" ) ;
RequireEqual ( "delegated-runtime-required" , rejected . Reason , "delegated rejection reason" ) ;
}
private static void HostAuthoritativeAcceptsOnlyHostRuntime ( )
{
var policy = Policy ( AetheriaRuntimeAuthorityModes . HostAuthoritative ) ;
var accepted = AetheriaRuntimeAuthorityRouter . Authorize (
Command ( "host-daemon" , "entity:raven" ) ,
policy ,
leases : null ,
localRuntimeId : "host-daemon" ) ;
var rejected = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "pilot-client" , "entity:raven" ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases : null ,
localRuntimeId : "host-daemon" ) ;
Require ( accepted . Authorized , "host-authoritative should accept host runtime" ) ;
Require ( ! rejected . Authorized , "host-authoritative should reject non-host runtime" ) ;
RequireEqual ( "host-authority-required" , rejected . Reason , "host-authoritative rejection reason" ) ;
}
private static void InterestLeaseAcceptsOnlyActiveMatchingLease ( )
{
var now = DateTimeOffset . UtcNow ;
var policy = Policy (
AetheriaRuntimeAuthorityModes . AnyTrustedRuntime ,
new AetheriaRuntimeAuthorityRule
{
RuleId = "hostile.combat.lease" ,
SubjectPrefix = "entity:hostile" ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Combat ] ,
Mode = AetheriaRuntimeAuthorityModes . InterestLease ,
LeaseScope = "combat" ,
Priority = 20
} ) ;
var leases = new [ ]
{
new AetheriaRuntimeAuthorityLeaseDocument
{
2026-07-05 20:57:22 +01:00
LeaseId = "lease:commander:hostile" ,
RuntimeId = "commander-client" ,
2026-06-25 18:09:33 +01:00
SubjectPrefix = "entity:hostile" ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Combat ] ,
Scope = "combat" ,
ValidFromUtc = now . AddSeconds ( - 5 ) . ToString ( "O" ) ,
ExpiresAtUtc = now . AddSeconds ( 30 ) . ToString ( "O" )
}
} ;
var accepted = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "commander-client" , "entity:hostile:001" , AetheriaRuntimeDaemonCommandKinds . FireWeaponGroup ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "pilot-client" ) ;
2026-06-25 18:09:33 +01:00
var rejected = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "pilot-client" , "entity:hostile:001" , AetheriaRuntimeDaemonCommandKinds . FireWeaponGroup ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "pilot-client" ) ;
2026-06-25 18:09:33 +01:00
Require ( accepted . Authorized , "interest lease should accept active matching lease" ) ;
Require ( ! rejected . Authorized , "interest lease should reject missing runtime lease" ) ;
RequireEqual ( "authority-lease-required" , rejected . Reason , "interest lease rejection reason" ) ;
}
private static void UnsupportedAuthorityModesReject ( )
{
var policy = Policy ( AetheriaRuntimeAuthorityModes . WitnessQuorum ) ;
var decision = AetheriaRuntimeAuthorityRouter . Authorize (
2026-07-05 20:57:22 +01:00
Command ( "pilot-client" , "entity:raven" ) ,
2026-06-25 18:09:33 +01:00
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "pilot-client" ) ;
2026-06-25 18:09:33 +01:00
Require ( ! decision . Authorized , "witness quorum should be represented but fail closed" ) ;
RequireEqual ( "authority-mode-not-implemented" , decision . Reason , "unsupported mode rejection reason" ) ;
}
private static void AuthorizedCommandsReportsRejectedIds ( )
{
var policy = Policy ( AetheriaRuntimeAuthorityModes . HostAuthoritative ) ;
var host = Command ( "host-daemon" , "entity:raven" ) ;
2026-07-05 20:57:22 +01:00
var client = Command ( "pilot-client" , "entity:raven" ) ;
2026-06-25 18:09:33 +01:00
var rejectedIds = new List < string > ( ) ;
var accepted = AetheriaRuntimeAuthorityRouter . AuthorizedCommands (
[host, client] ,
policy ,
leases : null ,
localRuntimeId : "host-daemon" ,
rejectedCommandIds : rejectedIds ) ;
RequireEqual ( 1 , accepted . Count , "accepted command count" ) ;
RequireEqual ( host . CommandId , accepted [ 0 ] . CommandId , "accepted command id" ) ;
RequireEqual ( 1 , rejectedIds . Count , "rejected command count" ) ;
RequireEqual ( client . CommandId , rejectedIds [ 0 ] , "rejected command id" ) ;
}
private static void PreRejectedCommandsEnterFrameReceipts ( )
{
2026-07-05 20:57:22 +01:00
var command = Command ( "pilot-client" , "entity:raven" ) ;
2026-06-25 18:09:33 +01:00
var result = AetheriaRuntimeDaemonTickRunner . Tick (
Path . Combine ( Path . GetTempPath ( ) , "aetheria-authority-smoke.cc" ) ,
new AetheriaRuntimeRunCheckpointCommit ( ) ,
new AetheriaRuntimeDaemonTickOptions
{
DaemonId = "host-daemon" ,
SessionId = "authority-smoke" ,
FrameId = 42 ,
SimulationTimeSeconds = 1 ,
FixedDeltaSeconds = 0.02 ,
ObservedCommands = Array . Empty < AetheriaRuntimeDaemonCommandDocument > ( ) ,
PreRejectedCommandIds = [ command . CommandId ] ,
2026-06-28 07:28:45 +01:00
BuildPublications = false
2026-06-25 18:09:33 +01:00
} ) ;
Require ( result . Frame . RejectedCommandIds . Contains ( command . CommandId ) , "pre-rejected command should enter frame rejection receipts" ) ;
Require ( result . Frame . AccountedCommandIds . Contains ( command . CommandId ) , "pre-rejected command should enter accounted receipts" ) ;
}
private static void TwoLocalRuntimeDelegatedPolicyHarness ( )
{
2026-07-05 20:57:22 +01:00
const string pilotRuntime = "pilot-client" ;
const string commanderRuntime = "commander-client" ;
2026-06-25 18:09:33 +01:00
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
var policy = CoopPolicy ( ) ;
2026-07-05 20:57:22 +01:00
var ravenByRaven = MovementCommand ( pilotRuntime , ravenKey , directionX : 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByRaven = MovementCommand ( pilotRuntime , hostileKey , directionX : 0 , directionY : 1 , magnitude : 1 ) ;
2026-06-25 18:09:33 +01:00
var ravenFrame = TickWithPolicy (
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
InitialCoopRun ( ) ,
policy ,
[ravenByRaven, hostileByRaven] ) ;
Require ( ravenFrame . AppliedCommandIds . Contains ( ravenByRaven . CommandId ) , "raven node should apply Raven-authored Raven movement" ) ;
Require ( ravenFrame . RejectedCommandIds . Contains ( hostileByRaven . CommandId ) , "raven node should reject Raven-authored hostile movement" ) ;
Require ( ravenFrame . AccountedCommandIds . Contains ( ravenByRaven . CommandId ) , "raven node should account applied Raven command" ) ;
Require ( ravenFrame . AccountedCommandIds . Contains ( hostileByRaven . CommandId ) , "raven node should account rejected hostile command" ) ;
2026-07-05 20:57:22 +01:00
var ravenByCommander = MovementCommand ( commanderRuntime , ravenKey , directionX : - 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByCommander = MovementCommand ( commanderRuntime , hostileKey , directionX : 0 , directionY : - 1 , magnitude : 1 ) ;
var commanderFrame = TickWithPolicy (
"commander-local" ,
2026-06-25 18:09:33 +01:00
InitialCoopRun ( ) ,
policy ,
2026-07-05 20:57:22 +01:00
[ravenByCommander, hostileByCommander] ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
Require ( commanderFrame . RejectedCommandIds . Contains ( ravenByCommander . CommandId ) , "commander node should reject Commander-authored Raven movement" ) ;
Require ( commanderFrame . AppliedCommandIds . Contains ( hostileByCommander . CommandId ) , "commander node should apply Commander-authored hostile movement" ) ;
Require ( commanderFrame . AccountedCommandIds . Contains ( ravenByCommander . CommandId ) , "commander node should account rejected Raven command" ) ;
Require ( commanderFrame . AccountedCommandIds . Contains ( hostileByCommander . CommandId ) , "commander node should account applied hostile command" ) ;
2026-06-25 18:09:33 +01:00
}
2026-07-05 20:57:22 +01:00
private static void GameDocumentsBuildLocalViewportFromFrame ( )
2026-06-25 18:09:33 +01:00
{
var run = new AetheriaRuntimeRunCheckpointCommit
{
2026-07-05 20:57:22 +01:00
RunId = "game-documents-smoke" ,
2026-06-25 18:09:33 +01:00
CurrentZoneIndex = 0 ,
EntranceZoneIndex = 0 ,
ExitZoneIndex = 1 ,
DiscoveredZoneIndices = [ 0 ] ,
2026-07-05 20:57:22 +01:00
CurrentEntityKey = EntityKey ( "game-documents-smoke" , 0 , 0 ) ,
2026-06-25 18:09:33 +01:00
Zones =
[
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 0 ,
2026-06-30 19:14:49 +01:00
Name = "Document Zone" ,
2026-06-25 18:09:33 +01:00
PositionX = 12 ,
PositionY = 34 ,
AdjacentZoneIndices = [ 1 ] ,
Entities =
[
2026-06-30 19:14:49 +01:00
SnapshotEntity (
2026-06-25 18:09:33 +01:00
0 ,
"Raven" ,
"player" ,
x : 0 ,
z : 0 ,
visibility : 80 ,
hull : 120 ,
cargoItem : "reactor-cell" ) ,
2026-06-30 19:14:49 +01:00
SnapshotEntity (
2026-06-25 18:09:33 +01:00
1 ,
2026-07-05 20:57:22 +01:00
"Commander" ,
2026-06-25 18:09:33 +01:00
"player" ,
x : 240 ,
z : 0 ,
visibility : 160 ,
hull : 140 ,
cargoItem : "sensor-pack" ) ,
2026-06-30 19:14:49 +01:00
SnapshotEntity (
2026-06-25 18:09:33 +01:00
2 ,
"Raider In Shared Sight" ,
"raider" ,
x : 360 ,
z : 0 ,
visibility : 60 ,
hull : 70 ,
cargoItem : "scrap" ) ,
2026-06-30 19:14:49 +01:00
SnapshotEntity (
2026-06-25 18:09:33 +01:00
3 ,
"Outside Viewport" ,
"raider" ,
x : 900 ,
z : 0 ,
visibility : 60 ,
hull : 70 ,
cargoItem : "scrap" )
] ,
Bodies =
[
new AetheriaRuntimeBodySnapshotCommit
{
BodyKey = "body:near" ,
OrbitKey = "orbit:near" ,
Name = "Gravity Brush" ,
Kind = "planet" ,
GravityInfluenceCenterX = 390 ,
GravityInfluenceCenterZ = 0 ,
GravityInfluenceRadius = 75 ,
GravityWellDepth = 3 ,
GravityDepthExponent = 2 ,
GravityWaveRadius = 32 ,
GravityWaveDepth = 0.5 ,
GravityWaveSpeed = 1
} ,
new AetheriaRuntimeBodySnapshotCommit
{
BodyKey = "body:far" ,
OrbitKey = "orbit:far" ,
Name = "Too Far" ,
Kind = "planet" ,
GravityInfluenceCenterX = 1200 ,
GravityInfluenceCenterZ = 0 ,
GravityInfluenceRadius = 50
}
]
} ,
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 1 ,
2026-06-30 19:14:49 +01:00
Name = "Document Neighbor" ,
2026-06-25 18:09:33 +01:00
PositionX = 72 ,
PositionY = 34 ,
AdjacentZoneIndices = [ 0 ] ,
OwnerFactionIndex = 2 ,
FactionIndices = [ 2 ]
}
]
} ;
var frame = AetheriaRuntimeDaemonFrameDocument . Create (
run ,
2026-06-30 19:14:49 +01:00
"documents-daemon" ,
"documents-session" ,
2026-06-25 18:09:33 +01:00
12 ,
0.24 ,
0.02 ) ;
2026-07-05 19:56:18 +01:00
var viewportDocument = AetheriaRuntimeGameDocuments . Viewport (
2026-06-25 18:09:33 +01:00
frame ,
2026-07-05 19:56:18 +01:00
new AetheriaRuntimeViewportBounds
2026-06-25 18:09:33 +01:00
{
MinX = 500 ,
MinY = - 100 ,
MaxX = - 50 ,
MaxY = 100
} ) ;
2026-07-05 19:56:18 +01:00
var objectsViewport = AetheriaRuntimeGameDocuments . ObjectsViewport (
2026-06-25 18:09:33 +01:00
frame ,
2026-06-30 19:14:49 +01:00
viewportDocument . Viewport ) ;
2026-07-05 19:56:18 +01:00
var gravityViewport = AetheriaRuntimeGameDocuments . GravityViewport (
2026-06-25 18:09:33 +01:00
frame ,
2026-06-30 19:14:49 +01:00
viewportDocument . Viewport ) ;
2026-07-05 19:56:18 +01:00
var currentZone = AetheriaRuntimeGameDocuments . CurrentZone ( frame ) ;
var sectorMap = AetheriaRuntimeGameDocuments . SectorMap ( frame ) ;
2026-06-30 19:14:49 +01:00
2026-07-05 19:56:18 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . GameViewport , viewportDocument . Schema , "viewport document schema" ) ;
2026-06-30 19:14:49 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . ObjectsViewport , objectsViewport . Schema , "objects viewport document schema" ) ;
RequireEqual ( AetheriaRuntimeDaemonSchemas . GravityViewport , gravityViewport . Schema , "gravity viewport document schema" ) ;
RequireEqual ( AetheriaRuntimeDaemonSchemas . CurrentZone , currentZone . Schema , "current-zone document schema" ) ;
RequireEqual ( AetheriaRuntimeDaemonSchemas . SectorMap , sectorMap . Schema , "sector-map document schema" ) ;
RequireEqual ( "Document Zone" , currentZone . ZoneName , "current-zone document zone name" ) ;
RequireEqual ( 12.0 , currentZone . PositionX , "current-zone document position x" ) ;
RequireEqual ( 34.0 , currentZone . PositionY , "current-zone document position y" ) ;
RequireEqual ( 2 , sectorMap . Zones . Count , "sector-map document zone count" ) ;
2026-06-25 18:09:33 +01:00
Require ( sectorMap . Zones . Any ( zone = > zone . ZoneIndex = = 0 & & zone . Current & & zone . Entrance & & zone . Discovered ) , "sector-map should mark current entrance zone" ) ;
Require ( sectorMap . Zones . Any ( zone = > zone . ZoneIndex = = 1 & & zone . Exit & & ! zone . Discovered ) , "sector-map should mark undiscovered exit zone" ) ;
Require ( sectorMap . Links . Any ( link = > link . FromZoneIndex = = 0 & & link . ToZoneIndex = = 1 & & ! link . Discovered ) , "sector-map should include normalized topology link" ) ;
2026-06-30 19:14:49 +01:00
RequireEqual ( 12L , viewportDocument . FrameId , "viewport document frame id" ) ;
RequireEqual ( - 50.0 , viewportDocument . Viewport . MinX , "normalized viewport min x" ) ;
RequireEqual ( 500.0 , viewportDocument . Viewport . MaxX , "normalized viewport max x" ) ;
Require ( viewportDocument . ControlledEntityIndices . SequenceEqual ( [ 0 , 1 ] ) , "viewport document should expose controlled unit set" ) ;
Require ( viewportDocument . Objects . Any ( item = > item . DisplayName = = "Raider In Shared Sight" ) , "viewport document should use union of controlled unit visibility" ) ;
Require ( ! viewportDocument . Objects . Any ( item = > item . DisplayName = = "Outside Viewport" ) , "viewport document should exclude objects outside viewport" ) ;
Require ( objectsViewport . Objects . Select ( item = > item . EntityIndex ) . SequenceEqual ( viewportDocument . Objects . Select ( item = > item . EntityIndex ) ) , "objects viewport should match composed map object set" ) ;
var raven = viewportDocument . Objects . First ( item = > item . DisplayName = = "Raven" ) ;
RequireEqual ( 120.0 , raven . Status . Hull , "viewport document should include entity status" ) ;
Require ( raven . Inventory . Any ( item = > item . ItemKey = = "reactor-cell" & & item . Source = = "cargo" ) , "viewport document should include inventory" ) ;
Require ( viewportDocument . GravityInfluences . Any ( item = > item . BodyKey = = "body:near" ) , "viewport document should include intersecting gravity influence" ) ;
Require ( ! viewportDocument . GravityInfluences . Any ( item = > item . BodyKey = = "body:far" ) , "viewport document should exclude non-intersecting gravity influence" ) ;
Require ( gravityViewport . GravityInfluences . Select ( item = > item . BodyKey ) . SequenceEqual ( viewportDocument . GravityInfluences . Select ( item = > item . BodyKey ) ) , "gravity viewport should match composed map gravity set" ) ;
2026-06-25 18:09:33 +01:00
}
private static void StarbridgeSessionSummaryProjectsScenarioFacts ( )
{
2026-06-30 19:14:49 +01:00
var baseEntity = SnapshotEntity (
2026-06-25 18:09:33 +01:00
4 ,
"Starbridge Base" ,
"player" ,
x : 0 ,
z : 0 ,
visibility : 500 ,
hull : 850 ,
cargoItem : "coolant-beam" ) ;
baseEntity . Kind = "station" ;
var run = new AetheriaRuntimeRunCheckpointCommit
{
RunId = "starbridge-session-smoke" ,
CurrentZoneIndex = 0 ,
Zones =
[
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 0 ,
Name = "Starbridge Defense" ,
Entities =
[
baseEntity ,
2026-06-30 19:14:49 +01:00
SnapshotEntity ( 5 , "Pilot Raven" , "player" , 120 , 0 , 300 , 140 , "repair-pod" )
2026-06-25 18:09:33 +01:00
]
}
]
} ;
var frame = AetheriaRuntimeDaemonFrameDocument . Create (
run ,
"starbridge-daemon" ,
"starbridge-smoke-session" ,
19 ,
0.38 ,
0.02 ) ;
var scenario = new AetheriaRuntimeStarbridgeScenarioDocument
{
ScenarioId = "starbridge.frontier-fabricator" ,
DisplayName = "Frontier Fabricator Defense" ,
StartingBaseKey = EntityKey ( "starbridge-session-smoke" , 0 , 4 ) ,
StationStock =
[
new AetheriaRuntimeStarbridgeStationStockItem
{
ItemKey = "coolant-beam" ,
Quantity = 2 ,
Quality = 0.75 ,
Durability = 1
}
] ,
Waves =
[
new AetheriaRuntimeStarbridgeWaveDefinition
{
WaveIndex = 0 ,
DisplayName = "Scout Probe" ,
AttackerKeys = [ "scout" ] ,
BossKey = "scout-captain" ,
RecoveredTechnologyKeys = [ "sensor-calibration" ]
} ,
new AetheriaRuntimeStarbridgeWaveDefinition
{
WaveIndex = 1 ,
DisplayName = "Bomber Line" ,
AttackerKeys = [ "bomber" , "skirmisher" ] ,
BossKey = "bomber-frame" ,
RecoveredTechnologyKeys = [ "missile-rack-burst" ]
}
] ,
RuntimeRoles =
[
new AetheriaRuntimeStarbridgeRuntimeRole
{
2026-07-05 20:57:22 +01:00
RuntimeId = "commander-client" ,
2026-06-25 18:09:33 +01:00
Role = "commander"
} ,
new AetheriaRuntimeStarbridgeRuntimeRole
{
2026-07-05 20:57:22 +01:00
RuntimeId = "pilot-client" ,
2026-06-25 18:09:33 +01:00
Role = "pilot" ,
EntityKey = EntityKey ( "starbridge-session-smoke" , 0 , 5 )
}
]
} ;
var session = new AetheriaRuntimeStarbridgeSessionDocument
{
SessionId = "starbridge-smoke-session" ,
ScenarioId = scenario . ScenarioId ,
RunId = run . RunId ,
BaseEntityKey = EntityKey ( "starbridge-session-smoke" , 0 , 4 ) ,
StationEntityKey = EntityKey ( "starbridge-session-smoke" , 0 , 4 ) ,
Phase = "pre-wave" ,
CurrentWaveIndex = 1
} ;
2026-06-30 19:14:49 +01:00
var summary = AetheriaRuntimeStarbridgeDocuments . SessionSummary ( frame , scenario , session ) ;
2026-06-25 18:09:33 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . StarbridgeSessionSummary , summary . Schema , "starbridge session summary schema" ) ;
RequireEqual ( "starbridge.frontier-fabricator" , summary . ScenarioId , "starbridge scenario id" ) ;
RequireEqual ( "Frontier Fabricator Defense" , summary . ScenarioName , "starbridge scenario name" ) ;
RequireEqual ( "pre-wave" , summary . Phase , "starbridge session phase" ) ;
RequireEqual ( "Starbridge Base" , summary . BaseStatus . DisplayName , "starbridge base status name" ) ;
RequireEqual ( 850.0 , summary . BaseStatus . Hull , "starbridge base hull" ) ;
Require ( summary . StationStock . Any ( item = > item . ItemKey = = "coolant-beam" ) , "starbridge station stock should project scenario stock" ) ;
Require ( summary . WaveForecast . Length = = 1 & & summary . WaveForecast [ 0 ] . DisplayName = = "Bomber Line" , "starbridge wave forecast should start at current wave" ) ;
2026-07-05 20:57:22 +01:00
Require ( summary . RuntimeRoles . Any ( role = > role . RuntimeId = = "commander-client" & & role . Role = = "commander" ) , "starbridge runtime roles should project scenario roles" ) ;
2026-06-25 18:09:33 +01:00
var gameSurface = AetheriaRuntimeDaemonGameSurfaceBuilder . Build (
frame ,
new AetheriaRuntimeDaemonHealthDocument
{
DaemonId = "starbridge-daemon" ,
VerseId = "aetheria.starbridge-smoke" ,
Status = "healthy"
} ,
AetheriaRuntimeDaemonCommandBoundaryDocument . Create ( "starbridge-daemon" ) ,
summary ) ;
RequireSurfaceMetric ( gameSurface , "aetheria.daemon.game.starbridge.scenario" , "Frontier Fabricator Defense" , "daemon game surface starbridge scenario" ) ;
RequireSurfaceMetric ( gameSurface , "aetheria.daemon.game.starbridge.base" , "Starbridge Base" , "daemon game surface starbridge base" ) ;
RequireSurfaceMetric ( gameSurface , "aetheria.daemon.game.starbridge.stock.0.item" , "coolant-beam" , "daemon game surface starbridge stock" ) ;
RequireSurfaceMetric ( gameSurface , "aetheria.daemon.game.starbridge.wave.0.name" , "Bomber Line" , "daemon game surface starbridge wave forecast" ) ;
2026-07-05 20:57:22 +01:00
RequireSurfaceMetric ( gameSurface , "aetheria.daemon.game.starbridge.role.0.runtime" , "commander-client" , "daemon game surface starbridge runtime role" ) ;
2026-06-25 18:09:33 +01:00
}
2026-06-28 06:04:54 +01:00
private static async Task AetheriaClientStateDocumentsProjectAndSubmitAsync ( )
2026-06-25 18:09:33 +01:00
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
2026-06-28 06:04:54 +01:00
var statePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-client-state-documents-{smokeId}.cc" ) ;
2026-06-25 18:09:33 +01:00
var frame = AetheriaRuntimeDaemonFrameDocument . Create (
new AetheriaRuntimeRunCheckpointCommit
{
2026-06-28 06:04:54 +01:00
RunId = "client-state-documents-smoke" ,
2026-06-25 18:09:33 +01:00
CurrentZoneIndex = 0 ,
2026-06-28 06:04:54 +01:00
CurrentEntityKey = EntityKey ( "client-state-documents-smoke" , 0 , 0 ) ,
2026-06-25 18:09:33 +01:00
Zones =
[
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 0 ,
2026-06-28 06:04:54 +01:00
Name = "Client State Documents Zone" ,
2026-06-25 18:09:33 +01:00
Entities =
[
2026-06-30 19:14:49 +01:00
SnapshotEntity ( 0 , "Document Raven" , "player" , 0 , 0 , 600 , 140 , "document-cargo" ) ,
SnapshotEntity ( 1 , "Document Raider" , "raider" , 100 , 0 , 120 , 80 , "raider-cargo" )
2026-06-25 18:09:33 +01:00
]
}
]
} ,
2026-06-28 06:04:54 +01:00
"state-documents-daemon" ,
"state-documents-session" ,
2026-06-25 18:09:33 +01:00
7 ,
0.14 ,
0.02 ) ;
var health = new AetheriaRuntimeDaemonHealthDocument
{
2026-06-28 06:04:54 +01:00
DaemonId = "state-documents-daemon" ,
VerseId = "aetheria.state-documents-smoke" ,
2026-06-25 18:09:33 +01:00
FrameId = frame . FrameId ,
Status = "healthy" ,
Transport = "cultcache-witness"
} ;
var policy = AetheriaRuntimeVerseAuthorityPolicyDocument . TrustedCoop (
2026-06-28 06:04:54 +01:00
"aetheria.state-documents-smoke" ,
"state-documents-daemon" ) ;
2026-06-25 18:09:33 +01:00
var scenario = new AetheriaRuntimeStarbridgeScenarioDocument
{
2026-06-28 06:04:54 +01:00
ScenarioId = "starbridge.state-documents" ,
DisplayName = "Document Starbridge" ,
StartingBaseKey = EntityKey ( "client-state-documents-smoke" , 0 , 0 ) ,
2026-06-25 18:09:33 +01:00
StationStock =
[
new AetheriaRuntimeStarbridgeStationStockItem
{
2026-06-28 06:04:54 +01:00
ItemKey = "document-cargo" ,
2026-06-25 18:09:33 +01:00
Quantity = 3 ,
Quality = 1 ,
Durability = 1
}
] ,
Waves =
[
new AetheriaRuntimeStarbridgeWaveDefinition
{
WaveIndex = 0 ,
2026-06-28 06:04:54 +01:00
DisplayName = "Document Wave" ,
2026-06-25 18:09:33 +01:00
AttackerKeys = [ "raider" ] ,
2026-06-28 06:04:54 +01:00
BossKey = "document-boss"
2026-06-25 18:09:33 +01:00
}
]
} ;
var session = new AetheriaRuntimeStarbridgeSessionDocument
{
2026-06-28 06:04:54 +01:00
SessionId = "state-documents-session" ,
ScenarioId = "starbridge.state-documents" ,
BaseEntityKey = EntityKey ( "client-state-documents-smoke" , 0 , 0 ) ,
2026-06-25 18:09:33 +01:00
Phase = "pre-wave"
} ;
using ( var writer = await AetheriaRuntimeVerseClient
2026-06-28 06:04:54 +01:00
. OpenAsync ( statePath , "state-documents-writer" , startServer : false , pullOnOpen : false )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) )
{
await writer . Database
. PutAsync ( AetheriaRuntimeVerseRecordKeys . DaemonFrameLatest , frame )
. ConfigureAwait ( false ) ;
await writer . Database
. PutAsync ( AetheriaRuntimeVerseRecordKeys . DaemonHealth , health )
. ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await writer . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy )
2026-06-28 06:04:54 +01:00
. ReplaceAsync ( policy )
. ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await writer . MutableDocument < AetheriaRuntimeStarbridgeScenarioDocument > ( AetheriaRuntimeVerseRecordKeys . StarbridgeScenarioLatest )
2026-06-28 06:40:28 +01:00
. ReplaceAsync ( scenario )
. ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await writer . MutableDocument < AetheriaRuntimeStarbridgeSessionDocument > ( AetheriaRuntimeVerseRecordKeys . StarbridgeSessionLatest )
2026-06-28 06:40:28 +01:00
. ReplaceAsync ( session )
. ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
await writer . FlushAsync ( ) . ConfigureAwait ( false ) ;
}
using var client = await AetheriaClient
2026-07-05 20:57:22 +01:00
. OpenAsync ( statePath , "pilot-client" , sessionId : "state-documents-session" , pullOnOpen : true )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) ;
2026-06-30 19:14:49 +01:00
var state = client . State ;
2026-07-05 19:56:18 +01:00
var viewportBounds = new AetheriaRuntimeViewportBounds { MinX = - 20 , MinY = - 20 , MaxX = 150 , MaxY = 20 } ;
2026-06-30 19:14:49 +01:00
var viewport = await state
2026-07-05 19:56:18 +01:00
. GameViewport ( viewportBounds )
2026-06-28 06:04:54 +01:00
. LatestAsync ( )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
Require ( viewport . Objects . Any ( item = > item . DisplayName = = "Document Raven" ) , "managed map document should include controlled object" ) ;
Require ( viewport . Objects . Any ( item = > item . DisplayName = = "Document Raider" ) , "managed map document should include visible hostile object" ) ;
2026-06-30 19:14:49 +01:00
var objectsViewport = await state
. ObjectsViewport ( viewportBounds )
2026-06-28 06:04:54 +01:00
. LatestAsync ( )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . ObjectsViewport , objectsViewport . Schema , "managed objects viewport document schema" ) ;
Require ( objectsViewport . Objects . Any ( item = > item . DisplayName = = "Document Raven" ) , "managed objects viewport document should include controlled object" ) ;
Require ( objectsViewport . Objects . Any ( item = > item . DisplayName = = "Document Raider" ) , "managed objects viewport document should include visible hostile object" ) ;
2026-06-30 19:14:49 +01:00
var gravityViewport = await state
. GravityViewport ( viewportBounds )
2026-06-28 06:04:54 +01:00
. LatestAsync ( )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . GravityViewport , gravityViewport . Schema , "managed gravity viewport document schema" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var currentZone = await state . CurrentZone . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . CurrentZone , currentZone . Schema , "managed current-zone document schema" ) ;
RequireEqual ( "Client State Documents Zone" , currentZone . ZoneName , "managed current-zone document name" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var sectorMap = await state . SectorMap . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . SectorMap , sectorMap . Schema , "managed sector-map document schema" ) ;
Require ( sectorMap . Zones . Any ( zone = > zone . ZoneIndex = = currentZone . ZoneIndex & & zone . Current ) , "managed sector-map document should include current zone marker" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var selected = await state . SelectedObject ( 0 ) . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . SelectedObject , selected . Schema , "managed selected-object document schema" ) ;
Require ( selected . Selected ? . DisplayName = = "Document Raven" , "managed selected-object document should resolve entity" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var inventory = await state . Inventory ( 0 ) . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . Inventory , inventory . Schema , "managed inventory document schema" ) ;
Require ( inventory . Cargo . Any ( item = > item . ItemKey = = "document-cargo" ) , "managed inventory document should expose cargo" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var starbridgeSummary = await state . StarbridgeSummary . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( "Document Starbridge" , starbridgeSummary . ScenarioName , "managed starbridge summary document should project scenario name" ) ;
RequireEqual ( "pre-wave" , starbridgeSummary . Phase , "managed starbridge summary document should project session phase" ) ;
Require ( starbridgeSummary . StationStock . Any ( item = > item . ItemKey = = "document-cargo" ) , "managed starbridge summary document should expose station stock" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var healthDocument = await state . Health . LatestAsync ( ) . ConfigureAwait ( false ) ;
Require ( healthDocument ? . Status = = "healthy" , "managed daemon health document should read local health" ) ;
2026-06-25 18:09:33 +01:00
2026-06-30 19:14:49 +01:00
var authorityPolicy = await state . AuthorityPolicy . LatestAsync ( ) . ConfigureAwait ( false ) ;
RequireEqual ( "aetheria.trusted-coop.v1" , authorityPolicy ? . PolicyId , "managed authority policy document id" ) ;
2026-06-25 18:09:33 +01:00
var command = client . SetMoveVector ( 1 , 0 , 0.5 ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( AetheriaRuntimeDaemonCommandKinds . SetMoveVector , command . Kind , "managed client command kind" ) ;
2026-07-05 20:57:22 +01:00
RequireEqual ( "pilot-client" , command . ClientId , "managed client command client id" ) ;
2026-06-28 06:04:54 +01:00
RequireEqual ( frame . FrameId , command . ObservedFrameId , "managed client command observed frame id" ) ;
2026-06-25 18:09:33 +01:00
using var reader = await AetheriaRuntimeVerseClient
2026-06-28 06:04:54 +01:00
. OpenAsync ( statePath , "state-documents-reader" , startServer : false , pullOnOpen : true )
2026-06-25 18:09:33 +01:00
. ConfigureAwait ( false ) ;
var stored = await reader . Database
. GetAsync < AetheriaRuntimeDaemonCommandDocument > (
AetheriaRuntimeVerseRecordKeys . DaemonCommand ( command . CommandId ) )
. ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
Require ( stored ! = null , "managed client command should be stored as typed daemon command document" ) ;
RequireEqual ( AetheriaRuntimeClaimKinds . Movement , stored ! . ClaimKind , "managed client command claim kind" ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task DaemonOncePublishesStarbridgeSessionFactsAsync ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var statePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-starbridge-daemon-{smokeId}.cc" ) ;
2026-07-05 20:33:45 +01:00
var clientCultMeshPort = GetFreeUdpPort ( ) ;
2026-06-25 18:09:33 +01:00
const string runtimeId = "starbridge-daemon-smoke" ;
2026-07-05 20:33:45 +01:00
await RunDaemonOnceAsync ( statePath , runtimeId , clientCultMeshPort ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
using var client = await AetheriaClient
. OpenAsync ( statePath , "starbridge-smoke-client" , sessionId : "authority-smoke" , pullOnOpen : true )
. ConfigureAwait ( false ) ;
2026-06-30 19:14:49 +01:00
var summary = await client . State . StarbridgeSummary . LatestAsync ( ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
RequireEqual ( AetheriaRuntimeDaemonSchemas . StarbridgeSessionSummary , summary . Schema , "daemon starbridge summary schema" ) ;
RequireEqual ( "starbridge.frontier-fabricator" , summary . ScenarioId , "daemon starbridge scenario id" ) ;
RequireEqual ( "Frontier Fabricator Defense" , summary . ScenarioName , "daemon starbridge scenario name" ) ;
RequireEqual ( "authority-smoke" , summary . SessionId , "daemon starbridge session id" ) ;
RequireEqual ( "pre-wave" , summary . Phase , "daemon starbridge phase" ) ;
RequireEqual ( "Anchor Station" , summary . BaseStatus . DisplayName , "daemon starbridge base name" ) ;
Require ( summary . StationStock . Any ( item = > item . ItemKey = = "repair-parts" ) , "daemon starbridge summary should expose station stock" ) ;
Require ( summary . WaveForecast . Any ( wave = > wave . DisplayName = = "Scout Probe" ) , "daemon starbridge summary should expose wave forecast" ) ;
2026-07-05 20:57:22 +01:00
Require ( summary . RuntimeRoles . Any ( role = > role . RuntimeId = = "commander-client" & & role . Role = = "commander" ) , "daemon starbridge summary should expose commander role" ) ;
Require ( summary . RuntimeRoles . Any ( role = > role . RuntimeId = = "pilot-client" & & role . Role = = "pilot" ) , "daemon starbridge summary should expose pilot role" ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task SamePolicyDocumentCanBeLoadedByTwoNodesAsync ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var ravenPath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-raven-{smokeId}.cc" ) ;
2026-07-05 20:57:22 +01:00
var commanderPath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-commander-{smokeId}.cc" ) ;
2026-06-25 18:09:33 +01:00
var policy = CoopPolicy ( ) ;
await using var ravenNode = await AetheriaStateNode . OpenAsync (
ravenPath ,
2026-07-05 20:57:22 +01:00
runtimeId : "pilot-local" ,
2026-06-25 18:09:33 +01:00
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
await using var commanderNode = await AetheriaStateNode . OpenAsync (
commanderPath ,
runtimeId : "commander-local" ,
2026-06-25 18:09:33 +01:00
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await ravenNode . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy )
2026-06-28 06:40:28 +01:00
. ReplaceAsync ( policy )
. ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
await commanderNode . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy )
2026-06-28 06:40:28 +01:00
. ReplaceAsync ( policy )
. ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
2026-06-29 01:04:09 +01:00
var ravenPolicy = await ravenNode . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy ) . ReadAsync ( ) . ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
var commanderPolicy = await commanderNode . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy ) . ReadAsync ( ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
Require ( ravenPolicy ! = null , "raven node should load authority policy" ) ;
2026-07-05 20:57:22 +01:00
Require ( commanderPolicy ! = null , "commander node should load authority policy" ) ;
2026-06-25 18:09:33 +01:00
RequireEqual ( policy . PolicyId , ravenPolicy ! . PolicyId , "raven loaded policy id" ) ;
2026-07-05 20:57:22 +01:00
RequireEqual ( policy . PolicyId , commanderPolicy ! . PolicyId , "commander loaded policy id" ) ;
2026-06-25 18:09:33 +01:00
RequireEqual ( policy . Rules . Length , ravenPolicy . Rules . Length , "raven loaded rule count" ) ;
2026-07-05 20:57:22 +01:00
RequireEqual ( policy . Rules . Length , commanderPolicy . Rules . Length , "commander loaded rule count" ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task TwoDaemonProcessesApplyDelegatedPolicyAsync ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var policy = CoopPolicy ( ) ;
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
2026-07-05 20:57:22 +01:00
var ravenByRaven = MovementCommand ( "pilot-client" , ravenKey , directionX : 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByRaven = MovementCommand ( "pilot-client" , hostileKey , directionX : 0 , directionY : 1 , magnitude : 1 ) ;
2026-06-25 18:09:33 +01:00
var ravenStatePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-raven-daemon-{smokeId}.cc" ) ;
await SeedDaemonStateAsync (
ravenStatePath ,
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
policy ,
[ravenByRaven, hostileByRaven] ) . ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
await RunDaemonOnceAsync ( ravenStatePath , "pilot-local" , clientCultMeshPort : 41076 ) . ConfigureAwait ( false ) ;
var ravenFrame = await ReadPublishedFrameAsync ( ravenStatePath , "pilot-local" ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
Require ( ravenFrame . AppliedCommandIds . Contains ( ravenByRaven . CommandId ) , "raven daemon should apply Raven-authored Raven movement" ) ;
Require ( ravenFrame . RejectedCommandIds . Contains ( hostileByRaven . CommandId ) , "raven daemon should reject Raven-authored hostile movement" ) ;
Require ( ravenFrame . AccountedCommandIds . Contains ( ravenByRaven . CommandId ) , "raven daemon should account applied command" ) ;
Require ( ravenFrame . AccountedCommandIds . Contains ( hostileByRaven . CommandId ) , "raven daemon should account rejected command" ) ;
2026-07-05 20:57:22 +01:00
var ravenByCommander = MovementCommand ( "commander-client" , ravenKey , directionX : - 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByCommander = MovementCommand ( "commander-client" , hostileKey , directionX : 0 , directionY : - 1 , magnitude : 1 ) ;
var commanderStatePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-commander-daemon-{smokeId}.cc" ) ;
2026-06-25 18:09:33 +01:00
await SeedDaemonStateAsync (
2026-07-05 20:57:22 +01:00
commanderStatePath ,
"commander-local" ,
2026-06-25 18:09:33 +01:00
policy ,
2026-07-05 20:57:22 +01:00
[ravenByCommander, hostileByCommander] ) . ConfigureAwait ( false ) ;
await RunDaemonOnceAsync ( commanderStatePath , "commander-local" , clientCultMeshPort : 41077 ) . ConfigureAwait ( false ) ;
var commanderFrame = await ReadPublishedFrameAsync ( commanderStatePath , "commander-local" ) . ConfigureAwait ( false ) ;
Require ( commanderFrame . RejectedCommandIds . Contains ( ravenByCommander . CommandId ) , "commander daemon should reject Commander-authored Raven movement" ) ;
Require ( commanderFrame . AppliedCommandIds . Contains ( hostileByCommander . CommandId ) , "commander daemon should apply Commander-authored hostile movement" ) ;
Require ( commanderFrame . AccountedCommandIds . Contains ( ravenByCommander . CommandId ) , "commander daemon should account rejected command" ) ;
Require ( commanderFrame . AccountedCommandIds . Contains ( hostileByCommander . CommandId ) , "commander daemon should account applied command" ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task ConcurrentDaemonsPublishRemoteFramesToLocalReplicasAsync ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var policy = CoopPolicy ( ) ;
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
var ravenStatePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-raven-live-{smokeId}.cc" ) ;
2026-07-05 20:57:22 +01:00
var commanderStatePath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-commander-live-{smokeId}.cc" ) ;
2026-06-25 18:09:33 +01:00
var ravenReplicaPath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-raven-replica-{smokeId}.cc" ) ;
2026-07-05 20:57:22 +01:00
var commanderReplicaPath = Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-commander-replica-{smokeId}.cc" ) ;
2026-06-25 18:09:33 +01:00
var ravenPort = GetFreeUdpPort ( ) ;
2026-07-05 20:57:22 +01:00
var commanderPort = GetFreeUdpPort ( ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
var ravenByRaven = MovementCommand ( "pilot-client" , ravenKey , directionX : 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByRaven = MovementCommand ( "pilot-client" , hostileKey , directionX : 0 , directionY : 1 , magnitude : 1 ) ;
2026-06-25 18:09:33 +01:00
await SeedDaemonStateAsync (
ravenStatePath ,
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
policy ,
[ravenByRaven, hostileByRaven] ) . ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
var ravenByCommander = MovementCommand ( "commander-client" , ravenKey , directionX : - 1 , directionY : 0 , magnitude : 1 ) ;
var hostileByCommander = MovementCommand ( "commander-client" , hostileKey , directionX : 0 , directionY : - 1 , magnitude : 1 ) ;
2026-06-25 18:09:33 +01:00
await SeedDaemonStateAsync (
2026-07-05 20:57:22 +01:00
commanderStatePath ,
"commander-local" ,
2026-06-25 18:09:33 +01:00
policy ,
2026-07-05 20:57:22 +01:00
[ravenByCommander, hostileByCommander] ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
using var ravenDaemon = StartDaemonProcess (
ravenStatePath ,
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
ravenPort ,
once : false ,
2026-07-05 20:57:22 +01:00
peerEndpoints : [ $"rudp://127.0.0.1:{commanderPort}" ] ) ;
using var commanderDaemon = StartDaemonProcess (
commanderStatePath ,
"commander-local" ,
commanderPort ,
2026-06-25 18:09:33 +01:00
once : false ,
peerEndpoints : [ $"rudp://127.0.0.1:{ravenPort}" ] ) ;
try
{
var ravenRemoteFrame = await WaitForReplicaFrameAsync (
$"rudp://127.0.0.1:{ravenPort}" ,
2026-07-05 20:57:22 +01:00
commanderReplicaPath ,
"commander-observes-raven" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
frame = >
2026-07-05 20:57:22 +01:00
string . Equals ( frame . DaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
frame . CumulativeAppliedCommandIds . Contains ( ravenByRaven . CommandId ) & &
frame . CumulativeRejectedCommandIds . Contains ( hostileByRaven . CommandId ) ,
"Raven frame with Raven movement applied and hostile movement rejected" ) . ConfigureAwait ( false ) ;
2026-07-05 20:57:22 +01:00
var commanderRemoteFrame = await WaitForReplicaFrameAsync (
$"rudp://127.0.0.1:{commanderPort}" ,
2026-06-25 18:09:33 +01:00
ravenReplicaPath ,
2026-07-05 20:57:22 +01:00
"raven-observes-commander" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
frame = >
2026-07-05 20:57:22 +01:00
string . Equals ( frame . DaemonId , "commander-local" , StringComparison . Ordinal ) & &
frame . CumulativeAppliedCommandIds . Contains ( hostileByCommander . CommandId ) & &
frame . CumulativeRejectedCommandIds . Contains ( ravenByCommander . CommandId ) ,
"Commander frame with hostile movement applied and Raven movement rejected" ) . ConfigureAwait ( false ) ;
RequireEqual ( "pilot-local" , ravenRemoteFrame . DaemonId , "Commander local replica should observe Raven daemon id" ) ;
Require ( ravenRemoteFrame . CumulativeAppliedCommandIds . Contains ( ravenByRaven . CommandId ) , "Commander local replica should observe Raven-applied Raven command" ) ;
Require ( ravenRemoteFrame . CumulativeRejectedCommandIds . Contains ( hostileByRaven . CommandId ) , "Commander local replica should observe Raven rejection receipt" ) ;
var commanderObservedRavenFacts = await WaitForReplicaFactsAsync (
2026-06-25 18:09:33 +01:00
$"rudp://127.0.0.1:{ravenPort}" ,
2026-07-05 20:57:22 +01:00
commanderReplicaPath ,
"commander-observes-raven-facts" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
facts = >
facts . Any ( fact = >
2026-07-05 20:57:22 +01:00
string . Equals ( fact . SourceDaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . CommandId , ravenByRaven . CommandId , StringComparison . Ordinal ) & &
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) & &
facts . Any ( fact = >
2026-07-05 20:57:22 +01:00
string . Equals ( fact . SourceDaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . CommandId , hostileByRaven . CommandId , StringComparison . Ordinal ) & &
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Rejected , StringComparison . Ordinal ) ) ,
"Raven applied and rejected committed facts" ) . ConfigureAwait ( false ) ;
Require (
2026-07-05 20:57:22 +01:00
commanderObservedRavenFacts . Any ( fact = >
string . Equals ( fact . SourceDaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . CommandId , ravenByRaven . CommandId , StringComparison . Ordinal ) & &
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) ,
2026-07-05 20:57:22 +01:00
"Commander local replica should observe Raven committed movement fact" ) ;
2026-06-25 18:09:33 +01:00
Require (
2026-07-05 20:57:22 +01:00
commanderObservedRavenFacts . Any ( fact = >
string . Equals ( fact . SourceDaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . CommandId , hostileByRaven . CommandId , StringComparison . Ordinal ) & &
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Rejected , StringComparison . Ordinal ) ) ,
2026-07-05 20:57:22 +01:00
"Commander local replica should observe Raven policy rejection fact" ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
RequireEqual ( "commander-local" , commanderRemoteFrame . DaemonId , "Raven local replica should observe Commander daemon id" ) ;
Require ( commanderRemoteFrame . CumulativeAppliedCommandIds . Contains ( hostileByCommander . CommandId ) , "Raven local replica should observe Commander-applied hostile command" ) ;
Require ( commanderRemoteFrame . CumulativeRejectedCommandIds . Contains ( ravenByCommander . CommandId ) , "Raven local replica should observe Commander rejection receipt" ) ;
var ravenObservedCommanderFacts = await WaitForReplicaFactsAsync (
$"rudp://127.0.0.1:{commanderPort}" ,
2026-06-25 18:09:33 +01:00
ravenReplicaPath ,
2026-07-05 20:57:22 +01:00
"raven-observes-commander-facts" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
facts = >
facts . Any ( fact = >
2026-07-05 20:57:22 +01:00
string . Equals ( fact . SourceDaemonId , "commander-local" , StringComparison . Ordinal ) & &
string . Equals ( fact . CommandId , hostileByCommander . CommandId , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) & &
facts . Any ( fact = >
2026-07-05 20:57:22 +01:00
string . Equals ( fact . SourceDaemonId , "commander-local" , StringComparison . Ordinal ) & &
string . Equals ( fact . CommandId , ravenByCommander . CommandId , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Rejected , StringComparison . Ordinal ) ) ,
2026-07-05 20:57:22 +01:00
"Commander applied and rejected committed facts" ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
Require (
2026-07-05 20:57:22 +01:00
ravenObservedCommanderFacts . Any ( fact = >
string . Equals ( fact . SourceDaemonId , "commander-local" , StringComparison . Ordinal ) & &
string . Equals ( fact . CommandId , hostileByCommander . CommandId , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) ,
2026-07-05 20:57:22 +01:00
"Raven local replica should observe Commander committed hostile fact" ) ;
2026-06-25 18:09:33 +01:00
Require (
2026-07-05 20:57:22 +01:00
ravenObservedCommanderFacts . Any ( fact = >
string . Equals ( fact . SourceDaemonId , "commander-local" , StringComparison . Ordinal ) & &
string . Equals ( fact . CommandId , ravenByCommander . CommandId , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Rejected , StringComparison . Ordinal ) ) ,
2026-07-05 20:57:22 +01:00
"Raven local replica should observe Commander policy rejection fact" ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
var ravenMovementFactId = commanderObservedRavenFacts . First ( fact = >
string . Equals ( fact . SourceDaemonId , "pilot-local" , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . CommandId , ravenByRaven . CommandId , StringComparison . Ordinal ) & &
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) . FactId ;
2026-07-05 20:57:22 +01:00
var commanderHostileFactId = ravenObservedCommanderFacts . First ( fact = >
string . Equals ( fact . SourceDaemonId , "commander-local" , StringComparison . Ordinal ) & &
string . Equals ( fact . CommandId , hostileByCommander . CommandId , StringComparison . Ordinal ) & &
2026-06-25 18:09:33 +01:00
string . Equals ( fact . Outcome , AetheriaRuntimeCommandFactOutcomes . Applied , StringComparison . Ordinal ) ) . FactId ;
2026-07-05 20:57:22 +01:00
var commanderConvergedFrame = await WaitForLocalFrameAsync (
commanderStatePath ,
"commander-local-converges-raven" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
frame = >
frame . CumulativeImportedFactIds . Contains ( ravenMovementFactId ) & &
Entity ( frame . Run , ravenKey ) . PositionX > 0 ,
2026-07-05 20:57:22 +01:00
"Commander live daemon imports Raven movement fact and moves Raven locally" ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
Require (
2026-07-05 20:57:22 +01:00
commanderConvergedFrame . CumulativeImportedFactIds . Any ( ) ,
"Commander live daemon should record imported remote fact ids" ) ;
2026-06-25 18:09:33 +01:00
var ravenConvergedFrame = await WaitForLocalFrameAsync (
ravenStatePath ,
2026-07-05 20:57:22 +01:00
"pilot-local-converges-commander" ,
[ravenDaemon, commanderDaemon] ,
2026-06-25 18:09:33 +01:00
frame = >
2026-07-05 20:57:22 +01:00
frame . CumulativeImportedFactIds . Contains ( commanderHostileFactId ) & &
2026-06-25 18:09:33 +01:00
Entity ( frame . Run , hostileKey ) . PositionZ < 0 ,
2026-07-05 20:57:22 +01:00
"Raven live daemon imports Commander hostile movement fact and moves hostile locally" ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
Require (
ravenConvergedFrame . CumulativeImportedFactIds . Any ( ) ,
"Raven live daemon should record imported remote fact ids" ) ;
}
finally
{
StopProcess ( ravenDaemon ) ;
2026-07-05 20:57:22 +01:00
StopProcess ( commanderDaemon ) ;
2026-06-25 18:09:33 +01:00
}
}
private static async Task < IReadOnlyList < AetheriaRuntimeCommittedCommandFactDocument > > ReadFactsAsync (
string statePath ,
string runtimeId )
{
await using var node = await AetheriaStateNode . OpenAsync (
statePath ,
runtimeId ,
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-06-29 03:31:47 +01:00
return node . Documents < AetheriaRuntimeCommittedCommandFactDocument > ( )
. OrderBy ( fact = > fact . CommittedAtUtc ? ? "" , StringComparer . Ordinal )
. ThenBy ( fact = > fact . FactId ? ? "" , StringComparer . Ordinal )
. ToArray ( ) ;
2026-06-25 18:09:33 +01:00
}
private static void TrustedCommittedFactsConvergeLocalRuns ( )
{
var smokeId = Guid . NewGuid ( ) . ToString ( "N" ) ;
var policy = CoopPolicyWithMetadata ( ) ;
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
2026-07-05 20:57:22 +01:00
var ravenMovement = MovementCommand ( "pilot-client" , ravenKey , directionX : 1 , directionY : 0 , magnitude : 1 ) ;
2026-06-25 18:09:33 +01:00
var ravenSourceFrame = TickWithPolicy (
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
InitialCoopFactRun ( ) ,
policy ,
[ravenMovement] ) ;
var ravenMovementFact = AetheriaRuntimeCommittedCommandFactDocument . FromAppliedCommand (
ravenSourceFrame ,
ravenMovement ,
policy . VerseId ) ;
2026-07-05 20:57:22 +01:00
var commanderImport = AetheriaRuntimeCommittedFactImporter . ImportIntoFrame (
Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-facts-commander-{smokeId}.cc" ) ,
2026-06-25 18:09:33 +01:00
AetheriaRuntimeDaemonFrameDocument . Create (
InitialCoopFactRun ( ) ,
2026-07-05 20:57:22 +01:00
"commander-local" ,
2026-06-25 18:09:33 +01:00
"authority-smoke" ,
frameId : 0 ,
simulationTimeSeconds : 0 ,
fixedDeltaSeconds : 0.02 ) ,
[ravenMovementFact] ,
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "commander-local" ,
daemonId : "commander-local" ,
2026-06-25 18:09:33 +01:00
sessionId : "authority-smoke" ,
verseId : policy . VerseId ) ;
2026-07-05 20:57:22 +01:00
Require ( commanderImport . AcceptedFactIds . Contains ( ravenMovementFact . FactId ) , "Commander should accept Raven's committed Raven movement fact" ) ;
Require ( ! commanderImport . RejectedFactIds . Contains ( ravenMovementFact . FactId ) , "Commander should not reject Raven's authorized movement fact" ) ;
Require ( Entity ( commanderImport . Run , ravenKey ) . PositionX > 0 , "Commander local run should converge Raven movement into local state" ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
var hostileRename = MetadataNameCommand ( "commander-client" , hostileKey , "Commander Marked Hostile" ) ;
var commanderSourceFrame = TickWithPolicy (
"commander-local" ,
2026-06-25 18:09:33 +01:00
InitialCoopFactRun ( ) ,
policy ,
[hostileRename] ) ;
var hostileRenameFact = AetheriaRuntimeCommittedCommandFactDocument . FromAppliedCommand (
2026-07-05 20:57:22 +01:00
commanderSourceFrame ,
2026-06-25 18:09:33 +01:00
hostileRename ,
policy . VerseId ) ;
var ravenImport = AetheriaRuntimeCommittedFactImporter . ImportIntoFrame (
Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-facts-raven-{smokeId}.cc" ) ,
AetheriaRuntimeDaemonFrameDocument . Create (
InitialCoopFactRun ( ) ,
2026-07-05 20:57:22 +01:00
"pilot-local" ,
2026-06-25 18:09:33 +01:00
"authority-smoke" ,
frameId : 0 ,
simulationTimeSeconds : 0 ,
fixedDeltaSeconds : 0.02 ) ,
[hostileRenameFact] ,
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "pilot-local" ,
daemonId : "pilot-local" ,
2026-06-25 18:09:33 +01:00
sessionId : "authority-smoke" ,
verseId : policy . VerseId ) ;
2026-07-05 20:57:22 +01:00
Require ( ravenImport . AcceptedFactIds . Contains ( hostileRenameFact . FactId ) , "Raven should accept Commander's hostile metadata fact" ) ;
RequireEqual ( "Commander Marked Hostile" , Entity ( ravenImport . Run , hostileKey ) . Name , "Raven local run should converge Commander hostile metadata into local state" ) ;
2026-06-25 18:09:33 +01:00
2026-07-05 20:57:22 +01:00
var unauthorizedRename = MetadataNameCommand ( "pilot-client" , hostileKey , "Raven Should Not Own This" ) ;
2026-06-25 18:09:33 +01:00
var unauthorizedFact = AetheriaRuntimeCommittedCommandFactDocument . FromAppliedCommand (
ravenSourceFrame ,
unauthorizedRename ,
policy . VerseId ) ;
var rejectedImport = AetheriaRuntimeCommittedFactImporter . ImportIntoFrame (
Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-facts-rejected-{smokeId}.cc" ) ,
AetheriaRuntimeDaemonFrameDocument . Create (
InitialCoopFactRun ( ) ,
2026-07-05 20:57:22 +01:00
"commander-local" ,
2026-06-25 18:09:33 +01:00
"authority-smoke" ,
frameId : 0 ,
simulationTimeSeconds : 0 ,
fixedDeltaSeconds : 0.02 ) ,
[unauthorizedFact] ,
policy ,
leases : null ,
2026-07-05 20:57:22 +01:00
localRuntimeId : "commander-local" ,
daemonId : "commander-local" ,
2026-06-25 18:09:33 +01:00
sessionId : "authority-smoke" ,
verseId : policy . VerseId ) ;
2026-07-05 20:57:22 +01:00
Require ( rejectedImport . RejectedFactIds . Contains ( unauthorizedFact . FactId ) , "Commander should reject Raven-authored hostile metadata fact" ) ;
RequireEqual ( "Commander Hostile" , Entity ( rejectedImport . Run , hostileKey ) . Name , "Rejected facts should not mutate local state" ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task SeedDaemonStateAsync (
string statePath ,
string runtimeId ,
AetheriaRuntimeVerseAuthorityPolicyDocument policy ,
IReadOnlyList < AetheriaRuntimeDaemonCommandDocument > commands )
{
await using var node = await AetheriaStateNode . OpenAsync (
statePath ,
runtimeId ,
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await node . MutableDocument < AetheriaRuntimeVerseAuthorityPolicyDocument > ( AetheriaRuntimeVerseRecordKeys . VerseAuthorityPolicy )
2026-06-28 06:40:28 +01:00
. ReplaceAsync ( policy )
. ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
foreach ( var command in commands )
await node . SubmitDaemonCommandAsync ( command ) . ConfigureAwait ( false ) ;
await node . FlushAsync ( ) . ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
await node . MutableDocument < AetheriaRuntimeDaemonFrameDocument > ( AetheriaRuntimeVerseRecordKeys . DaemonFrameLatest )
2026-06-28 07:28:45 +01:00
. ReplaceAsync ( AetheriaRuntimeDaemonFrameDocument . Create (
2026-06-25 18:09:33 +01:00
InitialCoopRun ( ) ,
runtimeId ,
"authority-smoke" ,
frameId : - 1 ,
simulationTimeSeconds : 0 ,
2026-06-28 07:28:45 +01:00
fixedDeltaSeconds : 0.02 ) )
. ConfigureAwait ( false ) ;
await node . FlushAsync ( ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
}
private static async Task RunDaemonOnceAsync (
string statePath ,
string runtimeId ,
2026-07-05 20:33:45 +01:00
int clientCultMeshPort )
2026-06-25 18:09:33 +01:00
{
2026-07-05 20:33:45 +01:00
using var process = StartDaemonProcess ( statePath , runtimeId , clientCultMeshPort , once : true ) ;
2026-06-25 18:09:33 +01:00
await WaitForProcessSuccessAsync ( process , runtimeId , TimeSpan . FromSeconds ( 90 ) ) . ConfigureAwait ( false ) ;
}
private static Process StartDaemonProcess (
string statePath ,
string runtimeId ,
2026-07-05 20:33:45 +01:00
int clientCultMeshPort ,
2026-06-25 18:09:33 +01:00
bool once )
{
2026-07-05 20:33:45 +01:00
return StartDaemonProcess ( statePath , runtimeId , clientCultMeshPort , once , peerEndpoints : null ) ;
2026-06-25 18:09:33 +01:00
}
private static Process StartDaemonProcess (
string statePath ,
string runtimeId ,
2026-07-05 20:33:45 +01:00
int clientCultMeshPort ,
2026-06-25 18:09:33 +01:00
bool once ,
IReadOnlyList < string > ? peerEndpoints )
{
var repoRoot = Directory . GetCurrentDirectory ( ) ;
var executablePath = Path . Combine (
repoRoot ,
"Aetheria.State.Daemon" ,
"bin" ,
"Debug" ,
"net10.0" ,
"Aetheria.State.Daemon.exe" ) ;
var dllPath = Path . Combine (
repoRoot ,
"Aetheria.State.Daemon" ,
"bin" ,
"Debug" ,
"net10.0" ,
"Aetheria.State.Daemon.dll" ) ;
var projectPath = Path . Combine (
repoRoot ,
"Aetheria.State.Daemon" ,
"Aetheria.State.Daemon.csproj" ) ;
var executableExists = File . Exists ( executablePath ) ;
var dllExists = File . Exists ( dllPath ) ;
var commandPrefix = executableExists
? Quote ( executablePath )
: dllExists
? "dotnet " + Quote ( dllPath )
: "dotnet run --project " + Quote ( projectPath ) + " --" ;
var arguments = string . Join (
" " ,
"--state" ,
Quote ( statePath ) ,
"--daemon-id" ,
runtimeId ,
"--verse-id" ,
"aetheria.coop-smoke" ,
"--session-id" ,
"authority-smoke" ,
2026-07-05 20:33:45 +01:00
"--client-cultmesh-port" ,
clientCultMeshPort . ToString ( ) ,
2026-06-25 18:09:33 +01:00
"--api-publication-interval-ms" ,
"50" ,
string . Join ( " " , ( peerEndpoints ? ? Array . Empty < string > ( ) )
. Select ( endpoint = > "--peer-cultmesh-endpoint " + Quote ( endpoint ) ) ) ,
once ? "--once" : "" ) ;
var startInfo = executableExists
? new ProcessStartInfo ( executablePath , arguments )
: dllExists
? new ProcessStartInfo ( "dotnet" , Quote ( dllPath ) + " " + arguments )
: new ProcessStartInfo ( "dotnet" , "run --project " + Quote ( projectPath ) + " -- " + arguments ) ;
startInfo . WorkingDirectory = repoRoot ;
startInfo . RedirectStandardOutput = true ;
startInfo . RedirectStandardError = true ;
startInfo . UseShellExecute = false ;
startInfo . CreateNoWindow = true ;
if ( string . IsNullOrWhiteSpace ( commandPrefix ) )
{
throw new InvalidOperationException ( "Cannot resolve daemon command." ) ;
}
var process = Process . Start ( startInfo ) ? ?
throw new InvalidOperationException ( "Failed to start Aetheria daemon child process." ) ;
CaptureProcessOutput ( process , runtimeId ) ;
return process ;
}
private static async Task WaitForProcessSuccessAsync (
Process process ,
string runtimeId ,
TimeSpan timeout )
{
var waitTask = process . WaitForExitAsync ( ) ;
var completed = await Task . WhenAny ( waitTask , Task . Delay ( timeout ) )
. ConfigureAwait ( false ) ;
if ( completed ! = waitTask )
{
try
{
process . Kill ( entireProcessTree : true ) ;
}
catch
{
}
throw new TimeoutException ( $"Aetheria daemon child process timed out for {runtimeId}." ) ;
}
if ( process . ExitCode ! = 0 )
{
throw new InvalidOperationException (
$"Aetheria daemon child process failed for {runtimeId} with exit code {process.ExitCode}.\n{GetProcessOutputTail(process)}" ) ;
}
}
private static void CaptureProcessOutput ( Process process , string runtimeId )
{
lock ( ProcessOutputLock )
ProcessOutput [ process . Id ] = new List < string > ( ) ;
process . OutputDataReceived + = ( _ , eventArgs ) = >
{
if ( eventArgs . Data ! = null )
AppendProcessOutput ( process . Id , $"{runtimeId} stdout: {eventArgs.Data}" ) ;
} ;
process . ErrorDataReceived + = ( _ , eventArgs ) = >
{
if ( eventArgs . Data ! = null )
AppendProcessOutput ( process . Id , $"{runtimeId} stderr: {eventArgs.Data}" ) ;
} ;
process . BeginOutputReadLine ( ) ;
process . BeginErrorReadLine ( ) ;
}
private static void AppendProcessOutput ( int processId , string line )
{
lock ( ProcessOutputLock )
{
if ( ! ProcessOutput . TryGetValue ( processId , out var lines ) )
{
lines = new List < string > ( ) ;
ProcessOutput [ processId ] = lines ;
}
lines . Add ( line ) ;
if ( lines . Count > 80 )
lines . RemoveRange ( 0 , lines . Count - 80 ) ;
}
}
private static string GetProcessOutputTail ( Process process )
{
lock ( ProcessOutputLock )
{
if ( ! ProcessOutput . TryGetValue ( process . Id , out var lines ) | | lines . Count = = 0 )
return "No child output captured." ;
var builder = new StringBuilder ( ) ;
foreach ( var line in lines )
builder . AppendLine ( line ) ;
return builder . ToString ( ) ;
}
}
private static async Task < AetheriaRuntimeDaemonFrameDocument > WaitForReplicaFrameAsync (
string endpoint ,
string replicaPath ,
string runtimeId ,
IReadOnlyList < Process > childProcesses ,
Func < AetheriaRuntimeDaemonFrameDocument , bool > isReady ,
string expectedFrame )
{
var deadline = DateTimeOffset . UtcNow . AddSeconds ( 45 ) ;
Exception ? lastError = null ;
AetheriaRuntimeDaemonFrameDocument ? lastFrame = null ;
while ( DateTimeOffset . UtcNow < deadline )
{
try
{
await AetheriaVerseReplica . SyncScopedSnapshotAsync (
replicaPath ,
endpoint ,
runtimeId ,
schemaIds :
[
AetheriaRuntimeDaemonSchemas . Frame ,
AetheriaRuntimeDaemonSchemas . CommittedCommandFact
] ) . ConfigureAwait ( false ) ;
await using var node = await AetheriaStateNode . OpenAsync (
replicaPath ,
runtimeId ,
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
var frame = await node . MutableDocument < AetheriaRuntimeDaemonFrameDocument > ( AetheriaRuntimeVerseRecordKeys . DaemonFrameLatest ) . ReadAsync ( ) . ConfigureAwait ( false ) ;
2026-06-25 18:09:33 +01:00
if ( frame ! = null )
{
lastFrame = frame ;
}
if ( frame ! = null & & frame . FrameId > = 0 & & isReady ( frame ) )
return frame ;
}
catch ( Exception ex )
{
lastError = ex ;
}
await Task . Delay ( 250 ) . ConfigureAwait ( false ) ;
}
throw new TimeoutException (
$"Timed out waiting for replica frame from {endpoint}. Expected {expectedFrame}." +
$" Requested schemas=[{AetheriaRuntimeDaemonSchemas.Frame},{AetheriaRuntimeDaemonSchemas.CommittedCommandFact}]." +
( lastFrame = = null ? "" : $" Last frame: daemon={lastFrame.DaemonId}, frame={lastFrame.FrameId}, applied=[{string.Join(" , ", lastFrame.AppliedCommandIds)}], rejected=[{string.Join(" , ", lastFrame.RejectedCommandIds)}], cumulativeApplied=[{string.Join(" , ", lastFrame.CumulativeAppliedCommandIds)}], cumulativeRejected=[{string.Join(" , ", lastFrame.CumulativeRejectedCommandIds)}]." ) +
ProcessDiagnostics ( childProcesses ) +
( lastError = = null ? "" : $" Last error: {lastError.GetType().Name}: {lastError.Message}" ) ) ;
}
private static async Task < IReadOnlyList < AetheriaRuntimeCommittedCommandFactDocument > > WaitForReplicaFactsAsync (
string endpoint ,
string replicaPath ,
string runtimeId ,
IReadOnlyList < Process > childProcesses ,
Func < IReadOnlyList < AetheriaRuntimeCommittedCommandFactDocument > , bool > isReady ,
string expectedFacts )
{
var deadline = DateTimeOffset . UtcNow . AddSeconds ( 45 ) ;
Exception ? lastError = null ;
IReadOnlyList < AetheriaRuntimeCommittedCommandFactDocument > lastFacts = Array . Empty < AetheriaRuntimeCommittedCommandFactDocument > ( ) ;
while ( DateTimeOffset . UtcNow < deadline )
{
try
{
await AetheriaVerseReplica . SyncScopedSnapshotAsync (
replicaPath ,
endpoint ,
runtimeId ,
schemaIds :
[
AetheriaRuntimeDaemonSchemas . Frame ,
AetheriaRuntimeDaemonSchemas . CommittedCommandFact
] ) . ConfigureAwait ( false ) ;
var facts = await ReadFactsAsync ( replicaPath , runtimeId ) . ConfigureAwait ( false ) ;
lastFacts = facts ;
if ( isReady ( facts ) )
return facts ;
}
catch ( Exception ex )
{
lastError = ex ;
}
await Task . Delay ( 250 ) . ConfigureAwait ( false ) ;
}
throw new TimeoutException (
$"Timed out waiting for committed facts from {endpoint}. Expected {expectedFacts}." +
$" Requested schemas=[{AetheriaRuntimeDaemonSchemas.Frame},{AetheriaRuntimeDaemonSchemas.CommittedCommandFact}]." +
$" Last facts=[{string.Join(" , ", lastFacts.Select(fact => $" { fact . SourceDaemonId } : { fact . CommandId } : { fact . Outcome } "))}]." +
ProcessDiagnostics ( childProcesses ) +
( lastError = = null ? "" : $" Last error: {lastError.GetType().Name}: {lastError.Message}" ) ) ;
}
private static async Task < AetheriaRuntimeDaemonFrameDocument > WaitForLocalFrameAsync (
string statePath ,
string runtimeId ,
IReadOnlyList < Process > childProcesses ,
Func < AetheriaRuntimeDaemonFrameDocument , bool > isReady ,
string expectedFrame )
{
var deadline = DateTimeOffset . UtcNow . AddSeconds ( 45 ) ;
Exception ? lastError = null ;
AetheriaRuntimeDaemonFrameDocument ? lastFrame = null ;
while ( DateTimeOffset . UtcNow < deadline )
{
try
{
2026-06-28 07:28:45 +01:00
var frame = await TryReadPublishedFrameAsync ( statePath , runtimeId ) . ConfigureAwait ( false ) ;
if ( frame ! = null )
2026-06-25 18:09:33 +01:00
{
lastFrame = frame ;
if ( isReady ( frame ) )
return frame ;
}
}
catch ( Exception ex )
{
lastError = ex ;
}
await Task . Delay ( 250 ) . ConfigureAwait ( false ) ;
}
throw new TimeoutException (
$"Timed out waiting for local daemon frame at {statePath}. Expected {expectedFrame}." +
( lastFrame = = null ? "" : $" Last frame: daemon={lastFrame.DaemonId}, frame={lastFrame.FrameId}, imported=[{string.Join(" , ", lastFrame.ImportedFactIds)}], cumulativeImported=[{string.Join(" , ", lastFrame.CumulativeImportedFactIds)}], rejectedImported=[{string.Join(" , ", lastFrame.CumulativeRejectedImportedFactIds)}]." ) +
ProcessDiagnostics ( childProcesses ) +
( lastError = = null ? "" : $" Last error: {lastError.GetType().Name}: {lastError.Message}" ) ) ;
}
2026-06-28 07:28:45 +01:00
private static async Task < AetheriaRuntimeDaemonFrameDocument > ReadPublishedFrameAsync (
string statePath ,
string runtimeId )
2026-06-28 06:04:54 +01:00
{
2026-06-28 07:28:45 +01:00
var frame = await TryReadPublishedFrameAsync ( statePath , runtimeId ) . ConfigureAwait ( false ) ;
if ( frame = = null )
throw new InvalidOperationException ( $"No managed latest daemon frame is published at {statePath}." ) ;
return frame ;
2026-06-28 06:04:54 +01:00
}
2026-06-28 07:28:45 +01:00
private static async Task < AetheriaRuntimeDaemonFrameDocument ? > TryReadPublishedFrameAsync (
2026-06-28 06:04:54 +01:00
string statePath ,
2026-06-28 07:28:45 +01:00
string runtimeId )
2026-06-28 06:04:54 +01:00
{
2026-06-28 07:28:45 +01:00
await using var node = await AetheriaStateNode . OpenAsync (
statePath ,
runtimeId ,
startServer : false ,
enableDurableShardLogs : false ) . ConfigureAwait ( false ) ;
2026-06-29 01:04:09 +01:00
return await node . MutableDocument < AetheriaRuntimeDaemonFrameDocument > ( AetheriaRuntimeVerseRecordKeys . DaemonFrameLatest ) . ReadAsync ( ) . ConfigureAwait ( false ) ;
2026-06-28 06:04:54 +01:00
}
2026-06-25 18:09:33 +01:00
private static string ProcessDiagnostics ( IReadOnlyList < Process > childProcesses )
{
var lines = new List < string > ( ) ;
foreach ( var process in childProcesses ? ? Array . Empty < Process > ( ) )
{
try
{
lines . Add ( process . HasExited
? $" Child pid={process.Id} exited code={process.ExitCode}."
: $" Child pid={process.Id} still running." ) ;
lines . Add ( Environment . NewLine ) ;
lines . Add ( GetProcessOutputTail ( process ) ) ;
}
catch ( Exception ex )
{
lines . Add ( $" Child diagnostics failed: {ex.GetType().Name}: {ex.Message}." ) ;
}
}
return lines . Count = = 0 ? "" : string . Concat ( lines ) ;
}
private static void StopProcess ( Process process )
{
try
{
if ( ! process . HasExited )
process . Kill ( entireProcessTree : true ) ;
}
catch
{
}
try
{
process . WaitForExit ( 5000 ) ;
}
catch
{
}
}
private static AetheriaRuntimeDaemonFrameDocument TickWithPolicy (
string daemonId ,
AetheriaRuntimeRunCheckpointCommit run ,
AetheriaRuntimeVerseAuthorityPolicyDocument policy ,
IReadOnlyList < AetheriaRuntimeDaemonCommandDocument > observedCommands )
{
var rejectedIds = new List < string > ( ) ;
var authorizedCommands = AetheriaRuntimeAuthorityRouter . AuthorizedCommands (
observedCommands ,
policy ,
leases : null ,
localRuntimeId : daemonId ,
rejectedCommandIds : rejectedIds ) ;
var result = AetheriaRuntimeDaemonTickRunner . Tick (
Path . Combine ( Path . GetTempPath ( ) , $"aetheria-authority-smoke-{daemonId}.cc" ) ,
run ,
new AetheriaRuntimeDaemonTickOptions
{
DaemonId = daemonId ,
SessionId = "authority-smoke" ,
VerseId = policy . VerseId ,
FrameId = 1 ,
SimulationTimeSeconds = 0.02 ,
FixedDeltaSeconds = 0.02 ,
ObservedCommands = authorizedCommands ,
PreRejectedCommandIds = rejectedIds ,
2026-06-28 07:28:45 +01:00
BuildPublications = false
2026-06-25 18:09:33 +01:00
} ) ;
return result . Frame ;
}
private static AetheriaRuntimeVerseAuthorityPolicyDocument Policy (
string defaultMode ,
params AetheriaRuntimeAuthorityRule [ ] rules )
{
return new AetheriaRuntimeVerseAuthorityPolicyDocument
{
VerseId = "aetheria.test" ,
HostRuntimeId = "host-daemon" ,
DefaultMode = defaultMode ,
Rules = rules
} ;
}
private static AetheriaRuntimeVerseAuthorityPolicyDocument CoopPolicy ( )
{
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
var policy = Policy (
AetheriaRuntimeAuthorityModes . HostAuthoritative ,
new AetheriaRuntimeAuthorityRule
{
RuleId = "raven.runtime.owns.raven.movement" ,
SubjectPrefix = ravenKey ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Movement ] ,
Mode = AetheriaRuntimeAuthorityModes . DelegatedRuntime ,
2026-07-05 20:57:22 +01:00
RuntimeIds = [ "pilot-client" ] ,
2026-06-25 18:09:33 +01:00
Priority = 100
} ,
new AetheriaRuntimeAuthorityRule
{
2026-07-05 20:57:22 +01:00
RuleId = "commander.runtime.owns.hostile.movement" ,
2026-06-25 18:09:33 +01:00
SubjectPrefix = hostileKey ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Movement ] ,
Mode = AetheriaRuntimeAuthorityModes . DelegatedRuntime ,
2026-07-05 20:57:22 +01:00
RuntimeIds = [ "commander-client" ] ,
2026-06-25 18:09:33 +01:00
Priority = 100
} ) ;
policy . VerseId = "aetheria.coop-smoke" ;
policy . PolicyId = "aetheria.coop-smoke.delegated.v1" ;
return policy ;
}
private static AetheriaRuntimeVerseAuthorityPolicyDocument CoopPolicyWithMetadata ( )
{
var policy = CoopPolicy ( ) ;
var ravenKey = EntityKey ( "coop-smoke" , 0 , 0 ) ;
var hostileKey = EntityKey ( "coop-smoke" , 0 , 1 ) ;
policy . Rules = policy . Rules
. Concat ( new [ ]
{
new AetheriaRuntimeAuthorityRule
{
RuleId = "raven.runtime.owns.raven.metadata" ,
SubjectPrefix = ravenKey ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Metadata ] ,
Mode = AetheriaRuntimeAuthorityModes . DelegatedRuntime ,
2026-07-05 20:57:22 +01:00
RuntimeIds = [ "pilot-client" ] ,
2026-06-25 18:09:33 +01:00
Priority = 90
} ,
new AetheriaRuntimeAuthorityRule
{
2026-07-05 20:57:22 +01:00
RuleId = "commander.runtime.owns.hostile.metadata" ,
2026-06-25 18:09:33 +01:00
SubjectPrefix = hostileKey ,
ClaimKinds = [ AetheriaRuntimeClaimKinds . Metadata ] ,
Mode = AetheriaRuntimeAuthorityModes . DelegatedRuntime ,
2026-07-05 20:57:22 +01:00
RuntimeIds = [ "commander-client" ] ,
2026-06-25 18:09:33 +01:00
Priority = 90
}
} )
. ToArray ( ) ;
return policy ;
}
private static AetheriaRuntimeDaemonCommandDocument Command (
string runtimeId ,
string subjectKey ,
AetheriaRuntimeDaemonCommandKinds kind = AetheriaRuntimeDaemonCommandKinds . SetMoveVector )
{
var command = AetheriaRuntimeDaemonCommandDocument . Create (
kind ,
runtimeId ,
sessionId : "authority-smoke" ,
observedFrameId : 0 ,
actorEntityKey : subjectKey ) ;
command . SubjectKey = subjectKey ;
command . AuthorRuntimeId = runtimeId ;
return command ;
}
private static AetheriaRuntimeDaemonCommandDocument MovementCommand (
string runtimeId ,
string subjectKey ,
double directionX ,
double directionY ,
double magnitude )
{
var command = Command ( runtimeId , subjectKey , AetheriaRuntimeDaemonCommandKinds . SetMoveVector ) ;
command . DirectionX = directionX ;
command . DirectionY = directionY ;
command . ScalarValue = magnitude ;
return command ;
}
private static AetheriaRuntimeDaemonCommandDocument MetadataNameCommand (
string runtimeId ,
string subjectKey ,
string name )
{
var command = Command ( runtimeId , subjectKey , AetheriaRuntimeDaemonCommandKinds . SetEntityName ) ;
command . TargetEntityKey = subjectKey ;
command . TextValue = name ;
command . ClaimKind = AetheriaRuntimeClaimKinds . Metadata ;
return command ;
}
private static AetheriaRuntimeRunCheckpointCommit InitialCoopRun ( )
{
return new AetheriaRuntimeRunCheckpointCommit
{
RunId = "coop-smoke" ,
CurrentZoneIndex = 0 ,
CurrentEntityKey = EntityKey ( "coop-smoke" , 0 , 0 ) ,
Zones =
[
new AetheriaRuntimeZoneSnapshotCommit
{
ZoneIndex = 0 ,
Name = "Co-op Smoke Zone" ,
Entities =
[
new AetheriaRuntimeEntitySnapshotCommit
{
EntityIndex = 0 ,
Name = "Raven Pilot" ,
Kind = "ship" ,
FactionKey = "player" ,
IsActive = true
} ,
new AetheriaRuntimeEntitySnapshotCommit
{
EntityIndex = 1 ,
2026-07-05 20:57:22 +01:00
Name = "Commander Hostile" ,
2026-06-25 18:09:33 +01:00
Kind = "ship" ,
FactionKey = "player" ,
IsActive = true
}
]
}
]
} ;
}
private static AetheriaRuntimeRunCheckpointCommit InitialCoopFactRun ( )
{
var run = InitialCoopRun ( ) ;
var zone = run . Zones [ 0 ] ;
zone . Entities [ 0 ] . FactionKey = "player" ;
zone . Entities [ 1 ] . FactionKey = "raider" ;
return run ;
}
private static AetheriaRuntimeEntitySnapshotCommit Entity (
AetheriaRuntimeRunCheckpointCommit run ,
string entityKey )
{
var parts = entityKey . Split ( '.' ) ;
var zoneIndex = Array . IndexOf ( parts , "zone" ) > = 0 & & int . TryParse ( parts [ Array . IndexOf ( parts , "zone" ) + 1 ] , out var parsedZone )
? parsedZone
: 0 ;
var entityIndex = Array . IndexOf ( parts , "entity" ) > = 0 & & int . TryParse ( parts [ Array . IndexOf ( parts , "entity" ) + 1 ] , out var parsedEntity )
? parsedEntity
: 0 ;
var zone = ( run . Zones ? ? Array . Empty < AetheriaRuntimeZoneSnapshotCommit > ( ) )
. First ( candidate = > candidate . ZoneIndex = = zoneIndex ) ;
return ( zone . Entities ? ? Array . Empty < AetheriaRuntimeEntitySnapshotCommit > ( ) )
. First ( candidate = > candidate . EntityIndex = = entityIndex ) ;
}
2026-06-30 19:14:49 +01:00
private static AetheriaRuntimeEntitySnapshotCommit SnapshotEntity (
2026-06-25 18:09:33 +01:00
int entityIndex ,
string name ,
string factionKey ,
double x ,
double z ,
double visibility ,
double hull ,
string cargoItem )
{
return new AetheriaRuntimeEntitySnapshotCommit
{
EntityIndex = entityIndex ,
Name = name ,
Kind = "ship" ,
FactionKey = factionKey ,
IsActive = true ,
PositionX = x ,
PositionZ = z ,
DirectionX = 1 ,
DirectionY = 0 ,
Visibility = visibility ,
TargetEntityIndex = - 1 ,
StatGrids =
[
new AetheriaRuntimeEntityStatGridCommit
{
Name = "hull" ,
Width = 1 ,
Height = 1 ,
Values = [ hull ]
} ,
new AetheriaRuntimeEntityStatGridCommit
{
Name = "shield" ,
Width = 1 ,
Height = 1 ,
Values = [ 25 ]
} ,
new AetheriaRuntimeEntityStatGridCommit
{
Name = "heat" ,
Width = 1 ,
Height = 1 ,
Values = [ 4 ]
}
] ,
CargoContents =
[
new AetheriaRuntimeCargoBayLoadoutCommit
{
Items =
[
new AetheriaRuntimeLoadoutItemSlotCommit
{
Item = new AetheriaRuntimeLoadoutItemCommit
{
ItemKey = cargoItem ,
Quantity = 1 ,
Quality = 1 ,
Durability = 1 ,
Enabled = true
}
}
]
}
]
} ;
}
private static string EntityKey ( string runId , int zoneIndex , int entityIndex )
{
return $"global:aetheria.run_state.{runId}.zone.{zoneIndex}.entity.{entityIndex}.v1" ;
}
private static string Quote ( string value )
{
return "\"" + value . Replace ( "\"" , "\\\"" , StringComparison . Ordinal ) + "\"" ;
}
private static int GetFreeUdpPort ( )
{
using var socket = new Socket ( AddressFamily . InterNetwork , SocketType . Dgram , ProtocolType . Udp ) ;
socket . Bind ( new IPEndPoint ( IPAddress . Loopback , 0 ) ) ;
return ( ( IPEndPoint ) socket . LocalEndPoint ! ) . Port ;
}
private static void Require ( bool condition , string message )
{
if ( ! condition )
throw new InvalidOperationException ( message ) ;
}
private static void RequireEqual < T > ( T expected , T actual , string message )
{
if ( ! EqualityComparer < T > . Default . Equals ( expected , actual ) )
throw new InvalidOperationException ( $"{message}: expected {expected}, got {actual}" ) ;
}
private static void RequireSurfaceMetric (
AetheriaRuntimeSurfaceDocument surface ,
string componentId ,
string expectedValue ,
string message )
{
var component = Flatten ( surface . Surface . Root )
. FirstOrDefault ( candidate = > string . Equals ( candidate . Id , componentId , StringComparison . Ordinal ) ) ;
if ( component = = null )
throw new InvalidOperationException ( $"{message}: missing component {componentId}" ) ;
if ( ! component . Props . TryGetValue ( "value" , out var actualValue ) | |
! string . Equals ( actualValue , expectedValue , StringComparison . Ordinal ) )
{
throw new InvalidOperationException ( $"{message}: expected {expectedValue}, got {actualValue ?? " ( missing ) "}" ) ;
}
}
private static IEnumerable < AetheriaRuntimeSurfaceComponent > Flatten ( AetheriaRuntimeSurfaceComponent component )
{
yield return component ;
foreach ( var child in component . Children ? ? Array . Empty < AetheriaRuntimeSurfaceComponent > ( ) )
{
foreach ( var nested in Flatten ( child ) )
yield return nested ;
}
}
}