@@ -49,7 +49,7 @@ def check_keys(value: Any, allowed: set[str], label: str) -> None:
4949 for field in ("reason_codes" , "evidence_refs" ):
5050 if not isinstance (gate .get (field ), list ):
5151 issues .append (f"{ gate .get ('id' , '<unknown>' )} .{ field } must be an array" )
52- elif any (not isinstance (item , str ) for item in gate [field ]):
52+ elif any (not isinstance (item , str ) or not item . strip () for item in gate [field ]):
5353 issues .append (f"{ gate .get ('id' , '<unknown>' )} .{ field } must contain strings" )
5454
5555 score = payload .get ("score" )
@@ -131,7 +131,7 @@ def check_keys(value: Any, allowed: set[str], label: str) -> None:
131131 recommendation = packet .get ("system_recommendation" )
132132 if not isinstance (recommendation , str ) or recommendation not in recommendations :
133133 issues .append ("decision_packet.system_recommendation is invalid" )
134- if not isinstance (packet .get ("technical_evidence_refs" ), list ) or any (not isinstance (item , str ) for item in packet .get ("technical_evidence_refs" , [])):
134+ if not isinstance (packet .get ("technical_evidence_refs" ), list ) or any (not isinstance (item , str ) or not item . strip () for item in packet .get ("technical_evidence_refs" , [])):
135135 issues .append ("decision_packet.technical_evidence_refs must be a string array" )
136136 boundary = packet .get ("automation_boundary" )
137137 if not isinstance (boundary , dict ):
@@ -233,6 +233,11 @@ def check_keys(value: Any, allowed: set[str], label: str) -> None:
233233 issues .append ("failed or insufficient hard gates require blocking_reason_codes" )
234234 if payload .get ("promotion_allowed" ) is not False :
235235 issues .append ("promotion_allowed must be false in v1 review output" )
236+ if isinstance (evidence , dict ) and isinstance (packet , dict ) and (
237+ payload .get ("decision" ) == "pass"
238+ or packet .get ("system_recommendation" ) in {"approve_research" , "approve_shadow" , "approve_canary" , "approve_live" }
239+ ) and str (evidence .get ("data_source" , "" )).strip ().lower () in SENTINELS :
240+ issues .append ("approved review cannot use a provenance sentinel as evidence.data_source" )
236241 if payload .get ("decision" ) == "pass" and failed :
237242 issues .append ("decision cannot be pass when a hard gate failed or lacks evidence" )
238243 if payload .get ("decision" ) == "pass" and blocking :
0 commit comments