@@ -15,6 +15,19 @@ def ledger_paths(tmp_path, monkeypatch):
1515 monkeypatch .setattr (service , "_UPLOADED_DIR" , stage / "uploaded" )
1616 monkeypatch .setattr (service , "_PENDING_FILE" , stage / "pending.jsonl" )
1717 stage .mkdir (parents = True , exist_ok = True )
18+
19+ # Keep CI fully offline: model a verified private remote by default.
20+ class PrivateHubInfo :
21+ private = True
22+
23+ class FakeHfApi :
24+ def __init__ (self , * args , ** kwargs ):
25+ pass
26+
27+ def dataset_info (self , * args , ** kwargs ):
28+ return PrivateHubInfo ()
29+
30+ monkeypatch .setattr (service , "HfApi" , FakeHfApi , raising = False )
1831 return stage / "training_integrity_ledger.sqlite3"
1932
2033
@@ -429,3 +442,90 @@ def push_to_hub(self, **kwargs):
429442 service .flush_queue ()
430443
431444 assert any (item .get ("integrity_hash" ) == row ["integrity_hash" ] for item in pushed )
445+
446+
447+
448+ def test_private_visibility_is_verified_and_allowed (monkeypatch ):
449+ class Info :
450+ private = True
451+
452+ class Api :
453+ def __init__ (self , * args , ** kwargs ):
454+ pass
455+
456+ def dataset_info (self , * args , ** kwargs ):
457+ return Info ()
458+
459+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
460+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
461+ assert service ._verify_remote_dataset_privacy () is True
462+
463+
464+ def test_public_remote_dataset_is_blocked_when_privacy_is_required (monkeypatch ):
465+ class Info :
466+ private = False
467+
468+ class Api :
469+ def __init__ (self , * args , ** kwargs ):
470+ pass
471+
472+ def dataset_info (self , * args , ** kwargs ):
473+ return Info ()
474+
475+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
476+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
477+ monkeypatch .setattr (service , "_dataset_private_env" , None )
478+ with pytest .raises (RuntimeError , match = "private dataset required but remote dataset is public" ):
479+ service ._verify_remote_dataset_privacy ()
480+
481+
482+ def test_public_visibility_requires_explicit_opt_in_and_metadata_only (monkeypatch ):
483+ class Info :
484+ private = False
485+
486+ class Api :
487+ def __init__ (self , * args , ** kwargs ):
488+ pass
489+
490+ def dataset_info (self , * args , ** kwargs ):
491+ return Info ()
492+
493+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
494+ monkeypatch .setattr (service , "_dataset_private_env" , "false" )
495+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , False )
496+ monkeypatch .setattr (service , "OMNI_HF_EXPORT_RAW_TEXT" , False )
497+ assert service ._verify_remote_dataset_privacy () is False
498+
499+ monkeypatch .setattr (service , "OMNI_HF_EXPORT_RAW_TEXT" , True )
500+ with pytest .raises (RuntimeError , match = "incompatible with" ):
501+ service ._verify_remote_dataset_privacy ()
502+
503+
504+ def test_privacy_verification_failure_fails_closed (monkeypatch ):
505+ class Api :
506+ def __init__ (self , * args , ** kwargs ):
507+ pass
508+
509+ def dataset_info (self , * args , ** kwargs ):
510+ raise ConnectionError ("visibility endpoint unavailable" )
511+
512+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
513+ monkeypatch .setattr (service , "OMNI_HF_DATASET_PRIVATE" , True )
514+ with pytest .raises (RuntimeError , match = "privacy could not be verified" ):
515+ service ._verify_remote_dataset_privacy ()
516+
517+
518+ def test_unknown_visibility_fails_closed (monkeypatch ):
519+ class Info :
520+ private = None
521+
522+ class Api :
523+ def __init__ (self , * args , ** kwargs ):
524+ pass
525+
526+ def dataset_info (self , * args , ** kwargs ):
527+ return Info ()
528+
529+ monkeypatch .setattr (service , "HfApi" , Api , raising = False )
530+ with pytest .raises (RuntimeError , match = "privacy is unknown" ):
531+ service ._verify_remote_dataset_privacy ()
0 commit comments