fix(correctness): false AllAir certificates and a stale shaft cache key; 44/44 tests green

The harness's first full suite run showed 16 of 44 tests failing. Two were real defects in the owner's world:

1. ParameterRoll: the tile classifier could certify a box AllAir while the final field is solid there (3 false proofs found, e.g. density -2.092319 at (-192,16,-224)). Cause: the box diagnostic narrowed 'tail reach' to 'air reach', so the swept tunnel FLOOR -- which writes solid -- did not count as reaching the box. A false AllAir skips meshing, i.e. missing floor in game. The classifier now uses the same reach predicate as the final writer (swept chain, floor band, relief, room-mouth envelope) and propagates it through Mixed refinement nodes. Re-run: 1,288,143 lattice samples, 0 violations.

2. VerticalShaftEquivalence: LedgeSpacing and LedgeDepth were missing from the production TLS cache key, so a shaft could reuse stale ledge parameters. Both are now in the key.

The other 14: broken fixtures (missing staged corpus assets, a sampler leaking the shaft TLS marker between queries, stale candidate IDs, a window entirely inside the common tail) or stale expectations after this week's owner decisions (no authored tunnel floor, slope in degrees, rooms owning their interior). No test was deleted or weakened into vacuity; retired legacy comparisons stay as telemetry and the current stack is asserted instead. PassageLandsInOpenSpace now requires a real player-capsule fit in the final density at each authored landing (14/14, worst gradient 0.115723).

Suite: 42 tests green in one run, the two long op-stack sweeps green in serialized filtered runs (the 1800 s launch guard); a harness timeout-recording bug was fixed. Bounded probe exports unchanged (canonical 94B47A1C, owner 44E7C813). ⚠️ Harness perf scenario moved 50.74 s -> 53.58 s worker (+5.6%): the wider reach predicate skips fewer boxes. Measure on the game path and decide before merging.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-18 13:13:21 +02:00
1 parent cc04c0bd4e
commit 7af8d0e870
18 files changed
+772 -465

No files matched your search

@@ -781,11 +781,17 @@ namespace
void VF_ValidateStructProperties(const TMap<FString, FProperty*>& Properties,
const TSet<FString>& ExpectedNames,
const FString& ParamStructName,
ECaveGeneratorType Archetype,
bool& bSchemaValid, FString& SchemaError)
{
for (const TPair<FString, FProperty*>& Pair : Properties)
{
if (!ExpectedNames.Contains(Pair.Key))
// A reflected compatibility property may be intentionally absent from the
// tunable-field X-macro. Keep it visible in reflection/serialization, but let the
// explicit exclusion list explain why it is not blended or rolled.
const bool bExplicitlyExcluded =
VF_IsTunnelArchetype(Archetype) && VF_FindExclusion(Pair.Key) != nullptr;
if (!ExpectedNames.Contains(Pair.Key) && !bExplicitlyExcluded)
{
bSchemaValid = false;
VF_AppendSchemaError(SchemaError,
@@ -1129,6 +1135,8 @@ namespace
if (FieldName == TEXT("RoomFloorCutMax")) return Set(0.0f, 1.0f);
if (FieldName == TEXT("FloorReliefStrength")) return Set(0.0f, HQuarter);
if (FieldName == TEXT("FloorReliefFrequency")) return Set(0.001f, 0.10f);
if (FieldName == TEXT("RoomMouthRiseStrength")) return Set(0.0f, 1.0f);
if (FieldName == TEXT("RoomMouthRiseBlendVoxels")) return Set(8.0f, 128.0f);
if (FieldName == TEXT("OriginRoomRadius")) return Set(24.0f, FMath::Max(64.0f, H * 0.75f));
if (FieldName == TEXT("TunnelMinRadius")) return Set(6.0f, FMath::Max(8.0f, HQuarter));
if (FieldName == TEXT("TunnelMaxRadius")) return Set(8.0f, FMath::Max(16.0f, H * 0.25f));
@@ -1422,11 +1430,19 @@ namespace
void* Memory,
FRandomStream& ScalarRng,
FRandomStream& CategoryRng,
float StrateHeightInVoxels)
float StrateHeightInVoxels,
FString* OutFailureReason = nullptr)
{
UStruct* Struct = VF_GetParamStruct(Archetype);
if (Struct == nullptr || Memory == nullptr)
{
if (OutFailureReason != nullptr)
{
*OutFailureReason = Struct == nullptr
? FString::Printf(TEXT("no reflected parameter struct for archetype %d"),
static_cast<int32>(Archetype))
: TEXT("reflected parameter memory was null");
}
return false;
}
@@ -1453,6 +1469,11 @@ namespace
if (!VF_IsScalarProperty(Property))
{
bValid = false;
if (OutFailureReason != nullptr && OutFailureReason->IsEmpty())
{
*OutFailureReason = FString::Printf(
TEXT("reflected field '%s' is not scalar"), *FieldName);
}
continue;
}
@@ -1467,6 +1488,11 @@ namespace
// No current non-tunnel family has an enum. Keep the failure explicit if one is
// added without a legal-value declaration instead of silently writing a default.
bValid = false;
if (OutFailureReason != nullptr && OutFailureReason->IsEmpty())
{
*OutFailureReason = FString::Printf(
TEXT("reflected enum field '%s' has no legal-value sampler"), *FieldName);
}
continue;
}
@@ -1475,10 +1501,21 @@ namespace
StrateHeightInVoxels, Range))
{
bValid = false;
if (OutFailureReason != nullptr && OutFailureReason->IsEmpty())
{
*OutFailureReason = FString::Printf(
TEXT("reflected field '%s' has no declared roll range"), *FieldName);
}
continue;
}
bValid = VF_WritePropertyValue(Property, Memory,
VF_RollCorpusFreeFloat(ScalarRng, Range)) && bValid;
const bool bWrote = VF_WritePropertyValue(Property, Memory,
VF_RollCorpusFreeFloat(ScalarRng, Range));
bValid = bWrote && bValid;
if (!bWrote && OutFailureReason != nullptr && OutFailureReason->IsEmpty())
{
*OutFailureReason = FString::Printf(
TEXT("could not write reflected field '%s'"), *FieldName);
}
}
return bValid;
}
@@ -1900,6 +1937,7 @@ namespace
Mode == EVoxelStrateCorpusFreeSamplingMode::ConstraintSampled;
bool bValid = false;
FString ReflectionFailure;
if (VF_IsTunnelArchetype(Archetype))
{
bValid = VF_SampleTunnelFields(Params.TunnelNetworkParams, ScalarRng,
@@ -1909,7 +1947,8 @@ namespace
else
{
bValid = VF_SampleReflectedFields(Archetype, VF_GetParamMemory(Params, Archetype),
ScalarRng, CategoryRng, StrateHeightInVoxels);
ScalarRng, CategoryRng, StrateHeightInVoxels,
&ReflectionFailure);
}
if (bValid && bConstraintSampled)
{
@@ -1949,7 +1988,11 @@ namespace
}
if (!bValid)
{
Result.FailureReason = TEXT("Corpus-free field schema has no declared roll range.");
Result.FailureReason = ReflectionFailure.IsEmpty()
? FString::Printf(TEXT("Corpus-free sampler rejected archetype %d (mode %d) "
"without a field-specific reason."),
static_cast<int32>(Archetype), static_cast<int32>(Mode))
: ReflectionFailure;
return Result;
}
@@ -3241,6 +3284,10 @@ const TArray<FVoxelStrateFieldExclusion>& FVoxelStrateCorpus::GetNonTunableField
VF_AddExclusion(Result, TEXT("ChimneyMaxRadius"), DeadTerrainOpReason);
VF_AddExclusion(Result, TEXT("ChimneyHeight"), DeadTerrainOpReason);
VF_AddExclusion(Result, TEXT("bTunnelFloorEnabled"), TEXT(
"Deprecated serialized compatibility field: tunnel geometry always owns its floor, "
"so this value is ignored and must not be blended or rolled."));
VF_AddExclusion(Result, TEXT("StrateTopWorldZ"), TEXT(
"Runtime Z bound supplied by UVoxelStrateManager for the active layout slot; not a tunable."));
VF_AddExclusion(Result, TEXT("StrateBottomWorldZ"), TEXT(
@@ -3324,14 +3371,15 @@ void FVoxelStrateCorpus::RebuildSpreads()
TEXT("StrateBottomWorldZ"), EVoxelStrateFieldKind::Continuous);
}
VF_ValidateStructProperties(Properties, ExpectedNames, ParamStructName,
VF_ValidateStructProperties(Properties, ExpectedNames, ParamStructName, Archetype,
bSchemaValid, SchemaError);
if (VF_IsTunnelArchetype(Archetype))
{
for (const FVoxelStrateFieldExclusion& Exclusion : GetNonTunableFields())
{
if (!ExpectedNames.Contains(Exclusion.FieldName))
if (!ExpectedNames.Contains(Exclusion.FieldName)
&& !Properties.Contains(Exclusion.FieldName))
{
bSchemaValid = false;
VF_AppendSchemaError(SchemaError,