@riddledc/riddle-proof 0.7.117 → 0.7.118

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
@@ -203,6 +203,7 @@ The package includes generic starter profiles:
203
203
  - `examples/profiles/page-content-basic.json` for route/content/layout smoke profiles.
204
204
  - `examples/profiles/route-inventory-basic.json` for source-link and direct-route audits.
205
205
  - `examples/profiles/handled-recovery-list-load.json` for malformed list-load recovery profiles.
206
+ - `examples/profiles/handled-recovery-action-malformed-success.json` for action recovery profiles where the request succeeds at HTTP level but returns an unusable body.
206
207
 
207
208
  Copy one of those shapes into a repository profile directory and replace the
208
209
  routes, selectors, mock URLs, and text checks with app-specific invariants.
@@ -220,6 +221,15 @@ when the list failed to load; and keep `no_fatal_console_errors` plus
220
221
  recovery-quality bugs and hidden browser-health debt without requiring a
221
222
  separate CI or wrapper-specific path.
222
223
 
224
+ For handled action recovery profiles, assert the action itself as well as the
225
+ recovery UI. Capture the request body when the action payload matters, preserve
226
+ the surrounding page state, and reject the success modal, toast, or row that
227
+ would imply the action completed. A useful malformed-success profile returns a
228
+ successful HTTP status with an invalid JSON body, waits for one generic failure
229
+ message, captures a recovery screenshot, and keeps parser text plus browser
230
+ console/page errors out of the final proof. This catches action paths that look
231
+ recovered to a user but still poison the browser evidence stream.
232
+
223
233
  Checks normally apply to every captured viewport. Add `viewports` (or
224
234
  `viewport_names`) to a check when responsive UI intentionally exposes an
225
235
  invariant only on named viewports, such as desktop-only helper copy while phone
@@ -0,0 +1,126 @@
1
+ {
2
+ "version": "riddle-proof.profile.v1",
3
+ "name": "handled-recovery-action-malformed-success",
4
+ "target": {
5
+ "route": "/account",
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_ms": 800,
13
+ "network_mocks": [
14
+ {
15
+ "label": "account-summary",
16
+ "url": "**/api/account/summary",
17
+ "method": "GET",
18
+ "status": 200,
19
+ "content_type": "application/json",
20
+ "required_hit_count": 3,
21
+ "json": {
22
+ "available_time": "4h 0m",
23
+ "active_jobs": 2
24
+ }
25
+ },
26
+ {
27
+ "label": "recent-jobs",
28
+ "url": "**/api/jobs?limit=10",
29
+ "method": "GET",
30
+ "status": 200,
31
+ "content_type": "application/json",
32
+ "required_hit_count": 3,
33
+ "json": {
34
+ "jobs": [
35
+ {
36
+ "id": "job_action_template_survives",
37
+ "status": "completed"
38
+ }
39
+ ]
40
+ }
41
+ },
42
+ {
43
+ "label": "existing-api-keys",
44
+ "url": "**/api/api-keys",
45
+ "method": "GET",
46
+ "status": 200,
47
+ "content_type": "application/json",
48
+ "required_hit_count": 3,
49
+ "json": {
50
+ "keys": [
51
+ {
52
+ "id": "key_action_template_existing",
53
+ "name": "Existing action template key",
54
+ "last4": "0001",
55
+ "status": "active"
56
+ }
57
+ ]
58
+ }
59
+ },
60
+ {
61
+ "label": "create-api-key-malformed-success",
62
+ "url": "**/api/api-keys",
63
+ "method": "POST",
64
+ "status": 200,
65
+ "content_type": "application/json",
66
+ "required_hit_count": 3,
67
+ "max_hit_count": 3,
68
+ "capture_request_body": true,
69
+ "request_body_contains": ["Action template malformed success key"],
70
+ "body": "{not valid create success json"
71
+ }
72
+ ],
73
+ "setup_actions": [
74
+ { "type": "clear_storage", "storage": "both", "reload": true },
75
+ { "type": "wait_for_selector", "selector": "[data-testid='account-page']", "timeout_ms": 30000 },
76
+ { "type": "wait_for_text", "selector": "body", "text": "4h 0m", "timeout_ms": 30000 },
77
+ { "type": "wait_for_text", "selector": "body", "text": "job_action_template_survives", "timeout_ms": 30000 },
78
+ { "type": "wait_for_text", "selector": "body", "text": "Existing action template key", "timeout_ms": 30000 },
79
+ { "type": "fill", "selector": "[data-testid='new-key-name']", "value": "Action template malformed success key" },
80
+ { "type": "clear_console" },
81
+ { "type": "screenshot", "label": "before-malformed-success-action" },
82
+ { "type": "click", "selector": "[data-testid='create-key-button']", "text": "Create API key" },
83
+ { "type": "wait_for_text", "selector": "body", "text": "Failed to create API key", "timeout_ms": 30000 },
84
+ { "type": "assert_text_visible", "selector": "body", "text": "Existing action template key", "timeout_ms": 5000 },
85
+ { "type": "assert_text_visible", "selector": "body", "text": "Active", "timeout_ms": 5000 },
86
+ { "type": "assert_text_absent", "selector": "body", "text": "API Key Created!", "timeout_ms": 1000 },
87
+ { "type": "assert_text_absent", "selector": "body", "text": "Expected property name", "timeout_ms": 1000 },
88
+ { "type": "assert_text_absent", "selector": "body", "text": "SyntaxError", "timeout_ms": 1000 },
89
+ { "type": "assert_text_absent", "selector": "body", "text": "[object Object]", "timeout_ms": 1000 },
90
+ { "type": "screenshot", "label": "malformed-success-action-visible-recovery" }
91
+ ]
92
+ },
93
+ "checks": [
94
+ { "type": "route_loaded", "expected_path": "/account" },
95
+ { "type": "selector_visible", "selector": "[data-testid='account-page']" },
96
+ { "type": "selector_visible", "selector": "[data-testid='api-key-create-error']" },
97
+ { "type": "text_visible", "text": "4h 0m" },
98
+ { "type": "text_visible", "text": "2 active" },
99
+ { "type": "text_visible", "text": "job_action_template_survives" },
100
+ { "type": "text_visible", "text": "Existing action template key" },
101
+ { "type": "text_visible", "text": "Failed to create API key" },
102
+ { "type": "text_visible", "text": "Active" },
103
+ { "type": "text_absent", "text": "API Key Created!" },
104
+ { "type": "text_absent", "text": "Expected property name" },
105
+ { "type": "text_absent", "text": "SyntaxError" },
106
+ { "type": "text_absent", "text": "[object Object]" },
107
+ { "type": "text_absent", "text": "Application error" },
108
+ { "type": "selector_count_equals", "selector": "[data-testid='api-key-create-error']", "expected_count": 1 },
109
+ { "type": "selector_count_equals", "selector": "[data-testid='recent-job-row']", "expected_count": 1 },
110
+ { "type": "selector_count_equals", "selector": "[data-testid='api-key-row']", "expected_count": 1 },
111
+ { "type": "selector_count_equals", "selector": "[data-testid='created-key-modal']", "expected_count": 0 },
112
+ { "type": "no_horizontal_overflow", "max_overflow_px": 1 },
113
+ { "type": "no_fatal_console_errors" },
114
+ { "type": "no_console_warnings" }
115
+ ],
116
+ "artifacts": ["screenshot", "console", "dom_summary", "proof_json"],
117
+ "baseline_policy": "invariant_only",
118
+ "failure_policy": {
119
+ "environment_blocked": "neutral",
120
+ "proof_insufficient": "fail",
121
+ "product_regression": "fail"
122
+ },
123
+ "metadata": {
124
+ "purpose": "Template for handled malformed action-success recovery: prove surrounding state still renders, the failed action shows one recovery message, success UI and raw parser text stay absent, the action request body is captured, and browser console evidence remains clean."
125
+ }
126
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.117",
3
+ "version": "0.7.118",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",