wip: opt-in landing-pad contract + Core.Liminal.Field v2 pads (L145)

Layers may publish certified arrival/departure pads; the passage planner binds endpoints and tangents to them;
no-pad layouts serialize unchanged (owner canonical hashes match v227). Pads removed the endpoint grade failures;
seeds 0-4 passed at a 45 m margin, but seed 5 still has 289 blocked passage-capsule samples ~29 m before the
departure pad, where the composed field stays solid (-0.162) inside the tube over native ground (-3.6). Ripple
audit now keeps true route distance across masked gaps (with a synthetic control).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-11-01 12:19:30 +01:00
1 parent a45ba9bb10
commit 7d654ff861
14 files changed
+1228 -66

No files matched your search

+121 -7
View File
@@ -613,7 +613,28 @@ namespace
for(std::size_t v=0;v<anchor.values.size();++v){if(v)out<<',';out<<anchor.values[v];}
out<<"]}";
}
out<<"]}";
out<<']';
if(!x.landingPads.empty())
{
out<<",\"landing_pads\":[";
for(std::size_t p=0;p<x.landingPads.size();++p)
{
if(p)out<<',';const auto& pad=x.landingPads[p];
out<<"{\"stable_id\":"<<LayoutEscape(pad.stableId)
<<",\"role\":"<<static_cast<std::uint32_t>(pad.role)
<<",\"position_q\":["<<pad.positionSubvoxels[0]<<','
<<pad.positionSubvoxels[1]<<','<<pad.positionSubvoxels[2]
<<"],\"floor_q\":"<<pad.floorHeightSubvoxels
<<",\"approach_q16\":["<<pad.approachDirectionQ16[0]<<','
<<pad.approachDirectionQ16[1]<<']'
<<",\"clearance_q\":"<<pad.clearanceSubvoxels
<<",\"support_depth_q\":"<<pad.supportDepthSubvoxels
<<",\"certified\":"
<<(pad.certifiedWalkableWithSupport?"true":"false")<<'}';
}
out<<']';
}
out<<'}';
}
out<<"],\"passages\":[";
for(std::size_t i=0;i<s.passages.size();++i)
@@ -957,6 +978,9 @@ bool ResolvedLayoutSnapshotV3::finalize(std::string& error)
for(std::size_t i=0;i<strates.size();++i)
{
auto& x=strates[i];x.order=static_cast<std::int32_t>(i);
std::stable_sort(x.landingPads.begin(),x.landingPads.end(),[](const auto& a,const auto& b)
{return a.role!=b.role?static_cast<std::uint32_t>(a.role)
<static_cast<std::uint32_t>(b.role):a.stableId<b.stableId;});
if(x.stableId.empty())x.stableId=worldIdentity+"/strate/"+std::to_string(x.strateIndex);
if(x.content.kind.empty())x.content.kind="content";
if(x.ceiling.kind.empty())x.ceiling.kind="ceiling";
@@ -1017,9 +1041,40 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
const auto add=[&](std::string code,std::string detail)
{issues.push_back({std::move(code),std::move(detail)});};
const bool strict=mode==ResolvedLayoutValidationModeV3::strict;
const std::int64_t playerCenterAboveFloorQ=static_cast<std::int64_t>(std::llround(
1.13*WorldAssemblySubvoxelsPerVoxel*1000000.0/coreVoxelSizeMicrometres));
for(std::size_t i=0;i<strates.size();++i)
{
const auto& s=strates[i];
std::vector<std::string> landingPadIds;
for(const auto& pad:s.landingPads)
{
if(pad.stableId.empty()
||std::find(landingPadIds.begin(),landingPadIds.end(),pad.stableId)
!=landingPadIds.end())
add("landing_pad_identity",s.stableId+" has an empty or duplicate landing-pad ID");
else landingPadIds.push_back(pad.stableId);
const auto role=static_cast<std::uint32_t>(pad.role);
const std::int64_t directionX=pad.approachDirectionQ16[0];
const std::int64_t directionY=pad.approachDirectionQ16[1];
const std::int64_t directionLengthSquared=directionX*directionX+directionY*directionY;
constexpr std::int64_t UnitQ16Squared=1ll<<32;
const bool unitDirection=directionLengthSquared>=UnitQ16Squared*98/100
&&directionLengthSquared<=UnitQ16Squared*102/100;
const std::int64_t floorMicrometres=pad.floorHeightSubvoxels
*static_cast<std::int64_t>(coreVoxelSizeMicrometres)
/WorldAssemblySubvoxelsPerVoxel;
if(role>static_cast<std::uint32_t>(ResolvedLayoutLandingPadRoleV1::departure)
||pad.positionSubvoxels[2]
!=pad.floorHeightSubvoxels+playerCenterAboveFloorQ
||!s.content.presentInCurrentField
||floorMicrometres<s.content.bottomMicrometres
||floorMicrometres>=s.content.topMicrometres
||!unitDirection||pad.clearanceSubvoxels<=0
||pad.supportDepthSubvoxels<=0
||!pad.certifiedWalkableWithSupport)
add("landing_pad_contract",s.stableId+" publishes an uncertified or malformed landing pad");
}
const std::int64_t effectiveTransitionWidth=LayoutTransitionLimit(s);
if(s.interiorTopMicrometres<=s.interiorBottomMicrometres)
add("invalid_interior",s.stableId+" has non-positive content height");
@@ -1643,6 +1698,22 @@ std::optional<ResolvedLayoutSnapshotV3> ResolvedLayoutSnapshotV3::FromJson(
for(const auto& a:v.Get("anchors").AsArray())
{ResolvedLayoutAnchorV2 p;p.kind=LayoutString(a,"kind");p.stableId=LayoutString(a,"stable_id");p.units=LayoutString(a,"units");
for(const auto& value:a.Get("values").AsArray())p.values.push_back(value.Integer());x.anchors.push_back(std::move(p));}
for(const auto& value:v.Get("landing_pads").AsArray())
{
ResolvedLayoutLandingPadV1 pad;pad.stableId=LayoutString(value,"stable_id");
pad.role=static_cast<ResolvedLayoutLandingPadRoleV1>(LayoutInt(value,"role"));
const auto& position=value.Get("position_q").AsArray();
for(std::size_t axis=0;axis<3&&axis<position.size();++axis)
pad.positionSubvoxels[axis]=position[axis].Integer();
pad.floorHeightSubvoxels=LayoutInt(value,"floor_q");
const auto& approach=value.Get("approach_q16").AsArray();
for(std::size_t axis=0;axis<2&&axis<approach.size();++axis)
pad.approachDirectionQ16[axis]=static_cast<std::int32_t>(approach[axis].Integer());
pad.clearanceSubvoxels=LayoutInt(value,"clearance_q");
pad.supportDepthSubvoxels=LayoutInt(value,"support_depth_q");
pad.certifiedWalkableWithSupport=LayoutBool(value,"certified");
x.landingPads.push_back(std::move(pad));
}
s.strates.push_back(std::move(x));
}
for(const auto& v:root.Get("passages").AsArray())
@@ -2566,6 +2637,17 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
{return c.upperStrateIndex==strate;});
return it==configs.end()?nullptr:&*it;
};
const auto landingPadFor=[](const ResolvedLayoutStratumV2& stratum,
ResolvedLayoutLandingPadRoleV1 role,std::uint32_t ordinal)
->const ResolvedLayoutLandingPadV1*
{
std::vector<const ResolvedLayoutLandingPadV1*> candidates;
for(const auto& pad:stratum.landingPads)
if(pad.role==role)candidates.push_back(&pad);
std::sort(candidates.begin(),candidates.end(),[](const auto* a,const auto* b)
{return a->stableId<b->stableId;});
return ordinal<candidates.size()?candidates[ordinal]:nullptr;
};
const auto routeAnchor=[](const ResolvedLayoutStratumV2& s,bool departure,
std::array<std::int64_t,3>& out)
{
@@ -2662,9 +2744,37 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
passage.upperStrateIndex=upper.strateIndex;passage.lowerStrateIndex=lower.strateIndex;
passage.placementRadiusSubvoxels=placementRadius;
passage.mouthRadiusSubvoxels=mouthRadius;passage.midRadiusSubvoxels=midRadius;
const auto* upperDeparturePad=landingPadFor(upper,
ResolvedLayoutLandingPadRoleV1::departure,connection);
const auto* lowerArrivalPad=landingPadFor(lower,
ResolvedLayoutLandingPadRoleV1::arrival,connection);
const auto validateLandingPad=[&](const ResolvedLayoutLandingPadV1* pad,
std::string_view side)
{
if(!pad)return true;
const std::int64_t requiredClearance=mouthRadius
+static_cast<std::int64_t>(std::llround(0.34*qPerMetre));
if(!pad->certifiedWalkableWithSupport||pad->clearanceSubvoxels<requiredClearance
||pad->supportDepthSubvoxels<static_cast<std::int64_t>(std::llround(0.50*qPerMetre))
||!radialWithin(pad->positionSubvoxels,placementRadius)
||pad->positionSubvoxels[2]
!=pad->floorHeightSubvoxels+playerCenterAboveFloorQ)
{
error=passage.stableId+" "+std::string(side)
+" landing pad is uncertified, unsupported, too tight, or outside PassageConfig.DistanceMax";
return false;
}
return true;
};
if(!validateLandingPad(upperDeparturePad,"departure")
||!validateLandingPad(lowerArrivalPad,"arrival"))return false;
std::array<std::int64_t,3> upperMouth{},lowerMouth{};
const bool hasUpperRoute=connection==0&&routeAnchor(upper,true,upperMouth);
const bool hasLowerRoute=connection==0&&routeAnchor(lower,false,lowerMouth);
const bool hasUpperRoute=upperDeparturePad
?(upperMouth=upperDeparturePad->positionSubvoxels,true)
:connection==0&&routeAnchor(upper,true,upperMouth);
const bool hasLowerRoute=lowerArrivalPad
?(lowerMouth=lowerArrivalPad->positionSubvoxels,true)
:connection==0&&routeAnchor(lower,false,lowerMouth);
const bool surfaceGroundDeparture=hasUpperRoute&&upperIsSurfaceWorld;
const ResolvedLayoutAnchorV2* passageAnchor=nullptr;
if(connection==0)
@@ -2713,13 +2823,17 @@ bool PlanResolvedLayoutPassagesV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
constexpr std::int64_t LandingExtensionQ=8;
std::array<std::int64_t,2> upperTangent{},lowerTangent{};
const bool hasUpperTangent=hasUpperRoute
&&routeTangent(upper,true,upperTangent);
const bool hasUpperTangent=upperDeparturePad
?(upperTangent={upperDeparturePad->approachDirectionQ16[0],
upperDeparturePad->approachDirectionQ16[1]},true)
:hasUpperRoute&&routeTangent(upper,true,upperTangent);
const bool hasPassageArrival=std::any_of(lower.anchors.begin(),lower.anchors.end(),
[](const auto& anchor){return anchor.kind=="passage_arrival"
&&anchor.values.size()>=3;});
const bool hasLowerTangent=hasLowerRoute&&!hasPassageArrival
&&routeTangent(lower,false,lowerTangent);
const bool hasLowerTangent=lowerArrivalPad
?(lowerTangent={lowerArrivalPad->approachDirectionQ16[0],
lowerArrivalPad->approachDirectionQ16[1]},true)
:hasLowerRoute&&!hasPassageArrival&&routeTangent(lower,false,lowerTangent);
const bool profiledSurfaceJoin=hasLowerTangent
&&std::any_of(lower.anchors.begin(),lower.anchors.end(),
[](const auto& anchor){return anchor.kind=="heightfield_profile"