diff --git a/coverage/browser-matrix-remediation.report.json b/coverage/browser-matrix-remediation.report.json
index 916fdfb..d1db868 100644
--- a/coverage/browser-matrix-remediation.report.json
+++ b/coverage/browser-matrix-remediation.report.json
@@ -66,21 +66,21 @@
"bytes": 11539,
"path": "coverage/compatibility-matrix.report.json",
"role": "compatibility_matrix",
- "sha256": "1079e4da3d18044a98b38e4e083eff90b26c6adfaa0d4903a636d19988af963b",
+ "sha256": "eb655edbcd2379f6b93a0b5e03e965d3c369fb2ba599684d99d25d8cdea79346",
"status": "present"
},
{
"bytes": 7196,
"path": "coverage/release-candidate-gate.report.json",
"role": "release_candidate_gate",
- "sha256": "2092257cc0aea41c5988b19a0e7aef74ed6ccae09062213e1a98f44adc4314b1",
+ "sha256": "ff46025b4d03a4ab002d22a4f6101c213a702ff6b36dc688274304f79ef8a7a8",
"status": "present"
},
{
"bytes": 15568,
"path": "coverage/release-remediation-intake.report.json",
"role": "remediation_intake",
- "sha256": "b88b3978114cb7347f890c558ea0b6c948533b8a87d61bcee3806cd0912b0a6d",
+ "sha256": "86ba1971fec3cbef1431fb211c9258b5ad568b3267aa8bbbd6f61706f3286b77",
"status": "present"
}
],
@@ -100,8 +100,8 @@
],
"exit_code": 0,
"status": "passed",
- "stderr_preview": "[354699:354699:0822/112700.686752:ERROR:mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:748] Message 853159353 rejected by interface blink.mojom.Frame",
- "stderr_sha256": "2c4d73f86043dd6c3ee198266456f336aa5749e713df89e05de2d6ab72fbf2cf",
+ "stderr_preview": "",
+ "stderr_sha256": "12ae32cb1ec02d01eda3581b127c1fee3b0dc53572ed6baf239721a03d82e126",
"stdout_preview": "
LinuxCNC WASM smoke",
"stdout_sha256": "f1516af3b272ea95719b5ce833d3afcbdf192eb69962fa5b59443faf60fc9f26"
},
@@ -167,7 +167,7 @@
"release_action": "STOP_RELEASE",
"release_decision": "blocked_not_release_candidate",
"remediation_status": "blocked_matrix_unverified",
- "report_sha256": "2f47276d3ea7ce985796881fb0ae6c009c5762c7f3ba199c7b101f9f63f4310a",
+ "report_sha256": "87d6715003d80e6e546d47c607d6d3c2624807970589062377dded8f999c2e6d",
"review_policy": {
"current_environment_limit": "Safari binary and browser farm are unavailable; observed Chromium/Firefox probes do not establish a release minimum",
"forbidden": [
diff --git a/coverage/browser-performance-matrix.report.json b/coverage/browser-performance-matrix.report.json
index e4178f7..ae8ad48 100644
--- a/coverage/browser-performance-matrix.report.json
+++ b/coverage/browser-performance-matrix.report.json
@@ -51,41 +51,41 @@
"bytes": 225468,
"path": "coverage/full-configuration-startup-matrix.report.json",
"role": "full_configuration_matrix",
- "sha256": "1a97f5fd66e86a0e6bbd22832040a7f8d839ba12677a5800b72d047a2bdde9f9",
+ "sha256": "eefde49a278a077e374b751d0d0ed59b1294ce399a757a665e3cc14f569f7656",
"status": "present"
},
{
"bytes": 3170,
"path": "coverage/recovery-offline-fault-matrix.report.json",
"role": "recovery_offline_fault_matrix",
- "sha256": "8ef9f92536fa04e7317fcc319a6f959c26494207f336132d3c454f0421c62f8c",
+ "sha256": "f8fa6f8f487b2c29c6581aa89e373d71c93af5a8b317055d7eb340f402974412",
"status": "present"
},
{
- "bytes": 6340,
+ "bytes": 6180,
"path": "coverage/browser-matrix-remediation.report.json",
"role": "browser_matrix_remediation",
- "sha256": "1ba374b8ebfcdabe5363c519011ae73a6535a5e5643149810ac0279a955896a5",
+ "sha256": "7e6a8f2dc51ad80a75504407d04f7be6727355dd9f7bcd1ff49cd47eb5cac284",
"status": "present"
},
{
"bytes": 3301,
"path": "coverage/frontend-m4.report.json",
"role": "frontend_m4",
- "sha256": "3fea18ba6ec7a76640bb2eafac6cabc13f53b6d438442d280f9bf5620b9fb26f",
+ "sha256": "213411ccef031c360b8db93c2ae2430019baa5b6ea541cd02896514172a11f6c",
"status": "present"
},
{
"bytes": 7196,
"path": "coverage/release-candidate-gate.report.json",
"role": "release_candidate_gate",
- "sha256": "2092257cc0aea41c5988b19a0e7aef74ed6ccae09062213e1a98f44adc4314b1",
+ "sha256": "ff46025b4d03a4ab002d22a4f6101c213a702ff6b36dc688274304f79ef8a7a8",
"status": "present"
}
],
"next_transition": "execute K8-REL-17 release gate refresh after implementation evidence",
"release_action": "STOP_RELEASE",
- "report_sha256": "db1be56cb41198b185fbf543f71d0bc2f61bfd93b3794dcb5e13851496415258",
+ "report_sha256": "0fc082fa4149cd847e2fc48cc2fd3736f16fa0e211765fe04cc44eea175ab847",
"runs": [
{
"exit_code": 0,
@@ -96,7 +96,7 @@
"file": "index.html"
},
{
- "bytes": 8105,
+ "bytes": 16777,
"file": "app.mjs"
},
{
@@ -104,7 +104,7 @@
"file": "worker-client.mjs"
},
{
- "bytes": 3133,
+ "bytes": 2731,
"file": "styles.css"
},
{
@@ -112,7 +112,7 @@
"file": "controls.mjs"
},
{
- "bytes": 4304,
+ "bytes": 5083,
"file": "state-panel.mjs"
},
{
@@ -124,7 +124,7 @@
"file": "recovery-panel.mjs"
},
{
- "bytes": 1318,
+ "bytes": 1587,
"file": "device-panel.mjs"
},
{
@@ -138,11 +138,11 @@
],
"schema": "browser-performance-sample.v1",
"stable": true,
- "total_bytes": 32908
+ "total_bytes": 42226
},
"status": "passed",
"stderr_sha256": "12ae32cb1ec02d01eda3581b127c1fee3b0dc53572ed6baf239721a03d82e126",
- "stdout_sha256": "41b51533a83efdf78425ec49fce1f8bc2260bc88c87fb668c8e3d6614130cbd1"
+ "stdout_sha256": "c1147df2ce4b0af41c858bc063f517a38a3ef3df1ac8678d859c3539e01bbcf9"
},
{
"exit_code": 0,
@@ -153,7 +153,7 @@
"file": "index.html"
},
{
- "bytes": 8105,
+ "bytes": 16777,
"file": "app.mjs"
},
{
@@ -161,7 +161,7 @@
"file": "worker-client.mjs"
},
{
- "bytes": 3133,
+ "bytes": 2731,
"file": "styles.css"
},
{
@@ -169,7 +169,7 @@
"file": "controls.mjs"
},
{
- "bytes": 4304,
+ "bytes": 5083,
"file": "state-panel.mjs"
},
{
@@ -181,7 +181,7 @@
"file": "recovery-panel.mjs"
},
{
- "bytes": 1318,
+ "bytes": 1587,
"file": "device-panel.mjs"
},
{
@@ -195,11 +195,11 @@
],
"schema": "browser-performance-sample.v1",
"stable": true,
- "total_bytes": 32908
+ "total_bytes": 42226
},
"status": "passed",
"stderr_sha256": "12ae32cb1ec02d01eda3581b127c1fee3b0dc53572ed6baf239721a03d82e126",
- "stdout_sha256": "41b51533a83efdf78425ec49fce1f8bc2260bc88c87fb668c8e3d6614130cbd1"
+ "stdout_sha256": "c1147df2ce4b0af41c858bc063f517a38a3ef3df1ac8678d859c3539e01bbcf9"
}
],
"schema": "browser-performance-matrix.v1",
diff --git a/coverage/gui-browser-visual-fe-m4.report.json b/coverage/gui-browser-visual-fe-m4.report.json
index 5aedb19..7682e67 100644
--- a/coverage/gui-browser-visual-fe-m4.report.json
+++ b/coverage/gui-browser-visual-fe-m4.report.json
@@ -7,9 +7,21 @@
"browser": {
"binary": "google-chrome",
"minimum_matrix": "not established",
- "scope": "Chromium visual smoke only"
+ "scope": "Chromium authorized visual slice",
+ "version": "Google Chrome 151.0.7922.169"
},
"checks": {
+ "chromium_authorized_slice": {
+ "authorization": "explicit_user_authorized_chromium_unblock",
+ "browser_version": "Google Chrome 151.0.7922.169",
+ "scope": [
+ "DOM",
+ "desktop_screenshot",
+ "mobile_screenshot",
+ "Three.js_canvas"
+ ],
+ "status": "verified"
+ },
"dom_controls": {
"status": "verified"
},
@@ -17,11 +29,11 @@
"status": "verified"
},
"official_browser_matrix": {
- "reason": "locked Chromium/Firefox/Safari minimums remain TBD; this is smoke evidence only",
+ "reason": "Firefox/Safari minimums remain TBD; Chromium authorization applies only to this slice",
"status": "blocked"
},
"opfs_recovery": {
- "reason": "existing OPFS browser fault matrix remains blocked/unavailable",
+ "reason": "OPFS crash/restart matrix remains blocked/unavailable",
"status": "blocked"
},
"screenshot_nonempty": {
@@ -36,13 +48,13 @@
"implementation_status": "verified",
"outputs": [
{
- "bytes": 90475,
- "sha256": "64e67b74290c5f7c30565cd35f3fd5174bc0129a4440c6a6cd9d7f6838288cc3",
+ "bytes": 132137,
+ "sha256": "71aa049b571d48cb65d3b0498a75cafd8ec8f1ea57bf672c4445118ac1e07ba0",
"viewport": "desktop"
},
{
- "bytes": 44029,
- "sha256": "fa4580a13418ae1a62e09e6098ed4396e5c6f863df85d8f21de2f579e53bb3c2",
+ "bytes": 48632,
+ "sha256": "266194aecddeb10f18e11ea13c8780d1239753dc43c02946dd321e0cb00ec370",
"viewport": "mobile"
}
],
@@ -56,35 +68,40 @@
"--disable-dev-shm-usage",
"--virtual-time-budget=4000",
"--window-size=1440,900",
- "--screenshot=/tmp/linuxcnc-gui-visual-2igzjfyz/desktop.png",
+ "--screenshot=/tmp/linuxcnc-gui-visual-yjhbj010/desktop.png",
"--dump-dom",
"http://127.0.0.1:5174/"
],
- "dom_sha256": "cf5e2dfcaf4b7d24b9de22bef91e2e3e1f6fead0de10625b23d9806cfe50575a",
+ "dom_sha256": "41512d21ba50815afd046499372587a78968daa5f08589600156c578e117733c",
"markers": {
- "Abort": true,
- "Diagnostics": true,
- "E-stop": true,
- "Home": true,
+ "Active G-Codes:": true,
+ "Coolant": true,
+ "DRO": true,
+ "File": true,
+ "Help": true,
+ "Home Axis": true,
"Load case": true,
- "Manual jog": true,
- "Operate": true,
+ "MDI [F5]": true,
+ "Machine": true,
+ "Manual Control [F3]": true,
"Pause": true,
- "Program": true,
- "Recover": true,
- "Restart": true,
+ "Preview": true,
"Run": true,
+ "Simulation case": true,
+ "Spindle": true,
"Step": true,
- "Three.js / authoritative pose": true
+ "Three.js / authoritative pose": true,
+ "Tool Touch Off": true,
+ "View": true
},
"returncode": 0,
"screenshot": {
- "bytes": 90475,
- "path": "/tmp/linuxcnc-gui-visual-2igzjfyz/desktop.png",
- "sha256": "64e67b74290c5f7c30565cd35f3fd5174bc0129a4440c6a6cd9d7f6838288cc3"
+ "bytes": 132137,
+ "path": "/tmp/linuxcnc-gui-visual-yjhbj010/desktop.png",
+ "sha256": "71aa049b571d48cb65d3b0498a75cafd8ec8f1ea57bf672c4445118ac1e07ba0"
},
"status": "verified",
- "stderr_sha256": "b5327507fc50e3cb0b7b4633d0c1ce43743dbd3188c920e28afe023035322464",
+ "stderr_sha256": "4c688f43737caa6998e38bac07e16b085f305cd1ea43052d482fc4d8ffc1157f",
"window": "1440,900"
},
"mobile": {
@@ -96,40 +113,45 @@
"--disable-dev-shm-usage",
"--virtual-time-budget=4000",
"--window-size=390,844",
- "--screenshot=/tmp/linuxcnc-gui-visual-2igzjfyz/mobile.png",
+ "--screenshot=/tmp/linuxcnc-gui-visual-yjhbj010/mobile.png",
"--dump-dom",
"http://127.0.0.1:5174/"
],
- "dom_sha256": "66a6f651ce8df4a26b271e603adeb36731bd44e3464b77a74a81180b53804b6b",
+ "dom_sha256": "1dc0c46b1fe8f2bd9c34cc9c70e97e0de2cbbe3695360a27d49230bed8c5cc69",
"markers": {
- "Abort": true,
- "Diagnostics": true,
- "E-stop": true,
- "Home": true,
+ "Active G-Codes:": true,
+ "Coolant": true,
+ "DRO": true,
+ "File": true,
+ "Help": true,
+ "Home Axis": true,
"Load case": true,
- "Manual jog": true,
- "Operate": true,
+ "MDI [F5]": true,
+ "Machine": true,
+ "Manual Control [F3]": true,
"Pause": true,
- "Program": true,
- "Recover": true,
- "Restart": true,
+ "Preview": true,
"Run": true,
+ "Simulation case": true,
+ "Spindle": true,
"Step": true,
- "Three.js / authoritative pose": true
+ "Three.js / authoritative pose": true,
+ "Tool Touch Off": true,
+ "View": true
},
"returncode": 0,
"screenshot": {
- "bytes": 44029,
- "path": "/tmp/linuxcnc-gui-visual-2igzjfyz/mobile.png",
- "sha256": "fa4580a13418ae1a62e09e6098ed4396e5c6f863df85d8f21de2f579e53bb3c2"
+ "bytes": 48632,
+ "path": "/tmp/linuxcnc-gui-visual-yjhbj010/mobile.png",
+ "sha256": "266194aecddeb10f18e11ea13c8780d1239753dc43c02946dd321e0cb00ec370"
},
"status": "verified",
- "stderr_sha256": "dc18bae409847b94397f09f6c73409ee6e4b6c8830d97670947bc37450a11001",
+ "stderr_sha256": "c3b4dd1da17368589e678b93a124c94befc05dcf0471e8dcfe6730336c31afb2",
"window": "390,844"
}
},
"release_action": "STOP_RELEASE",
- "report_sha256": "cd2eb920ba82a97a11b4d7e4b2f56a0e1f0739c840da61f63d5beef392df24a4",
+ "report_sha256": "6386db199317ae95cd5ce03ccb0d525a056f3a9736eb3a28263869b00a33be05",
"route": "http://127.0.0.1:5174/",
"schema": "gui-browser-visual-fe-m4-report.v1",
"status": "verified",
diff --git a/nextTask1.md b/nextTask1.md
index bd29971..b3ee76b 100644
--- a/nextTask1.md
+++ b/nextTask1.md
@@ -62,12 +62,14 @@ objective: >-
non_goals:
- 不复制桌面 GTK/Qt/Tk 窗口,不把宿主 Python/动态 loader/真实硬件变成 Web 能力
- 不修改 ABI、protocol、schema、context lock;manifest 归属缺口保留为可定位审计项
-completion_evidence:
+ completion_evidence:
status: blocked
report: coverage/gui-browser-visual-fe-m4.report.json
- report_sha256: cd2eb920ba82a97a11b4d7e4b2f56a0e1f0739c840da61f63d5beef392df24a4
+ report_sha256: 6386db199317ae95cd5ce03ccb0d525a056f3a9736eb3a28263869b00a33be05
implementation_status: verified
chromium_visual: verified
+ chromium_authorized_slice: verified
+ chromium_version: Google Chrome 151.0.7922.169
browser_matrix: blocked
opfs_recovery: blocked
prior_completion_evidence:
diff --git a/scripts/generate_gui_browser_visual_report.py b/scripts/generate_gui_browser_visual_report.py
index ff45aff..88fa3d6 100644
--- a/scripts/generate_gui_browser_visual_report.py
+++ b/scripts/generate_gui_browser_visual_report.py
@@ -8,6 +8,7 @@ import json
import os
import subprocess
import tempfile
+import shutil
from pathlib import Path
from typing import Any
@@ -21,11 +22,24 @@ def digest(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
+def browser_version() -> str | None:
+ binary = shutil.which("google-chrome")
+ if binary is None:
+ return None
+ result = subprocess.run([binary, "--version"], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False)
+ return result.stdout.decode("utf-8", errors="replace").strip() or None
+
+
def probe(size: str, screenshot: Path) -> dict[str, Any]:
command = ["google-chrome", "--headless=new", "--no-sandbox", "--disable-gpu", "--disable-dev-shm-usage", "--virtual-time-budget=4000", f"--window-size={size}", f"--screenshot={screenshot}", "--dump-dom", URL]
result = subprocess.run(command, cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False)
dom = result.stdout.decode("utf-8", errors="replace")
- markers = {marker: marker in dom for marker in ("Operate", "Program", "Diagnostics", "Load case", "Run", "Pause", "Step", "Restart", "Abort", "Home", "Recover", "E-stop", "Manual jog", "Three.js / authoritative pose")}
+ markers = {marker: marker in dom for marker in (
+ "File", "Machine", "View", "Help", "Simulation case", "Load case",
+ "Manual Control [F3]", "MDI [F5]", "Preview", "DRO", "Run", "Pause",
+ "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}
@@ -42,10 +56,10 @@ def generate() -> dict[str, Any]:
"status": "verified" if desktop["status"] == "verified" and mobile["status"] == "verified" else "blocked",
"implementation_status": "verified" if desktop["status"] == "verified" else "blocked",
"route": URL,
- "browser": {"binary": "google-chrome", "scope": "Chromium visual smoke only", "minimum_matrix": "not established"},
+ "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"}, "official_browser_matrix": {"status": "blocked", "reason": "locked Chromium/Firefox/Safari minimums remain TBD; this is smoke evidence only"}, "opfs_recovery": {"status": "blocked", "reason": "existing OPFS browser fault matrix remains blocked/unavailable"}},
+ "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"}},
"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"],
}
diff --git a/scripts/test_gui_browser_visual_report.py b/scripts/test_gui_browser_visual_report.py
index fcc8776..d6ab88b 100644
--- a/scripts/test_gui_browser_visual_report.py
+++ b/scripts/test_gui_browser_visual_report.py
@@ -19,6 +19,8 @@ class GuiBrowserVisualReportTests(unittest.TestCase):
self.assertEqual(report["schema"], "gui-browser-visual-fe-m4-report.v1")
self.assertEqual(report["task_id"], "FE-M4-GUI-06")
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"]["official_browser_matrix"]["status"], "blocked")
self.assertEqual(report["release_action"], "STOP_RELEASE")