hardware-observatory-acceptance.json
docs/evidence/hardware-observatory-acceptance.json
1{
2 "date": "2026-10-25",
3 "baselineCommit": "09dbb6a",
4 "scope": "Qualify the Observatory on a physical GPU; correct a false exact-equality sRGB diagnostic and prove omitted decoding remains detectable. Runtime renderer and artwork unchanged.",
5 "sourceSha256": {
6 "apps/probe/material-textures.ts": "6775967db71d1655fc09314d956de0f28b060d299796eacfc1346f50effa29b5",
7 "tests/browser/probe.spec.ts": "cf746591c6fd29636fc059e8bb4b6208e9879d11dbca3605f871f17d564084c3",
8 "playwright.config.ts": "1b21efa6240e9d9dcdf7cbc22a7694cf7111437b01b5b7ec2e7987017d46af90",
9 "tools/cli/qualify-gpu.ts": "13d716ac1b76aea30a2c0dbd9db7ef39255bd6a0f260aa4f06e02f725921a36d"
10 },
11 "hardware": {
12 "qualification": {
13 "capturedAt": "2026-10-26T04:36:53.655Z",
14 "adapter": {
15 "vendor": "intel",
16 "architecture": "xe-3lpg",
17 "device": "",
18 "description": "",
19 "isFallbackAdapter": false,
20 "features": [
21 "bgra8unorm-storage",
22 "chromium-experimental-multi-draw-indirect",
23 "chromium-experimental-snorm16-texture-formats",
24 "chromium-experimental-subgroup-matrix",
25 "chromium-experimental-timestamp-query-inside-passes",
26 "chromium-experimental-unorm16-texture-formats",
27 "clip-distances",
28 "core-features-and-limits",
29 "depth-clip-control",
30 "depth32float-stencil8",
31 "dual-source-blending",
32 "float32-blendable",
33 "float32-filterable",
34 "indirect-first-instance",
35 "primitive-index",
36 "rg11b10ufloat-renderable",
37 "shader-f16",
38 "subgroups",
39 "texture-component-swizzle",
40 "texture-compression-bc",
41 "texture-compression-bc-sliced-3d",
42 "texture-compression-etc2",
43 "timestamp-query"
44 ],
45 "maxTextureDimension2D": 8192,
46 "maxBufferSize": 268435456,
47 "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/141.0.7390.37 Safari/537.36"
48 },
49 "os": {
50 "platform": "linux",
51 "release": "7.2.8-9-omarchy",
52 "arch": "x64"
53 },
54 "cpu": "Intel(R) Core(TM) Ultra X7 358H",
55 "node": "v22.23.4",
56 "browser": "141.0.7390.37",
57 "launchArgs": [
58 "--enable-unsafe-webgpu",
59 "--use-angle=vulkan",
60 "--enable-features=Vulkan"
61 ]
62 },
63 "tests": [
64 {
65 "title": "owned renderer works on the main thread and survives worker resize, device loss and restart",
66 "status": "passed",
67 "durationMs": 27863
68 },
69 {
70 "title": "probe reports unsupported graphics without joining a room",
71 "status": "passed",
72 "durationMs": 245
73 },
74 {
75 "title": "cancelling a worker probe releases ownership and permits another run",
76 "status": "passed",
77 "durationMs": 11629
78 },
79 {
80 "title": "gesture probe confirms pointer release and closes the silent audio context",
81 "status": "passed",
82 "durationMs": 260
83 },
84 {
85 "title": "worker exceptions produce a bounded failure and the next run can recover",
86 "status": "passed",
87 "durationMs": 14150
88 },
89 {
90 "title": "a silent worker hits its deadline and releases ownership",
91 "status": "passed",
92 "durationMs": 692
93 },
94 {
95 "title": "contract worker failures release ownership and can be retried",
96 "status": "passed",
97 "durationMs": 22159
98 },
99 {
100 "title": "unavailable workers are reported as unsupported after main-thread rendering",
101 "status": "passed",
102 "durationMs": 596
103 },
104 {
105 "title": "replay worker failure and cancellation release ownership and allow recovery",
106 "status": "passed",
107 "durationMs": 29208
108 },
109 {
110 "title": "a silent simulation replay worker reaches its deadline and releases ownership",
111 "status": "passed",
112 "durationMs": 9278
113 }
114 ],
115 "materialTextures": {
116 "fixture": "material-textures.2",
117 "hash": "0cc4ae9a059e963bea6c825593f43a018aee809ab714beace476894c488bd36f",
118 "bytes": 552,
119 "textures": 3,
120 "uvOrientation": true,
121 "opaqueAlpha": true,
122 "srgbSampling": true,
123 "srgbReferences": [
124 {
125 "byte": 0,
126 "maxRgbError": 0,
127 "differentRgbChannels": 0,
128 "alphaExact": true
129 },
130 {
131 "byte": 10,
132 "maxRgbError": 1,
133 "differentRgbChannels": 29040,
134 "alphaExact": true
135 },
136 {
137 "byte": 11,
138 "maxRgbError": 0,
139 "differentRgbChannels": 0,
140 "alphaExact": true
141 },
142 {
143 "byte": 32,
144 "maxRgbError": 0,
145 "differentRgbChannels": 0,
146 "alphaExact": true
147 },
148 {
149 "byte": 64,
150 "maxRgbError": 1,
151 "differentRgbChannels": 14736,
152 "alphaExact": true
153 },
154 {
155 "byte": 128,
156 "maxRgbError": 1,
157 "differentRgbChannels": 10764,
158 "alphaExact": true
159 },
160 {
161 "byte": 192,
162 "maxRgbError": 1,
163 "differentRgbChannels": 11712,
164 "alphaExact": true
165 },
166 {
167 "byte": 255,
168 "maxRgbError": 0,
169 "differentRgbChannels": 0,
170 "alphaExact": true
171 }
172 ],
173 "srgbWrongLinearError": 57,
174 "metalRoughChannels": true,
175 "emissiveMap": true,
176 "mipSampling": true,
177 "samplerAddressing": true,
178 "rejectedPreservedFrame": true,
179 "replacementFrames": 4,
180 "recoveredFrame": true,
181 "catalogFrame": true,
182 "disposed": {
183 "buffers": 0,
184 "textures": 0,
185 "instances": 0
186 }
187 }
188 },
189 "software": {
190 "tests": [
191 {
192 "title": "owned renderer works on the main thread and survives worker resize, device loss and restart",
193 "status": "passed",
194 "durationMs": 62127
195 }
196 ],
197 "materialTextures": {
198 "fixture": "material-textures.2",
199 "hash": "0cc4ae9a059e963bea6c825593f43a018aee809ab714beace476894c488bd36f",
200 "bytes": 552,
201 "textures": 3,
202 "uvOrientation": true,
203 "opaqueAlpha": true,
204 "srgbSampling": true,
205 "srgbReferences": [
206 {
207 "byte": 0,
208 "maxRgbError": 0,
209 "differentRgbChannels": 0,
210 "alphaExact": true
211 },
212 {
213 "byte": 10,
214 "maxRgbError": 0,
215 "differentRgbChannels": 0,
216 "alphaExact": true
217 },
218 {
219 "byte": 11,
220 "maxRgbError": 0,
221 "differentRgbChannels": 0,
222 "alphaExact": true
223 },
224 {
225 "byte": 32,
226 "maxRgbError": 0,
227 "differentRgbChannels": 0,
228 "alphaExact": true
229 },
230 {
231 "byte": 64,
232 "maxRgbError": 0,
233 "differentRgbChannels": 0,
234 "alphaExact": true
235 },
236 {
237 "byte": 128,
238 "maxRgbError": 0,
239 "differentRgbChannels": 0,
240 "alphaExact": true
241 },
242 {
243 "byte": 192,
244 "maxRgbError": 0,
245 "differentRgbChannels": 0,
246 "alphaExact": true
247 },
248 {
249 "byte": 255,
250 "maxRgbError": 0,
251 "differentRgbChannels": 0,
252 "alphaExact": true
253 }
254 ],
255 "srgbWrongLinearError": 57,
256 "metalRoughChannels": true,
257 "emissiveMap": true,
258 "mipSampling": true,
259 "samplerAddressing": true,
260 "rejectedPreservedFrame": true,
261 "replacementFrames": 4,
262 "recoveredFrame": true,
263 "catalogFrame": true,
264 "disposed": {
265 "buffers": 0,
266 "textures": 0,
267 "instances": 0
268 }
269 }
270 },
271 "negativeControls": {
272 "hardware": {
273 "tests": [
274 {
275 "title": "probe detects omitted sRGB decoding and releases failed texture resources",
276 "status": "passed",
277 "durationMs": 6579
278 }
279 ],
280 "observed": {
281 "failed": [
282 {
283 "name": "Worker cycle 3",
284 "status": "failed",
285 "detail": "Material texture probe: sRGB 10 differs from equivalent linear factor: {\"maxRgbError\":34,\"differentRgbChannels\":101568,\"alphaExact\":true}"
286 }
287 ],
288 "errors": []
289 }
290 },
291 "software": {
292 "tests": [
293 {
294 "title": "probe detects omitted sRGB decoding and releases failed texture resources",
295 "status": "passed",
296 "durationMs": 9414
297 }
298 ],
299 "observed": {
300 "failed": [
301 {
302 "name": "Worker cycle 3",
303 "status": "failed",
304 "detail": "Material texture probe: sRGB 10 differs from equivalent linear factor: {\"maxRgbError\":34,\"differentRgbChannels\":100467,\"alphaExact\":true}"
305 }
306 ],
307 "errors": []
308 }
309 }
310 },
311 "precisionContract": {
312 "sourceBytes": [
313 0,
314 10,
315 11,
316 32,
317 64,
318 128,
319 192,
320 255
321 ],
322 "maxFullImageRgbOutputByteError": 1,
323 "alpha": "exact",
324 "wrongLinearReferenceMinimumErrorExclusive": 16,
325 "samePathChecks": "Existing channel-isolation, replacement and reconstruction checks remain exact.",
326 "basis": "Observed Arc B390 output differs by one RGB byte from CPU analytical sRGB reference; SwiftShader matches exactly. This project acceptance budget is not a normative WebGPU sampler guarantee."
327 },
328 "retainedFailures": [
329 {
330 "record": "hardware-observatory-initial-interrupted.log",
331 "outcome": "Initial suite interrupted after repeated strict sRGB comparison failures; no complete JSON emitted. Unsupported-graphics and input/audio checks passed before interruption. Not full-suite acceptance."
332 },
333 {
334 "record": "hardware-observatory-strict-reference-failure.json",
335 "outcome": "Focused measurement retained strict assertion and confirmed max RGB error 1, 10764 differing channels at source gray 128."
336 }
337 ],
338 "verification": {
339 "check": "TypeScript and package boundaries passed, 181 package source files.",
340 "productionBuild": {
341 "engine": "07b66a4d3f4599cbd298dcde11077733d51cd03f99854c5853d569d43303b40a",
342 "files": 28,
343 "bytes": 51367204,
344 "output": "/home/jason/coding/dw-web/engine-dist"
345 },
346 "browser": "Ten existing hardware scenarios plus a separately run negative case passed; software complete-renderer scenario and separate negative case passed. Full ten-case run preceded only the appended negative test; app source unchanged.",
347 "fullHeadlessSuite": "Not rerun; no engine, schema, simulation, network or server source changes."
348 },
349 "limits": [
350 "One short headless Chromium/Vulkan physical reference; no mobile, human input/audio, sustained FPS, battery or long-session qualification.",
351 "Existing five-second SwiftShader editor-restoration reload gate remains open; this increment does not retest or fix it.",
352 "No complete roadmap milestone closed. Full milestones 0\u201318 and final character/environment/arrival art remain required."
353 ],
354 "progressApproximatePercent": 80
355}
356