@@ -204,7 +204,7 @@ def reject_constant(_: str) -> None:
204204 if snapshot ["snapshot_version" ] != SNAPSHOT_VERSION :
205205 raise _error ("bundle_snapshot_version_invalid" )
206206 _string (snapshot ["source_run_id" ], _RUN_ID_RE , "bundle_snapshot_run_invalid" )
207- if snapshot ["source_attempt" ] != 1 :
207+ if type ( snapshot [ "source_attempt" ]) is not int or snapshot ["source_attempt" ] != 1 :
208208 raise _error ("bundle_snapshot_attempt_invalid" )
209209 _string (snapshot ["workflow_sha" ], _SHA1_RE , "bundle_snapshot_workflow_invalid" )
210210 _string (snapshot ["producer_sha" ], _SHA1_RE , "bundle_snapshot_producer_invalid" )
@@ -324,6 +324,9 @@ def pairs(items: list[tuple[str, object]]) -> dict[str, object]:
324324 _safe_int (parsed ["artifact_id" ], "bundle_manifest_invalid" )
325325 if type (parsed ["source_attempt" ]) is not int or parsed ["source_attempt" ] != 1 :
326326 raise _error ("bundle_manifest_invalid" )
327+ _string (parsed ["source_run_id" ], _RUN_ID_RE , "bundle_manifest_invalid" )
328+ if parsed ["lock_version" ] != LOCK_VERSION or parsed ["snapshot_version" ] != SNAPSHOT_VERSION :
329+ raise _error ("bundle_manifest_version_invalid" )
327330 if type (parsed ["retention_days" ]) is not int or not 1 <= parsed ["retention_days" ] <= 90 :
328331 raise _error ("bundle_manifest_invalid" )
329332 if _canonical_json (parsed , "bundle_manifest_invalid" ) != value :
@@ -360,6 +363,14 @@ def _manifest_bytes(
360363 )
361364
362365
366+ def _validate_snapshot_binding (
367+ snapshot : dict [str , object ], lock : PoliticalEventWeeklyPeriodLockV1 , reviewed_workflow_sha : str
368+ ) -> None :
369+ expected = _expected_snapshot (lock , reviewed_workflow_sha )
370+ if snapshot != expected :
371+ raise _error ("bundle_snapshot_mismatch" )
372+
373+
363374def build_period_bundle (
364375 lock_bytes : object ,
365376 snapshot_bytes : object ,
@@ -376,7 +387,8 @@ def build_period_bundle(
376387 _expected_snapshot (lock , identity ["reviewed_workflow_sha" ]), "bundle_snapshot_invalid"
377388 )
378389 parsed_snapshot = _snapshot (snapshot_bytes )
379- if snapshot_bytes != expected_snapshot or parsed_snapshot != json .loads (expected_snapshot ):
390+ _validate_snapshot_binding (parsed_snapshot , lock , identity ["reviewed_workflow_sha" ])
391+ if snapshot_bytes != expected_snapshot :
380392 raise _error ("bundle_snapshot_mismatch" )
381393 evidence = _artifact (artifact , lock .source_run_id )
382394 manifest = _manifest_bytes (lock , identity , evidence , lock_bytes , snapshot_bytes )
@@ -425,6 +437,8 @@ def verify_period_bundle(
425437 raise _error ("bundle_lock_mismatch" )
426438 if values ["snapshot_bytes" ] != expected_snapshot_bytes or actual_snapshot != expected_snapshot :
427439 raise _error ("bundle_snapshot_mismatch" )
440+ _validate_snapshot_binding (expected_snapshot , expected_lock , expected_identity ["reviewed_workflow_sha" ])
441+ _validate_snapshot_binding (actual_snapshot , actual_lock , manifest ["reviewed_workflow_sha" ])
428442 if actual_evidence != expected_evidence :
429443 raise _error ("bundle_artifact_mismatch" )
430444 if actual_lock .workflow_ref != TRUSTED_WORKFLOW_REF :
0 commit comments