@riddledc/riddle-proof 0.7.178 → 0.7.179

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/README.md CHANGED
@@ -240,6 +240,7 @@ The package includes generic starter profiles:
240
240
  - `examples/profiles/handled-recovery-list-load.json` for failed or malformed list-load recovery profiles.
241
241
  - `examples/profiles/handled-recovery-action-malformed-success.json` for action recovery profiles where the request succeeds at HTTP level but returns an unusable body.
242
242
  - `examples/profiles/terminal-result-partial-evidence.json` for API-console terminal error or timeout receipts that preserve partial screenshot, console, and HAR evidence.
243
+ - `examples/profiles/gameplay-window-call-until.json` for gameplay profiles that wait on a runtime state contract instead of a fixed sleep.
243
244
 
244
245
  Copy one of those shapes into a repository profile directory and replace the
245
246
  routes, selectors, mock URLs, and text checks with app-specific invariants.
@@ -487,6 +488,10 @@ progressive state until a window-state receipt is true. It accepts `path` plus
487
488
  optional `args`, `until_path`, `until_expected_value`, `max_calls` from 1 to
488
489
  100, and optional `interval_ms`; the action stops early when the predicate is
489
490
  met and records `call_count`, final `returned`, and final `until_value`.
491
+ For gameplay progression, prefer this to a fixed `wait` when frame cadence or
492
+ hosted-runner timing can vary by viewport; install a small `window` helper that
493
+ returns JSON-safe state, stores the latest receipt, and makes the pass condition
494
+ explicit. See `examples/profiles/gameplay-window-call-until.json`.
490
495
  Use `screenshot` with an optional `label` to capture durable Riddle screenshots
491
496
  at important setup milestones, such as after a route switch, terminal state, or
492
497
  reset. These labels are recorded in setup evidence and included in profile
@@ -0,0 +1,101 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "gameplay-window-call-until",
4
+ "target": {
5
+ "route": "/games/example",
6
+ "viewports": [
7
+ { "name": "mobile", "width": 390, "height": 844 },
8
+ { "name": "tablet", "width": 820, "height": 1180 },
9
+ { "name": "desktop", "width": 1440, "height": 1000 }
10
+ ],
11
+ "timeout_sec": 300,
12
+ "wait_for_selector": "#game-root canvas",
13
+ "screenshot_mode": "viewport",
14
+ "setup_actions": [
15
+ { "type": "clear_storage", "storage": "both", "reload": true },
16
+ { "type": "wait_for_selector", "selector": "#game-root", "timeout_ms": 20000 },
17
+ { "type": "wait_for_selector", "selector": "#game-root canvas", "timeout_ms": 20000 },
18
+ {
19
+ "type": "window_eval",
20
+ "label": "install-gameplay-proof-reader",
21
+ "timeout_ms": 10000,
22
+ "store_return_to": "__gameplayProof.ready",
23
+ "script": "window.__riddleGameplayStep=()=>{const api=window.__exampleGameProof;const state=api?.step?.()||api?.read?.()||{};const out={ready:state.ready===true,inputAccepted:state.inputAccepted===true,gameOver:state.gameOver===true,distance:Number(state.distance||0),score:Number(state.score||0),level:Number(state.level||0)};out.ok=out.ready&&out.inputAccepted&&out.gameOver===false&&out.distance>=2&&out.score>=10;window.__gameplayProof={...(window.__gameplayProof||{}),running:out};return out;};const api=window.__exampleGameProof;const initial=api?.read?.()||{};const out={ready:initial.ready===true,inputAccepted:initial.inputAccepted===true,gameOver:initial.gameOver===true,distance:Number(initial.distance||0),score:Number(initial.score||0),level:Number(initial.level||0)};window.__gameplayProof={...(window.__gameplayProof||{}),ready:out};return out;",
24
+ "return_summary_fields": [
25
+ { "path": "ready" },
26
+ { "path": "inputAccepted" },
27
+ { "path": "distance" },
28
+ { "path": "score" },
29
+ { "path": "gameOver" }
30
+ ]
31
+ },
32
+ { "type": "assert_window_value", "path": "__gameplayProof.ready.ready", "expected": true, "timeout_ms": 10000 },
33
+ {
34
+ "type": "canvas_signature",
35
+ "selector": "#game-root canvas",
36
+ "label": "ready",
37
+ "store_signature_to": "__gameplayProof.readyCanvas",
38
+ "timeout_ms": 10000
39
+ },
40
+ { "type": "screenshot", "label": "ready", "mode": "viewport" },
41
+ { "type": "press", "key": "Space", "after_ms": 120 },
42
+ { "type": "press", "key": "ArrowRight", "after_ms": 120 },
43
+ {
44
+ "type": "window_call_until",
45
+ "path": "__riddleGameplayStep",
46
+ "until_path": "__gameplayProof.running.ok",
47
+ "until_expected_value": true,
48
+ "max_calls": 36,
49
+ "interval_ms": 250,
50
+ "timeout_ms": 15000
51
+ },
52
+ {
53
+ "type": "window_eval",
54
+ "label": "capture-running-proof",
55
+ "timeout_ms": 10000,
56
+ "store_return_to": "__gameplayProof.running",
57
+ "script": "return window.__riddleGameplayStep?.()||{};",
58
+ "return_summary_fields": [
59
+ { "path": "ok" },
60
+ { "path": "distance" },
61
+ { "path": "score" },
62
+ { "path": "inputAccepted" },
63
+ { "path": "gameOver" }
64
+ ]
65
+ },
66
+ { "type": "assert_window_value", "path": "__gameplayProof.running.ok", "expected": true, "timeout_ms": 10000 },
67
+ { "type": "assert_window_value", "path": "__gameplayProof.running.gameOver", "expected": false, "timeout_ms": 10000 },
68
+ { "type": "assert_window_number", "path": "__gameplayProof.running.distance", "min_value": 2, "timeout_ms": 10000 },
69
+ { "type": "assert_window_number", "path": "__gameplayProof.running.score", "min_value": 10, "timeout_ms": 10000 },
70
+ {
71
+ "type": "canvas_signature",
72
+ "selector": "#game-root canvas",
73
+ "label": "running",
74
+ "store_signature_to": "__gameplayProof.runningCanvas",
75
+ "timeout_ms": 10000
76
+ },
77
+ { "type": "screenshot", "label": "running", "mode": "viewport" }
78
+ ]
79
+ },
80
+ "checks": [
81
+ { "type": "route_loaded", "expected_path": "/games/example" },
82
+ { "type": "selector_visible", "selector": "#game-root" },
83
+ { "type": "selector_visible", "selector": "#game-root canvas" },
84
+ { "type": "selector_count_equals", "selector": "#game-root canvas", "expected_count": 1 },
85
+ { "type": "text_absent", "pattern": "\\bNaN\\b" },
86
+ { "type": "text_absent", "pattern": "undefined", "flags": "i" },
87
+ { "type": "no_horizontal_overflow", "max_overflow_px": 1 },
88
+ { "type": "no_fatal_console_errors" },
89
+ { "type": "no_console_warnings" }
90
+ ],
91
+ "artifacts": ["screenshot", "console", "dom_summary", "proof_json"],
92
+ "baseline_policy": "invariant_only",
93
+ "failure_policy": {
94
+ "environment_blocked": "neutral",
95
+ "proof_insufficient": "fail",
96
+ "product_regression": "fail"
97
+ },
98
+ "metadata": {
99
+ "purpose": "Template for gameplay profiles where a route exposes window.__exampleGameProof.read() and optionally step(). Use window_call_until to wait for runtime state such as accepted input, distance, score, or level completion instead of relying on fixed sleeps that vary across hosted browser frame cadence."
100
+ }
101
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.178",
3
+ "version": "0.7.179",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",