From the AP-22 dual review (both lenses PASS). No production change.
THE RECORD WAS WRONG. bc4679cd claimed "Headless.Tests 89/89 exercises the
site-3 copy". The architecture review disproved it by sabotage: restoring the
invented cylinder in BOTH static sites left the entire suite green. No test
anywhere references PublishStaticCollision, and the headless suite's dummy DAT
proxy makes LandblockLoader.Load fail for every landblock, so CreatePublication
returns before reaching it. Two of the three deletions — including the
headless-only one — are pinned by the installed-DAT reachability proof ALONE.
The deletion is still correct; the evidence claim was not, and a successor
trusting it would think those sites had regression cover they do not have.
THE TEST NOW COVERS WHAT IT CLAIMED. Its comment said "the exact guard the
three deleted copies used", but site 1 guarded on `Radius > 0.0001f` while
sites 2 and 3 used the strictly wider `Radius > 0f`. Those are not the same
predicate: the review measured that they differ over the installed DAT by
exactly one Setup, 0x02001657, whose radius is the denormal 1.3e-39. The test
now evaluates BOTH and asserts each is empty, so the wider guard the
headless-reachable deletion actually used is no longer asserted by proxy.
Sabotage-verified: widening the new guard to `>= 0f` reddens it (1,652
zero-radius Setups appear), so the assertion is live rather than vacuously
empty over real DAT data.
AP-22's row also corrected for two precisions the reviews surfaced: the
load-bearing fact is that all 1,652 no-primitive Setups carry Radius exactly 0
(not the 1,294 first cited), and retail's `report_object_collision` DOES read
GetHeight for the quadrant field — recorded so a future reader does not mistake
it for a refutation of "never collision geometry", which is a claim about
FindObjCollisions' shape dispatch only.
Reachability now independently reproduced by four decoders — the contract's
sweep, the implementer's parser, and both reviewers' from-scratch parsers —
plus tools/SetupInspect agreeing bit-for-bit on the cited ids.
Content.Tests 125/125. No new skips; #302/#308/#321 did not fire.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
104 lines
4.3 KiB
C#
104 lines
4.3 KiB
C#
using AcDream.Core.Physics;
|
|
using DatReaderWriter;
|
|
using DatReaderWriter.DBObjs;
|
|
using DatReaderWriter.Options;
|
|
|
|
namespace AcDream.Content.Tests;
|
|
|
|
/// <summary>
|
|
/// AP-22 reachability proof. The deleted Setup-radius collision fallback fired
|
|
/// only for a Setup with no CylSphere, no Sphere, and a nonzero summary
|
|
/// Radius. This sweeps every Setup in the installed client_portal.dat and
|
|
/// asserts no such Setup exists, so the deletion cannot remove collision from
|
|
/// any real object.
|
|
/// </summary>
|
|
public sealed class InstalledSetupCollisionReachabilityTests
|
|
{
|
|
// Positive controls. These are EXTERNAL constants, measured on 2026-08-06
|
|
// by an independent raw client_portal.dat parse (B-tree directory walk +
|
|
// Setup record decode) that validated itself by byte accounting: all
|
|
// 5,935 records consumed with an exact residual tail of
|
|
// 20 + 48 * numLights and zero unexplained bytes.
|
|
//
|
|
// They are deliberately NOT derived from FlatCollisionAssetBuilder. A
|
|
// broken enumeration, a wrong dat path, or a silently-empty flatten all
|
|
// satisfy the negative claim vacuously and are caught only here.
|
|
private const int ExpectedSetups = 5935;
|
|
private const int ExpectedWithCylinder = 678;
|
|
private const int ExpectedSphereOnlyNoCylinder = 3605;
|
|
private const int ExpectedWithoutAnyPrimitive = 1652;
|
|
private const int ExpectedWithSummaryRadius = 4282;
|
|
|
|
[Fact]
|
|
public void InstalledSetups_NeverReachTheDeletedRadiusFallback()
|
|
{
|
|
string? datDir = ContentConformanceDats.ResolveDatDir();
|
|
if (datDir is null)
|
|
return;
|
|
|
|
using var dats = new DatCollection(datDir, DatAccessType.Read);
|
|
|
|
int total = 0;
|
|
int withCylinder = 0;
|
|
int sphereOnly = 0;
|
|
int withoutPrimitive = 0;
|
|
int withRadius = 0;
|
|
var fallbackReachable = new List<uint>();
|
|
var fallbackReachableWideGuard = new List<uint>();
|
|
|
|
foreach (uint id in dats.GetAllIdsOfType<Setup>())
|
|
{
|
|
if (!dats.Portal.TryGet<Setup>(id, out Setup? setup)
|
|
|| setup is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
FlatSetupCollision flat =
|
|
FlatCollisionAssetBuilder.FlattenSetup(setup);
|
|
total++;
|
|
|
|
bool hasCylinder = flat.Cylinders.Length > 0;
|
|
bool hasSphere = flat.Spheres.Length > 0;
|
|
if (hasCylinder)
|
|
withCylinder++;
|
|
else if (hasSphere)
|
|
sphereOnly++;
|
|
else
|
|
withoutPrimitive++;
|
|
|
|
if (flat.Radius > 0.0001f)
|
|
withRadius++;
|
|
|
|
// BOTH guard variants the deleted copies used — they are not the
|
|
// same predicate. Site 1 (LiveEntityCollisionBuilder) tested
|
|
// `Radius > 0.0001f`; sites 2 and 3 (LandblockPhysicsPublisher,
|
|
// LandblockPhysicsContentBuilder — the headless-reachable one)
|
|
// tested the strictly wider `Radius > 0f`. Corrected 2026-08-06 at
|
|
// the AP-22 architecture review, which measured that the two
|
|
// genuinely differ over the installed DAT by exactly one Setup:
|
|
// 0x02001657, whose radius is the denormal 1.3e-39. Asserting only
|
|
// the narrow guard would have claimed coverage of two deletions it
|
|
// never evaluated.
|
|
if (!hasCylinder && !hasSphere && flat.Radius > 0.0001f)
|
|
fallbackReachable.Add(id);
|
|
if (!hasCylinder && !hasSphere && flat.Radius > 0f)
|
|
fallbackReachableWideGuard.Add(id);
|
|
}
|
|
|
|
// (b) Positive controls first: if the enumeration is broken, fail here
|
|
// rather than passing (a) for the wrong reason.
|
|
Assert.Equal(ExpectedSetups, total);
|
|
Assert.Equal(ExpectedWithCylinder, withCylinder);
|
|
Assert.Equal(ExpectedSphereOnlyNoCylinder, sphereOnly);
|
|
Assert.Equal(ExpectedWithoutAnyPrimitive, withoutPrimitive);
|
|
Assert.Equal(ExpectedWithSummaryRadius, withRadius);
|
|
|
|
// (a) The negative claim the deletion rests on.
|
|
Assert.Empty(fallbackReachable);
|
|
// The wider guard sites 2 and 3 actually used. Zero here is what makes
|
|
// the headless-reachable deletion safe; the narrow guard above does
|
|
// not evaluate it.
|
|
Assert.Empty(fallbackReachableWideGuard);
|
|
}
|
|
}
|