using System.Text.Json; using System.Text.Json.Nodes; using XFEEDToolBox.Core.Navigation; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public sealed class ScoExitEstimatePolicyTests { private const double C=299792458; private static readonly ScoExitProfile Profile=new(1000*C,150*C,75*C,170*C,1,100*C,30000,.36,2.64){OrdinaryApproachThrottle=.75}; private static ScoExitNativeFrame Frame(int step,int state=2,double speed=400,double cap=40,int target=1)=>new() { Entity=10,World=20,At=(ulong)(1000+step*10),ClockEpoch=1,Steps=(ulong)step,SimulationSeconds=step*.01,StepSeconds=.01, SourceDomainVerified=true,ParameterBindingVerified=true,ShipIdentityHealthVerified=true,NativeOffStateVerified=state==0,InSupercruise=true,RawFsdState=2,ClockValid=true,TargetKey=target,State=state,Speed=speed*C,Distance=(1000000-step*4)*C, OrdinaryCap=cap*C,Blend=1,RawThrottle=.75,OriginalOrdinaryApproachThrottle=.75,SafeSpeed=1e6,SafeDistance=1e6,ArrivalWindow=6,CurrentAccelerationUpper=100*C,Profile=Profile, SampleScalarSpeed=speed*C,CurrentVectorSpeed=speed*C,CompletedPhysicsSpeed=speed*C,SpeedSource="max(current-dynamics-vector,last-completed-physics-scalar)" }; private static ScoExitEstimatePolicy Shadow(double activeRawThrottle=.75) { var policy=new ScoExitEstimatePolicy();policy.BindLoadout(new('a',64));for(var i=0;i<10;i++)policy.Observe(Frame(i) with{RawThrottle=activeRawThrottle});policy.OriginalStopped(true); for(var i=10;i<15;i++)policy.Observe(Frame(i,3,400-(i-9)*20) with{Blend=.5+(i-10)*.1}); for(var i=15;i<20;i++)policy.Observe(Frame(i,0,300-(i-14)*50)); policy.Observe(Frame(20,0,30));Check.That(policy.Status()["proofAvailable"]!.GetValue());return policy; } [Test]public void CompleteOriginalClockCountsEveryStepAndAnInvalidDeltaCannotPretendToBeWallTime() { var clock=new ScoExitSimulationClock();for(var i=0;i<1000;i++){Check.That(clock.AcceptIncoming(.005));clock.Complete(.005);} Check.Equal(1000UL,clock.CompletedSteps);Check.That(Math.Abs(clock.CompletedSeconds-5)<1e-10); var epoch=clock.Epoch;Check.That(!clock.AcceptIncoming(double.NaN));clock.Complete(.005); Check.That(!clock.Valid&&clock.Epoch>epoch&&clock.CompletedSteps==0&&clock.CompletedSeconds==0); clock.Reset();Check.That(clock.AcceptIncoming(.005));clock.Complete(.005);Check.Equal(1UL,clock.CompletedSteps); } [Test]public void AClockGapRequiresANewEpochAndFiveConsecutiveGoodUpdatesBeforeShadowRecovers() { var clock=new ScoExitSimulationClock();clock.Complete(.01);var before=clock.Epoch; Check.That(!clock.AcceptIncoming(.1));var broken=clock.Epoch;Check.That(broken>before); for(var i=0;i<4;i++){Check.That(!clock.AcceptIncoming(.01));clock.Complete(.01);} Check.Equal(0UL,clock.CompletedSteps);Check.That(clock.AcceptIncoming(.01));clock.Complete(.01); Check.That(clock.Valid&&clock.Epoch>broken&&clock.CompletedSteps==1&&clock.CompletedSeconds==.01); } private static ScoExitEstimatePolicy PassedTrial(double activeRawThrottle=.75) { var policy=Shadow(activeRawThrottle);Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst(); for(var i=21;i<=25;i++)Check.That(policy.Observe(Frame(i,2,350,50) with{RawThrottle=activeRawThrottle}).UseEstimatedStop); policy.OriginalStopped(true); for(var i=26;i<=30;i++)policy.Observe(Frame(i,3,350-(i-25)*20,50) with{Blend=.5+(i-26)*.1}); for(var i=31;i<=35;i++)policy.Observe(Frame(i,0,250-(i-30)*45,50)); Check.Equal(1,policy.Status()["successfulTrialExits"]!.GetValue());return policy; } [Test]public void ProductionRequiresAnExplicitSuccessfulTrialAndATrustedSha256Fingerprint() { var shadow=Shadow();Check.That(!shadow.PromoteProduction(10,20,1200,10000,out _)); var policy=PassedTrial();Check.That(!policy.PromoteProduction(10,20,1350,604801351,out _)); Check.That(policy.PromoteProduction(10,20,1350,10000,out _)); policy.BindLoadout(new('b',64));Check.That(!policy.Status()["productionAvailable"]!.GetValue()); } [Test]public void ACompleteTrialReceiptPreservesNativeClocksIntegralBudgetAndABoundedCurve() { var receipt=PassedTrial().Status()["lastExitReceipt"]!.AsObject(); Check.That(receipt["pass"]!.GetValue()&&receipt["trial"]!.GetValue()); Check.Equal(25UL,receipt["startCompletedSteps"]!.GetValue());Check.Equal(35UL,receipt["endCompletedSteps"]!.GetValue()); Check.That(receipt["integratedPathDistanceMetres"]!.GetValue()>0); Check.That(receipt["forecastStopDistanceMetres"]!.GetValue()>receipt["integratedPathDistanceMetres"]!.GetValue()+receipt["ordinaryArrivalEnvelopeMetres"]!.GetValue()); Check.That(receipt["curve"]!.AsArray().Count is >1 and <=64); } [Test]public void ActiveFullInputRecordsTheRealStartButForecastUsesTheBoundOrdinaryController() { var ordinary=Shadow();var activeFull=Shadow(1); Check.Equal(1d,activeFull.Status()["lastExitReceipt"]!["stopRawThrottle"]!.GetValue()); Check.Equal(.75,activeFull.Status()["lastExitReceipt"]!["originalOrdinaryApproachThrottle"]!.GetValue()); foreach(var policy in new[]{ordinary,activeFull}) {Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst();} var a=ordinary.Observe(Frame(21,2,350,50));var b=activeFull.Observe(Frame(21,2,350,50) with{RawThrottle=1}); Check.That(a.UseEstimatedStop&&b.UseEstimatedStop);Check.Equal(a.StopDistance,b.StopDistance); var receipt=PassedTrial(1).Status()["lastExitReceipt"]!; Check.That(receipt["pass"]!.GetValue()&&receipt["trial"]!.GetValue()); Check.Equal(1d,receipt["stopRawThrottle"]!.GetValue());Check.Equal(.75,receipt["originalOrdinaryApproachThrottle"]!.GetValue()); } [Test]public void FullInputPersistingAfterOriginalStopCannotUseTheOrdinaryServoOrCompleteAProof() { foreach(var state in new[]{0,3}) { var policy=new ScoExitEstimatePolicy();for(var i=0;i<10;i++)policy.Observe(Frame(i) with{RawThrottle=1});policy.OriginalStopped(true); Check.That(policy.Status()["shadowExitPending"]!.GetValue()); policy.Observe(Frame(10,state,350) with{RawThrottle=1}); Check.That(!policy.Status()["proofAvailable"]!.GetValue()&&!policy.Status()["shadowExitPending"]!.GetValue()); Check.That(!policy.Status()["lastExitReceipt"]!["pass"]!.GetValue()); } } [Test]public void ProductionUsesFreshNewSceneIdentityAndPreservesTheDominatingBaselineEnvelope() { var policy=PassedTrial();Check.That(policy.PromoteProduction(10,20,1350,10000,out _)); var status=policy.Status();Check.Equal(400*C,status["productionMaximumProvenStopSpeedMetresPerSecond"]!.GetValue()); Check.Equal(10d,status["productionMaximumProvenSpeedCapRatio"]!.GetValue()); // trial was only 350c/ratio7 var start=Frame(0,0,30,target:2) with{Entity=11,World=21,ClockEpoch=2,At=2000};policy.Observe(start);policy.BeginOwnedBurst(); var next=policy.Observe(Frame(1,2,75,15,target:2) with{Entity=11,World=21,ClockEpoch=2,At=2010}); Check.That(next.UseEstimatedStop&&next.Mode=="production"&&next.Entity==11&&next.World==21); Check.That(!next.Applies(10,20,2,2010));Check.That(next.Applies(11,21,2,2010)); policy.Observe(Frame(2,2,75,15,target:2) with{Entity=11,World=21,ClockEpoch=2,At=2020,Profile=Profile with{Jerk=101*C}}); Check.That(!policy.Status()["productionAvailable"]!.GetValue()); } [Test]public void NoCrossSessionFixtureOrOneActiveReceiptCanArmATrial() { var policy=new ScoExitEstimatePolicy();policy.Observe(Frame(0));policy.OriginalStopped(true);policy.Observe(Frame(1,0,30)); Check.That(!policy.ArmTrial(10,20,1010,2000,1,out _)); Check.That(!policy.Latest.UseEstimatedStop&&!policy.Status()["proofAvailable"]!.GetValue()); } [Test]public void SameBindingShadowThenExplicitBoundedTrialCanSurviveANormalTargetAndRunnerChange() { var policy=Shadow();var fresh=Frame(21,0,30,target:2);policy.Observe(fresh); Check.That(policy.ArmTrial(10,20,fresh.At,3000,2,out _));policy.BeginOwnedBurst(); var next=policy.Observe(Frame(22,2,350,50,target:2)); Check.That(next.UseEstimatedStop&&next.ShadowKnown&&next.TargetKey==2&&next.Entity==10&&next.World==20); Check.That(next.StopDistance<350*C*13);Check.Equal(1,policy.Status()["maximumTrialBurstsRemaining"]!.GetValue()); } [Test]public void DefaultShadowNeverChangesTheThirteenSecondRule() { var policy=Shadow();var next=policy.Observe(Frame(21,2,350,50)); Check.That(next.ShadowKnown&&!next.UseEstimatedStop); Check.That(next.RequiresStop(350*C*12,350*C,true,true,6,10,20,1,next.At)); } [Test]public void BriefTargetGeometryResetInOrdinaryFlightPreservesOnlyTheCompletedSameBindingProof() { var policy=Shadow();policy.Observe(Frame(21,0,30,target:2) with{SourceDomainVerified=false}); Check.That(policy.Status()["proofAvailable"]!.GetValue()); policy.Observe(Frame(22,0,30,target:2));Check.That(policy.ArmTrial(10,20,1220,3000,1,out _)); policy.BeginOwnedBurst();Check.That(policy.Observe(Frame(23,2,350,50,target:2)).UseEstimatedStop); policy.Observe(Frame(24,0,30,target:3) with{SourceDomainVerified=false}); Check.That(!policy.Status()["proofAvailable"]!.GetValue()); // a current trial is never carried through it } [Test]public void TrialRequiresFreshExactBindingAHardDeadlineAndAtMostTwoBursts() { var policy=Shadow(); foreach(var args in new[]{(11UL,20UL,1200UL,2000UL,1),(10UL,21UL,1200UL,2000UL,1),(10UL,20UL,1500UL,2000UL,1), (10UL,20UL,1200UL,601201UL,1),(10UL,20UL,1200UL,1200UL,1),(10UL,20UL,1200UL,2000UL,3)}) Check.That(!policy.ArmTrial(args.Item1,args.Item2,args.Item3,args.Item4,args.Item5,out _)); Check.That(policy.ArmTrial(10,20,1200,2000,1,out _));policy.BeginOwnedBurst(); Check.That(!policy.Observe(Frame(100,2,350,50)).UseEstimatedStop); // discontinuity and deadline } [Test]public void RebindingParameterChangesMissingSourcesAndClockGapsDiscardTheShadowProof() { foreach(var changed in new[]{Frame(21) with{Entity=11},Frame(21) with{World=21},Frame(21) with{ClockEpoch=2}, Frame(21) with{Profile=Profile with{Jerk=101*C}},Frame(21) with{SourceDomainVerified=false},Frame(22), Frame(21) with{OriginalOrdinaryApproachThrottle=.5,RawThrottle=.5,Profile=Profile with{OrdinaryApproachThrottle=.5}}}) { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,2000,1,out _));policy.BeginOwnedBurst(); Check.That(!policy.Observe(changed).UseEstimatedStop);Check.That(!policy.Status()["proofAvailable"]!.GetValue()); } } [Test]public void HigherSpeedOrWorseCoolingRatioFallsBackToLegacyRatherThanExtrapolatingTheProof() { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,3000,1,out _));policy.BeginOwnedBurst(); var speedFallback=policy.Observe(Frame(21,2,401,50));Check.That(!speedFallback.UseEstimatedStop); Check.Equal(ScoExitApproachDecision.OutsideCalibrationReason,speedFallback.Reason); var ratioFallback=policy.Observe(Frame(22,2,350,30));Check.That(!ratioFallback.UseEstimatedStop); Check.Equal(ScoExitApproachDecision.OutsideCalibrationReason,ratioFallback.Reason); Check.That(policy.Observe(Frame(23,2,350,50)).UseEstimatedStop); } [Test]public void UnqualifiedShadowKeepsMixedBelowCapEvidenceUntilTheActualOffHandoff() { var policy=new ScoExitEstimatePolicy();for(var i=0;i<10;i++)policy.Observe(Frame(i));policy.OriginalStopped(true); policy.Observe(Frame(10,3,30,40) with{Blend=.5}); Check.That(!policy.Status()["proofAvailable"]!.GetValue()&&policy.Status()["shadowExitPending"]!.GetValue()); for(var i=11;i<=15;i++)policy.Observe(Frame(i,0,30,40)); Check.That(policy.Status()["lastExitReceipt"]!["mixedBelowCapSeen"]!.GetValue()); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()); } [Test]public void NativeDecisionProjectionKeepsBindingAndExpiryAndOnlyAffectsActiveApproach() { var choice=new ScoExitApproachDecision{UseEstimatedStop=true,ShadowKnown=true,Entity=10,World=20,TargetKey=1,At=1200,TrialExpiresAt=2000,SourceSpeed=75*C,StopDistance=600*C}; var node=new JsonObject{["scoExitApproach"]=choice.Json()};var wire=JsonSerializer.SerializeToElement(node); var read=ScoExitApproachDecision.Read(wire)!;Check.That(read.Applies(10,20,1,1201)); Check.That(!read.RequiresStop(700*C,75*C,true,true,6,10,20,1,1201)); Check.That(read.RequiresStop(500*C,75*C,true,true,6,10,20,1,1201)); foreach(var changed in new[]{(11UL,20UL,1,1201UL),(10UL,21UL,1,1201UL),(10UL,20UL,2,1201UL),(10UL,20UL,1,1401UL),(10UL,20UL,1,2000UL)}) Check.That(read.RequiresStop(700*C,75*C,true,true,6,changed.Item1,changed.Item2,changed.Item3,changed.Item4)); Check.That(read.RequiresStop(700*C,75*C,false,true,6,10,20,1,1201)); } [Test]public void NativeAndManagedGuardsUseTheSameBoundedDecisionWithoutWeakeningHeatOrIdentity() { var now=DateTimeOffset.FromUnixTimeMilliseconds(1200);var choice=new ScoExitApproachDecision {UseEstimatedStop=true,Entity=10,World=20,TargetKey=1,At=1200,TrialExpiresAt=2000,SourceSpeed=75*C,StopDistance=600*C}; var thermal=new ScoThermalInput{Verified=true,HeatCapacity=100,HeatDisplayScale=1,ScoInputUpper=10,OtherInputUpper=5, CoolingPassive=10,CoolingMaximum=10,CoolingScale=1,CoolingHeatLower=0,CoolingHeatUpper=1,LeaseRemainingSeconds=.15,ResponseDelaySeconds=.01,AfterStopSeconds=.5}; var gate=new CruiseOverchargeGateFrame{IdentityVerified=true,GeometryVerified=true,TargetVerified=true,InSupercruise=true,NativeCanEngage=true, RawFsdState=2,OverchargeState=2,ObservedAt=1200,Hull=1,Heat=40,MainFuel=32,FuelCapacity=32,FuelRateUpper=1,RequiredFuelReserve=8, Distance=700*C,Speed=75*C,AimErrorDegrees=0,CruiseParametersVerified=true,CruiseApproachSeconds=6, ShipEntity=10,ReferenceWorld=20,TargetKey=1,ExitApproach=choice,ThermalInput=thermal}; var flight=new SystemFlightFrame{ObservedAt=now,InGame=true,GeometryVerified=true,GameSha256=new('a',64),ShipEntity=10,ReferenceWorld=20, SystemAddress=1,Mode=LocalFlightMode.Supercruise,Position=new(0,0,0),TargetPosition=new(0,0,700*C),Forward=new(0,0,1),TargetDistance=700*C, Speed=75*C,CruiseParametersVerified=true,CruiseApproachSeconds=6,SelectedTarget=new(1,9,"Station",SystemTargetKind.Station,10){NativeKey=1}}; var observed=new CruiseOverchargeObservation{ObservedAt=now,ShipEntity=10,ReferenceWorld=20,GameSha256=new('a',64),OriginalInterfacesVerified=true, OriginalCanEngage=true,NativeFlightConstraintsVerified=true,NativeGeometryVerified=true,State=CruiseOverchargeState.Active,HeatPercent=40, FuelMainTonnes=32,FuelCapacityTonnes=32,FuelBurnTonnesPerSecond=0,FuelRateUpperTonnesPerSecond=1,ThermalInput=thermal,ExitApproach=choice}; Check.That(CruiseOverchargeNativeGuard.Refusal(gate,1200,1350) is null); Check.That(new CruiseOverchargePolicy().Decide(flight,observed,8,now).UseOvercharge); Check.Equal("approach-or-alignment",CruiseOverchargeNativeGuard.Refusal(gate with{ExitApproach=null},1200,1350)); Check.Equal(CruiseOverchargeReason.TargetClose,new CruiseOverchargePolicy().Decide(flight,observed with{ExitApproach=null},8,now).Reason); Check.Equal("heat",CruiseOverchargeNativeGuard.Refusal(gate with{Heat=100},1200,1350)); Check.Equal(CruiseOverchargeReason.Heat,new CruiseOverchargePolicy().Decide(flight,observed with{HeatPercent=100},8,now).Reason); Check.Equal("identity-or-target",CruiseOverchargeNativeGuard.Refusal(gate with{TargetVerified=false},1200,1350)); Check.Equal(CruiseOverchargeReason.Ownership,new CruiseOverchargePolicy().Decide(flight,observed with{ShipEntity=11},8,now).Reason); } private static JsonObject NativeJson() { var p=new JsonObject { ["sameFrameSourceVerified"]=true,["targetVelocityCorrectionDisabled"]=true,["externalMotionDisabled"]=true,["externalMotionPredicateVerified"]=true, ["completedPhysicsEffects"]=new JsonObject { ["available"]=true,["phase"]="after-original-PhysicsUpdate-return",["entityId"]="10",["referenceWorldAddress"]="20",["owningThread"]=7, ["observedAtUnixMilliseconds"]=1000,["completedPhysicsSteps"]=1,["originalPhysicsStepSeconds"]=.01,["targetWeight620"]=0, ["completedPhysicsSpeedMetresPerSecond"]=400*C, ["rawTranslationInputAtCompletion"]=new JsonObject{["x"]=0,["y"]=0,["z"]=.75}, ["targetVector660"]=new JsonObject{["x"]=0,["y"]=0,["z"]=0},["externalVector720"]=new JsonObject{["x"]=0,["y"]=0,["z"]=0}, ["externalVector740"]=new JsonObject{["x"]=0,["y"]=0,["z"]=0},["externalPredicateVerified"]=true,["externalActuallyDisabled"]=true }, ["originalBrakeScalingMode"]=2,["physicsMode980"]=0,["controlFlag5E0"]=1,["translationScale"]=1,["forwardTargetBiasSentinel"]=0, ["forwardVelocityCosine"]=1,["angularSpeedRadiansPerSecond"]=0,["linearVelocityMagnitude"]=400*C, ["rawTranslationInput5D0"]=new JsonObject{["x"]=0,["y"]=0,["z"]=.75},["flightAssistBlend"]=1, ["baseMaximumSpeedMetresPerSecond"]=Profile.Maximum,["baseOverspeedBrakeAcceleration"]=Profile.Brake, ["baseForwardAcceleration"]=Profile.Forward,["baseSideAcceleration"]=Profile.Side,["currentResponseTimeSeconds"]=1, ["nativeJerkMetresPerSecondCubed"]=Profile.Jerk,["forwardTargetBiasMetresPerSecond"]=Profile.Bias, ["currentForwardAcceleration"]=75*C,["currentOverspeedBrakeAcceleration"]=150*C,["currentSideAcceleration"]=170*C }; return new() { ["verified"]=true,["inSupercruise"]=true,["rawFsdState"]=2,["localTargetSelected"]=true,["hullFraction"]=1,["geometryVerified"]=true,["healthEmergency"]=false,["playerOverride"]=false, ["entityId"]="10",["referenceWorldAddress"]="20",["observedAtUnixMilliseconds"]=1000,["state"]=2,["speedMetresPerSecond"]=400*C, ["distanceMetres"]=1000000*C,["target"]=new JsonObject{["key"]=1},["cruiseParametersVerified"]=true,["cruiseApproachSeconds"]=6,["cruiseApproachThrottle"]=.75, ["safeDropSpeedMetresPerSecond"]=1e6,["safeDropDistanceMetres"]=1e6, ["cruiseBrakeProviderDiagnostics"]=new JsonObject { ["available"]=true,["entityId"]="10",["referenceWorldAddress"]="20",["observedAtUnixMilliseconds"]=1000,["owningThread"]=7,["sampleThread"]=7, ["cachedSpeedValue"]=1000*C,["speedReduction"]=.96,["physicsConfiguration"]=p, ["coolingParameters"]=new JsonObject{["available"]=true,["coolingDragPerSecond"]=.36,["coolingEndFraction"]=2.64} } }; } [Test]public void MissingFastgateWrongWorldThreadAndStaleProviderCannotBecomeASourceQualifiedFrame() { var valid=NativeJson();Check.That(ScoExitNativeFrame.Read(valid,1,1,.01,true,.01).SourceDomainVerified); foreach(var field in new[]{"sameFrameSourceVerified","targetVelocityCorrectionDisabled","externalMotionDisabled","nativeJerkMetresPerSecondCubed","forwardVelocityCosine"}) { var node=NativeJson();node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!.AsObject().Remove(field); var frame=ScoExitNativeFrame.Read(node,1,1,.01,true,.01); if(field=="nativeJerkMetresPerSecondCubed") {var policy=new ScoExitEstimatePolicy();Check.That(!policy.Observe(frame).UseEstimatedStop);} else Check.That(!frame.SourceDomainVerified); } foreach(var change in new[]{("entityId","11"),("referenceWorldAddress","21"),("sampleThread","8"),("observedAtUnixMilliseconds","999")}) { var node=NativeJson();var provider=node["cruiseBrakeProviderDiagnostics"]!.AsObject(); provider[change.Item1]=change.Item1.EndsWith("Id")||change.Item1=="referenceWorldAddress"?JsonValue.Create(change.Item2):JsonValue.Create(int.Parse(change.Item2)); Check.That(!ScoExitNativeFrame.Read(node,1,1,.01,true,.01).SourceDomainVerified); } } [Test]public void RegisteredTargetContextCanQualifyOnlyThroughFreshCompletedZeroEffectsAndTheFullExternalPredicate() { var valid=NativeJson();var p=valid["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!.AsObject(); p["targetVelocityCorrectionDisabled"]=false;p["externalMotionPrefixDisabled"]=false; Check.That(ScoExitNativeFrame.Read(valid,1,1,.01,true,.01).SourceDomainVerified); foreach(var change in new[]{"missing-target-weight","nonzero-target","nonzero-external","unknown-external","enabled-external","old-output","wrong-phase"}) { var node=valid.DeepClone().AsObject();var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!.AsObject(); var output=physics["completedPhysicsEffects"]!.AsObject(); switch(change) { case "missing-target-weight":output.Remove("targetWeight620");break; case "nonzero-target":output["targetWeight620"]=.5;output["targetVector660"]!["z"]=1;break; case "nonzero-external":output["externalVector720"]!["x"]=1;break; case "unknown-external":output["externalPredicateVerified"]=false;break; case "enabled-external":output["externalActuallyDisabled"]=false;break; case "old-output":output["observedAtUnixMilliseconds"]=900;break; case "wrong-phase":output["phase"]="before-original-PhysicsUpdate";break; } Check.That(!ScoExitNativeFrame.Read(node,1,1,.01,true,.01).SourceDomainVerified); } } [Test]public void NativeFullInputIsAnActiveStartingConditionOnlyWithAKnownBoundOrdinaryThrottle() { foreach(var state in new[]{0,1,2,3}) { var node=NativeJson();node["state"]=state;node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!["rawTranslationInput5D0"]!["z"]=1; node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!["completedPhysicsEffects"]!["rawTranslationInputAtCompletion"]!["z"]=1; var frame=ScoExitNativeFrame.Read(node,1,1,.01,true,.01); Check.Equal(state is 1 or 2,frame.SourceDomainVerified);Check.Equal(1d,frame.RawThrottle);Check.Equal(.75,frame.OriginalOrdinaryApproachThrottle); } foreach(var invalid in new[]{0d,-.1,.7500001,1}) { var node=NativeJson();node["cruiseApproachThrottle"]=invalid; Check.That(!ScoExitNativeFrame.Read(node,1,1,.01,true,.01).SourceDomainVerified); } foreach(var change in new[]{"missing","unknown","unverified","over-full","negative","ordinary-mismatch"}) { var node=NativeJson();var raw=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!["rawTranslationInput5D0"]!; if(change=="missing")node.Remove("cruiseApproachThrottle"); else if(change=="unknown")node["cruiseApproachThrottle"]=null; else if(change=="unverified")node["cruiseParametersVerified"]=false; else if(change=="over-full")raw["z"]=1.0000001; else if(change=="negative")raw["z"]=-.001; else{node["state"]=3;node["cruiseApproachThrottle"]=.5;raw["z"]=.75;} Check.That(!ScoExitNativeFrame.Read(node,1,1,.01,true,.01).SourceDomainVerified); } } [Test]public void ARejectedFirstExitFrameAndAnUnqualifiedOriginalStopKeepOnlyBoundedSourceDiagnostics() { var node=NativeJson();node["state"]=3;node["observedAtUnixMilliseconds"]=1100; var provider=node["cruiseBrakeProviderDiagnostics"]!;provider["observedAtUnixMilliseconds"]=1100; var physics=provider["physicsConfiguration"]!;physics["rawTranslationInput5D0"]!["z"]=1; var effects=physics["completedPhysicsEffects"]!;effects["available"]=false;effects["unavailableReason"]="completed-raw-input-mismatch"; effects["failureDiagnostics"]=new JsonObject{["readerAvailable"]=true,["rawMatch"]=false,["completedAt"]=1095,["currentAt"]=1100, ["ageMilliseconds"]=5,["dt"]=.005,["completedRaw"]=new JsonArray(0,0,1),["currentRaw"]=new JsonArray(0,0,.75)}; var failed=ScoExitNativeFrame.Read(node,1,10,.1,true,.01); Check.That(!failed.SourceDomainVerified&&!failed.SourceFailureDiagnostics!["throttleDomain"]!.GetValue()); Check.Equal("completed-raw-input-mismatch",failed.SourceFailureDiagnostics["effectsUnavailableReason"]!.GetValue()); Check.That(failed.SourceFailureDiagnostics.ToJsonString().Length<2500); var policy=new ScoExitEstimatePolicy();for(var i=0;i<10;i++)policy.Observe(Frame(i) with{RawThrottle=1});policy.OriginalStopped(true); policy.Observe(failed); var receipt=policy.Status()["lastExitReceipt"]!;Check.That(!receipt["pass"]!.GetValue()); Check.Equal(1d,receipt["failureFrame"]!["rawThrottle"]!.GetValue()); Check.Equal("completed-raw-input-mismatch",receipt["failureFrame"]!["source"]!["effectsUnavailableReason"]!.GetValue()); policy.OriginalStopped(true); var denied=policy.Status()["lastStopQualificationFailure"]!; Check.Equal("last-frame-not-Active",denied["reason"]!.GetValue()); Check.Equal(3,denied["frame"]!["state"]!.GetValue()); } [Test]public void RapidAccelerationComparesTheScalarWithItsCompletedPhaseAndBudgetsTheCurrentVector() { const double scalar=19734650,vector=20197590.89757189; // real n observation: 2.346% phase difference var node=NativeJson();node["speedMetresPerSecond"]=scalar; var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!; physics["linearVelocityMagnitude"]=vector;physics["rawTranslationInput5D0"]!["z"]=1; physics["completedPhysicsEffects"]!["completedPhysicsSpeedMetresPerSecond"]=scalar; physics["completedPhysicsEffects"]!["rawTranslationInputAtCompletion"]!["z"]=1; var frame=ScoExitNativeFrame.Read(node,1,1,.01,true,.01); Check.That(frame.SourceDomainVerified);Check.Equal(vector,frame.Speed); Check.Equal(scalar,frame.SampleScalarSpeed);Check.Equal(scalar,frame.CompletedPhysicsSpeed);Check.Equal(vector,frame.CurrentVectorSpeed); Check.That(frame.SourceFailureDiagnostics!["completedScalarPhaseMatch"]!.GetValue()); Check.Equal("max(current-dynamics-vector,last-completed-physics-scalar)",frame.SpeedSource); physics["completedPhysicsEffects"]!["completedPhysicsSpeedMetresPerSecond"]=scalar*1.010001; Check.That(!ScoExitNativeFrame.Read(node,1,1,.01,true,.01).SourceDomainVerified); } [Test]public void DecelerationRetainsTheLargerCompletedScalarRatherThanCreditingTheNewerLowerSpeed() { var node=NativeJson();node["state"]=3; node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!["linearVelocityMagnitude"]=390*C; var frame=ScoExitNativeFrame.Read(node,1,1,.01,true,.01); Check.That(frame.SourceDomainVerified);Check.Equal(400*C,frame.Speed);Check.Equal(390*C,frame.CurrentVectorSpeed); Check.Equal(400*C,frame.CompletedPhysicsSpeed);Check.Equal(400*C,frame.SampleScalarSpeed); } [Test]public void WrongOrMissingCompletedScalarAndUnknownCurrentVectorCannotBecomeASpeedEnvelope() { foreach(var invalid in new[]{"missing-completed","zero-completed","wrong-completed","missing-vector","unknown-vector","negative-vector","missing-output"}) { var node=NativeJson();var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!; var effects=physics["completedPhysicsEffects"]!; if(invalid=="missing-completed")effects.AsObject().Remove("completedPhysicsSpeedMetresPerSecond"); else if(invalid=="zero-completed")effects["completedPhysicsSpeedMetresPerSecond"]=0; else if(invalid=="wrong-completed")effects["completedPhysicsSpeedMetresPerSecond"]=405*C; else if(invalid=="missing-vector")physics.AsObject().Remove("linearVelocityMagnitude"); else if(invalid=="unknown-vector")physics["linearVelocityMagnitude"]="unknown"; else if(invalid=="negative-vector")physics["linearVelocityMagnitude"]=-1; else effects["available"]=false; var frame=ScoExitNativeFrame.Read(node,1,1,.01,true,.01);Check.That(!frame.SourceDomainVerified); if(invalid is not ("wrong-completed" or "missing-output"))Check.That(double.IsNaN(frame.Speed)); } } private static ScoExitNativeFrame StopTransitionFrame(int step=10,Action? alter=null) { var node=NativeJson();var at=1000+step*10;node["state"]=3;node["observedAtUnixMilliseconds"]=at; var provider=node["cruiseBrakeProviderDiagnostics"]!;provider["observedAtUnixMilliseconds"]=at; var output=provider["physicsConfiguration"]!["completedPhysicsEffects"]!;output["observedAtUnixMilliseconds"]=at-5; output["rawTranslationInputAtCompletion"]!["z"]=1;alter?.Invoke(node); return ScoExitNativeFrame.Read(node,1,(ulong)step,step*.01,true,.01); } private static ScoExitEstimatePolicy PendingFullInputStop(bool called=true,int nativeStateBefore=-1,int nativeStateAfter=-1) { var policy=new ScoExitEstimatePolicy();for(var i=0;i<10;i++)policy.Observe(Frame(i) with{RawThrottle=1});policy.OriginalStopped(called,nativeStateBefore,nativeStateAfter);return policy; } [Test]public void OnlyTheFirstCoolingCallbackCanUseTheKnownCompletedActiveInputAfterARealOriginalStop() { var transition=StopTransitionFrame();Check.That(!transition.SourceDomainVerified&&transition.SourceExceptCompletedInputVerified &&transition.OriginalStopInputTransitionCandidate&&!transition.CompletedInputMatchesCurrent); var policy=PendingFullInputStop();policy.Observe(transition); Check.That(policy.Status()["shadowExitPending"]!.GetValue()&&policy.Status()["currentSourceDomainVerified"]!.GetValue()); for(var i=11;i<15;i++)policy.Observe(Frame(i,3,400-(i-9)*20) with{Blend=.5+(i-10)*.1}); for(var i=15;i<20;i++)policy.Observe(Frame(i,0,300-(i-14)*50));policy.Observe(Frame(20,0,30)); var receipt=policy.Status()["lastExitReceipt"]!;Check.That(receipt["pass"]!.GetValue()); Check.Equal(1,receipt["originalStopInputTransitionFrames"]!.GetValue()); var repeated=PendingFullInputStop();repeated.Observe(transition);repeated.Observe(StopTransitionFrame(11)); Check.That(!repeated.Status()["shadowExitPending"]!.GetValue()&&!repeated.Status()["lastExitReceipt"]!["pass"]!.GetValue()); } [Test]public void ACompletedInputMismatchCannotAuthorizeItselfWithoutTheExactStopBindingAndBoundedCallback() { var candidate=StopTransitionFrame(); var noStop=PendingFullInputStop(false);noStop.Observe(candidate);Check.That(!noStop.Status()["currentSourceDomainVerified"]!.GetValue()); foreach(var invalid in new[]{candidate with{Entity=11},candidate with{World=21},candidate with{TargetKey=2},candidate with{ClockEpoch=2}, candidate with{Steps=11},candidate with{At=1116},candidate with{ClockValid=false},candidate with{State=0}, candidate with{SourceExceptCompletedInputVerified=false},candidate with{Profile=Profile with{Jerk=101*C}}}) { var policy=PendingFullInputStop();policy.Observe(invalid); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()&&!policy.Status()["proofAvailable"]!.GetValue()); } } [Test]public void UnknownInputsAndNonzeroEffectsCannotBorrowARealStopTransitionWitness() { foreach(var invalid in new[]{"missing-input","unknown-input","transverse-input","other-old-input","nonzero-effect","enabled-external"}) { var frame=StopTransitionFrame(alter:node=> { var output=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!["completedPhysicsEffects"]!; if(invalid=="missing-input")output.AsObject().Remove("rawTranslationInputAtCompletion"); else if(invalid=="unknown-input")output["rawTranslationInputAtCompletion"]!["z"]=null; else if(invalid=="transverse-input")output["rawTranslationInputAtCompletion"]!["x"]=.1; else if(invalid=="other-old-input")output["rawTranslationInputAtCompletion"]!["z"]=.9; else if(invalid=="nonzero-effect")output["externalVector720"]!["x"]=1; else output["externalActuallyDisabled"]=false; }); var policy=PendingFullInputStop();policy.Observe(frame); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()&&!policy.Status()["proofAvailable"]!.GetValue()); } } [Test]public void ARealSynchronousCoolingStateCanBeFollowedByOffWithoutInventingACoolingCallback() { var policy=PendingFullInputStop(true,2,3);var firstOff=StopTransitionFrame(alter:node=>node["state"]=0); policy.Observe(firstOff);Check.That(policy.Status()["shadowExitPending"]!.GetValue()&&policy.Status()["currentSourceDomainVerified"]!.GetValue()); for(var i=11;i<=15;i++)policy.Observe(Frame(i,0,400-(i-10)*75)); var receipt=policy.Status()["lastExitReceipt"]!;Check.That(receipt["pass"]!.GetValue()&&receipt["coolingSeen"]!.GetValue()); Check.That(receipt["synchronousCoolingStateConfirmed"]!.GetValue()&&receipt["zeroCompleteCoolingCallbacks"]!.GetValue()); Check.Equal(0,receipt["coolingObservedCallbacks"]!.GetValue());Check.Equal(1,receipt["originalStopInputTransitionFrames"]!.GetValue()); Check.Equal(2,receipt["originalStopStateBefore"]!.GetValue());Check.Equal(3,receipt["originalStopStateAfter"]!.GetValue()); Check.That(receipt["integratedPathDistanceMetres"]!.GetValue()>0&&receipt["offFrames"]!.GetValue()>=5); } [Test]public void AnImmediateOffCannotBorrowAnUnknownUnconfirmedOrRepeatedCoolingState() { var off=StopTransitionFrame(alter:node=>node["state"]=0); foreach(var state in new[]{(-1,-1),(2,-1),(2,0),(2,2),(-1,3),(0,3)}) { var policy=PendingFullInputStop(true,state.Item1,state.Item2);policy.Observe(off); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()&&!policy.Status()["proofAvailable"]!.GetValue()); } var repeated=PendingFullInputStop(true,2,3);repeated.Observe(off); repeated.Observe(StopTransitionFrame(11,node=>node["state"]=0)); Check.That(!repeated.Status()["shadowExitPending"]!.GetValue()&&!repeated.Status()["lastExitReceipt"]!["pass"]!.GetValue()); } private static ScoExitNativeFrame OrdinaryExitInputFrame(int step,double completed,double current,Action? alter=null) =>StopTransitionFrame(step,node=> { var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!; physics["rawTranslationInput5D0"]!["z"]=current;physics["completedPhysicsEffects"]!["rawTranslationInputAtCompletion"]!["z"]=completed; alter?.Invoke(node); }); private static ScoExitEstimatePolicy AcceptedFirstStopTransition() {var policy=PendingFullInputStop(true,2,3);policy.Observe(StopTransitionFrame());Check.That(policy.Status()["shadowExitPending"]!.GetValue());return policy;} [Test]public void OrdinaryInputChangesWithinTheSameWorstCaseServoDomainPreserveARealExitIntegral() { var policy=AcceptedFirstStopTransition();var down=OrdinaryExitInputFrame(11,.75,0);var up=OrdinaryExitInputFrame(12,0,.75); Check.That(!down.SourceDomainVerified&&down.SourceExceptCompletedInputVerified&&down.OrdinaryInputTransitionCandidate); policy.Observe(down);policy.Observe(up);Check.That(policy.Status()["shadowExitPending"]!.GetValue()&&policy.Status()["currentSourceDomainVerified"]!.GetValue()); for(var i=13;i<=17;i++)policy.Observe(Frame(i,0,400-(i-12)*75)); var receipt=policy.Status()["lastExitReceipt"]!;Check.That(receipt["pass"]!.GetValue()); Check.Equal(2,receipt["ordinaryInputTransitionFrames"]!.GetValue());Check.Equal(1,receipt["originalStopInputTransitionFrames"]!.GetValue()); Check.That(receipt["integratedPathDistanceMetres"]!.GetValue()>0); } [Test]public void OrdinaryInputDomainChangesCannotArmATrialOrBorrowAnUnrelatedOrLowCapExit() { var frame=OrdinaryExitInputFrame(11,.75,0);var noStop=new ScoExitEstimatePolicy();noStop.Observe(frame); Check.That(!noStop.Status()["currentSourceDomainVerified"]!.GetValue()&&!noStop.ArmTrial(10,20,frame.At,3000,1,out _)); foreach(var wrong in new[]{frame with{Entity=11},frame with{World=21},frame with{TargetKey=2},frame with{ClockEpoch=2},frame with{Steps=12}, frame with{Profile=Profile with{Bias=30001}},frame with{OrdinaryCap=29999},frame with{At=1126}}) { var policy=AcceptedFirstStopTransition();policy.Observe(wrong); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()&&!policy.Status()["proofAvailable"]!.GetValue()); } var lowPrior=PendingFullInputStop(true,2,3);lowPrior.Observe(StopTransitionFrame() with{OrdinaryCap=29999});lowPrior.Observe(frame); Check.That(!lowPrior.Status()["shadowExitPending"]!.GetValue()); } [Test]public void NegativeExcessiveTransverseOrUnknownOrdinaryInputCannotUseTheServoDomainWitness() { foreach(var bad in new[]{"negative-old","excessive-old","missing-old","unknown-old","transverse-old","negative-current","excessive-current","transverse-current","nonzero-effect"}) { var frame=OrdinaryExitInputFrame(11,.75,0,node=> { var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!;var output=physics["completedPhysicsEffects"]!; if(bad=="negative-old")output["rawTranslationInputAtCompletion"]!["z"]=-.001; else if(bad=="excessive-old")output["rawTranslationInputAtCompletion"]!["z"]=.750001; else if(bad=="missing-old")output.AsObject().Remove("rawTranslationInputAtCompletion"); else if(bad=="unknown-old")output["rawTranslationInputAtCompletion"]!["z"]=null; else if(bad=="transverse-old")output["rawTranslationInputAtCompletion"]!["x"]=.01; else if(bad=="negative-current")physics["rawTranslationInput5D0"]!["z"]=-.001; else if(bad=="excessive-current")physics["rawTranslationInput5D0"]!["z"]=.750001; else if(bad=="transverse-current")physics["rawTranslationInput5D0"]!["y"]=.01; else output["externalVector720"]!["x"]=1; }); var policy=AcceptedFirstStopTransition();policy.Observe(frame); Check.That(!policy.Status()["shadowExitPending"]!.GetValue()&&!policy.Status()["proofAvailable"]!.GetValue()); } } [Test]public void TheFirstAuthorizedDomainRevocationKeepsItsFrameAndIsNotOverwrittenByLaterFailures() { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,4000,2,out _));policy.BeginOwnedBurst(); policy.Observe(Frame(21,1) with{SourceDomainVerified=false,SourceFailureDiagnostics=new(){["first-cause"]="phase-input"}}); var first=policy.Status()["lastPolicyRevocationFailure"]!; Check.That(first["trialBurst"]!.GetValue());Check.Equal(4000UL,first["trialUntil"]!.GetValue()); Check.Equal(0,first["previousFrame"]!["state"]!.GetValue());Check.Equal(20UL,first["previousFrame"]!["steps"]!.GetValue()); Check.Equal(1,first["failureFrame"]!["state"]!.GetValue());Check.Equal("phase-input",first["failureFrame"]!["source"]!["first-cause"]!.GetValue()); policy.Observe(Frame(22,2) with{SourceDomainVerified=false,SourceFailureDiagnostics=new(){["later-cause"]=true}}); Check.Equal(first.ToJsonString(),policy.Status()["lastPolicyRevocationFailure"]!.ToJsonString()); } [Test]public void AKeptOrdinaryProofIsNotARevocationAndTheNextSuccessfulTrialArmClearsOldEvidence() { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,4000,2,out _)); policy.Observe(Frame(21,0,30) with{SourceDomainVerified=false});Check.That(policy.Status()["lastPolicyRevocationFailure"] is null); policy.BeginOwnedBurst();policy.Observe(Frame(22,1) with{SourceDomainVerified=false});Check.That(policy.Status()["lastPolicyRevocationFailure"] is not null); for(var i=23;i<=32;i++)policy.Observe(Frame(i));policy.OriginalStopped(true); for(var i=33;i<=37;i++)policy.Observe(Frame(i,3,400-(i-32)*20)); for(var i=38;i<=42;i++)policy.Observe(Frame(i,0,300-(i-37)*50));policy.Observe(Frame(43,0,30)); Check.That(policy.Status()["proofAvailable"]!.GetValue());Check.That(policy.ArmTrial(10,20,1430,6000,1,out _)); Check.That(policy.Status()["lastPolicyRevocationFailure"] is null); } private static ScoExitNativeFrame EnableTransitionFrame(int step=21,Action? alter=null) =>StopTransitionFrame(step,node=> { node["state"]=1;var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!; physics["rawTranslationInput5D0"]!["z"]=1;physics["completedPhysicsEffects"]!["rawTranslationInputAtCompletion"]!["z"]=.75; alter?.Invoke(node); }); [Test]public void ARealOffToArmedOriginalCallPreservesTheCompletedProofThroughItsSingleInputPhaseBoundary() { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst(true,0,1); var first=EnableTransitionFrame();Check.That(first.SourceExceptCompletedInputVerified&&first.OriginalEnableInputTransitionCandidate&&!first.SourceDomainVerified); policy.Observe(first);Check.That(policy.Status()["currentSourceDomainVerified"]!.GetValue()&&policy.Status()["proofAvailable"]!.GetValue()); Check.Equal(1,policy.Status()["originalEnableInputTransitionFrames"]!.GetValue());Check.That(policy.Status()["lastPolicyRevocationFailure"] is null); for(var i=22;i<=26;i++)Check.That(policy.Observe(Frame(i,2,350,50) with{RawThrottle=1}).UseEstimatedStop); policy.OriginalStopped(true,2,3); for(var i=27;i<=31;i++)policy.Observe(Frame(i,3,350-(i-26)*20,50)); for(var i=32;i<=36;i++)policy.Observe(Frame(i,0,250-(i-31)*45,50)); var receipt=policy.Status()["lastExitReceipt"]!;Check.That(receipt["pass"]!.GetValue()&&receipt["trial"]!.GetValue()); Check.Equal(1,receipt["originalEnableInputTransitionFrames"]!.GetValue());Check.Equal(0,receipt["originalEnableStateBefore"]!.GetValue()); Check.Equal(1,receipt["originalEnableStateAfter"]!.GetValue()); } [Test]public void UnknownExternalOrWrongNativeEnableReceiptsCannotClaimTheOffToArmedBoundary() { foreach(var native in new[]{(false,0,1),(true,-1,-1),(true,-1,1),(true,0,-1),(true,0,2),(true,1,1)}) { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst(native.Item1,native.Item2,native.Item3); policy.Observe(EnableTransitionFrame());Check.That(!policy.Status()["proofAvailable"]!.GetValue()&&!policy.Status()["currentSourceDomainVerified"]!.GetValue()); } } [Test]public void AnEnableBoundaryCannotBeReusedLateAcrossBindingsOrWithUnknownAndUnmatchedInputs() { var candidate=EnableTransitionFrame(); foreach(var wrong in new[]{candidate with{Entity=11},candidate with{World=21},candidate with{TargetKey=2},candidate with{ClockEpoch=2}, candidate with{Steps=22},candidate with{At=1226},candidate with{State=2},candidate with{ClockValid=false}, candidate with{SourceExceptCompletedInputVerified=false},candidate with{Profile=Profile with{Jerk=101*C}},candidate with{CompletedRawThrottle=.5}}) { var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst(true,0,1);policy.Observe(wrong); Check.That(!policy.Status()["proofAvailable"]!.GetValue()&&!policy.Status()["currentSourceDomainVerified"]!.GetValue()); } foreach(var bad in new[]{"missing-old","negative-old","above-ordinary-old","old-transverse","current-transverse","unknown-old","nonzero-effect"}) { var wrong=EnableTransitionFrame(alter:node=> { var physics=node["cruiseBrakeProviderDiagnostics"]!["physicsConfiguration"]!;var output=physics["completedPhysicsEffects"]!; if(bad=="missing-old")output.AsObject().Remove("rawTranslationInputAtCompletion"); else if(bad=="negative-old")output["rawTranslationInputAtCompletion"]!["z"]=-.001; else if(bad=="above-ordinary-old")output["rawTranslationInputAtCompletion"]!["z"]=.750001; else if(bad=="old-transverse")output["rawTranslationInputAtCompletion"]!["x"]=.01; else if(bad=="current-transverse")physics["rawTranslationInput5D0"]!["y"]=.01; else if(bad=="unknown-old")output["rawTranslationInputAtCompletion"]!["z"]=null; else output["externalVector720"]!["x"]=1; }); var policy=Shadow();Check.That(policy.ArmTrial(10,20,1200,5000,2,out _));policy.BeginOwnedBurst(true,0,1);policy.Observe(wrong); Check.That(!policy.Status()["proofAvailable"]!.GetValue()); } var repeated=Shadow();Check.That(repeated.ArmTrial(10,20,1200,5000,2,out _));repeated.BeginOwnedBurst(true,0,1); repeated.Observe(candidate);repeated.Observe(EnableTransitionFrame(22));Check.That(!repeated.Status()["proofAvailable"]!.GetValue()); Check.Equal(1,repeated.Status()["originalEnableInputTransitionFrames"]!.GetValue()); } private static ScoExitEstimatePolicy Promoted() {var policy=PassedTrial();Check.That(policy.PromoteProduction(10,20,1350,86400000,out _));return policy;} private static ScoExitNativeFrame IdleReferenceGap()=>Frame(0,0,30) with{World=21,ClockEpoch=2,At=1400,SourceDomainVerified=false,ParameterBindingVerified=false,Profile=null}; [Test]public void AVerifiedOrdinaryOffReferenceGapKeepsApprovalButCannotUseAnOldFrameAsTheNewSource() { var policy=Promoted();var before=policy.Status();var gap=IdleReferenceGap(); Check.That(!policy.Observe(gap).UseEstimatedStop);var waiting=policy.Status(); Check.That(waiting["productionAvailable"]!.GetValue()&&waiting["productionCalibrationValid"]!.GetValue()); Check.That(!waiting["productionCalibrationReadyForCurrentProfile"]!.GetValue()&&waiting["productionSourceSuspended"]!.GetValue()); policy.ResetBinding(); // normal new-world watch must not destroy the proven idle context policy.Observe(Frame(1,0,30) with{World=21,ClockEpoch=3,At=1450}); var fresh=policy.Status();Check.That(fresh["productionCalibrationValid"]!.GetValue()&&fresh["productionCalibrationReadyForCurrentProfile"]!.GetValue()); Check.That(fresh["productionIdleSourceQuarantine"] is null); Check.That(!fresh["productionSourceSuspended"]!.GetValue()); Check.Equal(before["productionAuthorizationExpiresAtUnixMilliseconds"]!.GetValue(),fresh["productionAuthorizationExpiresAtUnixMilliseconds"]!.GetValue()); Check.Equal(before["productionMaximumProvenStopSpeedMetresPerSecond"]!.GetValue(),fresh["productionMaximumProvenStopSpeedMetresPerSecond"]!.GetValue()); policy.BeginOwnedBurst();Check.That(policy.Observe(Frame(2,2,75,15) with{World=21,ClockEpoch=3,At=1460}).UseEstimatedStop); } [Test]public void AnIdleClockRecoveryWithholdsCurrentUseWithoutRenewingTheOriginalCalibrationAge() { var policy=Promoted();policy.Observe(Frame(0,0,30) with{ClockEpoch=2,At=1400,ClockValid=false,SourceDomainVerified=false}); Check.That(policy.Status()["productionCalibrationValid"]!.GetValue()&&!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); policy.Observe(Frame(1,0,30) with{ClockEpoch=3,At=1450});Check.That(policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); policy.ResetBinding();policy.Observe(Frame(0,0,30) with{World=22,ClockEpoch=4,At=7201400}); Check.That(!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue(),"Requalification must not move the original envelope timestamp forward."); } [Test]public void AnActivePredictionOrPendingExitLostAtAReferenceChangeStillInvalidatesProduction() { foreach(var pending in new[]{false,true}) { var policy=Promoted();policy.BeginOwnedBurst(); for(var i=36;i<=40;i++)Check.That(policy.Observe(Frame(i,2,75,15)).UseEstimatedStop); if(pending)policy.OriginalStopped(true,2,3); policy.Observe(IdleReferenceGap() with{At=1410}); Check.That(!policy.Status()["productionCalibrationValid"]!.GetValue()&&policy.Status()["productionIdleSourceQuarantine"] is null); policy.Observe(Frame(1,0,30) with{World=21,ClockEpoch=3,At=1420}); Check.That(!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); } } [Test]public void MissingIdleSourcesPreserveOnlyPhysicalApprovalDataAndCannotAuthorizeAControlFrame() { foreach(var bad in new[]{IdleReferenceGap() with{Entity=11},IdleReferenceGap() with{World=0},IdleReferenceGap() with{ShipIdentityHealthVerified=false}, IdleReferenceGap() with{TargetKey=2},IdleReferenceGap() with{At=1600}}) { var policy=Promoted();Check.That(!policy.Observe(bad).UseEstimatedStop); Check.That(policy.Status()["productionCalibrationValid"]!.GetValue()&&!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); } var timed=Promoted();timed.Observe(IdleReferenceGap());timed.Observe(IdleReferenceGap() with{Steps=1,SimulationSeconds=.01,At=3401}); Check.That(timed.Status()["productionCalibrationValid"]!.GetValue()&&!timed.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); timed.Observe(Frame(2,0,30) with{World=21,ClockEpoch=2,At=3410});Check.That(timed.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); } [Test]public void KnownProfileAndTrustedLoadoutChangesClearTheApprovalDuringIdleRequalification() { var profile=Promoted();profile.Observe(IdleReferenceGap()); profile.Observe(Frame(1,0,30) with{World=21,ClockEpoch=3,At=1450,Profile=Profile with{Jerk=101*C}}); Check.That(!profile.Status()["productionAvailable"]!.GetValue()); var loadout=Promoted();loadout.Observe(IdleReferenceGap());loadout.BindLoadout(new('c',64));Check.That(!loadout.Status()["productionAvailable"]!.GetValue()); } [Test]public void NormalScExitDockAndNewScenePreserveTheOriginalApprovalWithoutUsingNormalModeParameters() { var policy=Promoted();var before=policy.Status(); var leaving=Frame(36,0,30) with{RawFsdState=5,InSupercruise=false,ShipIdentityHealthVerified=false,SourceDomainVerified=false,ParameterBindingVerified=false,World=21,Profile=null}; Check.That(!policy.Observe(leaving).UseEstimatedStop); // Normal-space physics is not the approved supercruise profile. Even a // typed normal-mode parameter record must not be compared with it. var normal=leaving with{At=5000,Steps=1,World=22,RawFsdState=0,ParameterBindingVerified=true,Profile=Profile with{Maximum=1000,Brake=100}}; Check.That(!policy.Observe(normal).UseEstimatedStop); policy.ResetBinding(); Check.That(!policy.Observe(normal with{At=60000,Steps=0,Entity=0,World=0,Profile=null,ParameterBindingVerified=false,ClockValid=false}).UseEstimatedStop); var suspended=policy.Status();Check.That(suspended["productionCalibrationValid"]!.GetValue()&&!suspended["productionCalibrationReadyForCurrentProfile"]!.GetValue()); Check.Equal(before["productionAuthorizationExpiresAtUnixMilliseconds"]!.GetValue(),suspended["productionAuthorizationExpiresAtUnixMilliseconds"]!.GetValue()); Check.Equal(before["productionCalibrationObservedAtUnixMilliseconds"]!.GetValue(),suspended["productionCalibrationObservedAtUnixMilliseconds"]!.GetValue()); var fresh=Frame(0,0,30,target:2) with{At=60100,Entity=12,World=23,ClockEpoch=8};policy.Observe(fresh); Check.That(policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); policy.BeginOwnedBurst();var active=policy.Observe(Frame(1,2,75,15,target:2) with{At=60110,Entity=12,World=23,ClockEpoch=8}); Check.That(active.UseEstimatedStop&&active.Mode=="production"&&active.Entity==12&&active.World==23); } [Test]public void IdleLifecycleSuspensionCannotRefreshCalibrationAgeOrTheHardDeadline() { var policy=Promoted();var at=policy.Status()["productionCalibrationObservedAtUnixMilliseconds"]!.GetValue(); policy.Observe(IdleReferenceGap() with{InSupercruise=false,RawFsdState=0,ShipIdentityHealthVerified=false}); policy.Observe(Frame(0,0,30) with{World=22,ClockEpoch=3,At=at+7200001}); Check.That(!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); var deadline=PassedTrial();Check.That(deadline.PromoteProduction(10,20,1350,2000,out _)); deadline.Observe(IdleReferenceGap());deadline.Observe(Frame(0,0,30) with{World=22,ClockEpoch=3,At=2001}); Check.That(!deadline.Status()["productionAvailable"]!.GetValue()&&!deadline.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); } [Test]public void ExplicitNativeSafetyEvidenceInvalidatesIdleApprovalAndPreservesTheFirstFailure() { foreach(var field in new[]{"healthEmergency","playerOverride","hullFraction"}) { var policy=Promoted();var node=NativeJson();node["state"]=0;node["inSupercruise"]=false;node["rawFsdState"]=0;node["observedAtUnixMilliseconds"]=1400; if(field=="hullFraction")node[field]=0;else node[field]=true; var unsafeFrame=ScoExitNativeFrame.Read(node,2,0,0,true,.01);Check.That(unsafeFrame.ExplicitSafetyFailureReason is not null); policy.Observe(unsafeFrame);var failure=policy.Status()["firstProductionCalibrationInvalidation"]!; Check.That(!policy.Status()["productionCalibrationValid"]!.GetValue()&&failure["frame"]!["at"]!.GetValue()==1400); var first=failure.ToJsonString();policy.Observe(Frame(1,0,30) with{At=1450,ClockEpoch=2}); Check.That(!policy.Status()["productionCalibrationReadyForCurrentProfile"]!.GetValue()); Check.Equal(first,policy.Status()["firstProductionCalibrationInvalidation"]!.ToJsonString()); } } [Test]public void AnUnverifiedOffClaimOrAPendingEnableCannotShelveALostPredictionAsIdleApproval() { var unverified=Promoted();unverified.Observe(IdleReferenceGap() with{NativeOffStateVerified=false}); Check.That(!unverified.Status()["productionCalibrationValid"]!.GetValue()); var enabling=Promoted();enabling.BeginOwnedBurst(true,0,1);enabling.Observe(IdleReferenceGap()); Check.That(!enabling.Status()["productionCalibrationValid"]!.GetValue()&&enabling.Status()["firstProductionCalibrationInvalidation"] is not null); } }