@riddledc/riddle-proof 0.5.36 → 0.5.38
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 +28 -8
- package/dist/chunk-NSWT3VSV.js +361 -0
- package/dist/engine-harness.js +2 -2
- package/dist/index.cjs +364 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +23 -11
- package/dist/playability.cjs +389 -0
- package/dist/playability.d.cts +44 -0
- package/dist/playability.d.ts +44 -0
- package/dist/playability.js +14 -0
- package/dist/types.d.cts +2 -1
- package/dist/types.d.ts +2 -1
- package/lib/workspace-core.mjs +32 -1
- package/package.json +7 -2
- package/runtime/lib/author.py +2 -1
- package/runtime/lib/setup.py +55 -9
- package/runtime/lib/verify.py +333 -2
- package/dist/{chunk-7R6ZQE3X.js → chunk-GN7HSZ6G.js} +3 -3
package/README.md
CHANGED
|
@@ -82,21 +82,25 @@ updates Discord, OpenClaw, GitHub, or another integration.
|
|
|
82
82
|
|
|
83
83
|
The packaged proof-run setup uses isolated git worktrees for before and after
|
|
84
84
|
states. By default those worktrees now live under
|
|
85
|
-
`/tmp/.riddle-proof-worktrees`, with dependency caches under
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
`/var/tmp/riddle-proof/.riddle-proof-worktrees`, with dependency caches under
|
|
86
|
+
the matching disk-backed scratch root. This keeps repeated `node_modules` cache
|
|
87
|
+
materialization off tmpfs `/tmp` and away from EFS or other shared workspace
|
|
88
|
+
filesystems.
|
|
89
89
|
|
|
90
90
|
Set `RIDDLE_PROOF_WORKTREE_ROOT` to choose an explicit location. Set
|
|
91
91
|
`RIDDLE_PROOF_USE_WORKSPACE_WORKTREE_ROOT=1` to keep the previous behavior of
|
|
92
|
-
placing proof worktrees next to the active repository.
|
|
92
|
+
placing proof worktrees next to the active repository. Set
|
|
93
|
+
`RIDDLE_PROOF_SCRATCH_ROOT` to choose the scratch parent, or
|
|
94
|
+
`RIDDLE_PROOF_USE_TMP_SCRATCH=1` to force tmp-backed scratch for a short-lived
|
|
95
|
+
test.
|
|
93
96
|
|
|
94
97
|
When local scratch storage is low, setup prunes stale
|
|
95
98
|
`riddle-proof-*` worktrees from the scratch root before creating the next run.
|
|
96
99
|
This preserves the dependency cache for speed while avoiding old failed runs
|
|
97
|
-
filling
|
|
98
|
-
|
|
99
|
-
`
|
|
100
|
+
filling the scratch disk. Setup also records scratch disk snapshots in the run
|
|
101
|
+
state so disk blockers are visible during proof inspection. Set
|
|
102
|
+
`RIDDLE_PROOF_KEEP_SCRATCH_WORKTREES=1` to disable that cleanup for debugging,
|
|
103
|
+
or tune the low-space threshold with `RIDDLE_PROOF_MIN_SCRATCH_FREE_MB`.
|
|
100
104
|
|
|
101
105
|
## Capture Diagnostics
|
|
102
106
|
|
|
@@ -158,6 +162,22 @@ transport state, current playhead time, instrument lane readiness, measured
|
|
|
158
162
|
frame drift, console errors, and screenshots of the intended view. The reviewer
|
|
159
163
|
still decides whether it sounds good.
|
|
160
164
|
|
|
165
|
+
### Playable / Game Proof
|
|
166
|
+
|
|
167
|
+
For games, canvas scenes, and interactive toys, use `verification_mode:
|
|
168
|
+
"playable"` or `"gameplay"` when a static screenshot is not enough. The capture
|
|
169
|
+
must prove the experience responds over time:
|
|
170
|
+
|
|
171
|
+
- accepted keyboard, pointer, or touch input
|
|
172
|
+
- game state or HUD values changed after input
|
|
173
|
+
- elapsed play/animation time progressed
|
|
174
|
+
- non-HUD playfield/canvas pixels changed by a measured threshold
|
|
175
|
+
|
|
176
|
+
Expose that as `window.__riddleProofEvidence.playability` or
|
|
177
|
+
`playability_evidence` with `version: "riddle-proof.playability.v1"`. A nice
|
|
178
|
+
still frame, including a generated image plate, is supporting evidence only and
|
|
179
|
+
does not satisfy playable proof by itself.
|
|
180
|
+
|
|
161
181
|
### Server Preview Usage
|
|
162
182
|
|
|
163
183
|
Server preview proof is most useful when the request, capture, and PR comment
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
// src/playability.ts
|
|
2
|
+
var RIDDLE_PROOF_PLAYABILITY_VERSION = "riddle-proof.playability.v1";
|
|
3
|
+
var RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION = "riddle-proof.playability.assessment.v1";
|
|
4
|
+
var PLAYABILITY_MODES = /* @__PURE__ */ new Set(["playable", "gameplay", "game"]);
|
|
5
|
+
var PLAYABILITY_CONTAINER_KEYS = [
|
|
6
|
+
"playability",
|
|
7
|
+
"playability_evidence",
|
|
8
|
+
"playabilityEvidence",
|
|
9
|
+
"playable",
|
|
10
|
+
"gameplay",
|
|
11
|
+
"gameplay_evidence",
|
|
12
|
+
"gameplayEvidence"
|
|
13
|
+
];
|
|
14
|
+
var INPUT_ASSERTION_KEYS = [
|
|
15
|
+
"inputAccepted",
|
|
16
|
+
"inputObserved",
|
|
17
|
+
"inputReceived",
|
|
18
|
+
"controlsWorked",
|
|
19
|
+
"keyboardWorked",
|
|
20
|
+
"pointerWorked",
|
|
21
|
+
"touchWorked",
|
|
22
|
+
"steeringInputAccepted",
|
|
23
|
+
"userInputObserved"
|
|
24
|
+
];
|
|
25
|
+
var STATE_ASSERTION_KEYS = [
|
|
26
|
+
"stateChanged",
|
|
27
|
+
"gameStateChanged",
|
|
28
|
+
"playStarted",
|
|
29
|
+
"simulationAdvanced",
|
|
30
|
+
"distanceAdvanced",
|
|
31
|
+
"scoreChanged",
|
|
32
|
+
"hudChanged",
|
|
33
|
+
"positionChanged",
|
|
34
|
+
"speedChanged"
|
|
35
|
+
];
|
|
36
|
+
var MOTION_ASSERTION_KEYS = [
|
|
37
|
+
"motionObserved",
|
|
38
|
+
"visualMotion",
|
|
39
|
+
"canvasChanged",
|
|
40
|
+
"pixelChanged",
|
|
41
|
+
"playfieldMoved",
|
|
42
|
+
"playfieldPixelsChanged",
|
|
43
|
+
"nonHudPixelsChanged",
|
|
44
|
+
"animationAdvanced",
|
|
45
|
+
"frameChanged",
|
|
46
|
+
"framesChanged"
|
|
47
|
+
];
|
|
48
|
+
var TIME_ASSERTION_KEYS = [
|
|
49
|
+
"timeProgressed",
|
|
50
|
+
"clockAdvanced",
|
|
51
|
+
"animationAdvanced",
|
|
52
|
+
"simulationAdvanced",
|
|
53
|
+
"playStarted"
|
|
54
|
+
];
|
|
55
|
+
var PERCENT_KEYS = [
|
|
56
|
+
"changed_percent",
|
|
57
|
+
"change_percent",
|
|
58
|
+
"percent_changed",
|
|
59
|
+
"diff_percent",
|
|
60
|
+
"motion_percent",
|
|
61
|
+
"pixel_change_percent"
|
|
62
|
+
];
|
|
63
|
+
var RATIO_KEYS = [
|
|
64
|
+
"changed_ratio",
|
|
65
|
+
"change_ratio",
|
|
66
|
+
"diff_ratio",
|
|
67
|
+
"motion_ratio",
|
|
68
|
+
"pixel_change_ratio"
|
|
69
|
+
];
|
|
70
|
+
var PIXEL_KEYS = [
|
|
71
|
+
"changed_pixels",
|
|
72
|
+
"changed_pixel_count",
|
|
73
|
+
"diff_pixels",
|
|
74
|
+
"motion_pixels",
|
|
75
|
+
"pixel_delta",
|
|
76
|
+
"changedPixels"
|
|
77
|
+
];
|
|
78
|
+
var AVERAGE_DELTA_KEYS = [
|
|
79
|
+
"average_delta",
|
|
80
|
+
"avg_delta",
|
|
81
|
+
"mean_delta",
|
|
82
|
+
"avg_abs_delta",
|
|
83
|
+
"mean_abs_delta"
|
|
84
|
+
];
|
|
85
|
+
var TIME_DELTA_KEYS = [
|
|
86
|
+
"time_delta_ms",
|
|
87
|
+
"elapsed_ms",
|
|
88
|
+
"duration_ms",
|
|
89
|
+
"sample_duration_ms",
|
|
90
|
+
"animation_delta_ms"
|
|
91
|
+
];
|
|
92
|
+
function isRiddleProofPlayabilityMode(mode) {
|
|
93
|
+
return PLAYABILITY_MODES.has(stringValue(mode).toLowerCase());
|
|
94
|
+
}
|
|
95
|
+
function extractPlayabilityEvidence(...sources) {
|
|
96
|
+
const seen = /* @__PURE__ */ new Set();
|
|
97
|
+
for (const source of sources) {
|
|
98
|
+
const found = findPlayabilityEvidence(source, seen);
|
|
99
|
+
if (found) return found;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
function assessPlayabilityEvidence(evidence, options = {}) {
|
|
104
|
+
const thresholds = {
|
|
105
|
+
minChangedPercent: options.minChangedPercent ?? 0.5,
|
|
106
|
+
minChangedPixels: options.minChangedPixels ?? 1e3,
|
|
107
|
+
minAverageDelta: options.minAverageDelta ?? 1,
|
|
108
|
+
minTimeDeltaMs: options.minTimeDeltaMs ?? 250
|
|
109
|
+
};
|
|
110
|
+
const required = {
|
|
111
|
+
requireInput: options.requireInput ?? true,
|
|
112
|
+
requireStateChange: options.requireStateChange ?? true,
|
|
113
|
+
requireMotion: options.requireMotion ?? true,
|
|
114
|
+
requireTimeProgression: options.requireTimeProgression ?? true
|
|
115
|
+
};
|
|
116
|
+
const record = extractPlayabilityEvidence(evidence);
|
|
117
|
+
const metrics = {};
|
|
118
|
+
const concerns = [];
|
|
119
|
+
if (!record) {
|
|
120
|
+
return {
|
|
121
|
+
version: RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
|
|
122
|
+
evidence_present: false,
|
|
123
|
+
passed: false,
|
|
124
|
+
input_observed: false,
|
|
125
|
+
state_changed: false,
|
|
126
|
+
motion_observed: false,
|
|
127
|
+
time_progressed: false,
|
|
128
|
+
concerns: ["playability evidence is missing"],
|
|
129
|
+
metrics,
|
|
130
|
+
thresholds,
|
|
131
|
+
required,
|
|
132
|
+
evidence_keys: []
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const assertions = recordValue(record.assertions) || record;
|
|
136
|
+
const inputObserved = inputObservedFrom(record, assertions);
|
|
137
|
+
const stateChanged = stateChangedFrom(record, assertions, metrics);
|
|
138
|
+
const motionObserved = motionObservedFrom(record, assertions, thresholds, metrics);
|
|
139
|
+
const timeProgressed = timeProgressedFrom(record, assertions, thresholds, metrics);
|
|
140
|
+
const explicitFailure = hasExplicitPlayabilityFailure(record, assertions);
|
|
141
|
+
if (required.requireInput && !inputObserved) {
|
|
142
|
+
concerns.push("no accepted player input was observed");
|
|
143
|
+
}
|
|
144
|
+
if (required.requireStateChange && !stateChanged) {
|
|
145
|
+
concerns.push("game state did not measurably change");
|
|
146
|
+
}
|
|
147
|
+
if (required.requireMotion && !motionObserved) {
|
|
148
|
+
concerns.push("playfield/canvas pixels did not measurably change");
|
|
149
|
+
}
|
|
150
|
+
if (required.requireTimeProgression && !timeProgressed) {
|
|
151
|
+
concerns.push("play time or animation time did not measurably progress");
|
|
152
|
+
}
|
|
153
|
+
if (explicitFailure) {
|
|
154
|
+
concerns.push("playability evidence includes an explicit failed assertion");
|
|
155
|
+
}
|
|
156
|
+
const passed = Boolean(
|
|
157
|
+
(!required.requireInput || inputObserved) && (!required.requireStateChange || stateChanged) && (!required.requireMotion || motionObserved) && (!required.requireTimeProgression || timeProgressed) && !explicitFailure
|
|
158
|
+
);
|
|
159
|
+
return {
|
|
160
|
+
version: RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
|
|
161
|
+
evidence_present: true,
|
|
162
|
+
passed,
|
|
163
|
+
input_observed: inputObserved,
|
|
164
|
+
state_changed: stateChanged,
|
|
165
|
+
motion_observed: motionObserved,
|
|
166
|
+
time_progressed: timeProgressed,
|
|
167
|
+
concerns,
|
|
168
|
+
metrics,
|
|
169
|
+
thresholds,
|
|
170
|
+
required,
|
|
171
|
+
evidence_keys: Object.keys(record)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function findPlayabilityEvidence(value, seen, depth = 0) {
|
|
175
|
+
if (depth > 6 || value === null || value === void 0) return null;
|
|
176
|
+
if (typeof value === "string") {
|
|
177
|
+
const parsed = parseJson(value);
|
|
178
|
+
return parsed === null ? null : findPlayabilityEvidence(parsed, seen, depth + 1);
|
|
179
|
+
}
|
|
180
|
+
if (Array.isArray(value)) {
|
|
181
|
+
if (seen.has(value)) return null;
|
|
182
|
+
seen.add(value);
|
|
183
|
+
for (const item of value) {
|
|
184
|
+
const found = findPlayabilityEvidence(item, seen, depth + 1);
|
|
185
|
+
if (found) return found;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const record = recordValue(value);
|
|
190
|
+
if (!record || seen.has(record)) return null;
|
|
191
|
+
seen.add(record);
|
|
192
|
+
if (record.version === RIDDLE_PROOF_PLAYABILITY_VERSION || hasPlayabilityShape(record)) {
|
|
193
|
+
return record;
|
|
194
|
+
}
|
|
195
|
+
for (const key of PLAYABILITY_CONTAINER_KEYS) {
|
|
196
|
+
if (Object.prototype.hasOwnProperty.call(record, key)) {
|
|
197
|
+
const nested = findPlayabilityEvidence(record[key], seen, depth + 1);
|
|
198
|
+
if (nested) return nested;
|
|
199
|
+
if (typeof record[key] === "boolean") {
|
|
200
|
+
return { assertions: { [key]: record[key] } };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
for (const item of Object.values(record)) {
|
|
205
|
+
const found = findPlayabilityEvidence(item, seen, depth + 1);
|
|
206
|
+
if (found) return found;
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function hasPlayabilityShape(record) {
|
|
211
|
+
return Boolean(
|
|
212
|
+
record.input_events || record.state_delta || record.pixel_delta || record.canvas_delta || record.motion_delta || record.playfield_delta || record.time_delta_ms !== void 0 || hasAnyKey(recordValue(record.assertions) || record, [
|
|
213
|
+
...INPUT_ASSERTION_KEYS,
|
|
214
|
+
...STATE_ASSERTION_KEYS,
|
|
215
|
+
...MOTION_ASSERTION_KEYS,
|
|
216
|
+
...TIME_ASSERTION_KEYS
|
|
217
|
+
])
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
function inputObservedFrom(record, assertions) {
|
|
221
|
+
if (trueForAnyKey(assertions, INPUT_ASSERTION_KEYS)) return true;
|
|
222
|
+
if (listValue(record.input_events).length > 0) return true;
|
|
223
|
+
if (listValue(record.inputs).length > 0) return true;
|
|
224
|
+
if (listValue(record.interactions).length > 0) return true;
|
|
225
|
+
const eventCount = numericFromAnyKey(record, ["input_event_count", "input_count", "interaction_count"]);
|
|
226
|
+
return eventCount !== null && eventCount > 0;
|
|
227
|
+
}
|
|
228
|
+
function stateChangedFrom(record, assertions, metrics) {
|
|
229
|
+
if (trueForAnyKey(assertions, STATE_ASSERTION_KEYS)) return true;
|
|
230
|
+
const stateDelta = recordValue(record.state_delta) || recordValue(record.stateDelta);
|
|
231
|
+
if (stateDelta) {
|
|
232
|
+
const changedKeys = listValue(stateDelta.changed_keys || stateDelta.changedKeys);
|
|
233
|
+
metrics.state_changed_keys = changedKeys;
|
|
234
|
+
if (stateDelta.changed === true || changedKeys.length > 0) return true;
|
|
235
|
+
}
|
|
236
|
+
const delta = numericFromAnyKey(record, [
|
|
237
|
+
"distance_delta",
|
|
238
|
+
"score_delta",
|
|
239
|
+
"position_delta",
|
|
240
|
+
"speed_delta",
|
|
241
|
+
"hud_delta"
|
|
242
|
+
]);
|
|
243
|
+
if (delta !== null) {
|
|
244
|
+
metrics.state_numeric_delta = delta;
|
|
245
|
+
return Math.abs(delta) > 0;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
function motionObservedFrom(record, assertions, thresholds, metrics) {
|
|
250
|
+
if (trueForAnyKey(assertions, MOTION_ASSERTION_KEYS)) return true;
|
|
251
|
+
for (const source of [
|
|
252
|
+
recordValue(record.playfield_delta),
|
|
253
|
+
recordValue(record.playfieldDelta),
|
|
254
|
+
recordValue(record.non_hud_delta),
|
|
255
|
+
recordValue(record.nonHudDelta),
|
|
256
|
+
recordValue(record.pixel_delta),
|
|
257
|
+
recordValue(record.pixelDelta),
|
|
258
|
+
recordValue(record.canvas_delta),
|
|
259
|
+
recordValue(record.canvasDelta),
|
|
260
|
+
recordValue(record.motion_delta),
|
|
261
|
+
recordValue(record.motionDelta),
|
|
262
|
+
recordValue(record.visual_delta),
|
|
263
|
+
recordValue(record.visualDelta),
|
|
264
|
+
record
|
|
265
|
+
]) {
|
|
266
|
+
if (!source) continue;
|
|
267
|
+
const percent = percentFrom(source);
|
|
268
|
+
const pixels = numericFromAnyKey(source, PIXEL_KEYS);
|
|
269
|
+
const averageDelta = numericFromAnyKey(source, AVERAGE_DELTA_KEYS);
|
|
270
|
+
if (percent !== null) metrics.changed_percent = percent;
|
|
271
|
+
if (pixels !== null) metrics.changed_pixels = pixels;
|
|
272
|
+
if (averageDelta !== null) metrics.average_delta = averageDelta;
|
|
273
|
+
if (percent !== null && percent >= thresholds.minChangedPercent) return true;
|
|
274
|
+
if (pixels !== null && pixels >= thresholds.minChangedPixels) return true;
|
|
275
|
+
if (averageDelta !== null && averageDelta >= thresholds.minAverageDelta) return true;
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
function timeProgressedFrom(record, assertions, thresholds, metrics) {
|
|
280
|
+
if (trueForAnyKey(assertions, TIME_ASSERTION_KEYS)) return true;
|
|
281
|
+
const timeDelta = numericFromAnyKey(record, TIME_DELTA_KEYS);
|
|
282
|
+
if (timeDelta !== null) {
|
|
283
|
+
metrics.time_delta_ms = timeDelta;
|
|
284
|
+
return timeDelta >= thresholds.minTimeDeltaMs;
|
|
285
|
+
}
|
|
286
|
+
const stateDelta = recordValue(record.state_delta) || recordValue(record.stateDelta);
|
|
287
|
+
const nestedDelta = numericFromAnyKey(stateDelta || {}, TIME_DELTA_KEYS);
|
|
288
|
+
if (nestedDelta !== null) {
|
|
289
|
+
metrics.time_delta_ms = nestedDelta;
|
|
290
|
+
return nestedDelta >= thresholds.minTimeDeltaMs;
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
function hasExplicitPlayabilityFailure(record, assertions) {
|
|
295
|
+
if (record.passed === false || record.playable === false || assertions.playabilityPassed === false) {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
for (const key of [
|
|
299
|
+
...INPUT_ASSERTION_KEYS,
|
|
300
|
+
...STATE_ASSERTION_KEYS,
|
|
301
|
+
...MOTION_ASSERTION_KEYS,
|
|
302
|
+
...TIME_ASSERTION_KEYS
|
|
303
|
+
]) {
|
|
304
|
+
if (assertions[key] === false) return true;
|
|
305
|
+
}
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
function trueForAnyKey(record, keys) {
|
|
309
|
+
return keys.some((key) => record[key] === true);
|
|
310
|
+
}
|
|
311
|
+
function hasAnyKey(record, keys) {
|
|
312
|
+
return keys.some((key) => Object.prototype.hasOwnProperty.call(record, key));
|
|
313
|
+
}
|
|
314
|
+
function percentFrom(record) {
|
|
315
|
+
const percent = numericFromAnyKey(record, PERCENT_KEYS);
|
|
316
|
+
if (percent !== null) return percent;
|
|
317
|
+
const ratio = numericFromAnyKey(record, RATIO_KEYS);
|
|
318
|
+
if (ratio !== null) return ratio <= 1 ? ratio * 100 : ratio;
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
function numericFromAnyKey(record, keys) {
|
|
322
|
+
for (const key of keys) {
|
|
323
|
+
const value = numericValue(record[key]);
|
|
324
|
+
if (value !== null) return value;
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
function recordValue(value) {
|
|
329
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
330
|
+
}
|
|
331
|
+
function listValue(value) {
|
|
332
|
+
return Array.isArray(value) ? value : [];
|
|
333
|
+
}
|
|
334
|
+
function numericValue(value) {
|
|
335
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
336
|
+
if (typeof value === "string" && value.trim()) {
|
|
337
|
+
const parsed = Number(value);
|
|
338
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
339
|
+
}
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
function stringValue(value) {
|
|
343
|
+
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
344
|
+
}
|
|
345
|
+
function parseJson(value) {
|
|
346
|
+
const trimmed = value.trim();
|
|
347
|
+
if (!trimmed || !/^[{[]/.test(trimmed)) return null;
|
|
348
|
+
try {
|
|
349
|
+
return JSON.parse(trimmed);
|
|
350
|
+
} catch {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export {
|
|
356
|
+
RIDDLE_PROOF_PLAYABILITY_VERSION,
|
|
357
|
+
RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
|
|
358
|
+
isRiddleProofPlayabilityMode,
|
|
359
|
+
extractPlayabilityEvidence,
|
|
360
|
+
assessPlayabilityEvidence
|
|
361
|
+
};
|
package/dist/engine-harness.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
createDisabledRiddleProofAgentAdapter,
|
|
3
3
|
readRiddleProofRunStatus,
|
|
4
4
|
runRiddleProofEngineHarness
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-GN7HSZ6G.js";
|
|
6
6
|
import "./chunk-OASB3CYU.js";
|
|
7
|
-
import "./chunk-4YCWZVBN.js";
|
|
8
7
|
import "./chunk-J2MERROF.js";
|
|
8
|
+
import "./chunk-4YCWZVBN.js";
|
|
9
9
|
export {
|
|
10
10
|
createDisabledRiddleProofAgentAdapter,
|
|
11
11
|
readRiddleProofRunStatus,
|