1use crate::container_10d::header::{Container10dHeader, HEADER_BYTE_SIZE};
34use crate::container_10d::mesh_section::{MeshMiniHeader, MESH_MINI_HEADER_SIZE};
35use crate::container_10d::metric_check::MetricBranchDescriptor;
36use crate::container_10d::node_section::{NodeMiniHeader, NODE_MINI_HEADER_SIZE, TENSOR10D_SIZE};
37use crate::container_10d::section::{SectionDescriptor, SECTION_DESCRIPTOR_SIZE};
41
42pub fn assert_layout_invariants() {
51 assert_eq!(std::mem::size_of::<Container10dHeader>(), 64, "header size");
53 assert_eq!(
54 std::mem::offset_of!(Container10dHeader, magic),
55 0,
56 "header.magic offset"
57 );
58 assert_eq!(
59 std::mem::offset_of!(Container10dHeader, version),
60 4,
61 "header.version offset"
62 );
63 assert_eq!(
64 std::mem::offset_of!(Container10dHeader, flags),
65 6,
66 "header.flags offset"
67 );
68 assert_eq!(
69 std::mem::offset_of!(Container10dHeader, axis_roles),
70 8,
71 "header.axis_roles offset"
72 );
73 assert_eq!(
74 std::mem::offset_of!(Container10dHeader, pad0),
75 18,
76 "header.pad0 offset"
77 );
78 assert_eq!(
79 std::mem::offset_of!(Container10dHeader, metric_descriptor),
80 20,
81 "header.metric_descriptor offset"
82 );
83 assert_eq!(
84 std::mem::offset_of!(Container10dHeader, header_crc32c),
85 52,
86 "header.header_crc32c offset"
87 );
88 assert_eq!(
89 std::mem::offset_of!(Container10dHeader, section_table_offset),
90 56,
91 "header.section_table_offset offset"
92 );
93 assert_eq!(
94 std::mem::offset_of!(Container10dHeader, section_count),
95 60,
96 "header.section_count offset"
97 );
98
99 assert_eq!(
101 std::mem::size_of::<MetricBranchDescriptor>(),
102 8,
103 "metric_branch_descriptor size"
104 );
105
106 assert_eq!(
108 std::mem::size_of::<SectionDescriptor>(),
109 24,
110 "section_descriptor size"
111 );
112 assert_eq!(
113 std::mem::offset_of!(SectionDescriptor, section_type),
114 0,
115 "section_descriptor.section_type offset"
116 );
117 assert_eq!(
118 std::mem::offset_of!(SectionDescriptor, alignment_tier),
119 1,
120 "section_descriptor.alignment_tier offset"
121 );
122 assert_eq!(
123 std::mem::offset_of!(SectionDescriptor, reserved16),
124 2,
125 "section_descriptor.reserved16 offset"
126 );
127 assert_eq!(
128 std::mem::offset_of!(SectionDescriptor, byte_offset),
129 4,
130 "section_descriptor.byte_offset offset"
131 );
132 assert_eq!(
133 std::mem::offset_of!(SectionDescriptor, byte_length),
134 8,
135 "section_descriptor.byte_length offset"
136 );
137 assert_eq!(
138 std::mem::offset_of!(SectionDescriptor, stride),
139 12,
140 "section_descriptor.stride offset"
141 );
142 assert_eq!(
143 std::mem::offset_of!(SectionDescriptor, element_count),
144 16,
145 "section_descriptor.element_count offset"
146 );
147 assert_eq!(
148 std::mem::offset_of!(SectionDescriptor, crc32c),
149 20,
150 "section_descriptor.crc32c offset"
151 );
152
153 assert_eq!(
155 std::mem::size_of::<NodeMiniHeader>(),
156 16,
157 "node_mini_header size"
158 );
159 assert_eq!(
160 std::mem::offset_of!(NodeMiniHeader, node_count),
161 0,
162 "node_mini_header.node_count offset"
163 );
164 assert_eq!(
165 std::mem::offset_of!(NodeMiniHeader, layout),
166 4,
167 "node_mini_header.layout offset"
168 );
169 assert_eq!(
170 std::mem::offset_of!(NodeMiniHeader, reserved_u8),
171 5,
172 "node_mini_header.reserved_u8 offset"
173 );
174 assert_eq!(
175 std::mem::offset_of!(NodeMiniHeader, reserved_u16),
176 6,
177 "node_mini_header.reserved_u16 offset"
178 );
179 assert_eq!(
180 std::mem::offset_of!(NodeMiniHeader, reserved_u64),
181 8,
182 "node_mini_header.reserved_u64 offset"
183 );
184
185 assert_eq!(
187 std::mem::size_of::<MeshMiniHeader>(),
188 40,
189 "mesh_mini_header size"
190 );
191 assert_eq!(
192 std::mem::offset_of!(MeshMiniHeader, flags),
193 0,
194 "mesh_mini_header.flags offset"
195 );
196 assert_eq!(
197 std::mem::offset_of!(MeshMiniHeader, reserved_u16),
198 2,
199 "mesh_mini_header.reserved_u16 offset"
200 );
201 assert_eq!(
202 std::mem::offset_of!(MeshMiniHeader, vertex_count),
203 4,
204 "mesh_mini_header.vertex_count offset"
205 );
206 assert_eq!(
207 std::mem::offset_of!(MeshMiniHeader, triangle_count),
208 8,
209 "mesh_mini_header.triangle_count offset"
210 );
211 assert_eq!(
212 std::mem::offset_of!(MeshMiniHeader, min),
213 12,
214 "mesh_mini_header.min offset"
215 );
216 assert_eq!(
217 std::mem::offset_of!(MeshMiniHeader, max),
218 24,
219 "mesh_mini_header.max offset"
220 );
221 assert_eq!(
222 std::mem::offset_of!(MeshMiniHeader, reserved_u32),
223 36,
224 "mesh_mini_header.reserved_u32 offset"
225 );
226
227 assert_eq!(HEADER_BYTE_SIZE, 64, "HEADER_BYTE_SIZE");
229 assert_eq!(SECTION_DESCRIPTOR_SIZE, 24, "SECTION_DESCRIPTOR_SIZE");
230 assert_eq!(NODE_MINI_HEADER_SIZE, 16, "NODE_MINI_HEADER_SIZE");
231 assert_eq!(MESH_MINI_HEADER_SIZE, 40, "MESH_MINI_HEADER_SIZE");
232 assert_eq!(TENSOR10D_SIZE, 40, "TENSOR10D_SIZE");
233}
234
235pub const GOLDEN_BARE_HEADER: [u8; HEADER_BYTE_SIZE] = [
267 0x31, 0x30, 0x64, 0x00, 0x01, 0x00, 0x01, 0x00,
271 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x00, 0x00,
276 0x00, 0x01, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00,
280 0x01, 0x02, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x02, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0xFF, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293];
294
295pub const GOLDEN_BARE_HEADER_CRC: u32 = 0xD6DD_ABF5; pub const GOLDEN_NODE_ONLY_CRC: u32 = 0x6865_D565; pub const GOLDEN_MESH_ONLY_CRC: u32 = 0x18B5_DD86; #[cfg(test)]
316mod tests {
317 use super::*;
318 use crate::container_10d::crc32c::crc32c;
319 use crate::container_10d::header::Container10dHeader;
320 use crate::container_10d::integrity::{seal_whole_file_crc32c, verify_whole_file_crc32c};
321 use crate::container_10d::node_section::{read_node, write_node_section_aos, NodeMiniHeader};
322 use crate::container_10d::section::{
323 encode_container, parse_section_table, AlignmentTier, SectionInput, SectionType,
324 };
325 use crate::tensor::Tensor10D;
326
327 #[test]
332 fn layout_invariants_hold() {
333 assert_layout_invariants();
334 }
335
336 #[test]
341 fn golden_bare_header_reproduces_byte_identical() {
342 let actual_crc = crc32c(&GOLDEN_BARE_HEADER);
344 assert_eq!(
345 actual_crc, GOLDEN_BARE_HEADER_CRC,
346 "golden bare header CRC-32C must match the pinned value; \
347 if you changed the header encoding, update both the golden bytes \
348 AND the pinned CRC, or bump the version"
349 );
350 let parsed =
352 Container10dHeader::parse(&GOLDEN_BARE_HEADER).expect("golden bare header must parse");
353 let mut reencoded = [0u8; HEADER_BYTE_SIZE];
355 parsed.encode(&mut reencoded);
356 assert_eq!(
358 &reencoded[..],
359 &GOLDEN_BARE_HEADER[..],
360 "re-encoding the decoded golden bare header must reproduce the \
361 golden bytes exactly (encode∘decode = identity)"
362 );
363 let reparsed = Container10dHeader::parse(&reencoded).expect("re-encoded must parse");
365 assert_eq!(parsed, reparsed);
366 }
367
368 #[test]
369 fn golden_bare_header_matches_proposed() {
370 let proposed = Container10dHeader::proposed();
374 let mut proposed_bytes = [0u8; HEADER_BYTE_SIZE];
375 proposed.encode(&mut proposed_bytes);
376 assert_eq!(
377 &proposed_bytes[..],
378 &GOLDEN_BARE_HEADER[..],
379 "Container10dHeader::proposed() must produce the golden bare header bytes; \
380 if the proposed defaults changed, update the golden vector"
381 );
382 }
383
384 #[test]
385 fn golden_node_only_container_round_trips_byte_identical() {
386 let tensors = [
389 Tensor10D::new(0.0, 0.0, 0.0, 0.1, 0.2, 0.3, 0.0, 1.0, 0.0, 0.5),
390 Tensor10D::new(0.5, 1.0, 2.0, 0.4, 0.5, 0.6, 1.0, 0.8, 0.2, 0.75),
391 Tensor10D::new(999.0, 2.0, 3.0, 0.7, 0.8, 0.9, 2.0, 0.6, 0.9, 0.25),
392 ];
393 let node_need = NodeMiniHeader::payload_bytes(tensors.len());
394 let mut node_payload = vec![0u8; node_need];
395 write_node_section_aos(&tensors, &mut node_payload).expect("node write");
396
397 let h = Container10dHeader::proposed();
398 let inputs = [SectionInput {
399 section_type: SectionType::Tensor10DNodes,
400 alignment_tier: AlignmentTier::CacheLine,
401 stride: 0,
402 element_count: 0,
403 payload: &node_payload,
404 }];
405 let mut out = vec![0u8; 512];
406 let n = encode_container(&h, &inputs, &mut out).expect("container encode");
407 seal_whole_file_crc32c(&mut out[..n]);
408
409 verify_whole_file_crc32c(&mut out[..n]).expect("whole-file CRC must verify");
411
412 let parsed_h = Container10dHeader::parse(&out[..n]).expect("header parse");
414 let descs = parse_section_table(&out[..n], &parsed_h).expect("table parse");
415 assert_eq!(descs.len(), 1);
416 assert_eq!(descs[0].section_type, SectionType::Tensor10DNodes as u8);
417 let p_off = descs[0].byte_offset as usize;
418 let p_len = descs[0].byte_length as usize;
419 let node_payload_back = &out[p_off..p_off + p_len];
420 for i in 0..tensors.len() {
421 let t = read_node(node_payload_back, i).expect("node read");
422 assert_eq!(t, tensors[i], "node {i} must round-trip");
423 }
424
425 let mut reencoded = vec![0u8; 512];
427 let n2 = encode_container(&parsed_h, &inputs, &mut reencoded).expect("re-encode");
428 seal_whole_file_crc32c(&mut reencoded[..n2]);
429
430 assert_eq!(n, n2, "re-encode must produce the same byte count");
432 assert_eq!(
433 &out[..n],
434 &reencoded[..n2],
435 "re-encoding the decoded NODE-only container must reproduce the \
436 golden bytes exactly (encode∘decode = identity)"
437 );
438
439 let pinned_crc = crc32c(&out[..n]);
443 if GOLDEN_NODE_ONLY_CRC != 0 {
447 assert_eq!(
448 pinned_crc, GOLDEN_NODE_ONLY_CRC,
449 "golden NODE-only container CRC-32C must match the pinned value"
450 );
451 } else {
452 eprintln!(
456 "[conformance] golden NODE-only container CRC-32C = {pinned_crc:#010x}; \
457 pin this value in GOLDEN_NODE_ONLY_CRC to activate the double-lock gate"
458 );
459 }
460 }
461
462 #[test]
467 fn golden_mesh_container_round_trips_byte_identical() {
468 use crate::container_10d::mesh_section::{decode_mesh_section, encode_mesh_section};
469 use crate::render::assets::Mesh;
470
471 let positions = vec![
473 [0.0, 0.0, 0.0],
474 [1.0, 0.0, 0.0],
475 [1.0, 1.0, 0.0],
476 [0.0, 1.0, 0.0],
477 [0.0, 0.0, 1.0],
478 [1.0, 0.0, 1.0],
479 [1.0, 1.0, 1.0],
480 [0.0, 1.0, 1.0],
481 ];
482 let triangles = vec![
483 [0, 1, 2],
484 [0, 2, 3],
485 [4, 5, 6],
486 [4, 6, 7],
487 [0, 1, 5],
488 [0, 5, 4],
489 [2, 3, 7],
490 [2, 7, 6],
491 [1, 2, 6],
492 [1, 6, 5],
493 [0, 3, 7],
494 [0, 7, 4],
495 ];
496 let mesh = Mesh {
497 positions,
498 triangles,
499 min: [0.0; 3],
500 max: [1.0; 3],
501 };
502
503 let mesh_need = crate::container_10d::mesh_section::encoded_len(8, 12);
504 let mut mesh_payload = vec![0u8; mesh_need];
505 encode_mesh_section(&mesh, &mut mesh_payload).expect("mesh encode");
506
507 let h = Container10dHeader::proposed();
508 let inputs = [SectionInput {
509 section_type: SectionType::QuantizedMesh,
510 alignment_tier: AlignmentTier::Word,
511 stride: 0,
512 element_count: 0,
513 payload: &mesh_payload,
514 }];
515 let mut out = vec![0u8; 512];
516 let n = encode_container(&h, &inputs, &mut out).expect("container encode");
517 seal_whole_file_crc32c(&mut out[..n]);
518 verify_whole_file_crc32c(&mut out[..n]).expect("whole-file CRC");
519
520 let parsed_h = Container10dHeader::parse(&out[..n]).expect("header parse");
522 let descs = parse_section_table(&out[..n], &parsed_h).expect("table parse");
523 assert_eq!(descs.len(), 1);
524 assert_eq!(descs[0].section_type, SectionType::QuantizedMesh as u8);
525 let p_off = descs[0].byte_offset as usize;
526 let p_len = descs[0].byte_length as usize;
527 let mesh_back = decode_mesh_section(&out[p_off..p_off + p_len]).expect("mesh decode");
528 assert_eq!(
529 mesh_back.triangles, mesh.triangles,
530 "indices exact through container"
531 );
532
533 let mut reencoded = vec![0u8; 512];
535 let n2 = encode_container(&parsed_h, &inputs, &mut reencoded).expect("re-encode");
536 seal_whole_file_crc32c(&mut reencoded[..n2]);
537
538 assert_eq!(n, n2, "re-encode must produce the same byte count");
540 assert_eq!(
541 &out[..n],
542 &reencoded[..n2],
543 "re-encoding the decoded MESH-only container must reproduce the \
544 golden bytes exactly (encode∘decode = identity)"
545 );
546
547 let pinned_crc = crc32c(&out[..n]);
549 if GOLDEN_MESH_ONLY_CRC != 0 {
550 assert_eq!(
551 pinned_crc, GOLDEN_MESH_ONLY_CRC,
552 "golden MESH-only container CRC-32C must match the pinned value"
553 );
554 } else {
555 eprintln!(
556 "[conformance] golden MESH-only container CRC-32C = {pinned_crc:#010x}; \
557 pin this value in GOLDEN_MESH_ONLY_CRC to activate the double-lock gate"
558 );
559 }
560 }
561
562 #[test]
571 fn conformance_harness_confirms_metric_descriptor_is_honest() {
572 use crate::container_10d::metric_check::verify_descriptor_against_reality;
573 let h = Container10dHeader::proposed();
574 verify_descriptor_against_reality(&h.metric_descriptor)
575 .expect("the proposed header's metric descriptor must match full_distance reality");
576 }
577}