@@ -58,6 +58,43 @@ def write_parquet(path: Path) -> None:
5858 pq .write_table (table , path )
5959
6060
61+ def write_parquet_with_family_side_channels (path : Path ) -> None :
62+ pa = pytest .importorskip ("pyarrow" )
63+ pq = pytest .importorskip ("pyarrow.parquet" )
64+ table = pa .table (
65+ {
66+ "token_ids" : pa .array (
67+ [
68+ [1 , 2 , 3 , 4 ],
69+ [5 , 6 , 7 , 8 ],
70+ [9 , 10 , 11 , 12 ],
71+ [13 , 14 , 15 , 16 ],
72+ ],
73+ type = pa .large_list (pa .uint32 ()),
74+ ),
75+ "token_symbol_ids" : pa .array (
76+ [
77+ [10 , 11 , 12 , 13 ],
78+ [14 , 15 , 16 , 17 ],
79+ [18 , 19 , 20 , 21 ],
80+ [22 , 23 , 24 , 25 ],
81+ ],
82+ type = pa .large_list (pa .int32 ()),
83+ ),
84+ "edit_op_per_token" : pa .array (
85+ [
86+ [0 , 0 , 2 , 2 ],
87+ [0 , 3 , 0 , 3 ],
88+ [1 , 1 , 0 , 0 ],
89+ [4 , 0 , 4 , 0 ],
90+ ],
91+ type = pa .large_list (pa .int32 ()),
92+ ),
93+ }
94+ )
95+ pq .write_table (table , path )
96+
97+
6198def run_script (* args : str ) -> subprocess .CompletedProcess [str ]:
6299 return subprocess .run (
63100 [sys .executable , str (SCRIPT ), * args ],
@@ -209,6 +246,8 @@ def test_parquet_smoke_reports_local_ingress_contract(tmp_path: Path) -> None:
209246 }
210247 ]
211248 assert payload ["side_channels" ] == []
249+ assert payload ["family_side_channels" ] == []
250+ assert payload ["family_side_channel_presence" ] == {}
212251 assert payload ["structure_side_channels" ] == []
213252 assert payload ["structure_side_channels_present" ] is False
214253 assert payload ["local_only" ] is True
@@ -218,6 +257,46 @@ def test_parquet_smoke_reports_local_ingress_contract(tmp_path: Path) -> None:
218257 assert payload ["training_wired" ] is False
219258
220259
260+ def test_parquet_smoke_reports_generic_family_side_channels (tmp_path : Path ) -> None :
261+ dataset_path = tmp_path / "family_side_channels.parquet"
262+ write_parquet_with_family_side_channels (dataset_path )
263+
264+ result = run_script (
265+ str (dataset_path ),
266+ "--token-key" ,
267+ "token_ids" ,
268+ "--batch-size" ,
269+ "2" ,
270+ "--seq-len" ,
271+ "4" ,
272+ "--forward-smoke" ,
273+ )
274+
275+ assert result .returncode == 0 , result .stderr
276+ payload = load_json (result )
277+ assert payload ["side_channels" ] == []
278+ assert payload ["family_side_channels" ] == ["semantic_graph" , "temporal_diff" ]
279+ assert payload ["family_side_channel_presence" ] == {
280+ "semantic_graph" : {"token_symbol_ids" : True },
281+ "temporal_diff" : {"edit_op_per_token" : True },
282+ }
283+ assert payload ["dataset" ]["parquet_receipt" ]["family_side_channel_sources" ] == {
284+ "semantic_graph" : {
285+ "token_symbol_ids" : {
286+ "column" : "token_symbol_ids" ,
287+ "type" : "large_list<element: int32>" ,
288+ }
289+ },
290+ "temporal_diff" : {
291+ "edit_op_per_token" : {
292+ "column" : "edit_op_per_token" ,
293+ "type" : "large_list<element: int32>" ,
294+ }
295+ },
296+ }
297+ assert payload ["forward" ]["side_channel_model_kwargs" ] == []
298+
299+
221300def test_megatron_multishard_smoke_reports_side_channels (tmp_path : Path ) -> None :
222301 _write_structured_multishard_fixture (
223302 tmp_path ,
0 commit comments