Add AXIS UI structure evidence

This commit is contained in:
2026-08-23 09:01:19 +08:00
parent 5d71e6b0a2
commit a1edd8defe
6 changed files with 132 additions and 33 deletions

View File

@@ -40,7 +40,22 @@ def probe(size: str, screenshot: Path) -> dict[str, Any]:
"Step", "Home Axis", "Tool Touch Off", "Spindle", "Coolant",
"Active G-Codes:", "Three.js / authoritative pose",
)}
return {"command": command, "window": size, "returncode": result.returncode, "status": "verified" if result.returncode == 0 and all(markers.values()) and screenshot.is_file() and screenshot.stat().st_size > 1000 else "blocked", "dom_sha256": digest(result.stdout), "stderr_sha256": digest(result.stderr), "screenshot": {"path": str(screenshot), "bytes": screenshot.stat().st_size if screenshot.is_file() else 0, "sha256": digest(screenshot.read_bytes()) if screenshot.is_file() else None}, "markers": markers}
axis_features = ["AXIS-UI-01", "AXIS-UI-02", "AXIS-UI-05", "AXIS-UI-06", "AXIS-UI-07", "AXIS-SHELL-01", "AXIS-MACHINE-01", "AXIS-FILE-01", "AXIS-MACHINE-03", "AXIS-VIEW-01", "AXIS-VIEW-04", "AXIS-EDIT-01", "AXIS-EDIT-03", "AXIS-CTRL-03"]
feature_markers = {feature: f'data-axis-feature="{feature}"' in dom for feature in axis_features}
import re
tabs = re.findall(r'role="tab"[^>]+aria-controls="([^"]+)"', dom)
tabpanels = set(re.findall(r'id="(axis-panel-[^"]+)"[^>]+role="tabpanel"', dom))
toolbar_html = re.search(r'<section class="axis-toolbar[^"]*"[^>]*>(.*?)</section>', dom, re.DOTALL)
toolbar_images = re.findall(r'class="axis-tool-button[^"]*"[^>]*>\s*<img[^>]+src="([^"]+)"', toolbar_html.group(1) if toolbar_html else "")
dom_contract = {
"tab_count": len(tabs),
"tabpanel_count": len(tabpanels),
"tab_controls_resolve": len(tabs) == 4 and all(tab in tabpanels for tab in tabs),
"toolbar_icon_count": len(toolbar_images),
"toolbar_icon_scope": "axis-toolbar",
"aria_label_count": len(re.findall(r'aria-label="', dom)),
}
return {"command": command, "window": size, "returncode": result.returncode, "status": "verified" if result.returncode == 0 and all(markers.values()) and all(feature_markers.values()) and dom_contract["tab_controls_resolve"] and dom_contract["toolbar_icon_count"] >= 20 and screenshot.is_file() and screenshot.stat().st_size > 1000 else "blocked", "dom_sha256": digest(result.stdout), "stderr_sha256": digest(result.stderr), "screenshot": {"path": str(screenshot), "bytes": screenshot.stat().st_size if screenshot.is_file() else 0, "sha256": digest(screenshot.read_bytes()) if screenshot.is_file() else None}, "markers": markers, "axis_feature_markers": feature_markers, "axis_feature_count": len(set(re.findall(r'data-axis-feature="([^"]+)"', dom))), "dom_contract": dom_contract}
def generate() -> dict[str, Any]:
@@ -59,7 +74,7 @@ def generate() -> dict[str, Any]:
"browser": {"binary": "google-chrome", "version": browser_version(), "scope": "Chromium authorized visual slice", "minimum_matrix": "not established"},
"probes": {"desktop": desktop, "mobile": mobile},
"outputs": outputs,
"checks": {"dom_controls": {"status": "verified" if desktop["status"] == "verified" else "blocked"}, "screenshot_nonempty": {"status": "verified" if all(row["bytes"] > 1000 for row in outputs) else "blocked"}, "mobile_layout": {"status": "verified" if mobile["status"] == "verified" else "blocked"}, "threejs": {"status": "verified", "evidence": "React production preview emits Three.js r185 canvas"}, "chromium_authorized_slice": {"status": "verified" if desktop["status"] == "verified" and mobile["status"] == "verified" else "blocked", "authorization": "explicit_user_authorized_chromium_unblock", "browser_version": browser_version(), "scope": ["DOM", "desktop_screenshot", "mobile_screenshot", "Three.js_canvas"]}, "official_browser_matrix": {"status": "blocked", "reason": "Firefox/Safari minimums remain TBD; Chromium authorization applies only to this slice"}, "opfs_recovery": {"status": "blocked", "reason": "OPFS crash/restart matrix remains blocked/unavailable"}},
"checks": {"dom_controls": {"status": "verified" if desktop["status"] == "verified" else "blocked"}, "axis_feature_markers": {"status": "verified" if desktop["status"] == "verified" and mobile["status"] == "verified" else "blocked", "required": 14, "desktop_count": desktop["axis_feature_count"], "mobile_count": mobile["axis_feature_count"]}, "dom_accessibility_contract": {"status": "verified" if desktop["dom_contract"]["tab_controls_resolve"] and mobile["dom_contract"]["tab_controls_resolve"] else "blocked", "desktop": desktop["dom_contract"], "mobile": mobile["dom_contract"]}, "screenshot_nonempty": {"status": "verified" if all(row["bytes"] > 1000 for row in outputs) else "blocked"}, "mobile_layout": {"status": "verified" if mobile["status"] == "verified" else "blocked"}, "threejs": {"status": "verified", "evidence": "React production preview emits Three.js r185 canvas"}, "chromium_authorized_slice": {"status": "verified" if desktop["status"] == "verified" and mobile["status"] == "verified" else "blocked", "authorization": "explicit_user_authorized_chromium_unblock", "browser_version": browser_version(), "scope": ["DOM", "desktop_screenshot", "mobile_screenshot", "Three.js_canvas"]}, "official_browser_matrix": {"status": "blocked", "reason": "Firefox/Safari minimums remain TBD; Chromium authorization applies only to this slice"}, "opfs_recovery": {"status": "blocked", "reason": "OPFS crash/restart matrix remains blocked/unavailable"}},
"release_action": "STOP_RELEASE",
"boundaries": ["Chromium screenshot/DOM smoke does not establish the three-browser release matrix", "visual evidence does not replace native/WASM/Worker golden parity", "OPFS/recovery blocker remains explicit"],
}

View File

@@ -21,6 +21,11 @@ class GuiBrowserVisualReportTests(unittest.TestCase):
self.assertEqual(report["status"], "verified")
self.assertEqual(report["checks"]["chromium_authorized_slice"]["status"], "verified")
self.assertEqual(report["checks"]["chromium_authorized_slice"]["authorization"], "explicit_user_authorized_chromium_unblock")
self.assertEqual(report["checks"]["axis_feature_markers"]["status"], "verified")
self.assertGreaterEqual(report["checks"]["axis_feature_markers"]["desktop_count"], 14)
self.assertEqual(report["checks"]["dom_accessibility_contract"]["status"], "verified")
self.assertEqual(report["checks"]["dom_accessibility_contract"]["desktop"]["tab_count"], 4)
self.assertEqual(report["checks"]["dom_accessibility_contract"]["desktop"]["toolbar_icon_count"], 20)
self.assertEqual(report["checks"]["official_browser_matrix"]["status"], "blocked")
self.assertEqual(report["release_action"], "STOP_RELEASE")