@@ -44,6 +44,19 @@ def ledger_paths(tmp_path, monkeypatch):
4444 monkeypatch .setattr (service , "_UPLOADED_DIR" , stage / "uploaded" )
4545 monkeypatch .setattr (service , "_PENDING_FILE" , stage / "pending.jsonl" )
4646 stage .mkdir (parents = True , exist_ok = True )
47+
48+ # Keep CI fully offline: model a verified private remote by default.
49+ class PrivateHubInfo :
50+ private = True
51+
52+ class FakeHfApi :
53+ def __init__ (self , * args , ** kwargs ):
54+ pass
55+
56+ def dataset_info (self , * args , ** kwargs ):
57+ return PrivateHubInfo ()
58+
59+ monkeypatch .setattr (service , "HfApi" , FakeHfApi , raising = False )
4760 return stage / "training_integrity_ledger.sqlite3"
4861
4962
@@ -519,3 +532,90 @@ def test_queue_cleanup_preserves_unconsented_duplicate_payload(ledger_paths):
519532 remaining = service ._read_pending ()
520533 assert remaining == [unconsented ]
521534 assert remaining [0 ]["consent" ] is False
535+
536+
537+
538+ def test_private_visibility_is_verified_and_allowed (monkeypatch ):
539+ class Info :
540+ private = True
541+
542+ class Api :
543+ def __init__ (self , * args , ** kwargs ):
544+ pass
545+
546+ def dataset_info (self , * args , ** kwargs ):
547+ return Info ()
548+
549+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
550+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
551+ assert service ._verify_remote_dataset_privacy () is True
552+
553+
554+ def test_public_remote_dataset_is_blocked_when_privacy_is_required (monkeypatch ):
555+ class Info :
556+ private = False
557+
558+ class Api :
559+ def __init__ (self , * args , ** kwargs ):
560+ pass
561+
562+ def dataset_info (self , * args , ** kwargs ):
563+ return Info ()
564+
565+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
566+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
567+ monkeypatch .setattr (service , "_dataset_private_env" , None )
568+ with pytest .raises (RuntimeError , match = "private dataset required but remote dataset is public" ):
569+ service ._verify_remote_dataset_privacy ()
570+
571+
572+ def test_public_visibility_requires_explicit_opt_in_and_metadata_only (monkeypatch ):
573+ class Info :
574+ private = False
575+
576+ class Api :
577+ def __init__ (self , * args , ** kwargs ):
578+ pass
579+
580+ def dataset_info (self , * args , ** kwargs ):
581+ return Info ()
582+
583+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
584+ monkeypatch .setattr (service , "_dataset_private_env" , "false" )
585+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , False )
586+ monkeypatch .setattr (service , "OMNI_HF_EXPORT_RAW_TEXT" , False )
587+ assert service ._verify_remote_dataset_privacy () is False
588+
589+ monkeypatch .setattr (service , "OMNI_HF_EXPORT_RAW_TEXT" , True )
590+ with pytest .raises (RuntimeError , match = "incompatible with" ):
591+ service ._verify_remote_dataset_privacy ()
592+
593+
594+ def test_privacy_verification_failure_fails_closed (monkeypatch ):
595+ class Api :
596+ def __init__ (self , * args , ** kwargs ):
597+ pass
598+
599+ def dataset_info (self , * args , ** kwargs ):
600+ raise ConnectionError ("visibility endpoint unavailable" )
601+
602+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
603+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
604+ with pytest .raises (RuntimeError , match = "privacy could not be verified" ):
605+ service ._verify_remote_dataset_privacy ()
606+
607+
608+ def test_unknown_visibility_fails_closed (monkeypatch ):
609+ class Info :
610+ private = None
611+
612+ class Api :
613+ def __init__ (self , * args , ** kwargs ):
614+ pass
615+
616+ def dataset_info (self , * args , ** kwargs ):
617+ return Info ()
618+
619+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
620+ with pytest .raises (RuntimeError , match = "privacy is unknown" ):
621+ service ._verify_remote_dataset_privacy ()
0 commit comments