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:
1 parent
88c54eab44
commit
753cc9c259
22 files changed
+1831
-163
No files matched your search
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Measure adjacent route-relative mouth-profile steps; period fits are diagnostic."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
PROFILE = re.compile(
|
||||
r"\[PassageFloorRippleSample\] id=(\S+) distance_m=([-0-9.]+).*?"
|
||||
r"residual_m=([-0-9.]+)")
|
||||
RIPPLE = re.compile(r"\[PassageRippleAudit\] id=(\S+).*?period_m=([-0-9.]+)")
|
||||
STEP_LIMIT_M = 0.100
|
||||
MAX_ADJACENT_DISTANCE_M = 0.750
|
||||
|
||||
|
||||
def measure(text: str) -> dict[str, object]:
|
||||
profiles: dict[str, list[tuple[float, float]]] = defaultdict(list)
|
||||
for match in PROFILE.finditer(text):
|
||||
passage, distance, residual = match.groups()
|
||||
profiles[passage].append((float(distance), float(residual)))
|
||||
|
||||
adjacent: list[tuple[float, str, float, float]] = []
|
||||
group_counts: dict[str, int] = {}
|
||||
for key, samples in profiles.items():
|
||||
samples.sort()
|
||||
group_counts[key] = len(samples)
|
||||
for before, after in zip(samples, samples[1:]):
|
||||
delta_d = abs(after[0] - before[0])
|
||||
if delta_d <= MAX_ADJACENT_DISTANCE_M:
|
||||
adjacent.append((abs(after[1] - before[1]), key, before[0], after[0]))
|
||||
|
||||
periods = {passage: float(period) for passage, period in RIPPLE.findall(text)}
|
||||
maximum = max((item[0] for item in adjacent), default=0.0)
|
||||
return {
|
||||
"maximum_adjacent_step_m": maximum,
|
||||
"adjacent_pairs": len(adjacent),
|
||||
"profile_groups": len(profiles),
|
||||
"profile_group_counts": group_counts,
|
||||
"fitted_periods_m": periods,
|
||||
"passed": bool(adjacent) and maximum <= STEP_LIMIT_M,
|
||||
"worst": max(adjacent, default=None),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("log", type=Path)
|
||||
parser.add_argument("--expect-fail", action="store_true",
|
||||
help="pass only when the adjacent-step limit is exceeded")
|
||||
args = parser.parse_args()
|
||||
result = measure(args.log.read_text(encoding="utf-8", errors="replace"))
|
||||
detected = not bool(result["passed"])
|
||||
ok = detected if args.expect_fail else not detected
|
||||
print(f"[OwnerAdjacentProfileStep] log={args.log} pairs={result['adjacent_pairs']} "
|
||||
f"groups={result['profile_groups']} max_step_m={result['maximum_adjacent_step_m']:.6f} "
|
||||
f"limit_m={STEP_LIMIT_M:.3f} max_adjacent_distance_m={MAX_ADJACENT_DISTANCE_M:.3f} "
|
||||
f"fitted_periods_m={result['fitted_periods_m']} "
|
||||
"period_role=diagnostic "
|
||||
f"detected={str(detected).lower()} status={'PASS' if ok else 'FAIL'}")
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user