from pathlib import Path
import json
R=Path(__file__).resolve().parent
cases=json.loads((R/'fixtures/cases.json').read_text(encoding='utf-8'))['cases']
assert len(cases)==8
required={'id','artifact_version','deployed','deployment_evidence','flag_expected','flag_observed','flag_key','targeting_key','targeting_key_repeat','cohort_expected','cohort_observed','exposure_percent','feature_health','feature_health_evidence','bake_required_minutes','bake_observed_minutes','bake_status','rollback_trigger_met','flag_disabled','durable_side_effects','side_effects_reconciled','full_exposure','cleanup_ready','retirement_requested','transfer'}
assert all(required <= set(c) for c in cases)
assert any(c['deployed'] and c['flag_observed']!=c['flag_expected'] for c in cases)
assert any(c['targeting_key']!=c['targeting_key_repeat'] for c in cases)
assert any(c['cohort_observed']!=c['cohort_expected'] for c in cases)
assert any(c['feature_health']=='FAIL' and c['rollback_trigger_met'] for c in cases)
assert any(c['flag_disabled'] and c['durable_side_effects'] and not c['side_effects_reconciled'] for c in cases)
assert any(c['bake_status']=='INCOMPLETE' for c in cases)
assert any(c['full_exposure'] and c['retirement_requested'] and not c['cleanup_ready'] for c in cases)
assert any(c['transfer'] for c in cases)
print('PASS: 8 synthetic bounded-rollout fixtures are structurally valid; implement analyze_rollout(case) in starter.py')
