@riddledc/riddle-proof 0.7.150 → 0.7.152

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/cli.cjs CHANGED
@@ -15064,6 +15064,7 @@ function profileRiddleJobMarkdown(result) {
15064
15064
  const attempts = cliFiniteNumber(riddle.attempts);
15065
15065
  const submittedAt = cliString(riddle.submitted_at);
15066
15066
  const completedAt = cliString(riddle.completed_at);
15067
+ const artifactRecovery = riddle.artifact_recovery === true;
15067
15068
  const parts = [
15068
15069
  mode ? `mode ${markdownInlineCode(mode)}` : "",
15069
15070
  jobCount === void 0 ? "" : `jobs ${jobCount}`,
@@ -15080,6 +15081,9 @@ function profileRiddleJobMarkdown(result) {
15080
15081
  if (submittedAt || completedAt) {
15081
15082
  lines.push(`- timing:${submittedAt ? ` submitted ${markdownInlineCode(submittedAt)}` : ""}${completedAt ? ` completed ${markdownInlineCode(completedAt)}` : ""}`);
15082
15083
  }
15084
+ if (artifactRecovery) {
15085
+ lines.push("- artifact recovery: used artifacts endpoint after non-terminal poll");
15086
+ }
15083
15087
  const splitJobs = Array.isArray(riddle.split_jobs) ? riddle.split_jobs.map(cliRecord).filter((job) => Boolean(job)) : [];
15084
15088
  for (const job of splitJobs.slice(0, 12)) {
15085
15089
  const viewport = cliString(job.viewport) || "viewport";
@@ -15088,13 +15092,15 @@ function profileRiddleJobMarkdown(result) {
15088
15092
  const splitTerminal = typeof job.terminal === "boolean" ? job.terminal : void 0;
15089
15093
  const splitElapsedMs = cliFiniteNumber(job.elapsed_ms);
15090
15094
  const splitPreSubmissionElapsedMs = cliFiniteNumber(job.pre_submission_elapsed_ms);
15095
+ const splitArtifactRecovery = job.artifact_recovery === true;
15091
15096
  lines.push(
15092
15097
  `- ${viewport}: ${[
15093
15098
  splitJobId ? `job ${markdownInlineCode(splitJobId)}` : "",
15094
15099
  splitStatus ? `status ${markdownInlineCode(splitStatus)}` : "",
15095
15100
  splitTerminal === void 0 ? "" : `terminal ${splitTerminal ? "true" : "false"}`,
15096
15101
  splitElapsedMs === void 0 ? "" : `elapsed ${formatPollDuration(splitElapsedMs)}`,
15097
- splitPreSubmissionElapsedMs === void 0 || splitPreSubmissionElapsedMs < 1e3 ? "" : `pre-submit ${formatPollDuration(splitPreSubmissionElapsedMs)}`
15102
+ splitPreSubmissionElapsedMs === void 0 || splitPreSubmissionElapsedMs < 1e3 ? "" : `pre-submit ${formatPollDuration(splitPreSubmissionElapsedMs)}`,
15103
+ splitArtifactRecovery ? "artifact recovery" : ""
15098
15104
  ].filter(Boolean).join(", ") || "job metadata unavailable"}`
15099
15105
  );
15100
15106
  }
@@ -15112,6 +15118,20 @@ function profileCheckTextTarget(evidence) {
15112
15118
  const pattern = cliString(evidence.pattern);
15113
15119
  return pattern ? `pattern ${markdownInlineCode(pattern)}` : void 0;
15114
15120
  }
15121
+ function observeWithinMarkdownReceipt(evidence) {
15122
+ const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
15123
+ if (!viewports.length) return void 0;
15124
+ const receipts = viewports.slice(0, 4).map((viewport) => {
15125
+ const name = cliString(viewport.viewport) || cliString(viewport.name) || "viewport";
15126
+ const matched = viewport.matched === true ? "matched" : viewport.matched === false ? "missed" : "observed";
15127
+ const elapsedMs3 = cliFiniteNumber(viewport.elapsed_ms);
15128
+ const attempts = cliFiniteNumber(viewport.attempts);
15129
+ const sample = cliString(viewport.sample);
15130
+ return `${name} ${matched}${elapsedMs3 === void 0 ? "" : ` in ${elapsedMs3}ms`}${attempts === void 0 ? "" : `, ${attempts} attempt${attempts === 1 ? "" : "s"}`}${sample ? `, sample ${markdownInlineCode(sample, 70)}` : ""}`;
15131
+ });
15132
+ if (viewports.length > receipts.length) receipts.push(`${viewports.length - receipts.length} more viewport${viewports.length - receipts.length === 1 ? "" : "s"}`);
15133
+ return receipts.join("; ");
15134
+ }
15115
15135
  function profileCheckMarkdownTarget(check) {
15116
15136
  const evidence = cliRecord(check.evidence);
15117
15137
  if (!evidence) return void 0;
@@ -15145,9 +15165,9 @@ function profileCheckMarkdownTarget(check) {
15145
15165
  const textTarget = profileCheckTextTarget(evidence);
15146
15166
  const timeoutMs = cliFiniteNumber(evidence.timeout_ms);
15147
15167
  const withinLabel = timeoutMs === void 0 ? "within timeout" : `within ${timeoutMs}ms`;
15148
- if (selector && textTarget) return `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}`;
15149
- if (selector) return `${markdownInlineCode(selector)} visible ${withinLabel}`;
15150
- return textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
15168
+ const receipt = observeWithinMarkdownReceipt(evidence);
15169
+ const base = selector && textTarget ? `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}` : selector ? `${markdownInlineCode(selector)} visible ${withinLabel}` : textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
15170
+ return receipt ? `${base}; ${receipt}` : base;
15151
15171
  }
15152
15172
  if (check.type === "text_visible" || check.type === "text_absent") {
15153
15173
  return profileCheckTextTarget(evidence);
@@ -15734,7 +15754,8 @@ function withRiddleMetadata(result, input) {
15734
15754
  elapsed_ms: poll?.elapsed_ms ?? result.riddle?.elapsed_ms,
15735
15755
  attempt: poll?.attempt ?? result.riddle?.attempt,
15736
15756
  attempts: poll?.attempts ?? result.riddle?.attempts,
15737
- timed_out: poll?.timed_out ?? result.riddle?.timed_out
15757
+ timed_out: poll?.timed_out ?? result.riddle?.timed_out,
15758
+ artifact_recovery: input.artifactRecovery ?? result.riddle?.artifact_recovery
15738
15759
  },
15739
15760
  artifacts: {
15740
15761
  ...result.artifacts,
@@ -15742,6 +15763,52 @@ function withRiddleMetadata(result, input) {
15742
15763
  }
15743
15764
  };
15744
15765
  }
15766
+ function riddleArtifactsPayloadStatus(payload) {
15767
+ const record = cliRecord(payload);
15768
+ return cliString(record?.status) ?? cliString(cliRecord(record?.job)?.status);
15769
+ }
15770
+ async function recoverProfileResultFromRiddleArtifacts(profile, input) {
15771
+ if (input.poll.poll?.timed_out !== true) return void 0;
15772
+ let artifactPayload;
15773
+ try {
15774
+ artifactPayload = await input.client.requestJson(`/v1/jobs/${input.jobId}/artifacts`);
15775
+ } catch {
15776
+ return void 0;
15777
+ }
15778
+ const artifacts = collectRiddleProfileArtifactRefs(artifactPayload);
15779
+ if (!artifacts.length) return void 0;
15780
+ const artifactStatus = riddleArtifactsPayloadStatus(artifactPayload);
15781
+ const terminal = artifactStatus ? isTerminalRiddleJobStatus(artifactStatus) : true;
15782
+ const recoveredPoll = input.poll.poll ? {
15783
+ ...input.poll.poll,
15784
+ status: artifactStatus ?? input.poll.poll.status,
15785
+ terminal
15786
+ } : void 0;
15787
+ const artifactResult = await profileResultFromRiddleArtifacts(profile, artifacts, [artifactPayload, input.poll.job]);
15788
+ if (artifactResult) {
15789
+ return withRiddleMetadata(artifactResult, {
15790
+ job_id: input.jobId,
15791
+ status: artifactStatus ?? input.poll.status,
15792
+ terminal,
15793
+ poll: recoveredPoll,
15794
+ artifacts,
15795
+ artifactRecovery: true
15796
+ });
15797
+ }
15798
+ if (!terminal) return void 0;
15799
+ return createRiddleProofProfileInsufficientResult({
15800
+ profile,
15801
+ runner: input.runner,
15802
+ error: `Riddle job ${input.jobId} timed out in status ${input.poll.status || "unknown"}, but artifacts were recovered without a proof result.`,
15803
+ riddle: {
15804
+ ...riddleMetadataFromPoll(input.jobId, input.poll),
15805
+ status: artifactStatus ?? input.poll.status,
15806
+ terminal,
15807
+ artifact_recovery: true
15808
+ },
15809
+ artifacts
15810
+ });
15811
+ }
15745
15812
  function riddleMetadataFromPoll(jobId, poll) {
15746
15813
  return {
15747
15814
  job_id: jobId,
@@ -15804,13 +15871,15 @@ function splitViewportRiddleMetadata(childRuns) {
15804
15871
  elapsed_ms: result.riddle?.elapsed_ms,
15805
15872
  attempt: result.riddle?.attempt,
15806
15873
  attempts: result.riddle?.attempts,
15807
- timed_out: result.riddle?.timed_out
15874
+ timed_out: result.riddle?.timed_out,
15875
+ artifact_recovery: result.riddle?.artifact_recovery
15808
15876
  }));
15809
15877
  return {
15810
15878
  mode: "split-viewports",
15811
15879
  job_count: childRuns.length,
15812
15880
  status: "split-viewports",
15813
15881
  terminal: childRuns.every(({ result }) => result.riddle?.terminal !== false),
15882
+ artifact_recovery: childRuns.some(({ result }) => result.riddle?.artifact_recovery === true),
15814
15883
  queue_elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.queue_elapsed_ms)),
15815
15884
  pre_submission_elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.pre_submission_elapsed_ms)),
15816
15885
  elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.elapsed_ms)),
@@ -15933,6 +16002,13 @@ async function runSingleRiddleProfileForCli(profile, options, input) {
15933
16002
  });
15934
16003
  const artifacts = collectRiddleProfileArtifactRefs(poll.artifacts);
15935
16004
  if (!poll.ok || !poll.terminal) {
16005
+ const recoveredResult = await recoverProfileResultFromRiddleArtifacts(profile, {
16006
+ client,
16007
+ runner,
16008
+ jobId,
16009
+ poll
16010
+ });
16011
+ if (recoveredResult) return recoveredResult;
15936
16012
  return createRiddleProofProfileEnvironmentBlockedResult({
15937
16013
  profile,
15938
16014
  runner,
package/dist/cli.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from "./chunk-QJJ3ISMK.js";
17
17
  import {
18
18
  createRiddleApiClient,
19
+ isTerminalRiddleJobStatus,
19
20
  parseRiddleViewport
20
21
  } from "./chunk-M3ZTY6PQ.js";
21
22
  import {
@@ -430,6 +431,7 @@ function profileRiddleJobMarkdown(result) {
430
431
  const attempts = cliFiniteNumber(riddle.attempts);
431
432
  const submittedAt = cliString(riddle.submitted_at);
432
433
  const completedAt = cliString(riddle.completed_at);
434
+ const artifactRecovery = riddle.artifact_recovery === true;
433
435
  const parts = [
434
436
  mode ? `mode ${markdownInlineCode(mode)}` : "",
435
437
  jobCount === void 0 ? "" : `jobs ${jobCount}`,
@@ -446,6 +448,9 @@ function profileRiddleJobMarkdown(result) {
446
448
  if (submittedAt || completedAt) {
447
449
  lines.push(`- timing:${submittedAt ? ` submitted ${markdownInlineCode(submittedAt)}` : ""}${completedAt ? ` completed ${markdownInlineCode(completedAt)}` : ""}`);
448
450
  }
451
+ if (artifactRecovery) {
452
+ lines.push("- artifact recovery: used artifacts endpoint after non-terminal poll");
453
+ }
449
454
  const splitJobs = Array.isArray(riddle.split_jobs) ? riddle.split_jobs.map(cliRecord).filter((job) => Boolean(job)) : [];
450
455
  for (const job of splitJobs.slice(0, 12)) {
451
456
  const viewport = cliString(job.viewport) || "viewport";
@@ -454,13 +459,15 @@ function profileRiddleJobMarkdown(result) {
454
459
  const splitTerminal = typeof job.terminal === "boolean" ? job.terminal : void 0;
455
460
  const splitElapsedMs = cliFiniteNumber(job.elapsed_ms);
456
461
  const splitPreSubmissionElapsedMs = cliFiniteNumber(job.pre_submission_elapsed_ms);
462
+ const splitArtifactRecovery = job.artifact_recovery === true;
457
463
  lines.push(
458
464
  `- ${viewport}: ${[
459
465
  splitJobId ? `job ${markdownInlineCode(splitJobId)}` : "",
460
466
  splitStatus ? `status ${markdownInlineCode(splitStatus)}` : "",
461
467
  splitTerminal === void 0 ? "" : `terminal ${splitTerminal ? "true" : "false"}`,
462
468
  splitElapsedMs === void 0 ? "" : `elapsed ${formatPollDuration(splitElapsedMs)}`,
463
- splitPreSubmissionElapsedMs === void 0 || splitPreSubmissionElapsedMs < 1e3 ? "" : `pre-submit ${formatPollDuration(splitPreSubmissionElapsedMs)}`
469
+ splitPreSubmissionElapsedMs === void 0 || splitPreSubmissionElapsedMs < 1e3 ? "" : `pre-submit ${formatPollDuration(splitPreSubmissionElapsedMs)}`,
470
+ splitArtifactRecovery ? "artifact recovery" : ""
464
471
  ].filter(Boolean).join(", ") || "job metadata unavailable"}`
465
472
  );
466
473
  }
@@ -478,6 +485,20 @@ function profileCheckTextTarget(evidence) {
478
485
  const pattern = cliString(evidence.pattern);
479
486
  return pattern ? `pattern ${markdownInlineCode(pattern)}` : void 0;
480
487
  }
488
+ function observeWithinMarkdownReceipt(evidence) {
489
+ const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
490
+ if (!viewports.length) return void 0;
491
+ const receipts = viewports.slice(0, 4).map((viewport) => {
492
+ const name = cliString(viewport.viewport) || cliString(viewport.name) || "viewport";
493
+ const matched = viewport.matched === true ? "matched" : viewport.matched === false ? "missed" : "observed";
494
+ const elapsedMs = cliFiniteNumber(viewport.elapsed_ms);
495
+ const attempts = cliFiniteNumber(viewport.attempts);
496
+ const sample = cliString(viewport.sample);
497
+ return `${name} ${matched}${elapsedMs === void 0 ? "" : ` in ${elapsedMs}ms`}${attempts === void 0 ? "" : `, ${attempts} attempt${attempts === 1 ? "" : "s"}`}${sample ? `, sample ${markdownInlineCode(sample, 70)}` : ""}`;
498
+ });
499
+ if (viewports.length > receipts.length) receipts.push(`${viewports.length - receipts.length} more viewport${viewports.length - receipts.length === 1 ? "" : "s"}`);
500
+ return receipts.join("; ");
501
+ }
481
502
  function profileCheckMarkdownTarget(check) {
482
503
  const evidence = cliRecord(check.evidence);
483
504
  if (!evidence) return void 0;
@@ -511,9 +532,9 @@ function profileCheckMarkdownTarget(check) {
511
532
  const textTarget = profileCheckTextTarget(evidence);
512
533
  const timeoutMs = cliFiniteNumber(evidence.timeout_ms);
513
534
  const withinLabel = timeoutMs === void 0 ? "within timeout" : `within ${timeoutMs}ms`;
514
- if (selector && textTarget) return `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}`;
515
- if (selector) return `${markdownInlineCode(selector)} visible ${withinLabel}`;
516
- return textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
535
+ const receipt = observeWithinMarkdownReceipt(evidence);
536
+ const base = selector && textTarget ? `${markdownInlineCode(selector)} observes ${textTarget} ${withinLabel}` : selector ? `${markdownInlineCode(selector)} visible ${withinLabel}` : textTarget ? `${textTarget} ${withinLabel}` : withinLabel;
537
+ return receipt ? `${base}; ${receipt}` : base;
517
538
  }
518
539
  if (check.type === "text_visible" || check.type === "text_absent") {
519
540
  return profileCheckTextTarget(evidence);
@@ -1100,7 +1121,8 @@ function withRiddleMetadata(result, input) {
1100
1121
  elapsed_ms: poll?.elapsed_ms ?? result.riddle?.elapsed_ms,
1101
1122
  attempt: poll?.attempt ?? result.riddle?.attempt,
1102
1123
  attempts: poll?.attempts ?? result.riddle?.attempts,
1103
- timed_out: poll?.timed_out ?? result.riddle?.timed_out
1124
+ timed_out: poll?.timed_out ?? result.riddle?.timed_out,
1125
+ artifact_recovery: input.artifactRecovery ?? result.riddle?.artifact_recovery
1104
1126
  },
1105
1127
  artifacts: {
1106
1128
  ...result.artifacts,
@@ -1108,6 +1130,52 @@ function withRiddleMetadata(result, input) {
1108
1130
  }
1109
1131
  };
1110
1132
  }
1133
+ function riddleArtifactsPayloadStatus(payload) {
1134
+ const record = cliRecord(payload);
1135
+ return cliString(record?.status) ?? cliString(cliRecord(record?.job)?.status);
1136
+ }
1137
+ async function recoverProfileResultFromRiddleArtifacts(profile, input) {
1138
+ if (input.poll.poll?.timed_out !== true) return void 0;
1139
+ let artifactPayload;
1140
+ try {
1141
+ artifactPayload = await input.client.requestJson(`/v1/jobs/${input.jobId}/artifacts`);
1142
+ } catch {
1143
+ return void 0;
1144
+ }
1145
+ const artifacts = collectRiddleProfileArtifactRefs(artifactPayload);
1146
+ if (!artifacts.length) return void 0;
1147
+ const artifactStatus = riddleArtifactsPayloadStatus(artifactPayload);
1148
+ const terminal = artifactStatus ? isTerminalRiddleJobStatus(artifactStatus) : true;
1149
+ const recoveredPoll = input.poll.poll ? {
1150
+ ...input.poll.poll,
1151
+ status: artifactStatus ?? input.poll.poll.status,
1152
+ terminal
1153
+ } : void 0;
1154
+ const artifactResult = await profileResultFromRiddleArtifacts(profile, artifacts, [artifactPayload, input.poll.job]);
1155
+ if (artifactResult) {
1156
+ return withRiddleMetadata(artifactResult, {
1157
+ job_id: input.jobId,
1158
+ status: artifactStatus ?? input.poll.status,
1159
+ terminal,
1160
+ poll: recoveredPoll,
1161
+ artifacts,
1162
+ artifactRecovery: true
1163
+ });
1164
+ }
1165
+ if (!terminal) return void 0;
1166
+ return createRiddleProofProfileInsufficientResult({
1167
+ profile,
1168
+ runner: input.runner,
1169
+ error: `Riddle job ${input.jobId} timed out in status ${input.poll.status || "unknown"}, but artifacts were recovered without a proof result.`,
1170
+ riddle: {
1171
+ ...riddleMetadataFromPoll(input.jobId, input.poll),
1172
+ status: artifactStatus ?? input.poll.status,
1173
+ terminal,
1174
+ artifact_recovery: true
1175
+ },
1176
+ artifacts
1177
+ });
1178
+ }
1111
1179
  function riddleMetadataFromPoll(jobId, poll) {
1112
1180
  return {
1113
1181
  job_id: jobId,
@@ -1170,13 +1238,15 @@ function splitViewportRiddleMetadata(childRuns) {
1170
1238
  elapsed_ms: result.riddle?.elapsed_ms,
1171
1239
  attempt: result.riddle?.attempt,
1172
1240
  attempts: result.riddle?.attempts,
1173
- timed_out: result.riddle?.timed_out
1241
+ timed_out: result.riddle?.timed_out,
1242
+ artifact_recovery: result.riddle?.artifact_recovery
1174
1243
  }));
1175
1244
  return {
1176
1245
  mode: "split-viewports",
1177
1246
  job_count: childRuns.length,
1178
1247
  status: "split-viewports",
1179
1248
  terminal: childRuns.every(({ result }) => result.riddle?.terminal !== false),
1249
+ artifact_recovery: childRuns.some(({ result }) => result.riddle?.artifact_recovery === true),
1180
1250
  queue_elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.queue_elapsed_ms)),
1181
1251
  pre_submission_elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.pre_submission_elapsed_ms)),
1182
1252
  elapsed_ms: sumDefinedNumbers(splitJobs.map((job) => job.elapsed_ms)),
@@ -1299,6 +1369,13 @@ async function runSingleRiddleProfileForCli(profile, options, input) {
1299
1369
  });
1300
1370
  const artifacts = collectRiddleProfileArtifactRefs(poll.artifacts);
1301
1371
  if (!poll.ok || !poll.terminal) {
1372
+ const recoveredResult = await recoverProfileResultFromRiddleArtifacts(profile, {
1373
+ client,
1374
+ runner,
1375
+ jobId,
1376
+ poll
1377
+ });
1378
+ if (recoveredResult) return recoveredResult;
1302
1379
  return createRiddleProofProfileEnvironmentBlockedResult({
1303
1380
  profile,
1304
1381
  runner,
@@ -391,6 +391,7 @@ interface RiddleProofProfileResult {
391
391
  attempt?: number;
392
392
  attempts?: number;
393
393
  timed_out?: boolean;
394
+ artifact_recovery?: boolean;
394
395
  split_jobs?: Array<{
395
396
  viewport: string;
396
397
  job_id?: string;
@@ -402,6 +403,7 @@ interface RiddleProofProfileResult {
402
403
  attempt?: number;
403
404
  attempts?: number;
404
405
  timed_out?: boolean;
406
+ artifact_recovery?: boolean;
405
407
  }>;
406
408
  };
407
409
  environment_blocker?: Record<string, JsonValue>;
package/dist/profile.d.ts CHANGED
@@ -391,6 +391,7 @@ interface RiddleProofProfileResult {
391
391
  attempt?: number;
392
392
  attempts?: number;
393
393
  timed_out?: boolean;
394
+ artifact_recovery?: boolean;
394
395
  split_jobs?: Array<{
395
396
  viewport: string;
396
397
  job_id?: string;
@@ -402,6 +403,7 @@ interface RiddleProofProfileResult {
402
403
  attempt?: number;
403
404
  attempts?: number;
404
405
  timed_out?: boolean;
406
+ artifact_recovery?: boolean;
405
407
  }>;
406
408
  };
407
409
  environment_blocker?: Record<string, JsonValue>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.150",
3
+ "version": "0.7.152",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",