Specification

9. Verify algorithm

verify checks a pack and returns a report with the keys sha256_ok, header_footer_agree, record_count{declared, actual}, appendix{present, file_checksum_ok, sections[{index, type, crc_ok}]}, embrefs{total, resolved, dangling, type_mismatch}. Opening a pack runs steps 1 to 8 by default; the caller may opt out explicitly.

Input: the bytes of a .plxi file. If they start with 1F 8B (gzip ID1, ID2 [RFC1952]), a reader MAY decompress them and continue with the result; .plxi.gz is a transport encoding only (§11).

  1. Size. L >= 353, else invalid_header.
  2. Header. Bytes 0..257 are ASCII, byte 256 is LF, and bytes 0..256 match header-content padding (§3.1): else invalid_header. A version other than 6: unsupported_version.
  3. Footer. Bytes L-96 .. L per the §10.0 table: magic PLXF, else invalid_footer; version 6, else unsupported_version; reserved bytes 44..64 all zero, else invalid_footer.
  4. Header against footer. Classify the header (§3.3). Final: records, csdt_offset, csdt_size, digest equal the footer's, else header_footer_mismatch. Placeholder: continue with the footer's values. Neither: header_footer_mismatch.
  5. Layout. With T = text_section_size, A = csdt_offset, C = csdt_size, all integers from the footer, compared without overflow:
    • 257 <= T <= L - 96, else invalid_footer;
    • C = 0: A = 0 and T = L - 96, else invalid_footer;
    • C > 0: A mod 64 = 0, else appendix_alignment; A = T rounded up to a multiple of 64 and A + C = L - 96, else invalid_footer; the padding bytes T .. A are all 0x00, else invalid_footer.
    • The checks above are made in 64-bit arithmetic, before any conversion to an in-memory index, so a layout that fails them is invalid_footer on every platform. Only a layout that passes them and still holds an offset or size that cannot be represented as an in-memory index on the platform (for example at or above 2^32 on a 32-bit target) fails, with limit_exceeded; it MUST NOT be truncated.
  6. Digest. SHA-256 of bytes 257 .. L-96 equals footer bytes 64..96, else checksum_mismatch.
  7. Body. Bytes 257 .. T are valid UTF-8, else invalid_utf8. When C > 0, the last line is the marker line, else invalid_record. Every other non-empty line parses as a record (§4), else json or invalid_record. A marker line elsewhere: invalid_record.
  8. Count. The number of record lines equals the footer's record_count, else record_count_mismatch.
  9. Appendix (Reader-Appendix, only when C > 0): open the container at bytes A .. A+C with the checks of §7.3; check every section's CRC32C; compare the footer's csdt_file_checksum with the container's file_checksum.
  10. Bindings (Reader-Appendix): for each local target (§5.4), section_index is below the section count and record_index is below that section's record_count; for each ext target, a csdt_ref record with that ref_id exists in the pack. Each failure counts as dangling. Verify reports counts; a consumer that binds a dangling target fails with dangling_embref.
    • Type check under the Compact embedding profile (the entity-embedding binding that importers use): a local target of an embref is expected to name a section of type Compact (0x0020) whose record_stride equals the Compact record size (320 bytes), with dtype RECORD. Verify counts mismatches in type_mismatch; a consumer that binds one fails with section_type_mismatch. The profile belongs to the consumer, not to the file format: other kinds of section are legal embref targets.
Reader-Core 1–8Reader-Appendix 9–10
  1. 1Sizeinvalid_header
  2. 2Headerinvalid_headerunsupported_version
  3. 3Footerinvalid_footerunsupported_version
  4. 4Header against footerheader_footer_mismatch
  5. 5Layoutinvalid_footerappendix_alignmentlimit_exceeded
  6. 6Digestchecksum_mismatch
  7. 7Bodyinvalid_utf8invalid_recordjson
  8. 8Countrecord_count_mismatch
  9. 9Appendixappendix_invalidappendix_crc_mismatchonly when the pack has an appendix
  10. 10Bindingsdangling_embrefsection_type_mismatchcounts only; a consumer that binds a failing target reports dangling_embref or section_type_mismatch
Figure 9-1. The ten verify steps in the order they run, each with the error kinds it can report. Opening a pack runs steps 1 to 8 by default.A verifier that stops at the first failure reports the kind of that first failure.

Steps run in this order. A verifier that stops at the first failure MUST report the kind of that first failure, so every conforming implementation reports the same kind for the same file. Reports for steps it did not reach are absent.

© 2020-2026 Cintile Inc. All Rights Reserved.

Anyone may implement this format. Copying or republishing the text of this specification requires permission from Cintile Inc.

Sections