@riddledc/riddle-proof 0.8.63 → 0.8.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.8.63",
3
+ "version": "0.8.64",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -676,6 +676,64 @@ def first_url_from_command_output(*parts):
676
676
  return ''
677
677
 
678
678
 
679
+ def dict_value(value):
680
+ return value if isinstance(value, dict) else {}
681
+
682
+
683
+ def proof_provenance_facts(state):
684
+ assessment = dict_value(state.get('proof_assessment'))
685
+ bundle = dict_value(state.get('evidence_bundle'))
686
+ bundle_session = dict_value(bundle.get('proof_session'))
687
+ proof_session = dict_value(state.get('proof_session')) or bundle_session
688
+ publication = dict_value(state.get('proof_artifact_publication'))
689
+ checkpoint_packet = dict_value(state.get('checkpoint_packet'))
690
+ checkpoint_summary = dict_value(state.get('checkpoint_summary'))
691
+ return {
692
+ 'version': 'riddle-proof.provenance.v1',
693
+ 'run_id': str(state.get('run_id') or ''),
694
+ 'checkpoint_packet_id': str(
695
+ checkpoint_packet.get('packet_id')
696
+ or checkpoint_summary.get('latest_packet_id')
697
+ or ''
698
+ ),
699
+ 'checkpoint_response_packet_id': str(
700
+ checkpoint_summary.get('latest_response_packet_id')
701
+ or ''
702
+ ),
703
+ 'evidence_bundle_id': str(
704
+ bundle.get('evidence_bundle_id')
705
+ or bundle.get('bundle_id')
706
+ or bundle.get('id')
707
+ or ''
708
+ ),
709
+ 'proof_session_id': str(
710
+ proof_session.get('session_id')
711
+ or bundle_session.get('session_id')
712
+ or ''
713
+ ),
714
+ 'proof_session_fingerprint': str(
715
+ state.get('proof_session_fingerprint')
716
+ or proof_session.get('fingerprint')
717
+ or bundle_session.get('fingerprint')
718
+ or ''
719
+ ),
720
+ 'proof_assessment_id': str(
721
+ assessment.get('assessment_id')
722
+ or assessment.get('id')
723
+ or ''
724
+ ),
725
+ 'proof_assessment_source': str(
726
+ assessment.get('source')
727
+ or state.get('proof_assessment_source')
728
+ or ''
729
+ ),
730
+ 'proof_assessment_decision': str(assessment.get('decision') or ''),
731
+ 'artifact_publication_commit': str(publication.get('commit') or ''),
732
+ 'artifact_manifest_url': str(publication.get('manifest_url') or ''),
733
+ 'artifact_source_fingerprint': str(publication.get('source_fingerprint') or ''),
734
+ }
735
+
736
+
679
737
  def build_ship_report(state, marked_ready=None):
680
738
  branch = state.get('target_branch') or state.get('branch') or ''
681
739
  if marked_ready is None:
@@ -685,6 +743,7 @@ def build_ship_report(state, marked_ready=None):
685
743
  after_artifact_url = first_public_artifact_url(state, 'after', 'image') or state.get('after_cdn', '')
686
744
  artifact_publication = state.get('proof_artifact_publication') or {}
687
745
  ship_gate = ship_gate_report_facts(state)
746
+ proof_provenance = proof_provenance_facts(state)
688
747
  return {
689
748
  'pr_url': state.get('pr_url', ''),
690
749
  'pr_branch': branch,
@@ -703,6 +762,7 @@ def build_ship_report(state, marked_ready=None):
703
762
  'proof_artifacts_manifest_url': artifact_publication.get('manifest_url', '') if isinstance(artifact_publication, dict) else '',
704
763
  'proof_artifact_publication': artifact_publication if isinstance(artifact_publication, dict) else {},
705
764
  'ship_gate': ship_gate,
765
+ 'proof_provenance': proof_provenance,
706
766
  }
707
767
 
708
768
 
@@ -138,12 +138,27 @@ def main():
138
138
  "proof_summary": "All assertions passed.",
139
139
  "proof_assessment_source": "supervising_agent",
140
140
  "proof_assessment": {
141
+ "assessment_id": "assessment_ship_artifact_test",
141
142
  "source": "supervising_agent",
142
143
  "decision": "ready_to_ship",
143
144
  "summary": "Evidence is strong enough to ship.",
144
145
  },
146
+ "checkpoint_summary": {
147
+ "latest_packet_id": "rppkt_ship_artifact_test",
148
+ "latest_response_packet_id": "rppkt_ship_artifact_test",
149
+ },
150
+ "proof_session": {
151
+ "session_id": "session_ship_artifact_test",
152
+ "fingerprint": "fingerprint_ship_artifact_test",
153
+ },
154
+ "proof_session_fingerprint": "fingerprint_ship_artifact_test",
145
155
  "evidence_bundle": {
156
+ "id": "bundle_ship_artifact_test",
146
157
  "verification_mode": "proof",
158
+ "proof_session": {
159
+ "session_id": "session_ship_artifact_test",
160
+ "fingerprint": "fingerprint_ship_artifact_test",
161
+ },
147
162
  "after": {
148
163
  "observation": {"valid": True, "reason": "ok", "telemetry_ready": True},
149
164
  "supporting_artifacts": {
@@ -204,6 +219,46 @@ def main():
204
219
  "ship gate should expose proof decision"
205
220
  )
206
221
  assert gate_evidence.get("hard_blockers") == [], "ship gate should expose hard blockers"
222
+ provenance = ship_report.get("proof_provenance") or {}
223
+ assert provenance.get("version") == "riddle-proof.provenance.v1", (
224
+ "ship report should expose proof provenance version"
225
+ )
226
+ assert provenance.get("run_id") == "rp_ship_artifact_test", (
227
+ "ship report provenance should expose the run id"
228
+ )
229
+ assert provenance.get("checkpoint_packet_id") == "rppkt_ship_artifact_test", (
230
+ "ship report provenance should expose the checkpoint packet id"
231
+ )
232
+ assert provenance.get("checkpoint_response_packet_id") == "rppkt_ship_artifact_test", (
233
+ "ship report provenance should expose the checkpoint response packet id"
234
+ )
235
+ assert provenance.get("evidence_bundle_id") == "bundle_ship_artifact_test", (
236
+ "ship report provenance should expose the evidence bundle id"
237
+ )
238
+ assert provenance.get("proof_session_id") == "session_ship_artifact_test", (
239
+ "ship report provenance should expose the proof session id"
240
+ )
241
+ assert provenance.get("proof_session_fingerprint") == "fingerprint_ship_artifact_test", (
242
+ "ship report provenance should expose the proof session fingerprint"
243
+ )
244
+ assert provenance.get("proof_assessment_id") == "assessment_ship_artifact_test", (
245
+ "ship report provenance should expose the proof assessment id"
246
+ )
247
+ assert provenance.get("proof_assessment_source") == "supervising_agent", (
248
+ "ship report provenance should expose the proof assessment source"
249
+ )
250
+ assert provenance.get("proof_assessment_decision") == "ready_to_ship", (
251
+ "ship report provenance should expose the proof assessment decision"
252
+ )
253
+ assert provenance.get("artifact_publication_commit") == publication.get("commit"), (
254
+ "ship report provenance should expose the artifact publication commit"
255
+ )
256
+ assert provenance.get("artifact_manifest_url") == ship_report.get("proof_artifacts_manifest_url"), (
257
+ "ship report provenance should expose the artifact manifest URL"
258
+ )
259
+ assert provenance.get("artifact_source_fingerprint") == publication.get("source_fingerprint"), (
260
+ "ship report provenance should expose the artifact source fingerprint"
261
+ )
207
262
 
208
263
  comment = comment_body_path.read_text(encoding="utf-8")
209
264
  assert "file://" not in comment, "PR proof comment must not expose local file URLs"