The specimen is yours · pattern
The Archive That Disagrees With Itself
A ZIP keeps one central directory and a local file header beside every stored item. Those records repeat much of the same story. Drop an archive, Office document, EPUB, JAR, or APK and this page pairs the copies byte by byte, entirely inside your browser. A raw disagreement is not automatically an error: the published bit 3 rule requires three local zeros, and a generic ZIP has no universal conflict winner. A conformance verdict appears only when the package identifies itself as OPC.
The useful question is not whether the first four bytes say PK. It is whether the directory at the end points to complete local records, whether the sizes and CRCs agree after the one explicit exception is applied, and whether the bytes decompress to what either record promised.
The instrument is already running on a document made for this page. Bring nothing and every panel still works. Bring a file and the fixture steps aside. The complete file is read once into one ArrayBuffer. It is never uploaded, extracted to disk, executed, rendered as markup, placed in storage, or offered to any relationship target.
Layer one · the container
Open one ZIP-family file
Opening the published fixture anchor.
The complete byte map
Every central record, paired with its local header
The published anchor comes first
Three signatures, three fixed lengths, one exception
PKWARE APPNOTE 6.3.10 prints the local file header signature as 0x04034b50, the central file header signature as 0x02014b50, and End of Central Directory as 0x06054b50. Their fixed portions are respectively 30, 46, and 22 bytes, before their declared variable fields. Every multibyte integer used here is unsigned and little-endian.
Archive Fork A contains five original XML parts. Its word/document.xml entry sets general-purpose bit 3. The local header therefore stores CRC-32, compressed size, and uncompressed size as zero. The signed data descriptor after the stored bytes carries the values that agree with the central record. The three raw differences are an EXPECTED BIT 3 result, not a conflict.
This is the first check because it can fail in both directions. A checker that treats every unequal byte as corruption rejects a permitted package. A checker that simply trusts the directory accepts a contradictory package without noticing that the corresponding record said something else.
Reproduction · ECMA-376 Part 2 Annex B.2
Archive Fork A.docx through the same parser
The central directory is not called universally authoritative here, because APPNOTE does not appoint a universal winner for contradictory copies. Its authority is emergent rather than decreed: the directory is simply the only guaranteed way to enumerate an archive, since files may be stored in any order, a data descriptor may be unsigned, and the archive may sit behind a self-extracting stub. What follows from that is a distinction between classes of reader, not a rule about all readers. A random-access reader enumerates through the directory. A streaming or front-walking reader never sees the directory at all and takes the local record's word for it. A careful reader notices the disagreement and says so. For a generic ZIP this instrument reports UNEXPLAINED DIFFERENCE and stops, and it does not predict which of those a named extractor is.
ECMA-376 supplies the narrower rule for an Open Packaging Conventions package: corresponding appropriate values must be equal after the bit 3 data-descriptor case is resolved. That is why an OPC package can receive an Annex B.2 pass or fail while an APK cannot receive that verdict from this page. It also means a conforming Office document cannot disagree with itself in these fields, because Annex B.2 forbids it. Self-disagreement is a property of generic ZIP tooling and of packages that violate that clause, not of valid .docx files. So an Annex B.2 pass on a file your word processor wrote is the expected outcome and is close to no news at all. The informative outcomes are the failures, the entries the directory never mentions, and the differences a generic archive is free to carry.
Layer two · the package above ZIP
The directory is only the floor
A dismissal is available: these are duplicated bookkeeping fields, and a bookkeeping viewer has learned nothing about the document. So the next instrument follows the package's own declarations. It recognizes OPC only when [Content_Types].xml and _rels/.rels exist, carry the required package namespaces, and were safely decoded. Then it resolves internal relationship targets, keeps external targets inert, audits name equivalence and compression restrictions, and locates Word parts through relationships rather than guessed filenames.
OPC audit · structure, not extension
The abstract part graph
The selected specimen has not been audited yet.
An OPC syntax pass does not prove that Word, Excel, PowerPoint, an EPUB reader, Java, Android, or any other named product will accept the package. Those profiles add rules this page does not implement. XML is shown only as escaped text. Macros, scripts, SVG, HTML, media, and external relationship targets are never executed or requested.
WordprocessingML · cautious lineage signal
Compare a second .docx by revision identifiers
The fallback comparison uses Archive Fork B. The package is recognized from structure, not from this filename filter.
Comparing the two synthetic fixtures.
What an RSID can say, and what it cannot
ECMA-376 Part 1 section 17.15.1.70 says that identical revision identifiers in documents with the same rsidRoot indicate the same editing session. Archive Fork A and B use the synthetic root 10000001. They share session identifiers 10000001 and 10000002, then A alone carries 10000003 and B alone carries 10000004. The page displays those as unordered sets.
Spennemann and Spennemann used this signal in a 2023 proof of concept involving more than 400 related templates from one publisher. That work demonstrates a genealogy method in that corpus, not an error rate for arbitrary pairs. Spennemann and Singh reported in 2024 that Microsoft Word does not reliably follow the increasing-value rule. This instrument never sorts RSIDs into a chronology.
Visible and live
The check
Recomputing the fixture, current specimen, refusal cases, and free choices.
Every free choice
Every named uncertainty
- APPNOTE defines correspondence and record anatomy, but not one universal winner for contradictory generic ZIP records.
- A valid EOCD signature can occur inside comments or payload. Candidates are accepted only after their bounds, comment, directory range, entry count, and header walk validate.
- CRC-32 checks accidental integrity against a stored 32-bit value. It does not authenticate bytes or identify intent.
- Unsupported methods, encryption, split archives, compressed central directories, and values above safe JavaScript integer range remain metadata-only or are refused with the field and byte offset named.
- Relationship and content-type checks cover the OPC rules implemented here, not all of ECMA-376 or any product profile.
- RSIDs can collide, travel in templates, survive deleted content, arise from non-edit actions, or be changed deliberately. They are not a full revision log.
- OPC recognition requires each XML part to have exactly one document element, with nothing but whitespace outside it, decoded as strict UTF-8. A part encoded in UTF-16 is legal XML and is refused here rather than guessed at, so such a package is shown as a generic ZIP with no conformance verdict.
- Unreferenced local headers are looked for only in bytes that no paired record claims, between the start of the archive and the central directory, and only where a complete local header parses. Compressed payload is never scanned, so a hidden entry stored inside another entry's data is not found.
- The same file supplied as both RSID specimens is reported as no linkage result. Every identifier would be shared by construction, and a document compared with itself carries no information about lineage.
The privacy ledger
It records what this page's application code can observe. It does not cover browser extensions or the initial HTML request. Open the browser network panel if you want the independent view.
The deployed policy above is read back from the document: checking. The parser has no upload path. connect-src 'none' blocks application connections even if a later edit accidentally tries one.