@riddledc/riddle-proof 0.8.57 → 0.8.59

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.
@@ -1,3 +1,7 @@
1
+ import {
2
+ summarizeRiddleProofPublicState
3
+ } from "./chunk-KG64Y5MC.js";
4
+
1
5
  // src/pr-comment.ts
2
6
  var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
3
7
  function asRecord(value) {
@@ -22,13 +26,6 @@ function firstStringValue(...values) {
22
26
  }
23
27
  return void 0;
24
28
  }
25
- function firstBooleanValue(...values) {
26
- for (const value of values) {
27
- const bool = booleanValue(value);
28
- if (typeof bool === "boolean") return bool;
29
- }
30
- return void 0;
31
- }
32
29
  function artifactKind(name, url) {
33
30
  const target = `${name} ${url}`.toLowerCase();
34
31
  if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
@@ -150,10 +147,15 @@ function summarizeRiddleProofPrComment(input) {
150
147
  rawDetails.checkpoint_summary,
151
148
  proofResult.checkpoint_summary
152
149
  );
150
+ const publicState = summarizeRiddleProofPublicState({
151
+ ...result,
152
+ status: firstStringValue(result.status, stopCondition.status),
153
+ checkpoint_summary: checkpointSummary || result.checkpoint_summary
154
+ });
153
155
  return {
154
156
  ok,
155
157
  status: stringValue(proofResult.status),
156
- result_status: firstStringValue(result.status, stopCondition.status),
158
+ result_status: publicState.status,
157
159
  job_id: stringValue(proofResult.job_id),
158
160
  duration_ms: numberValue(proofResult.duration_ms),
159
161
  proof_url: stringValue(runResponse.proofUrl),
@@ -161,12 +163,15 @@ function summarizeRiddleProofPrComment(input) {
161
163
  preview_url: stringValue(preview.preview_url) || stringValue(preview.url),
162
164
  preview_publish_recovered: booleanValue(preview.publish_recovered),
163
165
  preview_publish_error: stringValue(preview.publish_error),
164
- ship_held: firstBooleanValue(result.ship_held, stopCondition.ship_held, resultRaw.ship_held),
165
- shipping_disabled: firstBooleanValue(result.shipping_disabled, stopCondition.shipping_disabled, resultRaw.shipping_disabled),
166
- ship_authorized: firstBooleanValue(result.ship_authorized, stopCondition.ship_authorized, resultRaw.ship_authorized),
166
+ ship_held: publicState.ship_held,
167
+ shipping_disabled: publicState.shipping_disabled,
168
+ ship_authorized: publicState.ship_authorized,
169
+ merge_ready: publicState.merge_ready,
170
+ sync_allowed: publicState.sync_allowed,
167
171
  proof_decision: firstStringValue(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
168
172
  merge_recommendation: firstStringValue(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation),
169
173
  checkpoint_summary: checkpointSummary,
174
+ public_state: publicState,
170
175
  passed_checks: nestedChecks.passed,
171
176
  failed_checks: nestedChecks.failed,
172
177
  pages,
@@ -185,6 +190,7 @@ function markdownLink(label, url) {
185
190
  return `[${label.replace(/\]/g, "\\]")}](${url})`;
186
191
  }
187
192
  function resultLabel(summary) {
193
+ if (summary.public_state?.result_label) return summary.public_state.result_label;
188
194
  if (summary.ok === true) {
189
195
  if (summary.result_status === "shipped") return "shipped";
190
196
  if (summary.result_status === "completed") return "completed";
@@ -211,6 +217,14 @@ function formatBool(value) {
211
217
  function hasShipControl(summary) {
212
218
  return typeof summary.ship_held === "boolean" || typeof summary.shipping_disabled === "boolean" || typeof summary.ship_authorized === "boolean";
213
219
  }
220
+ function hasHandoffControl(summary) {
221
+ return typeof summary.merge_ready === "boolean" || typeof summary.sync_allowed === "boolean";
222
+ }
223
+ function shouldRenderMergeRecommendation(summary) {
224
+ if (!summary.merge_recommendation) return false;
225
+ const prohibited = summary.public_state?.prohibited_claims || [];
226
+ return !prohibited.includes("merge_ready") && !prohibited.includes("sync_allowed");
227
+ }
214
228
  function checkpointSummaryLine(summary) {
215
229
  const accepted = summary.response_count ?? 0;
216
230
  const rejected = summary.rejected_response_count ?? 0;
@@ -242,8 +256,11 @@ function buildRiddleProofPrCommentMarkdown(input) {
242
256
  if (hasShipControl(summary)) {
243
257
  lines.push(`**Ship control:** held=${formatBool(summary.ship_held)}, shipping_disabled=${formatBool(summary.shipping_disabled)}, authorized=${formatBool(summary.ship_authorized)}`);
244
258
  }
259
+ if (hasHandoffControl(summary)) {
260
+ lines.push(`**Handoff:** merge_ready=${formatBool(summary.merge_ready)}, sync_allowed=${formatBool(summary.sync_allowed)}`);
261
+ }
245
262
  if (summary.proof_decision) lines.push(`**Proof decision:** \`${summary.proof_decision}\``);
246
- if (summary.merge_recommendation) lines.push(`**Merge recommendation:** ${summary.merge_recommendation}`);
263
+ if (shouldRenderMergeRecommendation(summary)) lines.push(`**Merge recommendation:** ${summary.merge_recommendation}`);
247
264
  if (summary.checkpoint_summary) lines.push(`**Checkpoints:** ${checkpointSummaryLine(summary.checkpoint_summary)}`);
248
265
  if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
249
266
  if (summary.preview_id || summary.preview_url) {
@@ -0,0 +1,155 @@
1
+ // src/public-state.ts
2
+ function asRecord(value) {
3
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
4
+ }
5
+ function stringValue(value) {
6
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
7
+ }
8
+ function booleanValue(value) {
9
+ return typeof value === "boolean" ? value : void 0;
10
+ }
11
+ function numberValue(value) {
12
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
13
+ }
14
+ function firstStringValue(...values) {
15
+ for (const value of values) {
16
+ const text = stringValue(value);
17
+ if (text) return text;
18
+ }
19
+ return void 0;
20
+ }
21
+ function firstBooleanValue(...values) {
22
+ for (const value of values) {
23
+ const bool = booleanValue(value);
24
+ if (typeof bool === "boolean") return bool;
25
+ }
26
+ return void 0;
27
+ }
28
+ function firstRecordValue(...values) {
29
+ for (const value of values) {
30
+ const record = asRecord(value);
31
+ if (Object.keys(record).length) return record;
32
+ }
33
+ return void 0;
34
+ }
35
+ function countValue(value) {
36
+ const number = numberValue(value);
37
+ return typeof number === "number" && number > 0 ? Math.trunc(number) : 0;
38
+ }
39
+ function checkpointSummaryFrom(...values) {
40
+ const record = firstRecordValue(...values);
41
+ if (!record) return void 0;
42
+ const accepted = countValue(record.response_count);
43
+ const rejected = countValue(record.rejected_response_count);
44
+ const ignored = countValue(record.ignored_response_count);
45
+ const duplicate = countValue(record.duplicate_response_count);
46
+ const summary = {
47
+ pending: booleanValue(record.pending),
48
+ accepted_response_count: accepted,
49
+ rejected_response_count: rejected,
50
+ ignored_response_count: ignored,
51
+ duplicate_response_count: duplicate,
52
+ latest_decision: stringValue(record.latest_decision),
53
+ audit_disclosure_required: rejected > 0 || ignored > 0 || duplicate > 0
54
+ };
55
+ return Object.values(summary).some((value) => typeof value !== "undefined") ? summary : void 0;
56
+ }
57
+ function uniqueStrings(values) {
58
+ return [...new Set(values.filter(Boolean))];
59
+ }
60
+ function summarizeRiddleProofPublicState(input) {
61
+ const record = asRecord(input);
62
+ const runCard = asRecord(record.run_card);
63
+ const stopCondition = asRecord(runCard.stop_condition);
64
+ const raw = asRecord(record.raw);
65
+ const request = asRecord(record.request);
66
+ const requestMetadata = asRecord(record.request_metadata);
67
+ const prState = asRecord(record.pr_state);
68
+ const handoff = asRecord(record.pr_handoff_policy);
69
+ const handoffState = stringValue(handoff.state);
70
+ const status = firstStringValue(record.status, stopCondition.status);
71
+ const ok = booleanValue(record.ok) ?? null;
72
+ const shipMode = firstStringValue(request.ship_mode, requestMetadata.ship_mode, record.ship_mode, handoff.ship_mode);
73
+ const explicitShippingDisabled = firstBooleanValue(
74
+ record.shipping_disabled,
75
+ stopCondition.shipping_disabled,
76
+ raw.shipping_disabled,
77
+ handoff.shipping_disabled
78
+ );
79
+ const shippingDisabled = explicitShippingDisabled === true || shipMode === "none" || handoffState === "proof_complete_ship_disabled";
80
+ const explicitShipAuthorized = firstBooleanValue(
81
+ record.ship_authorized,
82
+ stopCondition.ship_authorized,
83
+ raw.ship_authorized
84
+ );
85
+ const authorizationEvidence = Boolean(
86
+ status === "shipped" || record.marked_ready === true || stringValue(prState.status) === "merged" || record.merge_commit || record.merged_at
87
+ );
88
+ const shipAuthorizedBeforeHold = explicitShipAuthorized ?? authorizationEvidence;
89
+ const explicitShipHeld = firstBooleanValue(record.ship_held, stopCondition.ship_held, raw.ship_held);
90
+ const inferredHeld = status === "ready_to_ship" && shippingDisabled && !shipAuthorizedBeforeHold;
91
+ const shipHeld = explicitShipHeld === true || inferredHeld;
92
+ const shipAuthorized = shipHeld ? false : shipAuthorizedBeforeHold === true;
93
+ const proofComplete = Boolean(
94
+ status === "ready_to_ship" || status === "shipped" || status === "completed" || status === "passed" || ok === true || handoff.proof_complete === true
95
+ );
96
+ const checkpointSummary = checkpointSummaryFrom(
97
+ record.checkpoint_summary,
98
+ stopCondition.checkpoint_summary,
99
+ asRecord(record.details).checkpoint_summary,
100
+ asRecord(raw.details).checkpoint_summary
101
+ );
102
+ const blockedOrWaiting = status === "blocked" || status === "failed" || status === "awaiting_checkpoint" || handoffState === "proof_blocked" || handoffState === "proof_review_required" || handoffState === "proof_failed" || handoffState === "proof_checkpoint_required";
103
+ const proofPassed = Boolean(proofComplete && !blockedOrWaiting);
104
+ const explicitMergeReady = firstBooleanValue(record.merge_ready, stopCondition.merge_ready, raw.merge_ready, handoff.merge_ready);
105
+ const normalPrAllowed = firstBooleanValue(record.normal_pr_allowed, raw.normal_pr_allowed, handoff.normal_pr_allowed);
106
+ const baseHandoffAllowed = !blockedOrWaiting && !shipHeld && !shippingDisabled;
107
+ const mergeReady = baseHandoffAllowed && normalPrAllowed !== false && (explicitMergeReady ?? shipAuthorized);
108
+ const syncAllowed = mergeReady;
109
+ let policyState = "unknown";
110
+ if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") policyState = "awaiting_checkpoint";
111
+ else if (status === "failed" || handoffState === "proof_failed") policyState = "proof_failed";
112
+ else if (status === "blocked" || handoffState === "proof_blocked" || handoffState === "proof_review_required") policyState = "proof_blocked";
113
+ else if (handoffState === "proof_complete_ship_disabled") policyState = "proof_complete_ship_disabled";
114
+ else if (proofComplete && shipHeld && !shipAuthorized) policyState = "proof_passed_ship_held";
115
+ else if (proofComplete && shippingDisabled && !shipAuthorized) policyState = "proof_complete_ship_disabled";
116
+ else if (shipAuthorized) policyState = "ship_authorized";
117
+ else if (proofPassed) policyState = "proof_passed";
118
+ else if (status === "running") policyState = "proof_in_progress";
119
+ const requiredDisclosures = [];
120
+ if (shipHeld) requiredDisclosures.push("ship_held");
121
+ if (shippingDisabled) requiredDisclosures.push("shipping_disabled");
122
+ if (checkpointSummary?.audit_disclosure_required) requiredDisclosures.push("checkpoint_audit_counters");
123
+ if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") requiredDisclosures.push("checkpoint_required");
124
+ const prohibitedClaims = [];
125
+ if (!shipAuthorized || shipHeld || shippingDisabled) prohibitedClaims.push("ship_authorized", "shipped");
126
+ if (!mergeReady) prohibitedClaims.push("merge_ready");
127
+ if (!syncAllowed) prohibitedClaims.push("sync_allowed");
128
+ if (blockedOrWaiting) {
129
+ prohibitedClaims.push("proof_passed", "ready_to_ship");
130
+ }
131
+ if (checkpointSummary?.audit_disclosure_required) {
132
+ prohibitedClaims.push("all_checkpoint_responses_accepted");
133
+ }
134
+ const resultLabel = policyState === "awaiting_checkpoint" ? "checkpoint required" : policyState === "proof_blocked" ? "blocked" : policyState === "proof_failed" ? "failed" : policyState === "proof_complete_ship_disabled" ? "proof complete; shipping disabled" : policyState === "proof_passed_ship_held" ? "proof passed; ship held" : policyState === "ship_authorized" ? status === "shipped" ? "shipped" : "ship authorized" : policyState === "proof_passed" ? "passed" : policyState === "proof_in_progress" ? "running" : status || "recorded";
135
+ return {
136
+ status,
137
+ ok,
138
+ policy_state: policyState,
139
+ result_label: resultLabel,
140
+ proof_complete: proofComplete,
141
+ proof_passed: proofPassed,
142
+ ship_held: shipHeld,
143
+ shipping_disabled: shippingDisabled,
144
+ ship_authorized: shipAuthorized,
145
+ merge_ready: mergeReady,
146
+ sync_allowed: syncAllowed,
147
+ checkpoint_summary: checkpointSummary,
148
+ required_disclosures: uniqueStrings(requiredDisclosures),
149
+ prohibited_claims: uniqueStrings(prohibitedClaims)
150
+ };
151
+ }
152
+
153
+ export {
154
+ summarizeRiddleProofPublicState
155
+ };
@@ -7,7 +7,7 @@ import {
7
7
  RIDDLE_PROOF_PR_COMMENT_MARKER,
8
8
  buildRiddleProofPrCommentMarkdown,
9
9
  summarizeRiddleProofPrComment
10
- } from "./chunk-JR7GFTLS.js";
10
+ } from "./chunk-2PKBTYOA.js";
11
11
  import {
12
12
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
13
13
  applyRiddleProofProfileArtifactCompleteness,
package/dist/cli/index.js CHANGED
@@ -1,7 +1,8 @@
1
- import "../chunk-LUFT7AGY.js";
1
+ import "../chunk-XSNMMAPJ.js";
2
2
  import "../chunk-DI2XNGEZ.js";
3
- import "../chunk-JR7GFTLS.js";
3
+ import "../chunk-2PKBTYOA.js";
4
4
  import "../chunk-EX7TO4I5.js";
5
+ import "../chunk-KG64Y5MC.js";
5
6
  import "../chunk-GHBNDHG7.js";
6
7
  import "../chunk-UZIX7M7D.js";
7
8
  import "../chunk-KNPCWWF3.js";
package/dist/cli.cjs CHANGED
@@ -17721,23 +17721,19 @@ function extractRiddleProofProfileResult(input) {
17721
17721
  return void 0;
17722
17722
  }
17723
17723
 
17724
- // src/pr-comment.ts
17725
- var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
17724
+ // src/public-state.ts
17726
17725
  function asRecord(value) {
17727
17726
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
17728
17727
  }
17729
- function asArray(value) {
17730
- return Array.isArray(value) ? value : [];
17731
- }
17732
17728
  function stringValue3(value) {
17733
17729
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
17734
17730
  }
17735
- function numberValue2(value) {
17736
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
17737
- }
17738
17731
  function booleanValue2(value) {
17739
17732
  return typeof value === "boolean" ? value : void 0;
17740
17733
  }
17734
+ function numberValue2(value) {
17735
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
17736
+ }
17741
17737
  function firstStringValue(...values) {
17742
17738
  for (const value of values) {
17743
17739
  const text = stringValue3(value);
@@ -17752,6 +17748,155 @@ function firstBooleanValue(...values) {
17752
17748
  }
17753
17749
  return void 0;
17754
17750
  }
17751
+ function firstRecordValue(...values) {
17752
+ for (const value of values) {
17753
+ const record = asRecord(value);
17754
+ if (Object.keys(record).length) return record;
17755
+ }
17756
+ return void 0;
17757
+ }
17758
+ function countValue(value) {
17759
+ const number = numberValue2(value);
17760
+ return typeof number === "number" && number > 0 ? Math.trunc(number) : 0;
17761
+ }
17762
+ function checkpointSummaryFrom(...values) {
17763
+ const record = firstRecordValue(...values);
17764
+ if (!record) return void 0;
17765
+ const accepted = countValue(record.response_count);
17766
+ const rejected = countValue(record.rejected_response_count);
17767
+ const ignored = countValue(record.ignored_response_count);
17768
+ const duplicate = countValue(record.duplicate_response_count);
17769
+ const summary = {
17770
+ pending: booleanValue2(record.pending),
17771
+ accepted_response_count: accepted,
17772
+ rejected_response_count: rejected,
17773
+ ignored_response_count: ignored,
17774
+ duplicate_response_count: duplicate,
17775
+ latest_decision: stringValue3(record.latest_decision),
17776
+ audit_disclosure_required: rejected > 0 || ignored > 0 || duplicate > 0
17777
+ };
17778
+ return Object.values(summary).some((value) => typeof value !== "undefined") ? summary : void 0;
17779
+ }
17780
+ function uniqueStrings(values) {
17781
+ return [...new Set(values.filter(Boolean))];
17782
+ }
17783
+ function summarizeRiddleProofPublicState(input) {
17784
+ const record = asRecord(input);
17785
+ const runCard = asRecord(record.run_card);
17786
+ const stopCondition = asRecord(runCard.stop_condition);
17787
+ const raw = asRecord(record.raw);
17788
+ const request = asRecord(record.request);
17789
+ const requestMetadata = asRecord(record.request_metadata);
17790
+ const prState = asRecord(record.pr_state);
17791
+ const handoff = asRecord(record.pr_handoff_policy);
17792
+ const handoffState = stringValue3(handoff.state);
17793
+ const status = firstStringValue(record.status, stopCondition.status);
17794
+ const ok = booleanValue2(record.ok) ?? null;
17795
+ const shipMode = firstStringValue(request.ship_mode, requestMetadata.ship_mode, record.ship_mode, handoff.ship_mode);
17796
+ const explicitShippingDisabled = firstBooleanValue(
17797
+ record.shipping_disabled,
17798
+ stopCondition.shipping_disabled,
17799
+ raw.shipping_disabled,
17800
+ handoff.shipping_disabled
17801
+ );
17802
+ const shippingDisabled = explicitShippingDisabled === true || shipMode === "none" || handoffState === "proof_complete_ship_disabled";
17803
+ const explicitShipAuthorized = firstBooleanValue(
17804
+ record.ship_authorized,
17805
+ stopCondition.ship_authorized,
17806
+ raw.ship_authorized
17807
+ );
17808
+ const authorizationEvidence = Boolean(
17809
+ status === "shipped" || record.marked_ready === true || stringValue3(prState.status) === "merged" || record.merge_commit || record.merged_at
17810
+ );
17811
+ const shipAuthorizedBeforeHold = explicitShipAuthorized ?? authorizationEvidence;
17812
+ const explicitShipHeld = firstBooleanValue(record.ship_held, stopCondition.ship_held, raw.ship_held);
17813
+ const inferredHeld = status === "ready_to_ship" && shippingDisabled && !shipAuthorizedBeforeHold;
17814
+ const shipHeld = explicitShipHeld === true || inferredHeld;
17815
+ const shipAuthorized = shipHeld ? false : shipAuthorizedBeforeHold === true;
17816
+ const proofComplete = Boolean(
17817
+ status === "ready_to_ship" || status === "shipped" || status === "completed" || status === "passed" || ok === true || handoff.proof_complete === true
17818
+ );
17819
+ const checkpointSummary = checkpointSummaryFrom(
17820
+ record.checkpoint_summary,
17821
+ stopCondition.checkpoint_summary,
17822
+ asRecord(record.details).checkpoint_summary,
17823
+ asRecord(raw.details).checkpoint_summary
17824
+ );
17825
+ const blockedOrWaiting = status === "blocked" || status === "failed" || status === "awaiting_checkpoint" || handoffState === "proof_blocked" || handoffState === "proof_review_required" || handoffState === "proof_failed" || handoffState === "proof_checkpoint_required";
17826
+ const proofPassed = Boolean(proofComplete && !blockedOrWaiting);
17827
+ const explicitMergeReady = firstBooleanValue(record.merge_ready, stopCondition.merge_ready, raw.merge_ready, handoff.merge_ready);
17828
+ const normalPrAllowed = firstBooleanValue(record.normal_pr_allowed, raw.normal_pr_allowed, handoff.normal_pr_allowed);
17829
+ const baseHandoffAllowed = !blockedOrWaiting && !shipHeld && !shippingDisabled;
17830
+ const mergeReady = baseHandoffAllowed && normalPrAllowed !== false && (explicitMergeReady ?? shipAuthorized);
17831
+ const syncAllowed = mergeReady;
17832
+ let policyState = "unknown";
17833
+ if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") policyState = "awaiting_checkpoint";
17834
+ else if (status === "failed" || handoffState === "proof_failed") policyState = "proof_failed";
17835
+ else if (status === "blocked" || handoffState === "proof_blocked" || handoffState === "proof_review_required") policyState = "proof_blocked";
17836
+ else if (handoffState === "proof_complete_ship_disabled") policyState = "proof_complete_ship_disabled";
17837
+ else if (proofComplete && shipHeld && !shipAuthorized) policyState = "proof_passed_ship_held";
17838
+ else if (proofComplete && shippingDisabled && !shipAuthorized) policyState = "proof_complete_ship_disabled";
17839
+ else if (shipAuthorized) policyState = "ship_authorized";
17840
+ else if (proofPassed) policyState = "proof_passed";
17841
+ else if (status === "running") policyState = "proof_in_progress";
17842
+ const requiredDisclosures = [];
17843
+ if (shipHeld) requiredDisclosures.push("ship_held");
17844
+ if (shippingDisabled) requiredDisclosures.push("shipping_disabled");
17845
+ if (checkpointSummary?.audit_disclosure_required) requiredDisclosures.push("checkpoint_audit_counters");
17846
+ if (status === "awaiting_checkpoint" || handoffState === "proof_checkpoint_required") requiredDisclosures.push("checkpoint_required");
17847
+ const prohibitedClaims = [];
17848
+ if (!shipAuthorized || shipHeld || shippingDisabled) prohibitedClaims.push("ship_authorized", "shipped");
17849
+ if (!mergeReady) prohibitedClaims.push("merge_ready");
17850
+ if (!syncAllowed) prohibitedClaims.push("sync_allowed");
17851
+ if (blockedOrWaiting) {
17852
+ prohibitedClaims.push("proof_passed", "ready_to_ship");
17853
+ }
17854
+ if (checkpointSummary?.audit_disclosure_required) {
17855
+ prohibitedClaims.push("all_checkpoint_responses_accepted");
17856
+ }
17857
+ const resultLabel2 = policyState === "awaiting_checkpoint" ? "checkpoint required" : policyState === "proof_blocked" ? "blocked" : policyState === "proof_failed" ? "failed" : policyState === "proof_complete_ship_disabled" ? "proof complete; shipping disabled" : policyState === "proof_passed_ship_held" ? "proof passed; ship held" : policyState === "ship_authorized" ? status === "shipped" ? "shipped" : "ship authorized" : policyState === "proof_passed" ? "passed" : policyState === "proof_in_progress" ? "running" : status || "recorded";
17858
+ return {
17859
+ status,
17860
+ ok,
17861
+ policy_state: policyState,
17862
+ result_label: resultLabel2,
17863
+ proof_complete: proofComplete,
17864
+ proof_passed: proofPassed,
17865
+ ship_held: shipHeld,
17866
+ shipping_disabled: shippingDisabled,
17867
+ ship_authorized: shipAuthorized,
17868
+ merge_ready: mergeReady,
17869
+ sync_allowed: syncAllowed,
17870
+ checkpoint_summary: checkpointSummary,
17871
+ required_disclosures: uniqueStrings(requiredDisclosures),
17872
+ prohibited_claims: uniqueStrings(prohibitedClaims)
17873
+ };
17874
+ }
17875
+
17876
+ // src/pr-comment.ts
17877
+ var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
17878
+ function asRecord2(value) {
17879
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
17880
+ }
17881
+ function asArray(value) {
17882
+ return Array.isArray(value) ? value : [];
17883
+ }
17884
+ function stringValue4(value) {
17885
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
17886
+ }
17887
+ function numberValue3(value) {
17888
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
17889
+ }
17890
+ function booleanValue3(value) {
17891
+ return typeof value === "boolean" ? value : void 0;
17892
+ }
17893
+ function firstStringValue2(...values) {
17894
+ for (const value of values) {
17895
+ const text = stringValue4(value);
17896
+ if (text) return text;
17897
+ }
17898
+ return void 0;
17899
+ }
17755
17900
  function artifactKind(name, url) {
17756
17901
  const target = `${name} ${url}`.toLowerCase();
17757
17902
  if (/\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(target)) return "image";
@@ -17759,18 +17904,18 @@ function artifactKind(name, url) {
17759
17904
  return "artifact";
17760
17905
  }
17761
17906
  function artifactDisplayName(value, fallback) {
17762
- const raw = stringValue3(value);
17907
+ const raw = stringValue4(value);
17763
17908
  if (raw) return raw;
17764
17909
  return fallback;
17765
17910
  }
17766
17911
  function collectArtifacts(runResponse) {
17767
- const proofResult = asRecord(runResponse.proofResult);
17912
+ const proofResult = asRecord2(runResponse.proofResult);
17768
17913
  const outputs = asArray(proofResult.outputs);
17769
17914
  const artifacts = [];
17770
17915
  const seen = /* @__PURE__ */ new Set();
17771
17916
  for (const [index, item] of outputs.entries()) {
17772
- const artifact = asRecord(item);
17773
- const url = stringValue3(artifact.url);
17917
+ const artifact = asRecord2(item);
17918
+ const url = stringValue4(artifact.url);
17774
17919
  if (!url || seen.has(url)) continue;
17775
17920
  seen.add(url);
17776
17921
  const name = artifactDisplayName(artifact.name, `artifact-${index + 1}`);
@@ -17778,7 +17923,7 @@ function collectArtifacts(runResponse) {
17778
17923
  name,
17779
17924
  url,
17780
17925
  kind: artifactKind(name, url),
17781
- size_bytes: numberValue2(artifact.size)
17926
+ size_bytes: numberValue3(artifact.size)
17782
17927
  });
17783
17928
  }
17784
17929
  return artifacts;
@@ -17786,9 +17931,9 @@ function collectArtifacts(runResponse) {
17786
17931
  function pageSummaries(result) {
17787
17932
  const pages = [];
17788
17933
  for (const page of asArray(result.pages)) {
17789
- const record = asRecord(page);
17790
- const route = stringValue3(record.route) || stringValue3(record.url) || "page";
17791
- const checks = asRecord(record.checks);
17934
+ const record = asRecord2(page);
17935
+ const route = stringValue4(record.route) || stringValue4(record.url) || "page";
17936
+ const checks = asRecord2(record.checks);
17792
17937
  let passed = 0;
17793
17938
  let failed = 0;
17794
17939
  for (const value of Object.values(checks)) {
@@ -17828,68 +17973,76 @@ function selectPrimaryImage(artifacts) {
17828
17973
  const images = artifacts.filter((artifact) => artifact.kind === "image");
17829
17974
  return images.find((artifact) => /after|proof|screenshot/i.test(artifact.name)) || images[0];
17830
17975
  }
17831
- function firstRecordValue(...values) {
17976
+ function firstRecordValue2(...values) {
17832
17977
  for (const value of values) {
17833
- const record = asRecord(value);
17978
+ const record = asRecord2(value);
17834
17979
  if (Object.keys(record).length) return record;
17835
17980
  }
17836
17981
  return void 0;
17837
17982
  }
17838
- function checkpointSummaryFrom(...values) {
17839
- const record = firstRecordValue(...values);
17983
+ function checkpointSummaryFrom2(...values) {
17984
+ const record = firstRecordValue2(...values);
17840
17985
  if (!record) return void 0;
17841
17986
  const summary = {
17842
- pending: booleanValue2(record.pending),
17843
- response_count: numberValue2(record.response_count),
17844
- rejected_response_count: numberValue2(record.rejected_response_count),
17845
- ignored_response_count: numberValue2(record.ignored_response_count),
17846
- duplicate_response_count: numberValue2(record.duplicate_response_count),
17847
- latest_decision: stringValue3(record.latest_decision),
17848
- latest_packet_id: stringValue3(record.latest_packet_id),
17849
- latest_resume_token: stringValue3(record.latest_resume_token)
17987
+ pending: booleanValue3(record.pending),
17988
+ response_count: numberValue3(record.response_count),
17989
+ rejected_response_count: numberValue3(record.rejected_response_count),
17990
+ ignored_response_count: numberValue3(record.ignored_response_count),
17991
+ duplicate_response_count: numberValue3(record.duplicate_response_count),
17992
+ latest_decision: stringValue4(record.latest_decision),
17993
+ latest_packet_id: stringValue4(record.latest_packet_id),
17994
+ latest_resume_token: stringValue4(record.latest_resume_token)
17850
17995
  };
17851
17996
  return Object.values(summary).some((value) => typeof value !== "undefined") ? summary : void 0;
17852
17997
  }
17853
17998
  function summarizeRiddleProofPrComment(input) {
17854
- const runResponse = asRecord(input.runResponse);
17855
- const result = asRecord(input.result);
17856
- const proofResult = asRecord(runResponse.proofResult);
17857
- const preview = asRecord(runResponse.preview);
17858
- const resultRunCard = asRecord(result.run_card);
17859
- const stopCondition = asRecord(resultRunCard.stop_condition);
17860
- const resultDetails = asRecord(result.details);
17861
- const resultRaw = asRecord(result.raw);
17862
- const rawDetails = asRecord(resultRaw.details);
17999
+ const runResponse = asRecord2(input.runResponse);
18000
+ const result = asRecord2(input.result);
18001
+ const proofResult = asRecord2(runResponse.proofResult);
18002
+ const preview = asRecord2(runResponse.preview);
18003
+ const resultRunCard = asRecord2(result.run_card);
18004
+ const stopCondition = asRecord2(resultRunCard.stop_condition);
18005
+ const resultDetails = asRecord2(result.details);
18006
+ const resultRaw = asRecord2(result.raw);
18007
+ const rawDetails = asRecord2(resultRaw.details);
17863
18008
  const artifacts = collectArtifacts(runResponse);
17864
18009
  const pages = pageSummaries(result);
17865
18010
  const checkSource = { ...result };
17866
18011
  delete checkSource.ok;
17867
18012
  const nestedChecks = summarizeExplicitChecks(checkSource);
17868
- const ok = booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
17869
- const checkpointSummary = checkpointSummaryFrom(
18013
+ const ok = booleanValue3(result.ok) ?? booleanValue3(runResponse.ok) ?? null;
18014
+ const checkpointSummary = checkpointSummaryFrom2(
17870
18015
  result.checkpoint_summary,
17871
18016
  stopCondition.checkpoint_summary,
17872
18017
  resultDetails.checkpoint_summary,
17873
18018
  rawDetails.checkpoint_summary,
17874
18019
  proofResult.checkpoint_summary
17875
18020
  );
18021
+ const publicState = summarizeRiddleProofPublicState({
18022
+ ...result,
18023
+ status: firstStringValue2(result.status, stopCondition.status),
18024
+ checkpoint_summary: checkpointSummary || result.checkpoint_summary
18025
+ });
17876
18026
  return {
17877
18027
  ok,
17878
- status: stringValue3(proofResult.status),
17879
- result_status: firstStringValue(result.status, stopCondition.status),
17880
- job_id: stringValue3(proofResult.job_id),
17881
- duration_ms: numberValue2(proofResult.duration_ms),
17882
- proof_url: stringValue3(runResponse.proofUrl),
17883
- preview_id: stringValue3(preview.id),
17884
- preview_url: stringValue3(preview.preview_url) || stringValue3(preview.url),
17885
- preview_publish_recovered: booleanValue2(preview.publish_recovered),
17886
- preview_publish_error: stringValue3(preview.publish_error),
17887
- ship_held: firstBooleanValue(result.ship_held, stopCondition.ship_held, resultRaw.ship_held),
17888
- shipping_disabled: firstBooleanValue(result.shipping_disabled, stopCondition.shipping_disabled, resultRaw.shipping_disabled),
17889
- ship_authorized: firstBooleanValue(result.ship_authorized, stopCondition.ship_authorized, resultRaw.ship_authorized),
17890
- proof_decision: firstStringValue(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
17891
- merge_recommendation: firstStringValue(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation),
18028
+ status: stringValue4(proofResult.status),
18029
+ result_status: publicState.status,
18030
+ job_id: stringValue4(proofResult.job_id),
18031
+ duration_ms: numberValue3(proofResult.duration_ms),
18032
+ proof_url: stringValue4(runResponse.proofUrl),
18033
+ preview_id: stringValue4(preview.id),
18034
+ preview_url: stringValue4(preview.preview_url) || stringValue4(preview.url),
18035
+ preview_publish_recovered: booleanValue3(preview.publish_recovered),
18036
+ preview_publish_error: stringValue4(preview.publish_error),
18037
+ ship_held: publicState.ship_held,
18038
+ shipping_disabled: publicState.shipping_disabled,
18039
+ ship_authorized: publicState.ship_authorized,
18040
+ merge_ready: publicState.merge_ready,
18041
+ sync_allowed: publicState.sync_allowed,
18042
+ proof_decision: firstStringValue2(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
18043
+ merge_recommendation: firstStringValue2(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation),
17892
18044
  checkpoint_summary: checkpointSummary,
18045
+ public_state: publicState,
17893
18046
  passed_checks: nestedChecks.passed,
17894
18047
  failed_checks: nestedChecks.failed,
17895
18048
  pages,
@@ -17908,6 +18061,7 @@ function markdownLink(label, url) {
17908
18061
  return `[${label.replace(/\]/g, "\\]")}](${url})`;
17909
18062
  }
17910
18063
  function resultLabel(summary) {
18064
+ if (summary.public_state?.result_label) return summary.public_state.result_label;
17911
18065
  if (summary.ok === true) {
17912
18066
  if (summary.result_status === "shipped") return "shipped";
17913
18067
  if (summary.result_status === "completed") return "completed";
@@ -17934,6 +18088,14 @@ function formatBool(value) {
17934
18088
  function hasShipControl(summary) {
17935
18089
  return typeof summary.ship_held === "boolean" || typeof summary.shipping_disabled === "boolean" || typeof summary.ship_authorized === "boolean";
17936
18090
  }
18091
+ function hasHandoffControl(summary) {
18092
+ return typeof summary.merge_ready === "boolean" || typeof summary.sync_allowed === "boolean";
18093
+ }
18094
+ function shouldRenderMergeRecommendation(summary) {
18095
+ if (!summary.merge_recommendation) return false;
18096
+ const prohibited = summary.public_state?.prohibited_claims || [];
18097
+ return !prohibited.includes("merge_ready") && !prohibited.includes("sync_allowed");
18098
+ }
17937
18099
  function checkpointSummaryLine(summary) {
17938
18100
  const accepted = summary.response_count ?? 0;
17939
18101
  const rejected = summary.rejected_response_count ?? 0;
@@ -17965,8 +18127,11 @@ function buildRiddleProofPrCommentMarkdown(input) {
17965
18127
  if (hasShipControl(summary)) {
17966
18128
  lines.push(`**Ship control:** held=${formatBool(summary.ship_held)}, shipping_disabled=${formatBool(summary.shipping_disabled)}, authorized=${formatBool(summary.ship_authorized)}`);
17967
18129
  }
18130
+ if (hasHandoffControl(summary)) {
18131
+ lines.push(`**Handoff:** merge_ready=${formatBool(summary.merge_ready)}, sync_allowed=${formatBool(summary.sync_allowed)}`);
18132
+ }
17968
18133
  if (summary.proof_decision) lines.push(`**Proof decision:** \`${summary.proof_decision}\``);
17969
- if (summary.merge_recommendation) lines.push(`**Merge recommendation:** ${summary.merge_recommendation}`);
18134
+ if (shouldRenderMergeRecommendation(summary)) lines.push(`**Merge recommendation:** ${summary.merge_recommendation}`);
17970
18135
  if (summary.checkpoint_summary) lines.push(`**Checkpoints:** ${checkpointSummaryLine(summary.checkpoint_summary)}`);
17971
18136
  if (summary.proof_url) lines.push(`**Proof URL:** ${markdownLink(summary.proof_url, summary.proof_url)}`);
17972
18137
  if (summary.preview_id || summary.preview_url) {
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-LUFT7AGY.js";
2
+ import "./chunk-XSNMMAPJ.js";
3
3
  import "./chunk-DI2XNGEZ.js";
4
- import "./chunk-JR7GFTLS.js";
4
+ import "./chunk-2PKBTYOA.js";
5
5
  import "./chunk-EX7TO4I5.js";
6
+ import "./chunk-KG64Y5MC.js";
6
7
  import "./chunk-GHBNDHG7.js";
7
8
  import "./chunk-UZIX7M7D.js";
8
9
  import "./chunk-KNPCWWF3.js";