fix: complete retail parity stability pass
All checks were successful
CI / linux-portable (push) Successful in 3m41s
CI / windows-gate (push) Successful in 6m49s
CI / release (push) Successful in 3m22s

This commit is contained in:
Erik 2026-08-28 20:01:39 +02:00
parent d3df4cb20a
commit f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions

View file

@ -275,18 +275,24 @@ public sealed class RuntimeAuthoritativePositionRouteClassifierTests
}
[Fact]
public void ForcePosition_IsRejectedForRemoteOrUnequalTeleport()
public void ForcePosition_AcceptsLocalNonRegressedTeleportAndRejectsRemoteOrRegressed()
{
RuntimeAuthoritativePositionAuthority force = Authority(
10, 10, PositionTimestampDisposition.ForcePosition);
RuntimeAuthoritativePositionRoute remote = ClassifyRemote(authority: force);
RuntimeAuthoritativePositionRoute unequal = ClassifyLocal(
RuntimeAuthoritativePositionRoute newer = ClassifyLocal(
Authority(10, 11, PositionTimestampDisposition.ForcePosition));
RuntimeAuthoritativePositionRoute regressed = ClassifyLocal(
Authority(11, 10, PositionTimestampDisposition.ForcePosition));
Assert.Equal(RuntimeAuthoritativePositionDisposition.RejectedAuthority,
remote.Disposition);
Assert.Equal(RuntimeAuthoritativePositionDisposition.SetPositionSimple,
newer.Disposition);
Assert.False(newer.ZeroVelocity);
Assert.Equal(RuntimeTeleportHookPhase.None, newer.TeleportHookPhase);
Assert.Equal(RuntimeAuthoritativePositionDisposition.RejectedAuthority,
unequal.Disposition);
regressed.Disposition);
}
[Fact]

View file

@ -330,23 +330,18 @@ public sealed partial class RuntimeCollisionPrefixQuiescenceTests
/// root holds an operation. (Additionally, a parked record has
/// <c>FullCellId == 0</c>, so it is not an affected resident at all.)
///
/// <para><b>The real hazard is not a throw, it is an unbounded streaming
/// stall — and this test PINS it as a stall, not as a pass.</b> A retained
/// preparation retry keeps its landblock prefix in placement debt, so the
/// retirement is refused on EVERY poll and the landblock never retires.
/// There is no bound: the retirement coordinator simply retries, and
/// <c>TickLostCellDeadlines</c> — the only expiry that could break the
/// cycle — has NO production caller, so its deadline never fires. The only
/// thing that clears it is an inbound packet for that same entity, which
/// is exactly what a <c>RetrySetupUnavailable</c> on an asset that never
/// loads does not produce.</para>
/// <para>#310: collision retirement now supersedes an authored mover that
/// is still waiting for its first preparation. The exact unprepared
/// operation is cancelled before ordinary placement-debt evaluation, so
/// the resident enters the normal retirement park and the prefix can
/// converge without an inbound packet or asset-readiness edge.</para>
///
/// <para>This is a pre-existing hazard independent of route 4b-1, filed as
/// its own issue. 4b-1 does NOT bound it; it only avoids widening it, by
/// declining to retain operations for destinations it cannot service.</para>
/// </summary>
[Fact]
public void RetainedPreparationRetryStallsPrefixRetirementIndefinitely()
public void RetainedPreparationRetryIsCancelledByPrefixRetirement()
{
using var fixture = new Fixture();
RuntimeEntityRecord record = fixture.Add(
@ -358,7 +353,7 @@ public sealed partial class RuntimeCollisionPrefixQuiescenceTests
// A retained preparation retry: begun, never prepared — the shape a
// RetrySetupUnavailable on an asset that never resolves leaves behind.
RuntimeEntityPlacementToken retained = fixture.Lifetime.Physics
.SetPosition.BeginAcceptedPlacement(
.SetPosition.BeginAuthoredPlacement(
record,
record.PositionAuthorityVersion,
RuntimeSetPositionOperationKind.RemoteAuthoritative);
@ -366,29 +361,14 @@ public sealed partial class RuntimeCollisionPrefixQuiescenceTests
RuntimeCollisionPrefixQuiescenceToken token = fixture.Begin(2UL);
// The production retirement path, polled hard. Permission is refused
// every single time; nothing in the system advances it.
for (int poll = 0; poll < 1_000; poll++)
{
Assert.False(
fixture.TryAcquire(token, out _),
$"retirement unexpectedly acquired permission on poll {poll}; "
+ "if this now succeeds the stall has been bounded and "
+ "this test's pinned decision must be revisited");
}
// The first production poll cancels the unprepared operation and
// enters the ordinary two-phase resident-withdrawal handshake.
Assert.False(fixture.TryAcquire(token, out _));
Assert.False(fixture.Lifetime.Physics.SetPosition
.IsPlacementCurrent(retained));
Assert.Equal(1, fixture.Lifetime.Physics.CaptureOwnership()
.SetPositionOperationCount); // the replacement retirement park
// ParkCollisionResidents was never entered, so its overlap throw could
// not fire — the contract's item 6, proven structurally.
Assert.True(fixture.Lifetime.Physics.IsSpatialRoot(record));
Assert.False(fixture.Lifetime.Physics.SetPosition.TryPeekProjection(
out _));
// And the discriminator: retiring the retained operation is what
// releases the prefix. Once the debt is gone the ordinary two-phase
// handshake proceeds — ParkCollisionResidents withdraws the residents
// and permission follows the withdrawal acknowledgements — so drain
// those exactly as the production host does.
_ = fixture.Lifetime.Physics.SetPosition.ForgetExactPlacement(retained);
bool acquired = false;
for (int poll = 0; poll < 32 && !acquired; poll++)
{
@ -404,8 +384,8 @@ public sealed partial class RuntimeCollisionPrefixQuiescenceTests
}
Assert.True(
acquired,
"clearing the retained preparation retry must let the prefix "
+ "retire; if it does not, the stall has a second cause");
"prefix retirement must converge after it supersedes an "
+ "unprepared mover operation");
}
[Fact]

View file

@ -116,6 +116,73 @@ public sealed class RuntimeSetPositionStateTests
Assert.Equal(1, ownership.PreparedMoverCount);
}
[Fact]
public void WarmedPendingProjectionRetryDoesNotAllocateSnapshotArray()
{
PhysicsEngine engine = FlatEngine(SourceLandblock, 0f);
using var lifetime = new RuntimeEntityObjectLifetime(engine);
RuntimeEntityRecord record = CreateRecord(lifetime, 0x70001042u, 1);
_ = AttachBody(lifetime, record, SourceCell);
var observer = new CountingPlacementObserver();
using IDisposable subscription = lifetime.Events.SubscribePlacement(observer);
RuntimeSetPositionOutcome outcome = lifetime.Physics.SetPosition.Apply(
record,
record.PositionAuthorityVersion,
Command(Request(SourceCell, new Vector3(13f, 18f, 7f))));
// Prime both retained retry scratch and the event stream's dispatch
// storage before measuring the normal N>0 per-tick path.
lifetime.Physics.SetPosition.RetryPendingProjections();
const int iterations = 256;
_ = GC.GetAllocatedBytesForCurrentThread();
long before = GC.GetAllocatedBytesForCurrentThread();
for (int iteration = 0; iteration < iterations; iteration++)
lifetime.Physics.SetPosition.RetryPendingProjections();
long allocated = GC.GetAllocatedBytesForCurrentThread() - before;
// The event stream itself currently costs 72 B/publication. The old
// Values.ToArray snapshot raised this exact fixture to 424 B/retry;
// keep enough runtime variance for the dispatch floor while making a
// fresh projection array (or equivalent regression) fail loudly.
Assert.InRange(allocated / iterations, 0L, 128L);
Assert.Equal(iterations + 2, observer.Count);
Assert.True(lifetime.Physics.SetPosition.AcknowledgeProjection(
outcome.Projection));
}
[Fact]
public void PendingProjectionRetryKeepsIndependentSnapshotWhenReentered()
{
PhysicsEngine engine = FlatEngine(SourceLandblock, 0f);
using var lifetime = new RuntimeEntityObjectLifetime(engine);
RuntimeEntityRecord record = CreateRecord(lifetime, 0x70001044u, 1);
_ = AttachBody(lifetime, record, SourceCell);
bool retrying = false;
bool nested = false;
var observer = new PlacementObserver(_ =>
{
if (!retrying || nested)
return;
nested = true;
lifetime.Physics.SetPosition.RetryPendingProjections();
});
using IDisposable subscription = lifetime.Events.SubscribePlacement(observer);
RuntimeSetPositionOutcome outcome = lifetime.Physics.SetPosition.Apply(
record,
record.PositionAuthorityVersion,
Command(Request(SourceCell, new Vector3(13f, 19f, 7f))));
retrying = true;
lifetime.Physics.SetPosition.RetryPendingProjections();
Assert.True(nested);
Assert.Equal(3, observer.Deltas.Count);
Assert.All(observer.Deltas,
delta => Assert.Equal(outcome.Projection, delta.Placement.Token));
Assert.True(lifetime.Physics.SetPosition.AcknowledgeProjection(
outcome.Projection));
}
[Theory]
[InlineData(PhysicsStateFlags.Hidden)]
[InlineData(PhysicsStateFlags.Hidden | PhysicsStateFlags.NoDraw)]
@ -3648,6 +3715,13 @@ public sealed class RuntimeSetPositionStateTests
}
}
private sealed class CountingPlacementObserver : IRuntimePlacementObserver
{
internal int Count { get; private set; }
public void OnPlacement(in RuntimePlacementDelta delta) => Count++;
}
/// <summary>
/// C0-3 test double: a minimal <see cref="IPreparedCollisionSource"/>
/// serving exactly one Setup id (matching <c>CanonicalSetupTableId</c>'s