tools(verify): fast/medium/full verification tiers with a compiled-in source stamp (L39); research R6

BuildLinux.sh hashes a sorted manifest of compiled inputs into VOXELFORGE_SOURCE_STAMP, printed first by
every executable; Standalone/Tools/verify/verify.py checks it before and after each tier and records
binary/input hashes and the resolved recipe, style map and layout. Fast (163 s) runs on the canonical owner
world only and asserts FI Style 2 / SW Style 1; medium (8 min) and full (26 min) add the style matrix,
GCC, determinism and cost. Controls: stale source, mislabelled style-0 owner, all-black capture, L30/L31,
L35/L36 and the L38 step are all rejected. No geometry change; owner hashes identical to L37.
Research R6: leak table, generator contract and a 10-step metre-native migration plan.

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-10-23 15:27:52 +02:00
1 parent 88c54eab44
commit 753cc9c259
22 files changed
+1831 -163

No files matched your search

@@ -25,7 +25,7 @@ FRAGMENT_MAX_AREA_M2 = 0.05
FRAGMENT_MAX_DISTANCE_M = 12.0
def small_components(triangles):
def small_components(triangles, center=None):
parent = list(range(len(triangles)))
sizes = [1] * len(triangles)
owners = {}
@@ -67,7 +67,7 @@ def small_components(triangles):
ab[0] * ac[1] - ab[1] * ac[0])
item["area"] += 0.5 * math.sqrt(sum(value * value for value in cross))
cx, cy = CENTER
cx, cy = center or CENTER
small = []
below_floor = []
for item in components.values():
@@ -81,12 +81,21 @@ def small_components(triangles):
return len(components), small, below_floor
def audit(path):
cx, cy = CENTER
bounds = (cx - OUTER, cx + OUTER, cy - OUTER, cy + OUTER)
voxel_um, triangles, tiles = RING.read_scene(
str(path), 0, HEIGHT_MIN, HEIGHT_MAX, bounds)
component_count, fragments, below_floor = small_components(triangles)
def audit(path, scene_data=None, center=None, height_min=None, height_max=None,
preferred=None, inner=None, outer=None, normal_limit=None,
coverage_limit=None, fragment_gate=True):
cx, cy = center or CENTER
inner = INNER if inner is None else inner
outer = OUTER if outer is None else outer
normal_limit = NORMAL_LIMIT_DEG if normal_limit is None else normal_limit
coverage_limit = COVERAGE_MIN if coverage_limit is None else coverage_limit
bounds = (cx - outer, cx + outer, cy - outer, cy + outer)
if scene_data is None:
scene_data = RING.read_scene(str(path), 0,
HEIGHT_MIN if height_min is None else height_min,
HEIGHT_MAX if height_max is None else height_max, bounds)
voxel_um, triangles, tiles = scene_data
component_count, fragments, below_floor = small_components(triangles, (cx, cy))
print(f"[MouthFragmentComponents] mesh={path.name} components={component_count} "
f"small_near_mouth={len(fragments)} subthreshold_near_mouth={len(below_floor)} "
f"limits=(triangles<={FRAGMENT_MAX_TRIANGLES},"
@@ -94,16 +103,18 @@ def audit(path):
f"distance<={FRAGMENT_MAX_DISTANCE_M:.1f}m) "
f"first={fragments[0] if fragments else None} "
f"subthreshold={below_floor[0] if below_floor else None} "
f"status={'PASS' if not fragments else 'FAIL'}")
f"gate={'on' if fragment_gate else 'diagnostic'} "
f"status={'PASS' if not fragments or not fragment_gate else 'FAIL'}")
preferred = PREFERRED if preferred is None else preferred
cell = max(2.0, 16.0 * voxel_um / 1_000_000.0)
buckets = RING.build_buckets(triangles, True, bounds, cell)
lines = []
count = round((OUTER - INNER) / STEP)
count = round((outer - inner) / STEP)
for degrees in (135.0, 180.0, 225.0, 270.0, 315.0):
angle = math.radians(degrees)
lines.append((f"radial-{degrees:.0f}", [
(cx + radius * math.cos(angle), cy + radius * math.sin(angle))
for radius in (INNER + i * STEP for i in range(count + 1))]))
for radius in (inner + i * STEP for i in range(count + 1))]))
tangent_count = round(8.0 / STEP)
for degrees in (225.0, 315.0):
angle = math.radians(degrees)
@@ -118,7 +129,7 @@ def audit(path):
max_pair = None
min_coverage = 1.0
for name, points in lines:
samples = [RING.sample_surface(buckets, x, y, True, cell, PREFERRED)
samples = [RING.sample_surface(buckets, x, y, True, cell, preferred)
for x, y in points]
coverage = sum(value is not None for value in samples) / len(samples)
min_coverage = min(min_coverage, coverage)
@@ -136,11 +147,11 @@ def audit(path):
max_pair = (name, points[index - 1], prior[0], points[index], current[0])
print(f"[MouthFadeLine] mesh={path.name} line={name} coverage={coverage:.3f} "
f"max_normal_jump_deg={line_max:.6f}")
normal_pass = max_angle <= NORMAL_LIMIT_DEG and min_coverage >= COVERAGE_MIN
passed = normal_pass and not fragments
normal_pass = max_angle <= normal_limit and min_coverage >= coverage_limit
passed = normal_pass and (not fragment_gate or not fragments)
print(f"[MouthFadeAudit] mesh={path.name} tiles={tiles} lines={len(lines)} "
f"coverage_min={min_coverage:.3f} coverage_limit={COVERAGE_MIN:.2f} "
f"max_normal_jump_deg={max_angle:.6f} normal_limit_deg={NORMAL_LIMIT_DEG:.1f} "
f"coverage_min={min_coverage:.3f} coverage_limit={coverage_limit:.2f} "
f"max_normal_jump_deg={max_angle:.6f} normal_limit_deg={normal_limit:.1f} "
f"fragments={len(fragments)} "
f"worst_pair={max_pair} status={'PASS' if passed else 'FAIL'}")
return passed, max_angle