def expected(x):
 if x.get('baseline_oracle_reuse'): return 'HOLD_BASELINE_ORACLE_REUSE'
 if not x.get('source_hash_valid',False): return 'HOLD_SOURCE_SNAPSHOT'
 if not x.get('span_present',False): return 'HOLD_SOURCE_SPAN'
 if not x.get('occupation_id'): return 'HOLD_OCCUPATION_MAPPING'
 if not x.get('mapping_version_matches',False): return 'HOLD_STALE_TAXONOMY_MAPPING'
 if x.get('forced_normalization'): return 'HOLD_FORCED_NORMALIZATION'
 if x.get('skill_confidence')=='LOW' and x.get('gap_state')=='GAP': return 'HOLD_LOW_CONFIDENCE_REVIEW'
 if x.get('prior_requirement_class') and x.get('prior_requirement_class')!=x.get('requirement_class') and x.get('gap_state')=='GAP': return 'HOLD_REQUIREMENT_RECOMPUTE'
 if x.get('gap_state')=='GAP' and not x.get('learner_evidence'): return 'HOLD_LEARNER_EVIDENCE'
 if not x.get('provenance',False): return 'HOLD_PROVENANCE'
 return 'REVIEW_REQUIRED'
def expected_transfer(x):
 if x.get('baseline_oracle_reuse') or not x.get('recomputed_from_new_source'): return 'HOLD_BASELINE_ORACLE_REUSE'
 if not x.get('source_hash_valid') or not x.get('span_present') or not x.get('provenance'): return 'HOLD_INSUFFICIENT_EVIDENCE'
 if any(s.get('matched') is False or s.get('confidence') in ('LOW','MEDIUM') for s in x.get('skills',[])): return 'REVIEW_REQUIRED'
 return 'REVIEW_REQUIRED'
def inspect_transfer(x):
 out=[]
 if x.get('baseline_oracle_reuse'): out.append('BASELINE_ORACLE_REUSE_FORBIDDEN')
 if not x.get('recomputed_from_new_source'): out.append('TRANSFER_MUST_RECOMPUTE')
 return out
