@riddledc/riddle-proof 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/openclaw.js +4 -4
- package/dist/advanced/engine-harness.cjs +25 -4
- package/dist/advanced/engine-harness.js +5 -5
- package/dist/advanced/index.cjs +25 -4
- package/dist/advanced/index.d.cts +1 -1
- package/dist/advanced/index.d.ts +1 -1
- package/dist/advanced/index.js +7 -7
- package/dist/advanced/proof-run-core.cjs +12 -0
- package/dist/advanced/proof-run-core.js +1 -1
- package/dist/advanced/proof-run-engine.cjs +19 -0
- package/dist/advanced/proof-run-engine.d.cts +1 -1
- package/dist/advanced/proof-run-engine.d.ts +1 -1
- package/dist/advanced/proof-run-engine.js +2 -2
- package/dist/advanced/runner.js +5 -5
- package/dist/checkpoint.cjs +3 -1
- package/dist/checkpoint.js +1 -1
- package/dist/{chunk-VZD5LH7U.js → chunk-OIFHYMHP.js} +2 -2
- package/dist/{chunk-TJ63IE65.js → chunk-RV6LK7HU.js} +12 -0
- package/dist/{chunk-2CFVREFI.js → chunk-SKIAZTQ7.js} +3 -1
- package/dist/{chunk-BTN76IGW.js → chunk-SMBZT46I.js} +1 -1
- package/dist/{chunk-OHJQRDST.js → chunk-TNCDVE5O.js} +1 -1
- package/dist/{chunk-BHL4JSGM.js → chunk-TZ3YMCDM.js} +8 -1
- package/dist/{chunk-Y2KTBACQ.js → chunk-U4FUFBSH.js} +1 -1
- package/dist/{chunk-IWLQQ5S5.js → chunk-YB5ACBZE.js} +7 -7
- package/dist/{chunk-COERZX63.js → chunk-ZX45XGDJ.js} +2 -2
- package/dist/cli/index.js +6 -6
- package/dist/cli.cjs +25 -4
- package/dist/cli.js +6 -6
- package/dist/engine-harness.cjs +25 -4
- package/dist/engine-harness.js +5 -5
- package/dist/index.cjs +25 -4
- package/dist/index.js +6 -6
- package/dist/openclaw.js +4 -4
- package/dist/proof-run-core.cjs +12 -0
- package/dist/proof-run-core.js +1 -1
- package/dist/{proof-run-engine-CSSc0mNn.d.ts → proof-run-engine-DxWW1VX1.d.ts} +3 -3
- package/dist/{proof-run-engine-HSRpUeBi.d.cts → proof-run-engine-Rkd_hXB-.d.cts} +3 -3
- package/dist/proof-run-engine.cjs +19 -0
- package/dist/proof-run-engine.d.cts +1 -1
- package/dist/proof-run-engine.d.ts +1 -1
- package/dist/proof-run-engine.js +2 -2
- package/dist/run-card.js +2 -2
- package/dist/runner.js +5 -5
- package/dist/spec/checkpoint.cjs +3 -1
- package/dist/spec/checkpoint.js +1 -1
- package/dist/spec/index.cjs +3 -1
- package/dist/spec/index.js +3 -3
- package/dist/spec/run-card.js +2 -2
- package/dist/spec/state.js +3 -3
- package/dist/state.js +3 -3
- package/dist/types.d.cts +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/runtime/lib/author.py +32 -0
- package/runtime/lib/setup.py +3 -0
- package/runtime/lib/verify.py +247 -8
- package/runtime/pipelines/riddle-proof-author.lobster +2 -1
- package/runtime/pipelines/riddle-proof-implement.lobster +2 -1
- package/runtime/pipelines/riddle-proof-recon.lobster +2 -1
- package/runtime/pipelines/riddle-proof-setup.lobster +4 -2
- package/runtime/pipelines/riddle-proof-ship.lobster +2 -1
- package/runtime/pipelines/riddle-proof-verify.lobster +2 -1
- package/runtime/tests/recon_verify_smoke.py +306 -8
|
@@ -228,6 +228,133 @@ class FakeRiddle:
|
|
|
228
228
|
'RIDDLE_PROOF_EVIDENCE:' + json.dumps(proof_evidence),
|
|
229
229
|
],
|
|
230
230
|
}
|
|
231
|
+
if 'prod.example.com/pricing' in script:
|
|
232
|
+
search = '?plan=pro' if 'plan=pro' in script else ''
|
|
233
|
+
return {
|
|
234
|
+
'ok': True,
|
|
235
|
+
'screenshots': [{'url': 'https://cdn.example.com/prod.png'}],
|
|
236
|
+
'outputs': [{'name': 'prod.png', 'url': 'https://cdn.example.com/prod.png'}],
|
|
237
|
+
'console': state_console({
|
|
238
|
+
'bodyTextLength': 180,
|
|
239
|
+
'visibleTextSample': 'Pricing CTA Buy Now',
|
|
240
|
+
'interactiveElements': 4,
|
|
241
|
+
'visibleInteractiveElements': 4,
|
|
242
|
+
'pathname': '/pricing',
|
|
243
|
+
'search': search,
|
|
244
|
+
'title': 'Prod',
|
|
245
|
+
'buttons': ['Buy Now'],
|
|
246
|
+
'headings': ['Pricing'],
|
|
247
|
+
'links': [],
|
|
248
|
+
'canvasCount': 0,
|
|
249
|
+
'largeVisibleElements': [{'tag': 'button', 'text': 'Buy Now'}],
|
|
250
|
+
}),
|
|
251
|
+
}
|
|
252
|
+
if 'clickedProofNavigation' in script:
|
|
253
|
+
page_state = {
|
|
254
|
+
'bodyTextLength': 180,
|
|
255
|
+
'visibleTextSample': 'Proof page Evidence Accepted',
|
|
256
|
+
'interactiveElements': 2,
|
|
257
|
+
'visibleInteractiveElements': 2,
|
|
258
|
+
'pathname': '/proof/',
|
|
259
|
+
'title': 'Proof',
|
|
260
|
+
'buttons': ['Proof'],
|
|
261
|
+
'headings': ['Proof'],
|
|
262
|
+
'links': [],
|
|
263
|
+
'canvasCount': 0,
|
|
264
|
+
'largeVisibleElements': [{'tag': 'h1', 'text': 'Proof'}],
|
|
265
|
+
}
|
|
266
|
+
proof_evidence = {
|
|
267
|
+
'before': {'path': '/'},
|
|
268
|
+
'action': 'clicked Proof',
|
|
269
|
+
'after': {'path': '/proof/'},
|
|
270
|
+
'assertions': {
|
|
271
|
+
'startedOnHome': True,
|
|
272
|
+
'clickedProofNavigation': True,
|
|
273
|
+
'terminalPathIsProof': True,
|
|
274
|
+
'proofContentVisible': True,
|
|
275
|
+
},
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
'ok': True,
|
|
279
|
+
'screenshots': [{'url': 'https://cdn.example.com/proof-after.png'}],
|
|
280
|
+
'outputs': [{'name': 'after-proof.png', 'url': 'https://cdn.example.com/proof-after.png'}],
|
|
281
|
+
'result': {'pageState': page_state, 'proofEvidence': proof_evidence},
|
|
282
|
+
'console': [
|
|
283
|
+
'RIDDLE_PROOF_STATE:' + json.dumps(page_state),
|
|
284
|
+
'RIDDLE_PROOF_EVIDENCE:' + json.dumps(proof_evidence),
|
|
285
|
+
],
|
|
286
|
+
'visual_diff': {
|
|
287
|
+
'diffPercentage': 1.2,
|
|
288
|
+
'differentPixels': 12000,
|
|
289
|
+
'totalPixels': 972000,
|
|
290
|
+
},
|
|
291
|
+
}
|
|
292
|
+
if 'clickedHomeNavigation' in script:
|
|
293
|
+
page_state = {
|
|
294
|
+
'bodyTextLength': 180,
|
|
295
|
+
'visibleTextSample': 'Riddle Proof homepage hero Start Free',
|
|
296
|
+
'interactiveElements': 4,
|
|
297
|
+
'visibleInteractiveElements': 4,
|
|
298
|
+
'pathname': '/',
|
|
299
|
+
'title': 'Riddle',
|
|
300
|
+
'buttons': ['Start Free'],
|
|
301
|
+
'headings': ['Riddle Proof'],
|
|
302
|
+
'links': [],
|
|
303
|
+
'canvasCount': 0,
|
|
304
|
+
'largeVisibleElements': [{'tag': 'h1', 'text': 'Riddle Proof'}],
|
|
305
|
+
}
|
|
306
|
+
proof_evidence = {
|
|
307
|
+
'before': {'path': '/proof/'},
|
|
308
|
+
'action': 'clicked Home',
|
|
309
|
+
'after': {'path': '/'},
|
|
310
|
+
'assertions': {
|
|
311
|
+
'startedOnProof': True,
|
|
312
|
+
'clickedHomeNavigation': True,
|
|
313
|
+
'terminalPathIsHome': True,
|
|
314
|
+
'homeContentVisible': True,
|
|
315
|
+
},
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
'ok': True,
|
|
319
|
+
'screenshots': [{'url': 'https://cdn.example.com/home-after.png'}],
|
|
320
|
+
'outputs': [{'name': 'after-home.png', 'url': 'https://cdn.example.com/home-after.png'}],
|
|
321
|
+
'result': {'pageState': page_state, 'proofEvidence': proof_evidence},
|
|
322
|
+
'console': [
|
|
323
|
+
'RIDDLE_PROOF_STATE:' + json.dumps(page_state),
|
|
324
|
+
'RIDDLE_PROOF_EVIDENCE:' + json.dumps(proof_evidence),
|
|
325
|
+
],
|
|
326
|
+
'visual_diff': {
|
|
327
|
+
'diffPercentage': 1.2,
|
|
328
|
+
'differentPixels': 12000,
|
|
329
|
+
'totalPixels': 972000,
|
|
330
|
+
},
|
|
331
|
+
}
|
|
332
|
+
if 'skipLinkTimeout' in script:
|
|
333
|
+
message = 'locator.click: Timeout 30000ms exceeded'
|
|
334
|
+
page_state = {
|
|
335
|
+
'bodyTextLength': 180,
|
|
336
|
+
'visibleTextSample': 'Riddle Proof homepage hero Start Free',
|
|
337
|
+
'interactiveElements': 4,
|
|
338
|
+
'visibleInteractiveElements': 4,
|
|
339
|
+
'pathname': '/',
|
|
340
|
+
'title': 'Riddle',
|
|
341
|
+
'buttons': ['Start Free'],
|
|
342
|
+
'headings': ['Riddle Proof'],
|
|
343
|
+
'links': [],
|
|
344
|
+
'canvasCount': 0,
|
|
345
|
+
'largeVisibleElements': [{'tag': 'h1', 'text': 'Riddle Proof'}],
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
'ok': True,
|
|
349
|
+
'result': {'pageState': page_state},
|
|
350
|
+
'console': [
|
|
351
|
+
'RIDDLE_PROOF_STATE:' + json.dumps(page_state),
|
|
352
|
+
message,
|
|
353
|
+
],
|
|
354
|
+
'_artifact_json': {
|
|
355
|
+
'proof.json': {'script_error': message},
|
|
356
|
+
},
|
|
357
|
+
}
|
|
231
358
|
if 'after-proof' in script:
|
|
232
359
|
after_url = 'https://cdn.example.com/after-artifact' if 'noVisualDelta' in script else 'https://cdn.example.com/after.png'
|
|
233
360
|
outputs = [{'name': 'after.png', 'url': after_url}]
|
|
@@ -258,13 +385,6 @@ class FakeRiddle:
|
|
|
258
385
|
'totalPixels': 972000,
|
|
259
386
|
}
|
|
260
387
|
return payload
|
|
261
|
-
if 'prod.example.com/pricing' in script:
|
|
262
|
-
return {
|
|
263
|
-
'ok': True,
|
|
264
|
-
'screenshots': [{'url': 'https://cdn.example.com/prod.png'}],
|
|
265
|
-
'outputs': [{'name': 'prod.png', 'url': 'https://cdn.example.com/prod.png'}],
|
|
266
|
-
'console': ['RIDDLE_PROOF_STATE:{"bodyTextLength":180,"interactiveElements":4,"pathname":"/pricing","title":"Prod"}'],
|
|
267
|
-
}
|
|
268
388
|
if 'prod.example.com/games/drum-sequencer' in script:
|
|
269
389
|
page_state = {
|
|
270
390
|
'bodyTextLength': 240,
|
|
@@ -1076,7 +1196,9 @@ def run_remote_audit_setup_without_repo():
|
|
|
1076
1196
|
assert state['server_path'] == '/pricing?plan=pro'
|
|
1077
1197
|
assert state['recon_status'] == 'ready_for_proof_plan'
|
|
1078
1198
|
assert state['proof_plan_status'] == 'ready'
|
|
1079
|
-
|
|
1199
|
+
assert state['capture_script'] == 'await page.waitForTimeout(1500);'
|
|
1200
|
+
assert state['capture_script_source'] == 'default_remote_audit_current_target'
|
|
1201
|
+
return {'ok': True, 'server_path': state['server_path'], 'capture_script_source': state['capture_script_source']}
|
|
1080
1202
|
finally:
|
|
1081
1203
|
sys.modules.pop('util', None)
|
|
1082
1204
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
@@ -2126,6 +2248,178 @@ def run_verify_capture_retry():
|
|
|
2126
2248
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2127
2249
|
|
|
2128
2250
|
|
|
2251
|
+
def run_remote_audit_verify_uses_default_capture_script():
|
|
2252
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-remote-audit-verify-'))
|
|
2253
|
+
state_path = tempdir / 'state.json'
|
|
2254
|
+
try:
|
|
2255
|
+
state = base_state(tempdir, reference='prod', prod_url='https://prod.example.com/pricing?plan=pro')
|
|
2256
|
+
state.update({
|
|
2257
|
+
'remote_audit': True,
|
|
2258
|
+
'workspace_kind': 'remote_audit',
|
|
2259
|
+
'mode': 'server',
|
|
2260
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2261
|
+
'author_status': 'ready',
|
|
2262
|
+
'proof_plan_status': 'ready',
|
|
2263
|
+
'implementation_status': 'not_required',
|
|
2264
|
+
'implementation_mode': 'none',
|
|
2265
|
+
'require_diff': False,
|
|
2266
|
+
'allow_code_changes': False,
|
|
2267
|
+
'server_path': '/pricing?plan=pro',
|
|
2268
|
+
'proof_plan': 'Audit the current pricing target.',
|
|
2269
|
+
'capture_script': '',
|
|
2270
|
+
'recon_results': {'baselines': {}, 'mode': 'remote_audit'},
|
|
2271
|
+
})
|
|
2272
|
+
write_state(state_path, state)
|
|
2273
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2274
|
+
|
|
2275
|
+
fake = FakeRiddle()
|
|
2276
|
+
load_util_with_fake(fake)
|
|
2277
|
+
load_module('verify_remote_audit_default_capture', VERIFY_PATH)
|
|
2278
|
+
after_verify = json.loads(state_path.read_text())
|
|
2279
|
+
|
|
2280
|
+
assert after_verify['verify_status'] == 'evidence_captured'
|
|
2281
|
+
assert after_verify['capture_script'] == 'await page.waitForTimeout(1500);'
|
|
2282
|
+
assert after_verify['capture_script_source'] == 'default_remote_audit_current_target'
|
|
2283
|
+
assert after_verify['after_cdn'] == 'https://cdn.example.com/prod.png'
|
|
2284
|
+
assert after_verify['evidence_bundle']['after']['visual_delta']['status'] == 'not_applicable'
|
|
2285
|
+
assert after_verify['verify_decision_request']['expected_path'] == '/pricing?plan=pro'
|
|
2286
|
+
return {
|
|
2287
|
+
'ok': True,
|
|
2288
|
+
'verify_status': after_verify['verify_status'],
|
|
2289
|
+
'capture_script_source': after_verify['capture_script_source'],
|
|
2290
|
+
}
|
|
2291
|
+
finally:
|
|
2292
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
def run_verify_interaction_terminal_route_from_proof_evidence():
|
|
2296
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-forward-'))
|
|
2297
|
+
state_path = tempdir / 'state.json'
|
|
2298
|
+
try:
|
|
2299
|
+
state = base_state(tempdir, reference='before')
|
|
2300
|
+
state.update({
|
|
2301
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2302
|
+
'author_status': 'ready',
|
|
2303
|
+
'proof_plan_status': 'ready',
|
|
2304
|
+
'implementation_status': 'changes_detected',
|
|
2305
|
+
'verification_mode': 'interaction',
|
|
2306
|
+
'server_path': '/',
|
|
2307
|
+
'before_cdn': 'https://cdn.example.com/before-home.png',
|
|
2308
|
+
'proof_plan': 'Start at /, click Proof, and verify the terminal /proof/ route.',
|
|
2309
|
+
'capture_script': "clickedProofNavigation(); await saveScreenshot('after-proof');",
|
|
2310
|
+
'recon_results': {
|
|
2311
|
+
'baselines': {'before': {'path': '/', 'url': 'https://cdn.example.com/before-home.png'}},
|
|
2312
|
+
},
|
|
2313
|
+
})
|
|
2314
|
+
write_state(state_path, state)
|
|
2315
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2316
|
+
|
|
2317
|
+
fake = FakeRiddle()
|
|
2318
|
+
load_util_with_fake(fake)
|
|
2319
|
+
load_module('verify_interaction_terminal_route', VERIFY_PATH)
|
|
2320
|
+
after_verify = json.loads(state_path.read_text())
|
|
2321
|
+
|
|
2322
|
+
assert after_verify['verify_status'] == 'evidence_captured'
|
|
2323
|
+
assert after_verify['route_expectation']['start_path'] == '/'
|
|
2324
|
+
assert after_verify['route_expectation']['expected_path'] == '/proof'
|
|
2325
|
+
assert after_verify['route_expectation']['source'] == 'proof_evidence_contract'
|
|
2326
|
+
route = after_verify['proof_assessment_request']['semantic_context']['route']
|
|
2327
|
+
assert route['expected_start_path'] == '/'
|
|
2328
|
+
assert route['expected_after_path'] == '/proof'
|
|
2329
|
+
assert route['after_observed_path'] == '/proof'
|
|
2330
|
+
assert 'wrong route' not in after_verify['verify_results']['after']['observation']['reason']
|
|
2331
|
+
return {
|
|
2332
|
+
'ok': True,
|
|
2333
|
+
'expected_path': after_verify['route_expectation']['expected_path'],
|
|
2334
|
+
'after_observed_path': route['after_observed_path'],
|
|
2335
|
+
}
|
|
2336
|
+
finally:
|
|
2337
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
def run_verify_interaction_reverse_terminal_route_from_proof_evidence():
|
|
2341
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-reverse-'))
|
|
2342
|
+
state_path = tempdir / 'state.json'
|
|
2343
|
+
try:
|
|
2344
|
+
state = base_state(tempdir, reference='before')
|
|
2345
|
+
state.update({
|
|
2346
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2347
|
+
'author_status': 'ready',
|
|
2348
|
+
'proof_plan_status': 'ready',
|
|
2349
|
+
'implementation_status': 'changes_detected',
|
|
2350
|
+
'verification_mode': 'interaction',
|
|
2351
|
+
'server_path': '/proof/',
|
|
2352
|
+
'before_cdn': 'https://cdn.example.com/before-proof.png',
|
|
2353
|
+
'proof_plan': 'Start at /proof/, click Home, and verify the terminal / route.',
|
|
2354
|
+
'capture_script': "clickedHomeNavigation(); await saveScreenshot('after-home');",
|
|
2355
|
+
'recon_results': {
|
|
2356
|
+
'baselines': {'before': {'path': '/proof/', 'url': 'https://cdn.example.com/before-proof.png'}},
|
|
2357
|
+
},
|
|
2358
|
+
})
|
|
2359
|
+
write_state(state_path, state)
|
|
2360
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2361
|
+
|
|
2362
|
+
fake = FakeRiddle()
|
|
2363
|
+
load_util_with_fake(fake)
|
|
2364
|
+
load_module('verify_interaction_reverse_terminal_route', VERIFY_PATH)
|
|
2365
|
+
after_verify = json.loads(state_path.read_text())
|
|
2366
|
+
|
|
2367
|
+
assert after_verify['verify_status'] == 'evidence_captured'
|
|
2368
|
+
assert after_verify['route_expectation']['start_path'] == '/proof'
|
|
2369
|
+
assert after_verify['route_expectation']['expected_path'] == '/'
|
|
2370
|
+
route = after_verify['proof_assessment_request']['semantic_context']['route']
|
|
2371
|
+
assert route['expected_start_path'] == '/proof'
|
|
2372
|
+
assert route['expected_after_path'] == '/'
|
|
2373
|
+
assert route['after_observed_path'] == '/'
|
|
2374
|
+
assert 'wrong route' not in after_verify['verify_results']['after']['observation']['reason']
|
|
2375
|
+
return {
|
|
2376
|
+
'ok': True,
|
|
2377
|
+
'expected_path': after_verify['route_expectation']['expected_path'],
|
|
2378
|
+
'after_observed_path': route['after_observed_path'],
|
|
2379
|
+
}
|
|
2380
|
+
finally:
|
|
2381
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
def run_verify_capture_retry_surfaces_script_timeout():
|
|
2385
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-capture-timeout-'))
|
|
2386
|
+
state_path = tempdir / 'state.json'
|
|
2387
|
+
try:
|
|
2388
|
+
state = base_state(tempdir, reference='before')
|
|
2389
|
+
state.update({
|
|
2390
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2391
|
+
'author_status': 'ready',
|
|
2392
|
+
'proof_plan_status': 'ready',
|
|
2393
|
+
'implementation_status': 'changes_detected',
|
|
2394
|
+
'before_cdn': 'https://cdn.example.com/before.png',
|
|
2395
|
+
'proof_plan': 'Click the skip link and capture the resulting focus state.',
|
|
2396
|
+
'capture_script': "skipLinkTimeout();",
|
|
2397
|
+
'recon_results': {
|
|
2398
|
+
'baselines': {'before': {'path': '/', 'url': 'https://cdn.example.com/before.png'}},
|
|
2399
|
+
},
|
|
2400
|
+
'server_path': '/',
|
|
2401
|
+
})
|
|
2402
|
+
write_state(state_path, state)
|
|
2403
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2404
|
+
|
|
2405
|
+
fake = FakeRiddle()
|
|
2406
|
+
load_util_with_fake(fake)
|
|
2407
|
+
load_module('verify_capture_timeout_summary', VERIFY_PATH)
|
|
2408
|
+
after_verify = json.loads(state_path.read_text())
|
|
2409
|
+
|
|
2410
|
+
assert after_verify['verify_status'] == 'capture_incomplete'
|
|
2411
|
+
capture_quality = after_verify['verify_decision_request']['capture_quality']
|
|
2412
|
+
assert capture_quality['recommended_stage'] == 'author'
|
|
2413
|
+
assert 'locator.click: Timeout 30000ms exceeded' in capture_quality['summary']
|
|
2414
|
+
assert any('locator.click: Timeout 30000ms exceeded' in reason for reason in capture_quality['reasons'])
|
|
2415
|
+
return {
|
|
2416
|
+
'ok': True,
|
|
2417
|
+
'summary': capture_quality['summary'],
|
|
2418
|
+
}
|
|
2419
|
+
finally:
|
|
2420
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2421
|
+
|
|
2422
|
+
|
|
2129
2423
|
def run_verify_missing_baseline():
|
|
2130
2424
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-missing-baseline-'))
|
|
2131
2425
|
state_path = tempdir / 'state.json'
|
|
@@ -2501,6 +2795,10 @@ if __name__ == '__main__':
|
|
|
2501
2795
|
'verify_audio_rejects_failed_nested_proof_evidence': run_verify_audio_rejects_failed_nested_proof_evidence(),
|
|
2502
2796
|
'verify_preserves_proof_evidence_on_capture_script_error': run_verify_preserves_proof_evidence_on_capture_script_error(),
|
|
2503
2797
|
'verify_capture_retry': run_verify_capture_retry(),
|
|
2798
|
+
'remote_audit_verify_uses_default_capture_script': run_remote_audit_verify_uses_default_capture_script(),
|
|
2799
|
+
'verify_interaction_terminal_route_from_proof_evidence': run_verify_interaction_terminal_route_from_proof_evidence(),
|
|
2800
|
+
'verify_interaction_reverse_terminal_route_from_proof_evidence': run_verify_interaction_reverse_terminal_route_from_proof_evidence(),
|
|
2801
|
+
'verify_capture_retry_surfaces_script_timeout': run_verify_capture_retry_surfaces_script_timeout(),
|
|
2504
2802
|
'missing_baseline_guard': run_verify_missing_baseline(),
|
|
2505
2803
|
'ship_supervisor_gate': run_ship_missing_supervisor_gate(),
|
|
2506
2804
|
'ship_blocks_unmeasured_visual_delta': run_ship_blocks_unmeasured_visual_delta(),
|