core: chamber floors planned into the passage h(s) profile (L152, v239; surface landing support open)

Seed 2 planned grades 9.58/6.58/8.28 deg (were 19 deg); 0 solid in 320,355 passage interior samples; 0 shell,
chamber, wall violations; envelope audit clean. Open: the upper Surface World landing plane, fitted to the surface
route, leaves 5 route + 2 chamber support samples unsupported.

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 19:17:14 +01:00
1 parent 5bd158d4eb
commit 11b59a9a9e
12 files changed
+1315 -81

No files matched your search

@@ -0,0 +1,318 @@
#!/usr/bin/env python3
"""Audit cave primitive bounds against passage envelopes, allowing chamber joints only."""
from __future__ import annotations
import math
from typing import Any
INFLUENCE_REACH_M = 1.053334
SHELL_THICKNESS_M = 0.75
def _point(control: dict[str, Any], scale: float) -> tuple[float, float, float, float]:
x, y, z = control["position_q"]
return (x * scale, y * scale, z * scale, control["radius_q"] * scale)
def _knot_span(a, b) -> float:
return max(1.0e-6, math.sqrt(math.sqrt((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2)))
def _evaluate(controls, span: int, t: float):
p1, p2 = controls[span], controls[span + 1]
p0 = controls[span - 1] if span else controls[0]
p3 = controls[min(span + 2, len(controls) - 1)]
dt0, dt1, dt2 = _knot_span(p0, p1), _knot_span(p1, p2), _knot_span(p2, p3)
t2, t3 = t * t, t * t * t
result = []
for axis in (0, 1, 3):
m1 = dt1 * ((p1[axis] - p0[axis]) / dt0
- (p2[axis] - p0[axis]) / (dt0 + dt1)
+ (p2[axis] - p1[axis]) / dt1)
m2 = dt1 * ((p2[axis] - p1[axis]) / dt1
- (p3[axis] - p1[axis]) / (dt1 + dt2)
+ (p3[axis] - p2[axis]) / dt2)
value = ((2 * t3 - 3 * t2 + 1) * p1[axis]
+ (-2 * t3 + 3 * t2) * p2[axis]
+ (t3 - 2 * t2 + t) * m1 + (t3 - t2) * m2)
result.append(value)
radius = min(max(result[2], min(p1[3], p2[3])), max(p1[3], p2[3]))
return result[0], result[1], p1[2] + (p2[2] - p1[2]) * t, radius
def _segments(passage: dict[str, Any], scale: float):
controls = [_point(row, scale) for row in passage["control_points"]]
route_end = min(max(1, int(passage.get("lower_mouth_control_index", len(controls) - 1))),
len(controls) - 1)
along = 0.0
for span in range(route_end):
a, b = controls[span], controls[span + 1]
chord = math.hypot(b[0] - a[0], b[1] - a[1])
steps = max(1, math.ceil(chord / 2.0))
prior = _evaluate(controls, span, 0.0)
for step in range(1, steps + 1):
current = _evaluate(controls, span, step / steps)
length = math.dist(prior[:3], current[:3])
yield prior, current, along, max(prior[3], current[3]) + INFLUENCE_REACH_M
along += length
prior = current
def _distance_squared(a, b, bounds, t: float) -> float:
total = 0.0
for axis in range(3):
pos = a[axis] + (b[axis] - a[axis]) * t
lo, hi = bounds[axis]
gap = lo - pos if pos < lo else pos - hi if pos > hi else 0.0
total += gap * gap
return total
def _overlap_interval(a, b, bounds, radius: float):
cuts = {0.0, 1.0}
for axis in range(3):
delta = b[axis] - a[axis]
if abs(delta) < 1.0e-15:
continue
for edge in bounds[axis]:
t = (edge - a[axis]) / delta
if 0.0 < t < 1.0:
cuts.add(t)
cuts = sorted(cuts)
best_t, best_d2 = 0.0, math.inf
for lo, hi in zip(cuts, cuts[1:]):
mid = (lo + hi) * 0.5
quadratic = linear = 0.0
for axis in range(3):
delta = b[axis] - a[axis]
pos = a[axis] + delta * mid
low, high = bounds[axis]
edge = low if pos < low else high if pos > high else None
if edge is not None:
quadratic += delta * delta
linear += delta * (a[axis] - edge)
candidate = min(hi, max(lo, -linear / quadratic)) if quadratic else lo
d2 = _distance_squared(a, b, bounds, candidate)
if d2 < best_d2:
best_t, best_d2 = candidate, d2
for t in (0.0, 1.0):
d2 = _distance_squared(a, b, bounds, t)
if d2 < best_d2:
best_t, best_d2 = t, d2
if best_d2 > radius * radius:
return None
radius2 = radius * radius
if _distance_squared(a, b, bounds, 0.0) <= radius2:
left = 0.0
else:
low, high = 0.0, best_t
for _ in range(42):
mid = (low + high) * 0.5
if _distance_squared(a, b, bounds, mid) <= radius2:
high = mid
else:
low = mid
left = high
if _distance_squared(a, b, bounds, 1.0) <= radius2:
right = 1.0
else:
low, high = best_t, 1.0
for _ in range(42):
mid = (low + high) * 0.5
if _distance_squared(a, b, bounds, mid) <= radius2:
low = mid
else:
high = mid
right = low
return left, right, best_t
def _inside_chamber(point, chamber: dict[str, Any], scale: float) -> bool:
cx, cy, cz = (value * scale for value in chamber["floor_center_q"])
radius = chamber["radius_q"] * scale
clear = chamber["clear_height_q"] * scale
gx, gy = (value / 65536.0 for value in chamber["floor_gradient_q16"])
floor = cz + gx * (point[0] - cx) + gy * (point[1] - cy)
chamber_distance = max(math.hypot(point[0] - cx, point[1] - cy) - radius,
floor - point[2], point[2] - (floor + clear))
return chamber_distance <= SHELL_THICKNESS_M
def _primitive_bounds(row: dict[str, Any]):
return tuple((row["bounds_min_um"][i] / 1.0e6,
row["bounds_max_um"][i] / 1.0e6) for i in range(3))
def _bezier(points, t: float):
u = 1.0 - t
return tuple(u**3 * points[0][axis] + 3*u*u*t * points[1][axis]
+ 3*u*t*t * points[2][axis] + t**3 * points[3][axis]
for axis in range(3))
def _distance_to_ellipse(radial: float, vertical: float,
radius: float, height: float) -> float:
"""Euclidean distance to the edge bore's horizontal/vertical ellipse."""
radial = abs(radial)
vertical = abs(vertical)
if (radial / radius) ** 2 + (vertical / height) ** 2 <= 1.0:
return 0.0
lo, hi = 0.0, math.pi / 2.0
ratio = (math.sqrt(5.0) - 1.0) / 2.0
def squared_distance(angle: float) -> float:
return ((radial - radius * math.cos(angle)) ** 2
+ (vertical - height * math.sin(angle)) ** 2)
left = hi - ratio * (hi - lo)
right = lo + ratio * (hi - lo)
left_value, right_value = squared_distance(left), squared_distance(right)
for _ in range(48):
if left_value < right_value:
hi, right, right_value = right, left, left_value
left = hi - ratio * (hi - lo)
left_value = squared_distance(left)
else:
lo, left, left_value = left, right, right_value
right = lo + ratio * (hi - lo)
right_value = squared_distance(right)
return math.sqrt(min(left_value, right_value))
def _actual_edge_clearance(passage, edge, scale: float,
chamber: dict[str, Any]) -> float:
"""Return minimum true tube clearance outside the landing chamber.
The route edge is a swept ellipse, with its recorded polyline as the axis.
Comparing the tunnel tube to that ellipse avoids the false clashes caused by
intersecting two enclosing boxes.
"""
controls = [tuple(value / 1.0e6 for value in point)
for point in edge["control_points_um"]]
axis = [tuple(value / 1.0e6 for value in point)
for point in edge.get("polyline_um", [])]
if len(axis) < 2:
axis = [_bezier(controls, index / 64.0) for index in range(65)]
edge_radius = (edge["bore_radius_um"]
+ edge["irregularity_amplitude_um"]) / 1.0e6
edge_height = (edge["bore_height_um"]
+ edge["irregularity_amplitude_um"]) / 1.0e6
passage_segments = passage.get("_audit_segments") or tuple(_segments(passage, scale))
minimum_clearance = math.inf
for a, b, _, passage_radius in passage_segments:
length = math.dist(a[:3], b[:3])
steps = max(1, math.ceil(length / 0.05))
for step in range(steps + 1):
t = step / steps
point = tuple(a[i] + (b[i] - a[i]) * t for i in range(3))
if _inside_chamber(point, chamber, scale):
continue
tunnel_radius = (a[3] + (b[3] - a[3]) * t
+ INFLUENCE_REACH_M)
for start, end in zip(axis, axis[1:]):
delta = tuple(end[i] - start[i] for i in range(3))
length_squared = sum(value * value for value in delta)
projection = (sum((point[i] - start[i]) * delta[i]
for i in range(3)) / length_squared
if length_squared else 0.0)
projection = min(1.0, max(0.0, projection))
center = tuple(start[i] + projection * delta[i] for i in range(3))
radial = math.hypot(point[0] - center[0], point[1] - center[1])
vertical = abs(point[2] - center[2])
clearance = (_distance_to_ellipse(radial, vertical,
edge_radius, edge_height)
- tunnel_radius)
minimum_clearance = min(minimum_clearance, clearance)
return minimum_clearance
def _test_bounds(bounds, strate_index: int, passages, scale: float,
*, allow_chamber: bool = True):
for passage in passages:
if strate_index not in (passage["upper_strate_index"], passage["lower_strate_index"]):
continue
chamber_key = ("upper_landing_chamber" if strate_index == passage["upper_strate_index"]
else "lower_landing_chamber")
chamber = passage[chamber_key]
segments = passage.get("_audit_segments")
if segments is None:
segments = tuple(_segments(passage, scale))
for a, b, along, radius in segments:
expanded = [(a[i] - radius, b[i] + radius) if a[i] <= b[i]
else (b[i] - radius, a[i] + radius) for i in range(3)]
if any(expanded[i][1] < bounds[i][0] or expanded[i][0] > bounds[i][1]
for i in range(3)):
continue
overlap = _overlap_interval(a, b, bounds, radius)
if overlap is None:
continue
first, last, closest = overlap
if allow_chamber:
points = [tuple(a[i] + (b[i] - a[i]) * t for i in range(3))
for t in (first, closest, last)]
if all(_inside_chamber(point, chamber, scale) for point in points):
continue
point = tuple(a[i] + (b[i] - a[i]) * closest for i in range(3))
return passage["stable_id"], along + closest * math.dist(a[:3], b[:3]), point
return None
def audit_layout(layout: dict[str, Any]) -> dict[str, Any]:
scale = layout["core_voxel_size_um"] / (256.0 * 1.0e6)
passages = [dict(row, _audit_segments=tuple(_segments(row, scale)))
for row in layout.get("passages", [])]
primitives = [*layout.get("cavern_rooms", []), *layout.get("cavern_edges", [])]
checked = conflicts = chamber_joints = bounds_candidates = refined_false_positives = 0
first_conflict = None
for primitive in primitives:
bounds = _primitive_bounds(primitive)
checked += 1
primitive_conflicted = False
for passage in passages:
found = _test_bounds(bounds, primitive["strate_index"], [passage], scale)
if not found:
continue
bounds_candidates += 1
passage_id, station, point = found
if "control_points_um" in primitive:
side = ("upper_landing_chamber"
if primitive["strate_index"] == passage["upper_strate_index"]
else "lower_landing_chamber")
clearance = _actual_edge_clearance(passage, primitive, scale,
passage[side])
if clearance >= 0.0:
refined_false_positives += 1
continue
primitive_conflicted = True
conflicts += 1
if first_conflict is None:
first_conflict = {"primitive": primitive["stable_id"],
"passage": passage_id, "station_m": round(station, 3),
"center_m": [round(value, 3) for value in point]}
break
if not primitive_conflicted:
# Count the edge's named landing association as a confirmed joint.
anchor = primitive.get("start_anchor_stable_id", "")
if anchor.endswith(("/upper-landing-chamber", "/lower-landing-chamber")):
chamber_joints += 1
negative_controls = 0
long_passage = max(passages, key=lambda row: len(row["control_points"]), default=None)
if long_passage:
controls = [_point(row, scale) for row in long_passage["control_points"]]
index = min(max(1, len(controls) // 2), len(controls) - 2)
center = controls[index]
bounds = tuple((center[axis] - 0.25, center[axis] + 0.25) for axis in range(3))
# Select the side whose chamber is farther from this forced tunnel overlap.
strate = long_passage["lower_strate_index"]
if _test_bounds(bounds, strate, [long_passage], scale, allow_chamber=False):
negative_controls = 1
return {"primitives_checked": checked, "bounds_candidates": bounds_candidates,
"refined_edge_false_positives": refined_false_positives,
"outside_chamber_conflicts": conflicts,
"chamber_joints": chamber_joints, "negative_controls": negative_controls,
"negative_controls_expected": 1, "first_conflict": first_conflict,
"passed": conflicts == 0 and negative_controls == 1}
@@ -0,0 +1,42 @@
# L152 — Chamber floors belong to the planned passage profile
## Eye-height views
The left images are the L151 state used before this round. No after images were captured: the third planned-floor adjustment failed strict layout validation, and the round stopped at the requested three-fix limit.
| Landing | Before (L151) | After (L152) |
|---|---|---|
| passage/0-1/0 · upper | ![L151 upper landing, passage 0-1](../Linux151/captures/after-l151-0-1-0-upper-landing.jpg) | Not captured |
| passage/0-1/0 · lower | ![L151 lower landing, passage 0-1](../Linux151/captures/after-l151-0-1-0-lower-landing.jpg) | Not captured |
| passage/1-2/0 · upper | ![L151 upper landing, passage 1-2](../Linux151/captures/after-l151-1-2-0-upper-landing.jpg) | Not captured |
| passage/1-2/0 · lower | ![L151 lower landing, passage 1-2](../Linux151/captures/after-l151-1-2-0-lower-landing.jpg) | Not captured |
| passage/2-3/0 · upper | ![L151 upper landing, passage 2-3](../Linux151/captures/after-l151-2-3-0-upper-landing.jpg) | Not captured |
| passage/2-3/0 · lower | ![L151 lower landing, passage 2-3](../Linux151/captures/after-l151-2-3-0-lower-landing.jpg) | Not captured |
## Result
**L152 is not accepted.** Planning the chamber floor into the passage profile brought all three seed-2 planned grades under 15° and kept the passage shell and interiors clear. The remaining upper SurfaceWorld landing still leaves five route support samples unsupported, so the composed route gate fails.
The final build in the working tree is the last snapshot-valid variant, source stamp `b299076d814ff7cc098aa373cdc3a26533ed8bfe1ef6df1ea9de4d400d231b25`. The evaluator version is 239. No canonical owner baselines were changed or promoted.
## Fix attempts
1. The continuous `h(s)` profile with a chamber plane matching its tunnel tangent passed grade, chamber interior, and shell checks. Its 9.58° upper plane rose about 1.2 m toward the SurfaceWorld route and blocked 481 route capsule samples. Log: [`seed2-recheck.log`](../../../../Saved/Linux/l152/seed2-recheck.log), source stamp `e31f7ffa…`.
2. Fitting the upper plane to the receiving surface route removed the blockage. Five route samples then had no support, and the upper chamber support audit reported two unsupported samples. The summary remained `2/3` passages walkable. Log: [`seed2-plane-fit.log`](../../../../Saved/Linux/l152/seed2-plane-fit.log), layout: [`seed2-plane-fit.json`](../../../../Saved/Linux/l152/seed2-plane-fit.json).
3. Reducing that surface entrance chamber to 3 m was rejected by strict layout validation: it violated the minimum radius/capsule-clearance rule. Log: [`seed2-final.log`](../../../../Saved/Linux/l152/seed2-final.log). I reverted this rejected change to the snapshot-valid second variant and stopped at three attempts.
## Checks
- Final Clang 19 build passed with `-fp-contract=off`, four jobs, and the 6 GiB limit. Build log: [`build-clang.log`](../../../../Saved/Linux/l152/build-clang.log).
- `git diff --check` passed on the final source.
- Focused seed 2, W8: planned grade audits passed at 9.581°, 6.582°, and 8.280°. Passage interiors had 0 solid samples in 320,355 samples; the shell audit reported zero floor, chamber, wall, and interior violations. Naturalness, mouth profile, ripple, interior-air, Tunnel Network route, Vertical Shafts route, and their negative controls passed.
- The composed passage summary failed: `passed=2/3`, `route_walkable=2`; the SurfaceWorld route reported `unsupported=5`. The upper landing chamber also reported `unsupported=2` in its floor-support audit.
- The seed-2 geometric envelope audit passed: 549 primitives checked, 0 outside-chamber conflicts, 3 named chamber joints, and its negative control passed 1/1. Result: [`passage-envelope-seed2.json`](../../../../Saved/Linux/l152/passage-envelope-seed2.json).
- The tile seam audit did not run: the headless process returned at the failed composed passage summary before emitting `[PassageTileSeamAudit]`.
- The 16-seed sweeps, owner baseline regeneration, L152 captures, fast tier, Clang/GCC W1/W8/W12 determinism, L80 timing, and Linux UE build/start/movement were not run after the three-fix stop.
No Unreal `Source/` files changed.
## Remaining risk
The passage `h(s)` and chamber-floor profile still need a representation that preserves both the 15° grade budget and support across the SurfaceWorld entrance. The current analytic chamber plane cannot represent the route's local floor variation without either overriding the surface route or leaving support gaps. Multi-seed behavior and every gate not listed above remain unverified.
@@ -0,0 +1,206 @@
#!/usr/bin/env python3
"""Capture matched eye-height views from both ends of every owner tunnel."""
from __future__ import annotations
import json
import math
import os
from pathlib import Path
import re
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Standalone/data/owner_world.json"
OUT = ROOT / "Saved/Linux/l152/captures"
LAYOUT = OUT / "after-resolved-layout.json"
ARTIFACTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux152/captures"
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
VERSIONS = {
"before-l151": {
"headless": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l151-clang",
"renderer": ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-l151-clang",
"stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
},
"after-l152": {
"headless": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l152-clang",
"renderer": ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-l152-clang",
"stamp": "b299076d814ff7cc098aa373cdc3a26533ed8bfe1ef6df1ea9de4d400d231b25",
},
}
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
def fmt(values) -> str:
return ",".join(f"{value:.6f}" for value in values)
def angles(camera, target) -> tuple[float, float]:
dx, dy, dz = (target[index] - camera[index] for index in range(3))
return math.degrees(math.atan2(dx, dy)), math.degrees(
math.atan2(dz, math.hypot(dx, dy)))
def point_q(layout: dict, values) -> tuple[float, float, float]:
scale = layout["core_voxel_size_um"] / (256.0 * 1_000_000.0)
return tuple(value * scale for value in values)
def chamber_views(layout: dict) -> list[dict]:
result = []
for passage in layout["passages"]:
controls = passage["control_points"]
for side, endpoint, neighbor in (
("upper", controls[0], controls[1]),
("lower", controls[-1], controls[-2])):
chamber = passage[f"{side}_landing_chamber"]
center = point_q(layout, chamber["floor_center_q"])
a = point_q(layout, neighbor["position_q"])
b = point_q(layout, endpoint["position_q"])
dx, dy = a[0] - b[0], a[1] - b[1]
length = math.hypot(dx, dy)
if length <= 1.0e-9:
raise ValueError(f"degenerate {side} tunnel tangent: {passage['stable_id']}")
dx, dy = dx / length, dy / length
eye_z = center[2] + 1.45
distance = 9.0
target = (center[0] + dx * distance, center[1] + dy * distance,
eye_z + (chamber["floor_gradient_q16"][0] / 65536.0 * dx
+ chamber["floor_gradient_q16"][1] / 65536.0 * dy)
* distance)
camera = (center[0], center[1], eye_z)
slug = passage["stable_id"].replace("passage/", "").replace("/", "-")
result.append({"name": f"{slug}-{side}-landing", "passage": passage["stable_id"],
"side": side, "camera": camera, "target": target,
"focus": (center[0], center[1], eye_z, 18.0)})
return result
def stamped_run(name: str, command: list[object], log: Path, expected_stamp: str,
env: dict[str, str]) -> str:
binary = Path(str(command[0]))
probe = subprocess.run([*LIMIT, "timeout", "15s", str(binary), "--print-source-stamp"],
cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=20)
match = STAMP_RE.search(probe.stdout or "")
if probe.returncode or not match or match.group(1) != expected_stamp:
raise RuntimeError(f"{name}: source stamp mismatch for {binary}")
log.parent.mkdir(parents=True, exist_ok=True)
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", "1740s", *map(str, command)],
cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT,
timeout=1745, check=False)
output = log.read_text(encoding="utf-8", errors="replace")
emitted = STAMP_RE.search(output)
if result.returncode or not emitted or emitted.group(1) != expected_stamp:
raise RuntimeError(f"{name}: export or render failed; see {log}")
return output
def resolve_layout(env: dict[str, str]) -> dict:
config = VERSIONS["after-l152"]
command = [config["headless"], DATA, "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12",
"--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world", "--resolved-layout-only",
f"--resolved-layout-output={LAYOUT}"]
stamped_run("after-l152-resolve-layout", list(map(str, command)),
OUT / "after-l152-resolved-layout.log", config["stamp"], env)
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
if len(layout.get("passages", [])) != 3:
raise RuntimeError("owner layout did not resolve the expected three tunnels")
return layout
def main() -> int:
if not DATA.is_file():
raise SystemExit("missing owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
ARTIFACTS.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(OUT / "xdg-cache")
layout = resolve_layout(env)
views = chamber_views(layout)
quality_tool = ROOT / "Standalone/Tools/verify/capture_quality.py"
manifest = []
failures = []
for version, config in VERSIONS.items():
for view in views:
camera, target = view["camera"], view["target"]
yaw, pitch = angles(camera, target)
mesh_dir = OUT / "meshes" / version
mesh_dir.mkdir(parents=True, exist_ok=True)
mesh = mesh_dir / f"{view['name']}.vfmesh"
capture_layout = mesh_dir / f"{view['name']}-layout.json"
export = [config["headless"], DATA, "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12",
"--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world",
"--render-distance-chunks=0",
f"--camera={fmt((*camera, yaw, pitch))}",
f"--resolved-layout-output={capture_layout}", f"--mesh-export={mesh}"]
stamped_run(f"{version}-{view['name']}-export", list(map(str, export)),
OUT / f"{version}-{view['name']}-export.log", config["stamp"], env)
if not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError(f"{version}-{view['name']}: empty mesh export")
png = OUT / f"{version}-{view['name']}.png"
jpg = ARTIFACTS / f"{version}-{view['name']}.jpg"
render = [config["renderer"], mesh, png, "--size=1280x720",
"--fov-deg=78.0", f"--camera-m={fmt(camera)}",
f"--yaw-deg={yaw:.6f}", f"--pitch-deg={pitch:.6f}",
"--tile-skirts=off", "--shade=readable", "--headlamp=on",
"--height-tint=on", "--height-center-m=-950", "--height-range-m=60",
"--tile-edges=off", f"--focus-region={fmt(view['focus'])}"]
stamped_run(f"{version}-{view['name']}-render", list(map(str, render)),
OUT / f"{version}-{view['name']}-render.log", config["stamp"], env)
subprocess.run([*LIMIT, "timeout", "120s", "ffmpeg", "-nostdin",
"-hide_banner", "-loglevel", "error", "-y", "-i", png,
"-frames:v", "1", "-q:v", "4", jpg], cwd=ROOT, env=env,
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT,
timeout=125)
check = subprocess.run([*LIMIT, "timeout", "120s", sys.executable,
quality_tool, jpg], cwd=ROOT, env=env, text=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
check=False, timeout=125)
quality_ok = check.returncode == 0 and "status=PASS" in check.stdout
if not quality_ok:
failures.append(f"{version}-{view['name']}")
quality_line = (check.stdout.strip().splitlines()[-1]
if check.stdout.strip() else f"quality exit={check.returncode}")
manifest.append({"version": version, "view": view["name"],
"passage": view["passage"], "side": view["side"],
"file": str(jpg.relative_to(ROOT)), "camera_m": camera,
"target_m": target, "yaw_deg": yaw, "pitch_deg": pitch,
"source_stamp": config["stamp"],
"pose_layout_identity": layout.get("stable_identity"),
"quality_status": "PASS" if quality_ok else "FAIL",
"quality": quality_line})
print(f"[L152Capture] version={version} view={view['name']} "
f"quality={'PASS' if quality_ok else 'FAIL'} "
f"file={jpg.relative_to(ROOT)}", flush=True)
(ARTIFACTS / "manifest.json").write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
with (ARTIFACTS / "INDEX.md").open("w", encoding="utf-8") as index:
index.write("# L152 matched owner tunnel landing captures\n\n"
"Seed 0 camera poses resolved from the L152 owner layout and reused for both "
"versions. Each view is at eye height at one of the three tunnel landing "
"chambers. Before uses the L151 head build; after uses L152 source stamp "
f"`{VERSIONS['after-l152']['stamp']}`.\n\n")
for view in views:
index.write(f"## {view['passage']} / {view['side']} landing\n\n"
f"- Before: [image](before-l151-{view['name']}.jpg)\n"
f"- After: [image](after-l152-{view['name']}.jpg)\n\n")
index.write(f"Capture quality failures: {len(failures)}/{len(manifest)}.\n")
print(f"[L152CaptureSummary] chamber_views={len(views)} "
f"images={len(manifest)} quality_failures={len(failures)}", flush=True)
return 0 if not failures else 1
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as error:
print(f"[L152CaptureFailure] {error}", file=sys.stderr, flush=True)
raise SystemExit(1)
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""Compare L152 hashes and layout identity at Clang/GCC W1, W8, and W12."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
from PassageEnvelopeAudit import audit_layout
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l152/determinism"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"clang": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l152-clang",
"gcc": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l152-gcc",
}
STAMP = "b299076d814ff7cc098aa373cdc3a26533ed8bfe1ef6df1ea9de4d400d231b25"
CAMERA = "-20.062500,-5.068359,-900.353516,0,0"
HASH_RE = re.compile(
r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$",
re.M)
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def main() -> int:
if any(not path.is_file() for path in (DATA, *BINARIES.values())):
raise SystemExit("missing L152 Clang/GCC binary or composed owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
rows = []
partial = OUT / "runs-partial.json"
for compiler, binary in BINARIES.items():
for workers in (1, 8, 12):
name = f"determinism-{compiler}-w{workers}"
log, layout = OUT / f"{name}.log", OUT / f"{name}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=0",
f"--camera={CAMERA}", "--stream-hash", "--force-generate", "--seed=2",
"--recipe=surface-world", "--render-distance-chunks=0",
"--density-dispatch-report", f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp_match = STAMP_RE.search(content)
stamp = stamp_match.group(1) if stamp_match else None
hashes = tuple(HASH_RE.findall(content))
identity = (json.loads(layout.read_text(encoding="utf-8")).get("stable_identity")
if layout.is_file() else None)
envelope_audit = (audit_layout(json.loads(layout.read_text(encoding="utf-8")))
if layout.is_file() else None)
row = {"compiler": compiler, "workers": workers, "exit": proc.returncode,
"stamp": stamp, "source_stamp_matches": stamp == STAMP,
"hash_lines": len(hashes), "hashes": hashes,
"layout_identity": identity,
"envelope_audit": envelope_audit,
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
rows.append(row)
partial.write_text(json.dumps(rows, indent=2) + "\n", encoding="utf-8")
print("[L152DeterminismRun] " + json.dumps(row, sort_keys=True), flush=True)
valid = [row for row in rows if row["exit"] == 0 and row["source_stamp_matches"]
and row["hash_lines"] == 12 and row["layout_identity"]]
reference_hashes = valid[0]["hashes"] if valid else []
reference_identity = valid[0]["layout_identity"] if valid else None
deterministic = len(valid) == 6 and all(
row["hashes"] == reference_hashes and row["layout_identity"] == reference_identity
for row in valid)
envelope_pass = all(row["envelope_audit"] and row["envelope_audit"]["passed"]
and row["envelope_audit"]["negative_controls"] == 1
for row in rows)
summary = {"status": "PASS" if deterministic else "FAIL",
"deterministic": deterministic, "envelope_pass": envelope_pass,
"source_stamp": STAMP, "layout_identity": reference_identity, "runs": rows}
summary["status"] = "PASS" if deterministic and envelope_pass else "FAIL"
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
encoding="utf-8")
print(f"[L152DeterminismSummary] runs={len(rows)} deterministic="
f"{'PASS' if deterministic else 'FAIL'} envelope="
f"{'PASS' if envelope_pass else 'FAIL'} status={summary['status']}", flush=True)
return 0 if summary["status"] == "PASS" else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,184 @@
#!/usr/bin/env python3
"""Run the L152 passage and envelope gates across the 16 owner seeds."""
from __future__ import annotations
import argparse
import json
import re
import subprocess
import time
from pathlib import Path
from PassageEnvelopeAudit import audit_layout
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l152/seeds"
BIN = ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l152-clang"
DATA = ROOT / "Standalone/data/owner_world.json"
STAMP = "b299076d814ff7cc098aa373cdc3a26533ed8bfe1ef6df1ea9de4d400d231b25"
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
DISPATCH = {
"tunnel-network": re.compile(
r"^\[DensityDispatch\] strate=2 generator=TunnelNetwork "
r"recipe=Core\.Caves\.PrimitiveField version=1 "
r"bound_path=Caves-native adapter=FCavesFieldAdapter$", re.M),
"vertical-shafts": re.compile(
r"^\[DensityDispatch\] strate=3 generator=VerticalShafts "
r"recipe=Core\.Caves\.PrimitiveField version=1 "
r"bound_path=Caves-native adapter=FCavesFieldAdapter$", re.M),
}
ROUTES = {
"tunnel-network": re.compile(
r"^\[ResolvedStrateRouteAudit\] strate=2 .*unsupported=0 "
r"grade_failures=0 .*status=PASS$", re.M),
"vertical-shafts": re.compile(
r"^\[ResolvedStrateRouteAudit\] strate=3 .*unsupported=0 "
r"grade_failures=0 .*status=PASS$", re.M),
}
CONTROLS = {
"tunnel-network": re.compile(
r"^\[TunnelNetworkBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
"vertical-shafts": re.compile(
r"^\[VerticalShaftsBlockedRouteControl\].*expected=FAIL status=PASS$", re.M),
}
REQUIRED = {
"passage_summary": re.compile(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", re.M),
"seams": re.compile(r"^\[PassageTileSeamAudit\].*status=PASS$", re.M),
"shell": re.compile(r"^\[PassageShellAuditSummary\].*status=PASS$", re.M),
"naturalness": re.compile(r"^\[PassageNaturalnessSummary\].*status=PASS$", re.M),
"mouth_profile": re.compile(r"^\[PassageMouthProfileSummary\].*status=PASS$", re.M),
"ripple": re.compile(r"^\[PassageRippleAuditSummary\].*status=PASS$", re.M),
"interior_capsules": re.compile(
r"^\[PassageInteriorCapsuleAuditSummary\].*status=PASS$", re.M),
"layout_controls": re.compile(
r"^\[ResolvedLayoutValidatorControls\] rejected=10/10 status=PASS$", re.M),
"floor_profile_controls": re.compile(
r"^\[FloorProfileBlendNegativeControls\].*detected=true/true status=PASS$", re.M),
"naturalness_control": re.compile(
r"^\[PassageNaturalnessNegativeControl\].*detected=true$", re.M),
"mouth_control": re.compile(
r"^\[PassageMouthProfileNegativeControl\].*detected=true$", re.M),
}
def passage_rows(content: str) -> list[str]:
return re.findall(r"^\[ResolvedPassageAudit\].*$", content, re.M)
def grade_audit(content: str) -> tuple[bool, list[str]]:
rows = re.findall(r"^\[PassagePlanGradeAudit\].*$", content, re.M)
ids = set()
passed = bool(rows)
for row in rows:
identifier = re.search(r"\bid=([^ ]+)", row)
maximum = re.search(r"\bmax_grade_deg=([0-9.]+)", row)
limit = re.search(r"\blimit_deg=([0-9.]+)", row)
violations = re.search(r"\bviolations=(\d+)", row)
status = "status=PASS" in row
if identifier:
ids.add(identifier.group(1))
passed &= bool(identifier and maximum and limit and violations and status
and float(maximum.group(1)) <= float(limit.group(1))
and float(limit.group(1)) == 15.0
and int(violations.group(1)) == 0)
return passed and len(ids) >= 3, rows
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--kind", choices=tuple(DISPATCH), required=True)
args = parser.parse_args()
if not BIN.is_file() or not DATA.is_file():
raise SystemExit("missing L152 Clang binary or composed owner fixture")
mode_out = OUT / args.kind
mode_out.mkdir(parents=True, exist_ok=True)
results = []
partial = mode_out / "runs-partial.json"
for seed in range(16):
log = mode_out / f"seed{seed}.log"
layout = mode_out / f"seed{seed}.json"
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8", "--clip-radius=3",
"--max-clip-level=8", "--max-level=0", "--force-generate", f"--seed={seed}",
"--recipe=surface-world", "--density-dispatch-report",
"--audit-resolved-layout-passages", "--audit-passage-tile-seams",
f"--resolved-layout-output={layout}"]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
stamp = STAMP_RE.search(content)
checks = {name: bool(pattern.search(content)) for name, pattern in REQUIRED.items()}
checks["process_exit_zero"] = proc.returncode == 0
checks["source_stamp"] = stamp is not None and stamp.group(1) == STAMP
checks["dispatch"] = bool(DISPATCH[args.kind].search(content))
checks["route"] = bool(ROUTES[args.kind].search(content))
checks["blocked_route_control"] = bool(CONTROLS[args.kind].search(content))
passages = passage_rows(content)
checks["three_passages_walkable_and_open"] = (
len(passages) == 3 and all("walkability=PASS" in row
and "interior_air=PASS" in row
and re.search(r"\bblocked=0\b", row)
and re.search(r"\bunsupported=0\b", row)
and re.search(r"\bgrade_failures=0\b", row)
for row in passages))
checks["three_interior_negative_controls"] = len(re.findall(
r"^\[ResolvedPassageInteriorNegativeControl\].*detected=true status=PASS$",
content, re.M)) == 3
checks["three_ripple_gap_controls"] = len(re.findall(
r"^\[PassageRippleSamplingControl\].*status=PASS$", content, re.M)) == 3
checks["three_blocked_passage_controls"] = len(re.findall(
r"^\[ResolvedPassageBlockedControl\].*detected=true$", content, re.M)) == 3
chamber_rows = re.findall(r"^\[PassageLandingChamberAudit\].*$", content, re.M)
checks["six_chamber_floors"] = (len(chamber_rows) == 6 and all(
"status=PASS" in row and re.search(r"\bsolid_samples=0\b", row)
and re.search(r"\bgrade_failures=0\b", row) for row in chamber_rows))
checks["plan_grade"] = grade_audit(content)[0]
chamber_controls = re.search(
r"^\[PassageLandingChamberNegativeControlSummary\] "
r"detected=(\d+)/6 .*status=OBSERVED$", content, re.M)
checks["chamber_negative_control"] = bool(
chamber_controls and int(chamber_controls.group(1)) > 0)
checks["three_ripple_profiles"] = len(re.findall(
r"^\[PassageRippleAudit\].*status=PASS$", content, re.M)) >= 3
checks["passage_count"] = len(re.findall(
r"^\[ResolvedPassageAudit\].*walkability=PASS", content, re.M)) == 3
checks["layout_output"] = layout.is_file()
envelope = audit_layout(json.loads(layout.read_text(encoding="utf-8"))) \
if layout.is_file() else None
checks["envelope"] = bool(envelope and envelope["passed"]
and envelope["outside_chamber_conflicts"] == 0)
checks["envelope_negative_control"] = bool(envelope
and envelope["negative_controls"] == envelope["negative_controls_expected"] == 1)
passed = all(checks.values())
failed = [name for name, ok in checks.items() if not ok]
row = {"kind": args.kind, "seed": seed,
"verdict": "PASS" if passed else "FAIL",
"reason": ", ".join(failed) if failed else "all requested gates pass",
"exit": proc.returncode, "checks": checks,
"plan_grade_rows": grade_audit(content)[1],
"envelope_audit": envelope,
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)), "layout": str(layout.relative_to(ROOT))}
results.append(row)
print("[L152SeedSweep] " + json.dumps(row, sort_keys=True), flush=True)
partial.write_text(json.dumps(results, indent=2) + "\n", encoding="utf-8")
passed_count = sum(row["verdict"] == "PASS" for row in results)
summary = {"kind": args.kind, "source_stamp": STAMP, "seeds": list(range(16)),
"passed": passed_count, "failed": 16 - passed_count, "results": results}
(mode_out / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
encoding="utf-8")
print(f"[L152SeedSweepSummary] kind={args.kind} passed={passed_count}/16 "
f"failed={16-passed_count} status={'PASS' if passed_count == 16 else 'FAIL'}",
flush=True)
return 0 if passed_count == 16 else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,174 @@
#!/usr/bin/env python3
"""L80 comparison of L152 with the assembler/world baseline."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l152/timing"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"assembler-world": (
ROOT / "Saved/Linux/l137/bin/VoxelForgeCoreHeadless-l137-aa-a",
"4499fb2a8a4ede7d6cbc68d1b794f104658cdaae93ed9cacbc91fe7ff3fc3621"),
"planner-head": (
ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l152-clang",
"b299076d814ff7cc098aa373cdc3a26533ed8bfe1ef6df1ea9de4d400d231b25"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M)
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
binary, expected_stamp = BINARIES[version]
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(binary), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", f"--workers={workers}",
"--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
proc = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline, near, stamp = PIPELINE.search(content), NEAR.search(content), STAMP.search(content)
if (proc.returncode or pipeline is None or near is None or stamp is None
or stamp.group(1) != expected_stamp):
raise SystemExit(f"L80 timing failed or source stamp mismatch: {log}; exit={proc.returncode}")
fields = dict(FIELDS.findall(pipeline.group(1)))
row = {
"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "source_stamp": stamp.group(1),
"lod02_ready_s": float(near.group(3)),
"whole_view_ready_s": float(fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(fields["whole_tiles"].split("/")[0]),
"wall_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT)),
}
print("[L152TimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def quiet_machine() -> tuple[float, float]:
load_1m = os.getloadavg()[0]
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text().splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + values[4]
before = totals()
time.sleep(2.0)
after = totals()
idle = 100.0 * (after[1] - before[1]) / max(1, after[0] - before[0])
return load_1m, idle
def main() -> int:
if any(not path.is_file() for path in [DATA, *(entry[0] for entry in BINARIES.values())]):
raise SystemExit("missing L152 timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle = quiet_machine()
(OUT / "machine-load-before.txt").write_text(
f"1-minute load: {load_1m:.2f}\n2-second CPU idle: {idle:.1f}%\n")
print(f"[L152TimingGate] load_1m={load_1m:.2f} cpu_idle_2s={idle:.1f}%", flush=True)
if load_1m >= 1.5 or idle < 97.0:
raise SystemExit("timing refused: machine is above the L80 quiet-load gate")
rows = []
versions = tuple(BINARIES)
for strate in range(4):
for workers in (8, 12):
for version in versions:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
order = versions if replicate % 2 else tuple(reversed(versions))
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
measured = [row for row in rows if row["phase"] == "measured"]
summary = []
for strate in range(4):
for workers in (8, 12):
group = [row for row in measured
if row["strate"] == strate and row["workers"] == workers]
medians = {
version: {
key: statistics.median(row[key] for row in group
if row["version"] == version)
for key in ("lod02_ready_s", "whole_view_ready_s")
}
for version in versions
}
entry = {"strate": strate, "workers": workers,
"replicates_per_version": 5, "medians": medians}
for key in ("lod02_ready_s", "whole_view_ready_s"):
entry[f"planner_head_vs_assembler_world_{key}_delta_pct"] = round(
100.0 * (medians["planner-head"][key]
/ medians["assembler-world"][key] - 1.0), 2)
entry[f"{key}_paired_deltas_pct"] = [
round(100.0 * (
next(row[key] for row in group
if row["version"] == "planner-head"
and row["replicate"] == replicate)
/ next(row[key] for row in group
if row["version"] == "assembler-world"
and row["replicate"] == replicate) - 1.0), 3)
for replicate in range(1, 6)]
summary.append(entry)
(OUT / "summary.json").write_text(json.dumps({
"a_a_noise_floor_pct": 1.0,
"timing_protocol": (
"one warm-up per binary, five interleaved runs per cell, W8/W12, "
"all four owner layers; L137 A/A median noise floor ±1%"),
"runs": rows,
"summary": summary,
}, indent=2) + "\n", encoding="utf-8")
failed_cells = []
for entry in summary:
for measure in ("lod02_ready_s", "whole_view_ready_s"):
delta = entry[f"planner_head_vs_assembler_world_{measure}_delta_pct"]
if delta > 1.0:
failed_cells.append({"strate": entry["strate"],
"workers": entry["workers"],
"measure": measure, "delta_pct": delta})
report = json.loads((OUT / "summary.json").read_text(encoding="utf-8"))
report["performance_floor_pct"] = 1.0
report["performance_floor_rule"] = (
"pass when no L152 median is more than 1% slower than assembler/world")
report["performance_floor_failures"] = failed_cells
report["status"] = "PASS" if not failed_cells else "FAIL"
(OUT / "summary.json").write_text(json.dumps(report, indent=2) + "\n",
encoding="utf-8")
print(f"[L152TimingSummary] cells={len(summary)} failing_metrics={len(failed_cells)} "
f"status={'PASS' if not failed_cells else 'FAIL'}", flush=True)
return 0 if not failed_cells else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,170 @@
#!/usr/bin/env python3
"""Measure planner HEAD and code-equivalent assembler/world with the L121/L127 runners."""
from __future__ import annotations
import importlib.util
import json
import os
from pathlib import Path
import statistics
import sys
ROOT = Path(__file__).resolve().parents[4]
RESEARCH = ROOT / "Standalone/Research/WorldAssemblerM3"
EDITOR = Path("/home/jahni/UnrealEngine/Engine/Binaries/Linux/UnrealEditor-Cmd")
HOSTS = {
"assembler-world": ROOT / "Saved/Linux/l127/ue-baseline-project",
"planner-head": Path("/home/jahni/VFHost"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
def load(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
if spec is None or spec.loader is None:
raise RuntimeError(f"cannot load {path}")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def configure(arrival, movement, label: str):
host = HOSTS[label].resolve()
out = ROOT / "Saved/Linux/l152/ue" / label
plugin_saved = host / "Plugins/VoxelForge/Saved/Linux/l152"
out.mkdir(parents=True, exist_ok=True)
plugin_saved.mkdir(parents=True, exist_ok=True)
os.environ["XDG_CONFIG_HOME"] = str(out / "config")
arrival.HOST = host
arrival.EDITOR = EDITOR
arrival.OUT = out / "start"
arrival.HOST_SAVED = out / "host"
arrival.HOST_PLUGIN_SAVED = plugin_saved
arrival.RUN_TIMEOUT_S = 1740
movement.HOST = host
movement.EDITOR = EDITOR
movement.OUT = out / "movement"
movement.HOST_SAVED = out / "host"
movement.HOST_OUT = plugin_saved / "movement"
movement.RUN_TIMEOUT_S = 1740
return host, out
def start_matrix(arrival, movement, label: str) -> dict:
host, out = configure(arrival, movement, label)
spawns = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
starts = []
for index, position in spawns.items():
stratum = "FI" if index == 1 else "SW"
arrival.SPAWNS_M[stratum] = position
row = arrival.run(stratum, 1, f"start-s{index}", 8, 1, 0, 1, 1, 0, 1,
False, False, 1)
row["strate_index"] = index
row["spawn_m"] = list(position)
if row.get("lod02_full_settled_t_s") is None:
raise RuntimeError(f"LOD0-2 did not settle for S{index}: {row}")
starts.append(row)
print("[L152UEStart] " + json.dumps(row, sort_keys=True), flush=True)
(out / "start-summary.json").write_text(
json.dumps(starts, indent=2, sort_keys=True) + "\n", encoding="utf-8")
row = moving_run(movement, label, 1)
(out / "movement-first.json").write_text(
json.dumps(row, indent=2, sort_keys=True) + "\n", encoding="utf-8")
print("[L152UEMovement] " + json.dumps(row, sort_keys=True), flush=True)
return {"host": str(host), "starts": starts, "first_movement": row}
def moving_run(movement, label: str, repetition: int) -> dict:
condition = "c743f2a" if label == "assembler-world" else "planner-head"
row = movement.run_unreal(condition, repetition)
events = movement.parse_events(ROOT / row["trace"])
row["supplemental_far_applies_moving"] = sum(
int(event.get("supplemental_far_applies", 0))
for event in events
if event.get("type") == "apply_frame"
and float(event.get("speed_cm_s", 0.0)) >= 50.0)
if row.get("effective_tile_slots") != 8:
raise RuntimeError(f"expected eight effective tile slots: {row}")
return row
def main() -> int:
out = ROOT / "Saved/Linux/l152/ue"
out.mkdir(parents=True, exist_ok=True)
arrival = load("l150_arrival", RESEARCH / "Linux121/RunL121Arrival.py")
movement = load("l150_movement", RESEARCH / "Linux121/RunL121Movement.py")
summaries = {}
all_runs = {label: [] for label in HOSTS}
for label in HOSTS:
summaries[label] = start_matrix(arrival, movement, label)
all_runs[label].append(summaries[label]["first_movement"])
for repetition in range(2, 6):
order = ("planner-head", "assembler-world") if repetition % 2 == 0 \
else ("assembler-world", "planner-head")
for label in order:
configure(arrival, movement, label)
row = moving_run(movement, label, repetition)
all_runs[label].append(row)
(out / "movement-runs-partial.json").write_text(
json.dumps(all_runs, indent=2, sort_keys=True) + "\n", encoding="utf-8")
print("[L152UEMovementRepeat] " + json.dumps({
key: row.get(key) for key in (
"condition", "repetition", "near_ready_moving_mean_pct",
"far_holes_moving_mean_pct", "game_thread_tick_p99_ms",
"game_thread_tick_max_ms", "supplemental_far_applies_moving",
"wall_s", "trace")}, sort_keys=True), flush=True)
keys = ("near_ready_moving_mean_pct", "far_holes_moving_mean_pct",
"game_thread_tick_p99_ms", "game_thread_tick_max_ms")
medians = {
label: {key: statistics.median(row[key] for row in rows) for key in keys}
for label, rows in all_runs.items()
}
delta = {
key: round(100.0 * (medians["planner-head"][key]
/ medians["assembler-world"][key] - 1.0), 2)
for key in keys
}
result = {
"baseline_commit": "c743f2a (code-equivalent to assembler/world eb47d72)",
"protocol": (
"L121 arrival and L127 movement; starts at four owner strata; five interleaved "
"30 m/s runs per build; 12 s move plus 5 s dwell; eight effective tile slots"),
"starts": summaries,
"movement_runs": all_runs,
"movement_medians": medians,
"planner_head_vs_assembler_world_delta_pct": delta,
}
(out / "summary.json").write_text(
json.dumps(result, indent=2, sort_keys=True) + "\n", encoding="utf-8")
print("[L152UESummary] " + json.dumps({
"movement_medians": medians,
"planner_head_vs_assembler_world_delta_pct": delta,
"starts_s": {
label: [round(row["lod02_full_settled_t_s"], 3)
for row in summary["starts"]]
for label, summary in summaries.items()
},
}, sort_keys=True), flush=True)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as error:
print(f"[L152UEFailure] {error}", file=sys.stderr, flush=True)
raise SystemExit(1)