@riddledc/riddle-proof 0.7.70 → 0.7.72

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.
@@ -1497,11 +1497,25 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
1497
1497
  requiredNetworkMockHitCount(mock)
1498
1498
  ])),
1499
1499
  max_hits_by_label: Object.fromEntries(mocks.filter((mock) => mock.max_hit_count !== void 0).map((mock) => [mock.label, mock.max_hit_count ?? null])),
1500
+ response_hits_by_label: networkMockResponseHitsByLabel(events),
1500
1501
  failed
1501
1502
  },
1502
1503
  message: failed.length ? `Network mocks failed or hit-count contracts failed for ${failed.length} mock(s).` : void 0
1503
1504
  };
1504
1505
  }
1506
+ function networkMockResponseHitsByLabel(events) {
1507
+ const responseHits = {};
1508
+ for (const event of events) {
1509
+ if (!event || event.ok === false) continue;
1510
+ const label = typeof event.label === "string" ? event.label : "";
1511
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
1512
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
1513
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
1514
+ responseHits[label] || (responseHits[label] = {});
1515
+ responseHits[label][responseLabel] = (responseHits[label][responseLabel] || 0) + 1;
1516
+ }
1517
+ return responseHits;
1518
+ }
1505
1519
  function requiredNetworkMockHitCount(mock) {
1506
1520
  if (mock.required === false) return 0;
1507
1521
  if (mock.required_hit_count !== void 0) return mock.required_hit_count;
@@ -2025,11 +2039,21 @@ function assessProfile(profile, evidence) {
2025
2039
  const hitsByLabel = {};
2026
2040
  const requiredHitsByLabel = {};
2027
2041
  const maxHitsByLabel = {};
2042
+ const responseHitsByLabel = {};
2028
2043
  for (const mock of profile.target.network_mocks) {
2029
2044
  hitsByLabel[mock.label] = hitCountForMock(mock);
2030
2045
  if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
2031
2046
  if (mock && mock.max_hit_count !== undefined) maxHitsByLabel[mock.label] = mock.max_hit_count;
2032
2047
  }
2048
+ for (const event of events) {
2049
+ if (!event || event.ok === false) continue;
2050
+ const label = typeof event.label === "string" ? event.label : "";
2051
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
2052
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
2053
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
2054
+ responseHitsByLabel[label] ||= {};
2055
+ responseHitsByLabel[label][responseLabel] = (responseHitsByLabel[label][responseLabel] || 0) + 1;
2056
+ }
2033
2057
  checks.push({
2034
2058
  type: "network_mocks_succeeded",
2035
2059
  label: "network mocks succeeded",
@@ -2041,6 +2065,7 @@ function assessProfile(profile, evidence) {
2041
2065
  hits_by_label: hitsByLabel,
2042
2066
  required_hits_by_label: requiredHitsByLabel,
2043
2067
  max_hits_by_label: maxHitsByLabel,
2068
+ response_hits_by_label: responseHitsByLabel,
2044
2069
  failed,
2045
2070
  },
2046
2071
  message: failed.length ? "Network mocks failed or hit-count contracts failed for " + failed.length + " mock(s)." : undefined,
package/dist/cli.cjs CHANGED
@@ -8370,11 +8370,25 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
8370
8370
  requiredNetworkMockHitCount(mock)
8371
8371
  ])),
8372
8372
  max_hits_by_label: Object.fromEntries(mocks.filter((mock) => mock.max_hit_count !== void 0).map((mock) => [mock.label, mock.max_hit_count ?? null])),
8373
+ response_hits_by_label: networkMockResponseHitsByLabel(events),
8373
8374
  failed
8374
8375
  },
8375
8376
  message: failed.length ? `Network mocks failed or hit-count contracts failed for ${failed.length} mock(s).` : void 0
8376
8377
  };
8377
8378
  }
8379
+ function networkMockResponseHitsByLabel(events) {
8380
+ const responseHits = {};
8381
+ for (const event of events) {
8382
+ if (!event || event.ok === false) continue;
8383
+ const label = typeof event.label === "string" ? event.label : "";
8384
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
8385
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
8386
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
8387
+ responseHits[label] || (responseHits[label] = {});
8388
+ responseHits[label][responseLabel] = (responseHits[label][responseLabel] || 0) + 1;
8389
+ }
8390
+ return responseHits;
8391
+ }
8378
8392
  function requiredNetworkMockHitCount(mock) {
8379
8393
  if (mock.required === false) return 0;
8380
8394
  if (mock.required_hit_count !== void 0) return mock.required_hit_count;
@@ -8882,11 +8896,21 @@ function assessProfile(profile, evidence) {
8882
8896
  const hitsByLabel = {};
8883
8897
  const requiredHitsByLabel = {};
8884
8898
  const maxHitsByLabel = {};
8899
+ const responseHitsByLabel = {};
8885
8900
  for (const mock of profile.target.network_mocks) {
8886
8901
  hitsByLabel[mock.label] = hitCountForMock(mock);
8887
8902
  if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
8888
8903
  if (mock && mock.max_hit_count !== undefined) maxHitsByLabel[mock.label] = mock.max_hit_count;
8889
8904
  }
8905
+ for (const event of events) {
8906
+ if (!event || event.ok === false) continue;
8907
+ const label = typeof event.label === "string" ? event.label : "";
8908
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
8909
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
8910
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
8911
+ responseHitsByLabel[label] ||= {};
8912
+ responseHitsByLabel[label][responseLabel] = (responseHitsByLabel[label][responseLabel] || 0) + 1;
8913
+ }
8890
8914
  checks.push({
8891
8915
  type: "network_mocks_succeeded",
8892
8916
  label: "network mocks succeeded",
@@ -8898,6 +8922,7 @@ function assessProfile(profile, evidence) {
8898
8922
  hits_by_label: hitsByLabel,
8899
8923
  required_hits_by_label: requiredHitsByLabel,
8900
8924
  max_hits_by_label: maxHitsByLabel,
8925
+ response_hits_by_label: responseHitsByLabel,
8901
8926
  failed,
8902
8927
  },
8903
8928
  message: failed.length ? "Network mocks failed or hit-count contracts failed for " + failed.length + " mock(s)." : undefined,
@@ -11231,6 +11256,10 @@ function profileResultMarkdown(result) {
11231
11256
  if (networkMockSummaryLines.length) {
11232
11257
  lines.push("", "## Network Mocks", "", ...networkMockSummaryLines);
11233
11258
  }
11259
+ const routeInventorySummaryLines = profileRouteInventorySummaryMarkdown(result);
11260
+ if (routeInventorySummaryLines.length) {
11261
+ lines.push("", "## Route Inventory", "", ...routeInventorySummaryLines);
11262
+ }
11234
11263
  if (result.artifacts.riddle_artifacts?.length) {
11235
11264
  lines.push("", "## Riddle Artifacts", "");
11236
11265
  for (const artifact of result.artifacts.riddle_artifacts.slice(0, 40)) {
@@ -11249,6 +11278,9 @@ function cliFiniteNumber(value) {
11249
11278
  function cliString(value) {
11250
11279
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
11251
11280
  }
11281
+ function cliStringArray(value) {
11282
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && Boolean(entry.trim())) : [];
11283
+ }
11252
11284
  function profileSetupSummaryMarkdown(result) {
11253
11285
  const setupCheck = result.checks.find((check) => check.type === "setup_actions_succeeded");
11254
11286
  const setupSummary = cliRecord(setupCheck?.evidence?.setup_summary);
@@ -11296,10 +11328,12 @@ function profileNetworkMockSummaryMarkdown(result) {
11296
11328
  const hitsByLabel = cliRecord(evidence.hits_by_label) || {};
11297
11329
  const requiredHitsByLabel = cliRecord(evidence.required_hits_by_label) || {};
11298
11330
  const maxHitsByLabel = cliRecord(evidence.max_hits_by_label) || {};
11331
+ const responseHitsByLabel = cliRecord(evidence.response_hits_by_label) || {};
11299
11332
  const labels = Array.from(/* @__PURE__ */ new Set([
11300
11333
  ...Object.keys(hitsByLabel),
11301
11334
  ...Object.keys(requiredHitsByLabel),
11302
- ...Object.keys(maxHitsByLabel)
11335
+ ...Object.keys(maxHitsByLabel),
11336
+ ...Object.keys(responseHitsByLabel)
11303
11337
  ])).sort();
11304
11338
  const mockCount = cliFiniteNumber(evidence.mock_count);
11305
11339
  const requiredCount = cliFiniteNumber(evidence.required_count);
@@ -11317,10 +11351,57 @@ function profileNetworkMockSummaryMarkdown(result) {
11317
11351
  if (requiredHits !== void 0) parts.push(`required ${requiredHits}`);
11318
11352
  if (maxHits !== void 0) parts.push(`max ${maxHits}`);
11319
11353
  lines.push(`- ${label}: ${parts.join(", ")}`);
11354
+ const responseHits = cliRecord(responseHitsByLabel[label]);
11355
+ const responseLabels = responseHits ? Object.keys(responseHits).sort() : [];
11356
+ if (responseHits && responseLabels.length) {
11357
+ const responseParts = responseLabels.slice(0, 8).map((responseLabel) => `${responseLabel} ${cliRecordNumber(responseHits, responseLabel) ?? 0}`);
11358
+ const omitted = responseLabels.length > 8 ? `; ${responseLabels.length - 8} additional response label(s) omitted` : "";
11359
+ lines.push(`- ${label} responses: ${responseParts.join("; ")}${omitted}`);
11360
+ }
11320
11361
  }
11321
11362
  if (labels.length > 16) lines.push(`- ${labels.length - 16} additional network mock label(s) omitted from summary.`);
11322
11363
  return lines;
11323
11364
  }
11365
+ function profileRouteInventorySummaryMarkdown(result) {
11366
+ const routeInventoryChecks = result.checks.filter((check) => check.type === "route_inventory");
11367
+ const lines = [];
11368
+ for (const check of routeInventoryChecks) {
11369
+ const evidence = cliRecord(check.evidence);
11370
+ if (!evidence) continue;
11371
+ const label = check.label || check.type;
11372
+ const expectedCount = cliFiniteNumber(evidence.expected_count);
11373
+ const sourceLinkCount = cliFiniteNumber(evidence.source_link_count);
11374
+ const sourceUniqueLinkCount = cliFiniteNumber(evidence.source_unique_link_count);
11375
+ const directRouteCount = cliFiniteNumber(evidence.direct_route_count);
11376
+ const clickthroughCount = cliFiniteNumber(evidence.clickthrough_count);
11377
+ const topLevelFailures = Array.isArray(evidence.failures) ? evidence.failures.length : void 0;
11378
+ const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
11379
+ const viewportFailureTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.failure_count) || 0), 0);
11380
+ const failureCount = topLevelFailures === void 0 ? viewportFailureTotal : topLevelFailures;
11381
+ lines.push(
11382
+ `- ${label}: expected ${expectedCount ?? "unknown"}, source links ${sourceLinkCount ?? "unknown"}${sourceUniqueLinkCount === void 0 ? "" : ` (${sourceUniqueLinkCount} unique)`}, direct ${directRouteCount ?? "unknown"}, clickthrough ${clickthroughCount ?? "unknown"}, failures ${failureCount}`
11383
+ );
11384
+ const duplicateCount = cliFiniteNumber(evidence.duplicate_source_link_count) || 0;
11385
+ const duplicateLinks = cliStringArray(evidence.duplicate_source_links);
11386
+ if (duplicateCount || duplicateLinks.length) {
11387
+ const duplicateText = duplicateLinks.length ? `: ${duplicateLinks.slice(0, 8).join(", ")}${duplicateLinks.length > 8 ? `, ${duplicateLinks.length - 8} more` : ""}` : "";
11388
+ lines.push(`- ${label} duplicate source links: ${duplicateCount}${evidence.duplicates_allowed === true ? " allowed" : ""}${duplicateText}`);
11389
+ }
11390
+ for (const viewport of viewports.slice(0, 8)) {
11391
+ const viewportName = cliString(viewport.viewport) || cliString(viewport.name) || "viewport";
11392
+ const viewportSourceLinkCount = cliFiniteNumber(viewport.source_link_count);
11393
+ const viewportSourceUniqueLinkCount = cliFiniteNumber(viewport.source_unique_link_count);
11394
+ const viewportDirectRouteCount = cliFiniteNumber(viewport.direct_route_count);
11395
+ const viewportClickthroughCount = cliFiniteNumber(viewport.clickthrough_count);
11396
+ const viewportFailureCount = cliFiniteNumber(viewport.failure_count) || 0;
11397
+ lines.push(
11398
+ `- ${label} ${viewportName}: source ${viewportSourceLinkCount ?? "unknown"}${viewportSourceUniqueLinkCount === void 0 ? "" : ` (${viewportSourceUniqueLinkCount} unique)`}, direct ${viewportDirectRouteCount ?? "unknown"}, clickthrough ${viewportClickthroughCount ?? "unknown"}, failures ${viewportFailureCount}`
11399
+ );
11400
+ }
11401
+ if (viewports.length > 8) lines.push(`- ${label}: ${viewports.length - 8} additional viewport(s) omitted from route inventory summary.`);
11402
+ }
11403
+ return lines;
11404
+ }
11324
11405
  function writeProfileOutput(outputDir, result) {
11325
11406
  if (!outputDir) return;
11326
11407
  (0, import_node_fs6.mkdirSync)(outputDir, { recursive: true });
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-KMJBTFLI.js";
13
+ } from "./chunk-HXYLTNZT.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
@@ -320,6 +320,10 @@ function profileResultMarkdown(result) {
320
320
  if (networkMockSummaryLines.length) {
321
321
  lines.push("", "## Network Mocks", "", ...networkMockSummaryLines);
322
322
  }
323
+ const routeInventorySummaryLines = profileRouteInventorySummaryMarkdown(result);
324
+ if (routeInventorySummaryLines.length) {
325
+ lines.push("", "## Route Inventory", "", ...routeInventorySummaryLines);
326
+ }
323
327
  if (result.artifacts.riddle_artifacts?.length) {
324
328
  lines.push("", "## Riddle Artifacts", "");
325
329
  for (const artifact of result.artifacts.riddle_artifacts.slice(0, 40)) {
@@ -338,6 +342,9 @@ function cliFiniteNumber(value) {
338
342
  function cliString(value) {
339
343
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
340
344
  }
345
+ function cliStringArray(value) {
346
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && Boolean(entry.trim())) : [];
347
+ }
341
348
  function profileSetupSummaryMarkdown(result) {
342
349
  const setupCheck = result.checks.find((check) => check.type === "setup_actions_succeeded");
343
350
  const setupSummary = cliRecord(setupCheck?.evidence?.setup_summary);
@@ -385,10 +392,12 @@ function profileNetworkMockSummaryMarkdown(result) {
385
392
  const hitsByLabel = cliRecord(evidence.hits_by_label) || {};
386
393
  const requiredHitsByLabel = cliRecord(evidence.required_hits_by_label) || {};
387
394
  const maxHitsByLabel = cliRecord(evidence.max_hits_by_label) || {};
395
+ const responseHitsByLabel = cliRecord(evidence.response_hits_by_label) || {};
388
396
  const labels = Array.from(/* @__PURE__ */ new Set([
389
397
  ...Object.keys(hitsByLabel),
390
398
  ...Object.keys(requiredHitsByLabel),
391
- ...Object.keys(maxHitsByLabel)
399
+ ...Object.keys(maxHitsByLabel),
400
+ ...Object.keys(responseHitsByLabel)
392
401
  ])).sort();
393
402
  const mockCount = cliFiniteNumber(evidence.mock_count);
394
403
  const requiredCount = cliFiniteNumber(evidence.required_count);
@@ -406,10 +415,57 @@ function profileNetworkMockSummaryMarkdown(result) {
406
415
  if (requiredHits !== void 0) parts.push(`required ${requiredHits}`);
407
416
  if (maxHits !== void 0) parts.push(`max ${maxHits}`);
408
417
  lines.push(`- ${label}: ${parts.join(", ")}`);
418
+ const responseHits = cliRecord(responseHitsByLabel[label]);
419
+ const responseLabels = responseHits ? Object.keys(responseHits).sort() : [];
420
+ if (responseHits && responseLabels.length) {
421
+ const responseParts = responseLabels.slice(0, 8).map((responseLabel) => `${responseLabel} ${cliRecordNumber(responseHits, responseLabel) ?? 0}`);
422
+ const omitted = responseLabels.length > 8 ? `; ${responseLabels.length - 8} additional response label(s) omitted` : "";
423
+ lines.push(`- ${label} responses: ${responseParts.join("; ")}${omitted}`);
424
+ }
409
425
  }
410
426
  if (labels.length > 16) lines.push(`- ${labels.length - 16} additional network mock label(s) omitted from summary.`);
411
427
  return lines;
412
428
  }
429
+ function profileRouteInventorySummaryMarkdown(result) {
430
+ const routeInventoryChecks = result.checks.filter((check) => check.type === "route_inventory");
431
+ const lines = [];
432
+ for (const check of routeInventoryChecks) {
433
+ const evidence = cliRecord(check.evidence);
434
+ if (!evidence) continue;
435
+ const label = check.label || check.type;
436
+ const expectedCount = cliFiniteNumber(evidence.expected_count);
437
+ const sourceLinkCount = cliFiniteNumber(evidence.source_link_count);
438
+ const sourceUniqueLinkCount = cliFiniteNumber(evidence.source_unique_link_count);
439
+ const directRouteCount = cliFiniteNumber(evidence.direct_route_count);
440
+ const clickthroughCount = cliFiniteNumber(evidence.clickthrough_count);
441
+ const topLevelFailures = Array.isArray(evidence.failures) ? evidence.failures.length : void 0;
442
+ const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
443
+ const viewportFailureTotal = viewports.reduce((sum, viewport) => sum + (cliFiniteNumber(viewport.failure_count) || 0), 0);
444
+ const failureCount = topLevelFailures === void 0 ? viewportFailureTotal : topLevelFailures;
445
+ lines.push(
446
+ `- ${label}: expected ${expectedCount ?? "unknown"}, source links ${sourceLinkCount ?? "unknown"}${sourceUniqueLinkCount === void 0 ? "" : ` (${sourceUniqueLinkCount} unique)`}, direct ${directRouteCount ?? "unknown"}, clickthrough ${clickthroughCount ?? "unknown"}, failures ${failureCount}`
447
+ );
448
+ const duplicateCount = cliFiniteNumber(evidence.duplicate_source_link_count) || 0;
449
+ const duplicateLinks = cliStringArray(evidence.duplicate_source_links);
450
+ if (duplicateCount || duplicateLinks.length) {
451
+ const duplicateText = duplicateLinks.length ? `: ${duplicateLinks.slice(0, 8).join(", ")}${duplicateLinks.length > 8 ? `, ${duplicateLinks.length - 8} more` : ""}` : "";
452
+ lines.push(`- ${label} duplicate source links: ${duplicateCount}${evidence.duplicates_allowed === true ? " allowed" : ""}${duplicateText}`);
453
+ }
454
+ for (const viewport of viewports.slice(0, 8)) {
455
+ const viewportName = cliString(viewport.viewport) || cliString(viewport.name) || "viewport";
456
+ const viewportSourceLinkCount = cliFiniteNumber(viewport.source_link_count);
457
+ const viewportSourceUniqueLinkCount = cliFiniteNumber(viewport.source_unique_link_count);
458
+ const viewportDirectRouteCount = cliFiniteNumber(viewport.direct_route_count);
459
+ const viewportClickthroughCount = cliFiniteNumber(viewport.clickthrough_count);
460
+ const viewportFailureCount = cliFiniteNumber(viewport.failure_count) || 0;
461
+ lines.push(
462
+ `- ${label} ${viewportName}: source ${viewportSourceLinkCount ?? "unknown"}${viewportSourceUniqueLinkCount === void 0 ? "" : ` (${viewportSourceUniqueLinkCount} unique)`}, direct ${viewportDirectRouteCount ?? "unknown"}, clickthrough ${viewportClickthroughCount ?? "unknown"}, failures ${viewportFailureCount}`
463
+ );
464
+ }
465
+ if (viewports.length > 8) lines.push(`- ${label}: ${viewports.length - 8} additional viewport(s) omitted from route inventory summary.`);
466
+ }
467
+ return lines;
468
+ }
413
469
  function writeProfileOutput(outputDir, result) {
414
470
  if (!outputDir) return;
415
471
  mkdirSync(outputDir, { recursive: true });
package/dist/index.cjs CHANGED
@@ -10211,11 +10211,25 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
10211
10211
  requiredNetworkMockHitCount(mock)
10212
10212
  ])),
10213
10213
  max_hits_by_label: Object.fromEntries(mocks.filter((mock) => mock.max_hit_count !== void 0).map((mock) => [mock.label, mock.max_hit_count ?? null])),
10214
+ response_hits_by_label: networkMockResponseHitsByLabel(events),
10214
10215
  failed
10215
10216
  },
10216
10217
  message: failed.length ? `Network mocks failed or hit-count contracts failed for ${failed.length} mock(s).` : void 0
10217
10218
  };
10218
10219
  }
10220
+ function networkMockResponseHitsByLabel(events) {
10221
+ const responseHits = {};
10222
+ for (const event of events) {
10223
+ if (!event || event.ok === false) continue;
10224
+ const label = typeof event.label === "string" ? event.label : "";
10225
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
10226
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
10227
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
10228
+ responseHits[label] || (responseHits[label] = {});
10229
+ responseHits[label][responseLabel] = (responseHits[label][responseLabel] || 0) + 1;
10230
+ }
10231
+ return responseHits;
10232
+ }
10219
10233
  function requiredNetworkMockHitCount(mock) {
10220
10234
  if (mock.required === false) return 0;
10221
10235
  if (mock.required_hit_count !== void 0) return mock.required_hit_count;
@@ -10739,11 +10753,21 @@ function assessProfile(profile, evidence) {
10739
10753
  const hitsByLabel = {};
10740
10754
  const requiredHitsByLabel = {};
10741
10755
  const maxHitsByLabel = {};
10756
+ const responseHitsByLabel = {};
10742
10757
  for (const mock of profile.target.network_mocks) {
10743
10758
  hitsByLabel[mock.label] = hitCountForMock(mock);
10744
10759
  if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
10745
10760
  if (mock && mock.max_hit_count !== undefined) maxHitsByLabel[mock.label] = mock.max_hit_count;
10746
10761
  }
10762
+ for (const event of events) {
10763
+ if (!event || event.ok === false) continue;
10764
+ const label = typeof event.label === "string" ? event.label : "";
10765
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
10766
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
10767
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
10768
+ responseHitsByLabel[label] ||= {};
10769
+ responseHitsByLabel[label][responseLabel] = (responseHitsByLabel[label][responseLabel] || 0) + 1;
10770
+ }
10747
10771
  checks.push({
10748
10772
  type: "network_mocks_succeeded",
10749
10773
  label: "network mocks succeeded",
@@ -10755,6 +10779,7 @@ function assessProfile(profile, evidence) {
10755
10779
  hits_by_label: hitsByLabel,
10756
10780
  required_hits_by_label: requiredHitsByLabel,
10757
10781
  max_hits_by_label: maxHitsByLabel,
10782
+ response_hits_by_label: responseHitsByLabel,
10758
10783
  failed,
10759
10784
  },
10760
10785
  message: failed.length ? "Network mocks failed or hit-count contracts failed for " + failed.length + " mock(s)." : undefined,
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-KMJBTFLI.js";
61
+ } from "./chunk-HXYLTNZT.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -1540,11 +1540,25 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
1540
1540
  requiredNetworkMockHitCount(mock)
1541
1541
  ])),
1542
1542
  max_hits_by_label: Object.fromEntries(mocks.filter((mock) => mock.max_hit_count !== void 0).map((mock) => [mock.label, mock.max_hit_count ?? null])),
1543
+ response_hits_by_label: networkMockResponseHitsByLabel(events),
1543
1544
  failed
1544
1545
  },
1545
1546
  message: failed.length ? `Network mocks failed or hit-count contracts failed for ${failed.length} mock(s).` : void 0
1546
1547
  };
1547
1548
  }
1549
+ function networkMockResponseHitsByLabel(events) {
1550
+ const responseHits = {};
1551
+ for (const event of events) {
1552
+ if (!event || event.ok === false) continue;
1553
+ const label = typeof event.label === "string" ? event.label : "";
1554
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
1555
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
1556
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
1557
+ responseHits[label] || (responseHits[label] = {});
1558
+ responseHits[label][responseLabel] = (responseHits[label][responseLabel] || 0) + 1;
1559
+ }
1560
+ return responseHits;
1561
+ }
1548
1562
  function requiredNetworkMockHitCount(mock) {
1549
1563
  if (mock.required === false) return 0;
1550
1564
  if (mock.required_hit_count !== void 0) return mock.required_hit_count;
@@ -2068,11 +2082,21 @@ function assessProfile(profile, evidence) {
2068
2082
  const hitsByLabel = {};
2069
2083
  const requiredHitsByLabel = {};
2070
2084
  const maxHitsByLabel = {};
2085
+ const responseHitsByLabel = {};
2071
2086
  for (const mock of profile.target.network_mocks) {
2072
2087
  hitsByLabel[mock.label] = hitCountForMock(mock);
2073
2088
  if (mock && mock.required !== false) requiredHitsByLabel[mock.label] = requiredNetworkMockHitCount(mock);
2074
2089
  if (mock && mock.max_hit_count !== undefined) maxHitsByLabel[mock.label] = mock.max_hit_count;
2075
2090
  }
2091
+ for (const event of events) {
2092
+ if (!event || event.ok === false) continue;
2093
+ const label = typeof event.label === "string" ? event.label : "";
2094
+ const responseLabel = typeof event.response_label === "string" ? event.response_label : "";
2095
+ const hasSequenceResponse = typeof event.response_index === "number" || event.sequence_cycle === true || Boolean(responseLabel && responseLabel !== label);
2096
+ if (!label || !responseLabel || !hasSequenceResponse) continue;
2097
+ responseHitsByLabel[label] ||= {};
2098
+ responseHitsByLabel[label][responseLabel] = (responseHitsByLabel[label][responseLabel] || 0) + 1;
2099
+ }
2076
2100
  checks.push({
2077
2101
  type: "network_mocks_succeeded",
2078
2102
  label: "network mocks succeeded",
@@ -2084,6 +2108,7 @@ function assessProfile(profile, evidence) {
2084
2108
  hits_by_label: hitsByLabel,
2085
2109
  required_hits_by_label: requiredHitsByLabel,
2086
2110
  max_hits_by_label: maxHitsByLabel,
2111
+ response_hits_by_label: responseHitsByLabel,
2087
2112
  failed,
2088
2113
  },
2089
2114
  message: failed.length ? "Network mocks failed or hit-count contracts failed for " + failed.length + " mock(s)." : undefined,
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-KMJBTFLI.js";
22
+ } from "./chunk-HXYLTNZT.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.70",
3
+ "version": "0.7.72",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",