--- slug: the-archive-that-disagrees-with-itself passed: 2026-10-18 by: the assay line (research/assay-line/queue-1018/), Codex fixer directed by claude-assaying-boyle-1014; source record by Codex, checked by Codex checked: 187 confirmed: 176 wrong: 10 unverifiable: 0 observed: 0 stale: 1 --- This was the tier A decide-and-fix pass for queue-1018, read at fbe74aba11. All ten original triage findings were decided from re-read evidence before the layer was edited; the omitted verifier finding in N2 was added as X11 and decided in the same step. The fixer reproduced the parser and rendered-output counterexamples, repaired the accepted findings, and retained below the 176 CONFIRMED claims and evidence the Codex checker had re-read. Those retained checks are attributed to N2 rather than represented as 176 new source fetches. The five MINOR findings count toward wrong in this record; only the five WRONG findings receive page correction lines. The assay date requested for this pass is 2026-10-18; the supplied source and checker records retain their own 2026-10-19 fetch/pass dates. ## Claims - WRONG | OPC recognition requires each XML part to have exactly one document element, with nothing but whitespace outside it, decoded as strict UTF-8. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [X1; recognition-scans-every-xml-part] Read archive.mjs:628-639 and 671-698 at fbe74aba11. Recognition scans only ctEntry and relEntry before "audit.recognized = true"; later loops scan relationships and the selected Word main/settings parts. Re-ran the checker probe against this working tree: adding extra.xml containing "" yields recognized:true, verdict:PASS, errors:[]. The original fixture passes and two roots in the recognition parts prevent recognition. Fix the page to name the two recognition parts and the later scan scope, including the matching historical explanation. Do not extend recognition to all XML parts. - WRONG | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [X2; utf16-always-means-generic-zip] Read archive.mjs:635-639 and 693-698: recognition is already true when the later catch adds "WordprocessingML XML refused: ". Recreated three outcomes: UTF-16 extra.xml passes, UTF-16 word/document.xml remains recognized and fails, and recognition-part scan failures return before recognition. W3C XML 1.0 fifth edition, section 2.2, says "All XML processors MUST accept the UTF-8 and UTF-16 encodings of Unicode". Preserve UTF-16 legality and describe the actual three outcomes, without suggesting a universal generic-ZIP result. - WRONG | XML stops at 1000 parts and 10 MiB per text part; relationship traversal is non-recursive here and bounded at 128 if extended. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [X3; xml-limits-applied-to-every-part] Read archive.mjs:12-19 and 671-698. The relationship-part counter advances only after entries without a relationship source or decoded content have been skipped; its error says "relationship XML part count exceeds". A recreated archive with 1006 XML parts passes; only relationship parts count toward 1000. The 10 MiB checks apply to the recognition, scanned relationship, and selected Word parts. Searched the complete layer code: relationshipDepth:128 is declared but never used. Fix the scope of the page limits and describe 128 as unused; also replace the verifier assertion label "all seven hard limits" with a description of declared values. - MINOR | APPNOTE 4.3.6 places the ZIP64 EOCD record and its locator between the directory and the EOCD, so that arithmetic was wrong by 76 bytes for every genuine ZIP64 archive and refused all of them. | git show a77c45dd68:memory/log.d/2026-08-09T1900Z-the-specimen-is-yours.md; https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [X4; zip64-gap-always-76-bytes] Re-read APPNOTE 6.3.10 sections 4.3.14 and 4.3.15 and the dated build log at memory/log.d/2026-08-09T1900Z-the-specimen-is-yours.md:100-107. APPNOTE includes "zip64 extensible data sector (variable size)". The fixed record widths total 56 bytes, and the locator is 20 bytes, so 76 is a minimum, not a universal size. Keep MINOR as the checker's numeric precision finding: qualify the page to at least 76 bytes without changing the recorded historical defect. Do not edit the log. - MINOR | Dirk H. R. Spennemann and Claire L. Singh (2024). “The Generation of Revision Identifier (rsid) Numbers in MS Word: Implications for Document Analysis,” International Journal of Digital Curation 18(1). Used for experimental limits, especially the unreliable increasing-value rule and non-edit events. | https://ijdc.net/index.php/ijdc/article/download/870/685/3282 | [X5; singh-given-name-spelling] Fetched the journal PDF and read its first page with pdftotext. The author line reads "Clare L. Singh"; the footer agrees with the existing year and journal volume. This is a cheap citation spelling repair under MINOR. Restore Clare in the HTML citation and the layer README; the paper title is unchanged. - MINOR | Part 2 normatively cites APPNOTE 6.2.0 | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [X6; opc-reference-excerpt-mismatch] Read the retained extraction of ECMA-376 Part 2 fifth edition, clause 2, printed page 3: "ZIP Appnote, ZIP File Format Specification Version 6.2.0, PKWARE Inc., 2004." Read the N1 entry opc-normative-version: its excerpt instead names W3C XML Schema Structures and its locator says page 2. The page claim is true. Fix only that source-record excerpt and locator, preserving the source's exact words; no page correction is warranted. - MINOR | APPNOTE 4.3.2 gives each central header its own local header. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [X7; pairing-policy-attributed-to-appnote] Re-read APPNOTE 6.3.10 section 4.3.2: each local header must have "a corresponding central directory header". It does not expressly state the reverse uniqueness rule attributed to it. Read archive.mjs:334-345 and 664 and page.mjs:181: uniqueness is this checker's policy. Keep MINOR for the loose attribution; name the policy in the rendered explanation, the OPC diagnostic and the code comment, without changing distinct-header counting. - WRONG | UTF-8 flag is set but the item name is not valid UTF-8: | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [X8; utf8-warning-invents-set-flag] Read archive.mjs:655: the condition is only "if (!entry.central.nameDecodeValid)" and does not test bit 11. Recreated forced UTF-8 filename decoding with flags 0 and 2048; both print "UTF-8 flag is set" for bytes e9 2e 78 6d 6c. Upgrade MINOR to WRONG because the flags-0 case makes a concrete false statement about stored bytes, rather than an imprecise description of checking. Replace it with a diagnostic about invalid UTF-8 under the selected decoding and add a dated correction. - STALE | "dateModified":"2026-08-09T00:00:00Z" | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/index.html; git show d4840e62371; git show 2e60bcb5dd1 | [X9; stale-jsonld-modification-date] Read index.html:29 and the layer diffs named by the checker: d4840e62371 adds the verification paragraph and 2e60bcb5dd1 changes the image metadata after the original publication. Set dateModified to the assay date 2026-10-18T00:00:00Z and retain datePublished. This is the explicit JSON-LD STALE exception: decision fix, no Updated line. It is the only STALE item, so no other stale findings need a grouped Updated line. - WRONG | (added) Complete. 2 central records paired with 2 local headers. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [X10; status-counts-central-records-as-local-headers] Read page.mjs:118: the status concatenates "currentParsed.entries.length" for both counts, while renderResult uses parsed.distinctLocals. Recreated makeDuplicatePairing(): status says "2 central records paired with 2 local headers" but the parser and summary show one distinct local header. Positive control: the default fixture has five central records and five distinct local headers. Fix the status to use distinctLocals and name distinct local headers, and add a dated correction. - MINOR | The verifier checks the published header-length figures in the sentence that states them. | research/assay-line/queue-1018/the-archive-that-disagrees-with-itself/N2-codex.md; research/the-archive-that-disagrees-with-itself/verify-the-archive-that-disagrees-with-itself.mjs:394 | [X11; anchor-number-check-is-unscoped] Read the verifier at line 394: it uses "must(html,shown" for bare numbers anywhere in the HTML. Re-ran a scratch copy against the current files with only the published fixed-length sentence changed from 30 to 31: it still reported "PASS 344/344" and "55/55 live checks pass". Added this omitted N2 finding before editing. Classify it MINOR under the rule for overclaims about the page's own checking. A small fix extracts the numbers from their specific signature and length sentences and compares them with the published layouts; add no dated page line. - CONFIRMED | A ZIP keeps one central directory and a local file header beside every stored item. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-00-00] APPNOTE 4.3.1 says "only one" end record; 4.3.2 says each file "MUST be preceded by" a local header with a corresponding central header. - CONFIRMED | Those records repeat much of the same story. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-00-01] The recorded excerpt establishes correspondence, not the repeated field list. Read APPNOTE 4.3.7 and 4.3.12 directly: both list "general purpose bit flag", "compression method", "crc-32", and both sizes. - CONFIRMED | Drop an archive, Office document, EPUB, JAR, or APK and this page pairs the copies byte by byte, entirely inside your browser. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-00-02] page.mjs:537 reads "new Uint8Array(await f.arrayBuffer())"; loadBytes calls inspect locally. No application network API is invoked by this path. CSP and the zero application-send counters corroborate it. - CONFIRMED | 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. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-00-03] APPNOTE 4.4.4: "the fields crc-32, compressed size and uncompressed size are set to zero in the local header." The record includes this as an additional excerpt for prose-00-03. Generic conflict handling is a reader policy, not an APPNOTE universal priority rule. - CONFIRMED | A conformance verdict appears only when the package identifies itself as OPC. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-00-04] page.mjs:187 gates the verdict on "parsed.opc.recognized"; otherwise it prints "GENERIC ZIP VIEW." archive.mjs:849 assigns "NOT AN OPC VERDICT" when recognition fails. A filename extension alone does not select this branch. - CONFIRMED | The instrument is already running on a document made for this page. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-02-00] Recreated with node audit-probes.mjs: "default live score: 55/55 live checks pass." start() wires the controls and calls "loadBytes(makeFixture('A'),...)" without a file input. - CONFIRMED | Bring a file and the fixture steps aside. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-02-02] loadBytes at page.mjs:96 replaces the held specimen with "currentBase = bytes.slice(); currentName = name". The duplicate and truncated-file inputs exercised the replacement path. - CONFIRMED | The complete file is read once into one ArrayBuffer. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-02-03] The input handler at page.mjs:537 makes one "await f.arrayBuffer()" call per accepted file. Later Uint8Array copies do not reread the file; this sentence describes the read, not total allocated memory. - CONFIRMED | It is never uploaded, extracted to disk, executed, rendered as markup, placed in storage, or offered to any relationship target. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-02-04] page.mjs:58 assigns "node.textContent = text"; the XML viewer at line 277 also uses textContent. Input inspection never opens relationship targets. Downloads use generated fixture Blobs, not extraction of the supplied archive. The input handlers do not store or execute file contents. - CONFIRMED | 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. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-03-00] Directly read APPNOTE 4.3.7, 4.3.12, and 4.3.16: "0x04034b50", "0x02014b50", and "0x06054b50" respectively. - CONFIRMED | Their fixed portions are respectively 30, 46, and 22 bytes, before their declared variable fields. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-03-01] Summing the published widths gives local 4+5*2+3*4+2*2=30, central 4+6*2+3*4+5*2+2*4=46, and EOCD 4+4*2+2*4+2=22. These are fixed portions, not whole records. - CONFIRMED | Every multibyte integer used here is unsigned and little-endian. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-03-02] archive.mjs:71-83 uses u16, u32, and u64; u32 ends ">>> 0", and u64 combines low and high unsigned words as BigInt. APPNOTE 4.4.1.1 also specifies unsigned little-endian fields. - CONFIRMED | This is the first check because it can fail in both directions. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-05-00] The original fixture passes with three raw unequal fields, while the single-byte name and CRC mutations fail. Baseline output: "mutations: local-name unexplained 1; central-CRC unexplained 3; central-CRC failures 1". These sentences describe why both comparison directions matter. - CONFIRMED | A checker that treats every unequal byte as corruption rejects a permitted package. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-05-01] The original fixture passes with three raw unequal fields, while the single-byte name and CRC mutations fail. Baseline output: "mutations: local-name unexplained 1; central-CRC unexplained 3; central-CRC failures 1". These sentences describe why both comparison directions matter. - CONFIRMED | A checker that simply trusts the directory accepts a contradictory package without noticing that the corresponding record said something else. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-05-02] The original fixture passes with three raw unequal fields, while the single-byte name and CRC mutations fail. Baseline output: "mutations: local-name unexplained 1; central-CRC unexplained 3; central-CRC failures 1". These sentences describe why both comparison directions matter. - CONFIRMED | The central directory is not called universally authoritative here, because APPNOTE does not appoint a universal winner for contradictory copies. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-06-00] Read APPNOTE 4.3 and 4.4, including correspondence, descriptor exceptions and masking. No general conflict-winner rule is specified there. Exact searches for "universal winner" and "authoritative" give zero; the same case-insensitive search finds "central directory" 141 times and the expected 4.3.2 correspondence clause. This is a scoped reading of the specification, not a claim that no consumer chooses a winner. - CONFIRMED | 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. | https://commons.apache.org/proper/commons-compress/zip.html | [prose-06-01] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | What follows from that is a distinction between classes of reader, not a rule about all readers. | https://commons.apache.org/proper/commons-compress/zip.html | [prose-06-02] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | A random-access reader enumerates through the directory. | https://commons.apache.org/proper/commons-compress/zip.html | [prose-06-03] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | A streaming or front-walking reader never sees the directory at all and takes the local record's word for it. | https://commons.apache.org/proper/commons-compress/zip.html | [prose-06-04] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | A careful reader notices the disagreement and says so. | https://commons.apache.org/proper/commons-compress/zip.html | [prose-06-05] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | For a generic ZIP this instrument reports UNEXPLAINED DIFFERENCE and stops, and it does not predict which of those a named extractor is. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-06-06] page.mjs:187 gates the verdict on "parsed.opc.recognized"; otherwise it prints "GENERIC ZIP VIEW." archive.mjs:849 assigns "NOT AN OPC VERDICT" when recognition fails. A filename extension alone does not select this branch. - CONFIRMED | 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. | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [prose-07-00] ECMA-376 Part 2, normative Annex B.2, p. 63: "shall ensure that the ZIP file holds equal values in the appropriate fields" of corresponding records, with the Table B.5 bit 3 exception. B.3 permits the optional descriptor signature. The claims concern the stated comparable fields, not all possible package validation. - CONFIRMED | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-07-01] page.mjs:187 gates the verdict on "parsed.opc.recognized"; otherwise it prints "GENERIC ZIP VIEW." archive.mjs:849 assigns "NOT AN OPC VERDICT" when recognition fails. A filename extension alone does not select this branch. - CONFIRMED | It also means a conforming Office document cannot disagree with itself in these fields, because Annex B.2 forbids it. | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [prose-07-02] ECMA-376 Part 2, normative Annex B.2, p. 63: "shall ensure that the ZIP file holds equal values in the appropriate fields" of corresponding records, with the Table B.5 bit 3 exception. B.3 permits the optional descriptor signature. The claims concern the stated comparable fields, not all possible package validation. - CONFIRMED | Self-disagreement is a property of generic ZIP tooling and of packages that violate that clause, not of valid .docx files. | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [prose-07-03] ECMA-376 Part 2, normative Annex B.2, p. 63: "shall ensure that the ZIP file holds equal values in the appropriate fields" of corresponding records, with the Table B.5 bit 3 exception. B.3 permits the optional descriptor signature. The claims concern the stated comparable fields, not all possible package validation. - CONFIRMED | 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. | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [prose-07-04] ECMA-376 Part 2, normative Annex B.2, p. 63: "shall ensure that the ZIP file holds equal values in the appropriate fields" of corresponding records, with the Table B.5 bit 3 exception. B.3 permits the optional descriptor signature. The claims concern the stated comparable fields, not all possible package validation. - CONFIRMED | The informative outcomes are the failures, the entries the directory never mentions, and the differences a generic archive is free to carry. | https://ecma-international.org/wp-content/uploads/ECMA-376-2_5th_edition_december_2021.zip | [prose-07-05] ECMA-376 Part 2, normative Annex B.2, p. 63: "shall ensure that the ZIP file holds equal values in the appropriate fields" of corresponding records, with the Table B.5 bit 3 exception. B.3 permits the optional descriptor signature. The claims concern the stated comparable fields, not all possible package validation. - CONFIRMED | A dismissal is available: these are duplicated bookkeeping fields, and a bookkeeping viewer has learned nothing about the document. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-08-00] This is an expressly offered interpretation ("A dismissal is available"), not an attributed empirical result. The duplicated bookkeeping fields are supported by APPNOTE 4.3.7 and 4.3.12. - CONFIRMED | So the next instrument follows the package's own declarations. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-08-01] auditOpc at archive.mjs:628-639 looks up "[Content_Types].xml" and "_rels/.rels", decodes and scans both, checks their document elements and namespaces, then sets "audit.recognized = true". Extension filters are not used for recognition. - CONFIRMED | It recognizes OPC only when [Content_Types].xml and _rels/.rels exist, carry the required package namespaces, and were safely decoded. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-08-02] auditOpc at archive.mjs:628-639 looks up "[Content_Types].xml" and "_rels/.rels", decodes and scans both, checks their document elements and namespaces, then sets "audit.recognized = true". Extension filters are not used for recognition. - CONFIRMED | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-08-03] archive.mjs:616-625 resolves internal targets; line 680 sets the external resolution to null. Lines 686-697 select officeDocument and settings relationships and the main content type. Lines 651-669 inspect names, methods and paired values. - CONFIRMED | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-09-00] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | Those profiles add rules this page does not implement. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-09-01] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | XML is shown only as escaped text. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-09-02] page.mjs:58 assigns "node.textContent = text"; the XML viewer at line 277 also uses textContent. Input inspection never opens relationship targets. Downloads use generated fixture Blobs, not extraction of the supplied archive. The input handlers do not store or execute file contents. - CONFIRMED | Macros, scripts, SVG, HTML, media, and external relationship targets are never executed or requested. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-09-03] page.mjs:58 assigns "node.textContent = text"; the XML viewer at line 277 also uses textContent. Input inspection never opens relationship targets. Downloads use generated fixture Blobs, not extraction of the supplied archive. The input handlers do not store or execute file contents. - CONFIRMED | The fallback comparison uses Archive Fork B. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-10-00] page.mjs:353 calls "inspect(makeFixture('B'))" for the fallback second specimen. - CONFIRMED | The package is recognized from structure, not from this filename filter. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-10-01] auditOpc at archive.mjs:628-639 looks up "[Content_Types].xml" and "_rels/.rels", decodes and scans both, checks their document elements and namespaces, then sets "audit.recognized = true". Extension filters are not used for recognition. - CONFIRMED | 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. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [prose-11-00] ECMA-376 Part 1, 17.15.1.70, pp. 1059-1060: "An identical rsid value between two documents with the same rsidRoot" indicates the same sessions; meanings across different roots are not defined. The surrounding note expressly permits independent collisions. These are qualified linkage semantics, not an identity proof. - CONFIRMED | Spennemann and Spennemann used this signal in a 2023 proof of concept involving more than 400 related templates from one publisher. | https://mdpi-res.com/d_attachment/publications/publications-11-00035/article_deploy/publications-11-00035.pdf | [prose-12-00] The 2023 paper abstract says "over 400 template files generated by a single publisher" and calls the study a "proof-of-concept". Author names, title, year, journal, volume and issue also agree with the PDF and Crossref. - CONFIRMED | That work demonstrates a genealogy method in that corpus, not an error rate for arbitrary pairs. | https://mdpi-res.com/d_attachment/publications/publications-11-00035/article_deploy/publications-11-00035.pdf | [prose-12-01] The quoted abstract restricts the demonstration to the publisher-template corpus. Reading the methods and conclusion confirms that scope; it does not provide a calibrated arbitrary-pair classification error rate. Positive control: the text contains both "over 400" and the actual corpus description. - CONFIRMED | Spennemann and Singh reported in 2024 that Microsoft Word does not reliably follow the increasing-value rule. | https://ijdc.net/index.php/ijdc/article/download/870/685/3282 | [prose-12-02] The 2024 paper abstract says a newly assigned value "may be larger or smaller than any or all" previous values. The printed year is "2024, Vol. 18, Iss. 1". - CONFIRMED | This instrument never sorts RSIDs into a chronology. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-12-03] compareRsids at archive.mjs:716-721 constructs shared and private sets with filter; it does not infer time from numeric order. The rendered verdict says "No chronology is inferred from numeric order." - CONFIRMED | APPNOTE defines correspondence and record anatomy, but not one universal winner for contradictory generic ZIP records. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [prose-13-00] Read APPNOTE 4.3 and 4.4, including correspondence, descriptor exceptions and masking. No general conflict-winner rule is specified there. Exact searches for "universal winner" and "authoritative" give zero; the same case-insensitive search finds "central directory" 141 times and the expected 4.3.2 correspondence clause. This is a scoped reading of the specification, not a claim that no consumer chooses a winner. - CONFIRMED | A valid EOCD signature can occur inside comments or payload. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-14-00] parseZip searches signature candidates rather than treating the first occurrence as a record. The verifier constructs comment and wrong-signature cases. A four-byte signature can also be ordinary payload data; validation supplies the record meaning. - CONFIRMED | Candidates are accepted only after their bounds, comment, directory range, entry count, and header walk validate. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-14-01] candidateAt at archive.mjs:256-296 checks comment bounds, disk/count fields and directory ranges; walkCentral checks signatures and consumes the declared directory exactly. Invalid candidates enter rejectedCandidates. - CONFIRMED | CRC-32 checks accidental integrity against a stored 32-bit value. | https://www.rfc-editor.org/rfc/rfc2828.txt | [prose-15-00] RFC 2828 defines CRC as "not a cryptographic hash" and an integrity mechanism "where accidental changes to data are expected". APPNOTE 4.4.7 gives the four-byte CRC field. It is not an authentication or intent test. - CONFIRMED | It does not authenticate bytes or identify intent. | https://www.rfc-editor.org/rfc/rfc2828.txt | [prose-15-01] RFC 2828 defines CRC as "not a cryptographic hash" and an integrity mechanism "where accidental changes to data are expected". APPNOTE 4.4.7 gives the four-byte CRC field. It is not an authentication or intent test. - CONFIRMED | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-16-00] checkContents emits "NOT CHECKED: encrypted" or an unsupported-method reason; candidateAt refuses split/malformed directories; safeBig throws "ZIP64_TOO_LARGE". Baseline reaches "34 codes defined, 34 reached by a specimen". Refusal messages carry the relevant field/offset where one applies. - CONFIRMED | Relationship and content-type checks cover the OPC rules implemented here, not all of ECMA-376 or any product profile. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-17-00] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | RSIDs can collide, travel in templates, survive deleted content, arise from non-edit actions, or be changed deliberately. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [prose-18-00] Read all additional excerpts: ECMA 17.15.1.70 permits collisions and 17.15.1.72 limits the information to last-saved sessions; the 2023 abstract says RSIDs "remain logged" after associated text is removed; the 2024 abstract covers template inheritance and non-edit events, and its introduction discusses substituting RSIDs. These support the stated limits together, not the short primary excerpt alone. - CONFIRMED | They are not a full revision log. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [prose-18-01] Read all additional excerpts: ECMA 17.15.1.70 permits collisions and 17.15.1.72 limits the information to last-saved sessions; the 2023 abstract says RSIDs "remain logged" after associated text is removed; the 2024 abstract covers template inheritance and non-edit events, and its introduction discusses substituting RSIDs. These support the stated limits together, not the short primary excerpt alone. - CONFIRMED | 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. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-20-00] unreferencedLocals at archive.mjs:362-381 scans gaps outside claimed local/header/payload/descriptor ranges and before the central directory. A hit requires a complete local header inside the gap. The hidden-entry fixture produces one hit; the original fixture produces zero. - CONFIRMED | Compressed payload is never scanned, so a hidden entry stored inside another entry's data is not found. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-20-01] unreferencedLocals at archive.mjs:362-381 scans gaps outside claimed local/header/payload/descriptor ranges and before the central directory. A hit requires a complete local header inside the gap. The hidden-entry fixture produces one hit; the original fixture produces zero. - CONFIRMED | The same file supplied as both RSID specimens is reported as no linkage result. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-21-00] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | Every identifier would be shared by construction, and a document compared with itself carries no information about lineage. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-21-01] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | It records what this page's application code can observe. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-22-00] renderPrivacy reads performance resource entries and wrapper counters; it does not claim access to browser extensions or navigation instrumentation. The actual meta policy contains "connect-src 'none'"; W3C CSP3 defines connect-src for script-interface connections. The application upload path is absent from the inspected input/relationship handlers. - CONFIRMED | It does not cover browser extensions or the initial HTML request. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-22-01] renderPrivacy reads performance resource entries and wrapper counters; it does not claim access to browser extensions or navigation instrumentation. The actual meta policy contains "connect-src 'none'"; W3C CSP3 defines connect-src for script-interface connections. The application upload path is absent from the inspected input/relationship handlers. - CONFIRMED | The deployed policy above is read back from the document: checking. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-23-00] The source-record sentence includes the initial "checking" placeholder. On execution page.mjs:528 reads the meta element and replaces it with "connect-src none is present in the deployed meta policy". It is not a persistent completed-check result. - CONFIRMED | The parser has no upload path. connect-src 'none' blocks application connections even if a later edit accidentally tries one. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-23-01] renderPrivacy reads performance resource entries and wrapper counters; it does not claim access to browser extensions or navigation instrumentation. The actual meta policy contains "connect-src 'none'"; W3C CSP3 defines connect-src for script-interface connections. The application upload path is absent from the inspected input/relationship handlers. - CONFIRMED | The page does not identify which ZIP consumer is correct, predict how a named extractor resolves a conflict, or prove a mismatch malicious. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-24-00] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | It does not certify every rule of ZIP, OPC, OOXML, EPUB, JAR, APK, or an application profile. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-24-01] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | It does not execute macros or prove that two documents look the same. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-24-02] page.mjs:58 assigns "node.textContent = text"; the XML viewer at line 277 also uses textContent. Input inspection never opens relationship targets. Downloads use generated fixture Blobs, not extraction of the supplied archive. The input handlers do not store or execute file contents. - CONFIRMED | It does not turn RSIDs into authorship, timestamps, plagiarism, misconduct, or an unbroken edit history. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-24-03] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | The file input hard stop is 512 MiB. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-25-00] LIMITS.input is "512 * 1024 * 1024". page.mjs:535 compares f.size before calling arrayBuffer and names the 536870912-byte cap. - CONFIRMED | The central directory hard stop is 100000 entries. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-25-01] LIMITS.entries is "100000"; walkCentral throws TOO_MANY_ENTRIES if the declared count exceeds it. - CONFIRMED | Defaults and maxima are 32 MiB per inflated entry and 128 MiB total. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-25-02] LIMITS has "entryInflated: 32 * 1024 * 1024" and "totalInflated: 128 * 1024 * 1024". selectedOptions and checkContents both apply Math.min against those maxima. - CONFIRMED | Reader controls can lower the inflate caps but cannot raise them. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-25-04] LIMITS has "entryInflated: 32 * 1024 * 1024" and "totalInflated: 128 * 1024 * 1024". selectedOptions and checkContents both apply Math.min against those maxima. - CONFIRMED | There is no recursive archive opening. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-25-05] inspect processes only the submitted ZIP entries; checkContents produces bytes and auditOpc follows declarations without recursively opening nested archives. - CONFIRMED | Method 0 uses stored bytes. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-26-00] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | Method 8 first attempts the browser's raw DEFLATE stream and otherwise uses the bundled local decoder. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-26-01] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | Other methods and encryption retain metadata and receive NOT CHECKED. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-26-02] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | ZIP64 sentinels are resolved from tag 0x0001 in the prescribed field order, with raw values retained. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-26-03] resolveZip64 at archive.mjs:131-147 reads tag "0x0001" in order: uncompressed size, compressed size, local-header offset, disk start. APPNOTE 4.5.3 gives that order. Raw fields remain in the returned record. - CONFIRMED | No 64-bit value above Number.MAX_SAFE_INTEGER is converted. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-26-04] safeBig at archive.mjs:82 throws before Number(value) whenever value exceeds "BigInt(Number.MAX_SAFE_INTEGER)". The refusal suite reaches the large-value case. - CONFIRMED | Both boundaries are now tried and the one that validated is named in the free choices. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-28-03] candidateAt builds anchors for "ZIP64 EOCD record" and "EOCD record", tries valid offset bases, and renderChoices prints the selected directoryEndAnchor. The genuine ZIP64 fixture is 2341 bytes and chooses the ZIP64 anchor. - CONFIRMED | Recognition now requires that element to be the single document element, and the two recognition parts are decoded as strict UTF-8 rather than repaired with replacement characters. | public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-29-03] N2 confirmed that rootIs uses documentElement, scanXml rejects a second document element and stray outer character data, and xmlText uses "fatal: true". The six malformed recognition fixtures are refused. X1 now explicitly names the two recognition parts; the fixer re-read the same recognition path. - CONFIRMED | The count is now the number of distinct local headers, with duplicates reported separately. | public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-30-03] N2 confirmed that parseZip maps local offsets, returns "distinctLocals: firstAt.size" and counts duplicatePairings separately. The summary already did this correctly. X10 now repairs the separate completion status as well; the fixer reproduced the two-record, one-header case. - CONFIRMED | It is replaced by a search for complete local headers in unclassified bytes that the directory never mentions, which is the case where an index hides a real entry from an index reader. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [prose-31-02] unreferencedLocals at archive.mjs:362-381 scans gaps outside claimed local/header/payload/descriptor ranges and before the central directory. A hit requires a complete local header inside the gap. The hidden-entry fixture produces one hit; the original fixture produces zero. - CONFIRMED | Those two settings are now named and refused, because the second compares a document with itself. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [prose-32-02] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | PKWARE, Inc. (2022), APPNOTE.TXT, version 6.3.10. Sections 4.3.1 to 4.3.16, 4.4.4, 4.4.7 to 4.4.9, 4.5.3, and Appendix D. Used for generic ZIP signatures, layouts, little-endian integers, flags, descriptors, CRC conditioning, ZIP64, and filenames. Source address: pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [citation-1] APPNOTE header: "Version: 6.3.10", "Status: FINAL", "Revised: Nov 01, 2022". The named record, bit-flag, CRC, ZIP64 and filename sections are present and were read. - CONFIRMED | Ecma International (2021), ECMA-376 Part 2, fifth edition. Clauses 5, 6.5, 7.3 and normative Annex B, especially B.2, B.3, and Table B.5. Used for OPC recognition, names, relationships, ZIP restrictions, copied-field equality, and the bit 3 exception. Part 2 normatively cites APPNOTE 6.2.0; current 6.3.10 is used here for compatible generic ZIP anatomy, not substituted as the normative OPC baseline. | https://ecma-international.org/publications-and-standards/standards/ecma-376/ | [citation-2] The Ecma publication page identifies Part 2, fifth edition, December 2021. The downloaded standard contains clauses 5, 6.5, 7.3 and normative Annex B, including B.2/B.3/Table B.5. Its normative references expressly name APPNOTE 6.2.0. - CONFIRMED | Ecma International (2016), ECMA-376 Part 1, fifth edition. Sections 17.15.1.70 to 17.15.1.72. Used for rsid, rsidRoot, rsids, and same-root session semantics. | https://ecma-international.org/publications-and-standards/standards/ecma-376/ | [citation-3] The Ecma publication page identifies Part 1, fifth edition, December 2016. Read printed pp. 1059-1062 in the downloaded PDF: 17.15.1.70 rsid, 17.15.1.71 rsidRoot, and 17.15.1.72 rsids. - CONFIRMED | Dirk H. R. Spennemann and Rudolf J. Spennemann (2023). “Establishing Genealogies of Born Digital Content: The Suitability of Revision Identifier (RSID) Numbers in MS Word for Forensic Enquiry,” Publications 11(3), article 35. DOI: 10.3390/publications11030035. | https://mdpi-res.com/d_attachment/publications/publications-11-00035/article_deploy/publications-11-00035.pdf | [citation-4] The PDF names "Dirk H. R. Spennemann" and "Rudolf J. Spennemann" and the cited title, Publications 2023, 11, 35. Crossref independently gives both names, year 2023, volume 11, issue 3. The online tool's initial-H MISMATCH is a regex false positive, not a bad citation. - CONFIRMED | Archive Fork A.docx and Archive Fork B.docx are deterministic minimal WordprocessingML packages generated from first principles by archive.mjs for this page. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/README.md | [prose-38-00] fixtureFiles and makeFixture at archive.mjs:748-762 generate five fixed XML parts using branch IDs 10000003/10000004, fixed DOS fields and the literal "Archive Fork " + branch + " is a synthetic CC0 fixture." installDownloads creates Blobs from those same bytes. The independent reader confirms their bytes and CRCs. - CONFIRMED | Their five XML parts contain only original fixture text and synthetic identifiers. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/README.md | [prose-38-01] fixtureFiles and makeFixture at archive.mjs:748-762 generate five fixed XML parts using branch IDs 10000003/10000004, fixed DOS fields and the literal "Archive Fork " + branch + " is a synthetic CC0 fixture." installDownloads creates Blobs from those same bytes. The independent reader confirms their bytes and CRCs. - CONFIRMED | The fixtures and generator are dedicated to the public domain under CC0-1.0. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/README.md | [prose-38-02] The committed research README explicitly states: "The packages and their generator are dedicated to the public domain under CC0-1.0." This is the author's dedication for the generated fixtures. - CONFIRMED | Saving either fixture creates the exact bytes audited above. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/README.md | [prose-38-03] fixtureFiles and makeFixture at archive.mjs:748-762 generate five fixed XML parts using branch IDs 10000003/10000004, fixed DOS fields and the literal "Archive Fork " + branch + " is a synthetic CC0 fixture." installDownloads creates Blobs from those same bytes. The independent reader confirms their bytes and CRCs. - CONFIRMED | The offline verifier is at research/the-archive-that-disagrees-with-itself/verify-the-archive-that-disagrees-with-itself.mjs. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/verify-the-archive-that-disagrees-with-itself.mjs | [prose-39-00] The public verifier URL returned HTTP 200 and 53239 bytes, identical to the pinned script. It is available to read, as the page promises. - CONFIRMED | This layer's check imports and runs the very module this page runs. | git show a77c45dd68:research/the-archive-that-disagrees-with-itself/verify-the-archive-that-disagrees-with-itself.mjs | [prose-40-00] The verifier imports from "../../public/strata/the-archive-that-disagrees-with-itself/archive.mjs" and later imports page.mjs under the DOM harness. The page imports the same archive.mjs. - CONFIRMED | It is published to read. | git show a77c45dd68:public/checks/manifest.json | [prose-40-02] The public verifier URL returned HTTP 200 and 53239 bytes, identical to the pinned script. It is available to read, as the page promises. - CONFIRMED | Running it needs the repository around it. | git show a77c45dd68:public/checks/manifest.json | [prose-40-03] Reader recreation in an empty directory exits 1 with "ERR_MODULE_NOT_FOUND" for archive.mjs. The manifest says two additional read dependencies cannot be published through /checks/. This corroborates the page's explicit repository requirement; it is not an undisclosed runnable-download promise. - CONFIRMED | the published bit 3 rule requires three local zeros | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [bit3-three-local-zeros] APPNOTE 4.4.4: "the fields crc-32, compressed size and uncompressed size are set to zero in the local header." The record includes this as an additional excerpt for prose-00-03. Generic conflict handling is a reader policy, not an APPNOTE universal priority rule. - CONFIRMED | A part encoded in UTF-16 is legal XML | https://www.w3.org/TR/REC-xml/ | [utf16-legal] W3C XML 1.0: "All XML processors MUST accept the UTF-8 and UTF-16 encodings of Unicode". This establishes legality; it does not establish the page's recognition behavior. - CONFIRMED | connect-src 'none' blocks application connections even if a later edit accidentally tries one. | https://www.w3.org/TR/CSP3/ | [csp-connections] W3C CSP3: "The connect-src directive restricts the URLs which can be loaded using script interfaces." The deployed meta sets its source list to none. This does not cover all resource loading, but it does cover the application connection interfaces meant here. - CONFIRMED | RSIDs can collide | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [rsid-collision] ECMA 17.15.1.70 explicitly says "it is possible for two independent sessions to result in the same value". The page makes no numerical collision-rate claim. - CONFIRMED | travel in templates | https://ijdc.net/index.php/ijdc/article/download/870/685/3282 | [rsid-templates] The 2024 abstract says template roots "will be embedded as legacy Rsid into every new file generated from that template file". - CONFIRMED | survive deleted content | https://mdpi-res.com/d_attachment/publications/publications-11-00035/article_deploy/publications-11-00035.pdf | [rsid-deleted] The 2023 abstract: "These RSIDs remain logged in the metadata even if the text with which they were associated has been removed." - CONFIRMED | arise from non-edit actions | https://ijdc.net/index.php/ijdc/article/download/870/685/3282 | [rsid-non-edit] The 2024 abstract gives a new Rsid on saving as rtf or emailing from Word "although the file was not edited in any way". - CONFIRMED | or be changed deliberately | https://ijdc.net/index.php/ijdc/article/download/870/685/3282 | [rsid-edited] The 2024 introduction describes "substituting the automatically allocated Rsid numbers" and deliberate false correlations. The copied excerpt supports deliberate editing directly. - CONFIRMED | Matching roots and session values are consistent with shared document history. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [limitation-0] ECMA-376 Part 1, 17.15.1.70, pp. 1059-1060: "An identical rsid value between two documents with the same rsidRoot" indicates the same sessions; meanings across different roots are not defined. The surrounding note expressly permits independent collisions. These are qualified linkage semantics, not an identity proof. - CONFIRMED | They do not prove a person, author, device, time, exact save order, fork direction, plagiarism, misconduct, or even that the values were not copied or deliberately edited. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [limitation-1] Read all additional excerpts: ECMA 17.15.1.70 permits collisions and 17.15.1.72 limits the information to last-saved sessions; the 2023 abstract says RSIDs "remain logged" after associated text is removed; the 2024 abstract covers template inheritance and non-edit events, and its introduction discusses substituting RSIDs. These support the stated limits together, not the short primary excerpt alone. - CONFIRMED | A different root makes this page's comparison undefined. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [limitation-2] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | It does not prove unrelatedness. | https://ecma-international.org/wp-content/uploads/ECMA-376-1_5th_edition_december_2016.zip | [limitation-3] ECMA-376 Part 1, 17.15.1.70, pp. 1059-1060: "An identical rsid value between two documents with the same rsidRoot" indicates the same sessions; meanings across different roots are not defined. The surrounding note expressly permits independent collisions. These are qualified linkage semantics, not an identity proof. - CONFIRMED | A ZIP stores a central directory and paired local file headers. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [front-dek-0] APPNOTE 4.3.1 says "only one" end record; 4.3.2 says each file "MUST be preceded by" a local header with a corresponding central header. - CONFIRMED | Drop your own ZIP, Office document, EPUB, JAR, or APK to compare every copied field locally. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [front-dek-1] page.mjs:537 reads "new Uint8Array(await f.arrayBuffer())"; loadBytes calls inspect locally. No application network API is invoked by this path. CSP and the zero application-send counters corroborate it. - CONFIRMED | Bit 3 zeros are classified as the required data-descriptor exception, generic ZIP differences receive no universal winner, and only recognized OPC packages receive an ECMA-376 Annex B.2 verdict. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [front-dek-2] page.mjs:187 gates the verdict on "parsed.opc.recognized"; otherwise it prints "GENERIC ZIP VIEW." archive.mjs:849 assigns "NOT AN OPC VERDICT" when recognition fails. A filename extension alone does not select this branch. - CONFIRMED | A ZIP repeats facts about each file in its central directory and in a local header beside the file. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [front-plain-0] The recorded excerpt establishes correspondence, not the repeated field list. Read APPNOTE 4.3.7 and 4.3.12 directly: both list "general purpose bit flag", "compression method", "crc-32", and both sizes. - CONFIRMED | Bring one of your own and this page checks the copies without uploading anything, while separating a permitted data-descriptor difference from a real unexplained conflict. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [front-plain-1] page.mjs:537 reads "new Uint8Array(await f.arrayBuffer())"; loadBytes calls inspect locally. No application network API is invoked by this path. CSP and the zero application-send counters corroborate it. - CONFIRMED | The complete instrument lives at the immersive page linked above. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [markdown-body-0] Frontmatter href is "/strata/the-archive-that-disagrees-with-itself/". Curl returned HTTP 200 and the complete pinned article text. - CONFIRMED | It reads the reader's whole file locally, reproduces the published bit 3 exception on two CC0 fixtures, audits recognized OPC structure, and keeps every refusal and free choice in the visible check. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [markdown-body-1] The input, fixture, OPC and refusal paths are implemented in the inspected modules. Recreated "rendered: anchor 15/15 pass; live 55/55 live checks pass; notes 0". Refusals and choices are displayed; this does not mean the live panel reaches every one of the 34 offline refusal codes. - CONFIRMED | Both layers make a file carry the argument instead of merely illustrating it. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-0-0] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | The Boolean Pythagorean layer asks whether a proof certificate survives a checker and makes a broken line refuse. | git show a77c45dd68:src/content/strata/boolean-pythagorean.md | [relation-0-1] The linked Boolean Pythagorean frontmatter says "sabotage a miniature proof to watch the checker reject it" and describes the four proof lines. This supports what the relation says that page asks the reader to do. - CONFIRMED | In each case the refusal path is evidence, not an error screen, and the limits of what a valid file proves stay beside the pass count. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-0-3] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | This archive instrument is built as a worked answer to that layer's central objection. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-1-0] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | Re-parsing a cooperative fixture would be easy to make vacuous, so the visible check also mutates a local filename and a central CRC, constructs truncated and lying-length inputs, and requires exact refusal codes. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-1-1] The local-name and central-CRC failures, truncated file and lying-length refusals were recreated. Baseline "PASS 344/344" includes both independent byte parsing and the rendered negative controls. - CONFIRMED | The two pages belong together because a parser that can only congratulate valid input has not yet demonstrated that it knows the rule it claims to enforce. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-1-2] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | Two investigations of the distance between filesystem language and stored bytes. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-2-0] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | The deletion layer shows that removing a directory entry is not the same act as destroying the data it named. | git show a77c45dd68:src/content/strata/does-emptying-the-trash-delete-files.md | [relation-2-1] The linked deletion page says "It removes the directory entry and marks the blocks free" and distinguishes that action from overwriting bytes. The relation only makes that distinction. - CONFIRMED | This layer shows that even inside one archive the directory and the record beside the data can state different facts. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-2-2] The local-name and central-CRC failures, truncated file and lying-length refusals were recreated. Baseline "PASS 344/344" includes both independent byte parsing and the rendered negative controls. - CONFIRMED | Both refuse the convenient fiction that a name or index is identical to the underlying bytes, but only this page can let the reader bring the disputed file itself. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-2-3] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | The connection is genealogy with its evidential floor kept visible. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-3-0] These are comparative interpretations of the linked instruments, not additional attributed measurements. The inspected page and linked frontmatter describe an operative file/checker, explicit refusal outcomes and limits; those are the factual premises of the comparison. - CONFIRMED | Everyone, or No One derives what a human pedigree must do when branches fold and then separates genealogical ancestry from genetic inheritance. | git show a77c45dd68:src/content/strata/everyone-or-no-one.md | [relation-3-1] The linked genealogy dek says "the tree is not a tree, it is a net that folds" and explicitly distinguishes "a genealogical ancestor" from "a genetic one". These are the two described subjects of that page. - CONFIRMED | This layer uses Word revision identifiers as a much narrower document-lineage signal, and likewise refuses to turn relatedness into identity: shared roots and sessions can be consistent with common history without establishing author, time, fork direction, plagiarism, or misconduct. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [relation-3-2] The code performs a limited ZIP/OPC audit and unordered RSID comparison. It contains no implementation of product acceptance, document rendering, chronology or authorship inference. Its result says "Implemented OPC checks pass. This is not a product acceptance certificate." The stated limits agree with the inspected operations. - CONFIRMED | Compare a ZIP's central directory with its paired local file headers on your own device. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [social-0-0] page.mjs:537 reads "new Uint8Array(await f.arrayBuffer())"; loadBytes calls inspect locally. No application network API is invoked by this path. CSP and the zero application-send counters corroborate it. - CONFIRMED | The instrument recognizes the bit 3 exception, reserves conformance verdicts for OPC, and never names a universal winner for a generic ZIP conflict. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [social-0-1] page.mjs:187 gates the verdict on "parsed.opc.recognized"; otherwise it prints "GENERIC ZIP VIEW." archive.mjs:849 assigns "NOT AN OPC VERDICT" when recognition fails. A filename extension alone does not select this branch. - CONFIRMED | Drop a ZIP-family file and compare every central record with its paired local header, with the permitted data-descriptor exception handled first. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [social-1-0] page.mjs:537 reads "new Uint8Array(await f.arrayBuffer())"; loadBytes calls inspect locally. No application network API is invoked by this path. CSP and the zero application-send counters corroborate it. - CONFIRMED | Off by default. When on, search the last 8 MiB and report every trailing byte. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [trailing-control] The HTML checkbox is initially unchecked. parseZip selects "8 * 1024 * 1024" as the recovery search window when allowTrailing is enabled and computes trailingBytes from the candidate record end. - CONFIRMED | Optional. The digest is computed with the browser's local cryptography API. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [digest-control] digest at page.mjs:89-93 calls "crypto.subtle.digest('SHA-256', bytes)". selectedOptions does not make it a network operation, and it runs only when the digest control is selected. - CONFIRMED | No specimen held. The last file was refused before any bytes were read. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-0] page.mjs:103-149 and the file handlers explicitly clear current/second parsed state on refusals and hide invalid previous results. The truncated-input probe prints "REFUSED: TRUNCATED_FILE" and "previous results hidden: true". - CONFIRMED | Complete. Local SHA-256 computed without a network call. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-1] page.mjs:119-122 awaits the local digest before setting this completion message; the hash input is the selected bytes. No network call appears in digest(). - CONFIRMED | The directory and the local records do not describe the same set of entries. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-2] renderResult at page.mjs:177 prints this when duplicatePairings or unreferenced local headers are present. The duplicate fixture has two central records, one distinct referenced local header, and a second unreferenced local header; the hidden-entry fixture also demonstrates a different local/index set. - CONFIRMED | A front-walking or streaming reader can reach that item; an index reader cannot. | https://commons.apache.org/proper/commons-compress/zip.html | [alternate-4] Apache Commons Compress documents the stream/index distinction: "ZipFile is able to read the central directory first"; ZipArchiveInputStream "may return entries that are not part of the central directory at all". Its documented descriptor and self-extracting limitations support the distinction. The page does not identify a particular extractor as careful or predict its choice. - CONFIRMED | OPC RECOGNIZED. ECMA-376 Annex B.2 FAIL or another implemented OPC rule failed. The exact rows are below. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-5] renderResult and renderOpc branch on recognized and opcVerdict. The original fixture gives PASS, paired-field mutations give FAIL, and malformed recognition XML gives "NOT AN OPC VERDICT" with the generic ZIP label. - CONFIRMED | GENERIC ZIP VIEW. Unexplained differences are reported, but this page issues no OPC conformance verdict and appoints no universal winner. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-6] renderResult and renderOpc branch on recognized and opcVerdict. The original fixture gives PASS, paired-field mutations give FAIL, and malformed recognition XML gives "NOT AN OPC VERDICT" with the generic ZIP label. - CONFIRMED | No OPC verdict. Recognition requires safely decoded [Content_Types].xml and _rels/.rels roots in their published package namespaces. The filename is not used. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-7] renderResult and renderOpc branch on recognized and opcVerdict. The original fixture gives PASS, paired-field mutations give FAIL, and malformed recognition XML gives "NOT AN OPC VERDICT" with the generic ZIP label. - CONFIRMED | NO LINKAGE RESULT. The two specimens are the same bytes, so every identifier is shared by construction and the comparison is a document against itself. Supply a different second document for this instrument to say anything. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-8] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | DEFINED BUT NO LINKAGE EVIDENCE. The roots match, so the standard permits the comparison, but the two settings parts share no session identifier. A matching root alone is not a linkage signal, and it is not evidence of unrelatedness either. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-9] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | No comparison. The second file was refused, so there is no second RSID set to intersect. The previous result has been cleared rather than left on screen. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-10] page.mjs:103-149 and the file handlers explicitly clear current/second parsed state on refusals and hide invalid previous results. The truncated-input probe prints "REFUSED: TRUNCATED_FILE" and "previous results hidden: true". - CONFIRMED | No comparison. The first specimen was refused, so there is no first RSID set to intersect. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-11] page.mjs:103-149 and the file handlers explicitly clear current/second parsed state on refusals and hide invalid previous results. The truncated-input probe prints "REFUSED: TRUNCATED_FILE" and "previous results hidden: true". - CONFIRMED | The second reader handles only the plain 32-bit shape with no comment and no prepended base, so it does not apply to this specimen. The parser result below is not cross-read. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-12] independentRead at page.mjs:295-315 requires a plain trailing 22-byte EOCD, zero comment, direct central offset and matching directory end. Unsupported shapes return null and are labelled not cross-read, rather than claimed verified by the second reader. - CONFIRMED | Refused before allocation. No bytes were read, and every panel below now describes this refusal rather than the previous specimen. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-13] page.mjs:103-149 and the file handlers explicitly clear current/second parsed state on refusals and hide invalid previous results. The truncated-input probe prints "REFUSED: TRUNCATED_FILE" and "previous results hidden: true". - CONFIRMED | comparison undefined: one or both rsidRoot values are missing | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [alternate-14] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | NOT CHECKED: declared size exceeds entry cap | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [alternate-15] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | NOT CHECKED: stored bytes exceed remaining inflate cap | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [alternate-16] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | NOT CHECKED: total cap reached | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [alternate-17] archive.mjs:503-521 skips encryption/caps, copies STORE bytes, tries "inflateNative(compressed, remaining) || inflateRawJs(compressed, remaining)" for method 8, and labels other methods NOT CHECKED. APPNOTE 4.4.5 independently identifies methods 0 and 8. - CONFIRMED | connect-src none is missing | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-18] renderPrivacy at page.mjs:528 selects this exact message if the inspected meta string lacks the connect-src none directive. The actual pinned meta gives the positive branch, also observed in the harness. - CONFIRMED | Central 0x7075 path accepted after its CRC over raw name bytes matched. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/page.mjs | [alternate-19] unicodePath at archive.mjs:120-128 checks version 1, the CRC of raw filename bytes and strict UTF-8 decoding before returning valid=true. The acceptance message is gated on that valid result. - CONFIRMED | 0x7075 name CRC does not match raw filename bytes | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-0] unicodePath at archive.mjs:126 produces this reason only when "storedCrc !== actualCrc". A valid CRC is the positive branch. - CONFIRMED | disk start uses a ZIP64 sentinel without a 4-byte replacement | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-1] resolveZip64 at archive.mjs:143-145 checks diskStartRaw==0xffff and refuses when the 0x0001 block has fewer than four replacement bytes. The refusal suite reaches MISSING_ZIP64_DISK. - CONFIRMED | EOCD uses a ZIP64 sentinel, but no 0x07064b50 locator begins 20 bytes before it | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-2] zip64Eocd at archive.mjs:244 checks the locator signature at eocdAt-20 and emits this exact reason if it is absent. The genuine ZIP64 positive control parses; removing its locator is refused. - CONFIRMED | split archives are metadata-only and are not opened | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-3] zip64Eocd refuses nonzero disks, a locator disk count other than one, or unequal on-disk/total counts with MULTI_DISK. The message describes the split shape; the implementation refuses to open it. - CONFIRMED | ZIP64 EOCD describes more than one disk | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-4] zip64Eocd refuses nonzero disks, a locator disk count other than one, or unequal on-disk/total counts with MULTI_DISK. The message describes the split shape; the implementation refuses to open it. - CONFIRMED | No offset basis ended at the central directory boundary. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-5] candidateAt at archive.mjs:290-293 uses this fallback reason only when no validated trial has start+centralSize equal to the directory anchor. The genuine ordinary and ZIP64 controls validate their boundaries. - CONFIRMED | code 16 appears before a code length | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-6] inflateRawJs at archive.mjs:456 throws DEFLATE_REPEAT for code 16 when "!lens.length". The offline corruption sweep reaches that exact code. - CONFIRMED | dynamic Huffman lengths overrun their declared count | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-7] inflateRawJs at archive.mjs:459 throws DEFLATE_CODE_LENGTHS when "lens.length > hlit + hdist". The offline sweep reaches this code as well. - CONFIRMED | XML has more than one document element; a second begins at character | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-8] scanXml at archive.mjs:574 throws this when a new top-level element increments roots above one. The two-root control reaches the message. - CONFIRMED | XML contains no document element | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-9] scanXml at archive.mjs:587 checks "if (!roots)" and throws this message; a single valid document element is accepted. - CONFIRMED | part bytes are not valid UTF-8, and this page decodes XML parts as strict UTF-8 only | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-10] xmlText at archive.mjs:600-602 catches failure of new TextDecoder("utf-8", {fatal:true}). The malformed-UTF-8 positive/negative probes exercise this condition. - CONFIRMED | [Content_Types].xml document element is not Types in the content-types namespace | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-11] auditOpc at archive.mjs:637-638 tests documentElement local name and namespace with rootIs, not the presence of a nested element. The valid fixture is accepted; the buried-root fixture is refused. - CONFIRMED | _rels/.rels document element is not Relationships in the relationships namespace | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-12] auditOpc at archive.mjs:637-638 tests documentElement local name and namespace with rootIs, not the presence of a nested element. The valid fixture is accepted; the buried-root fixture is refused. - CONFIRMED | no content type resolves for package part: | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-14] auditOpc at archive.mjs:648-650 resolves an Override or extension Default and emits this message when neither produces a type. The extra invalid-name probe exercises it; the original fixture resolves all five. - CONFIRMED | relationship part document element is not Relationships in the relationships namespace: | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-15] archive.mjs:678 checks rootIs(nodes,"Relationships",NS_REL) after decoding each relationship part and emits this diagnostic for a different root/namespace. - CONFIRMED | Word main document or settings part was not safely decoded | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-16] archive.mjs:693-694 checks existence and decoded content of both selected main and settings entries before accessing them. Missing/unchecked selected parts enter this branch. - CONFIRMED | the main part document element is not w:document in the strict or transitional WordprocessingML namespace | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-17] archive.mjs:699-700 checks the main document element is named document and has either the strict or transitional Word namespace before assigning a Word namespace result. - CONFIRMED | comparison undefined: rsidRoot values differ | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-18] compareRsids refuses missing/different roots. page.mjs:367 uses sameBytes for self-comparison; rsidVerdict at lines 285-288 explicitly distinguishes "NO LINKAGE RESULT", "DEFINED BUT NO LINKAGE EVIDENCE", and a shared-session signal. This is the instrument's conservative reporting policy. - CONFIRMED | the demonstration needs at least one entry with a nonempty local filename | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-19] mutateLocalName and mutateCentralCrc at archive.mjs:827-840 throw these reasons when the chosen mutation has no filename or central entry. The ordinary five-entry fixture is the positive control and both mutation paths are reached by the verifier. - CONFIRMED | the demonstration needs at least one central entry | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [diagnostic-20] mutateLocalName and mutateCentralCrc at archive.mjs:827-840 throw these reasons when the chosen mutation has no filename or central entry. The ordinary five-entry fixture is the positive control and both mutation paths are reached by the verifier. - CONFIRMED | A ZIP64 archive puts its ZIP64 EOCD and locator between the directory and the EOCD. | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [zip64-record-order] APPNOTE 4.3.6 gives the order central directory, "zip64 end of central directory record", "zip64 end of central directory locator", and "end of central directory record". - CONFIRMED | the printed catalogue check value CRC-32("123456789") recomputes to 0xcbf43926 | https://reveng.sourceforge.io/crc-catalogue/17plus.htm | [crc-catalogue-value] The CRC RevEng ISO-HDLC catalogue prints "check=0xcbf43926" and aliases PKZIP. The pinned CRC implementation and independent bitwise calculation both reproduce it for "123456789". - CONFIRMED | a message followed by its stored CRC leaves the single APPNOTE 4.4.7 residual 0xdebb20e3 | https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT | [crc-appnote-residual] APPNOTE 4.4.7 prints "0xdebb20e3" with all-ones preconditioning and complement postconditioning. crcResidual checks the uncomplemented residual after appending the stored little-endian CRC; the live run checks 302 messages and the independent offline run 514. - CONFIRMED | Both let an archive fail a structural audit before interpretation begins. | git show a77c45dd68:src/content/strata/darwin-had-no-global-clock.md | [nearby-darwin] The Darwin layer describes a structural prerequisite audit and says "The target refuses to run." This ZIP layer similarly detects missing/duplicate pairing before interpretation. The relation does not import the Darwin page's numerical claims. - CONFIRMED | Archive Fork A is a synthetic CC0 fixture. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [fixture-text-A] fixtureFiles and makeFixture at archive.mjs:748-762 generate five fixed XML parts using branch IDs 10000003/10000004, fixed DOS fields and the literal "Archive Fork " + branch + " is a synthetic CC0 fixture." installDownloads creates Blobs from those same bytes. The independent reader confirms their bytes and CRCs. - CONFIRMED | Archive Fork B is a synthetic CC0 fixture. | git show a77c45dd68:public/strata/the-archive-that-disagrees-with-itself/archive.mjs | [fixture-text-B] fixtureFiles and makeFixture at archive.mjs:748-762 generate five fixed XML parts using branch IDs 10000003/10000004, fixed DOS fields and the literal "Archive Fork " + branch + " is a synthetic CC0 fixture." installDownloads creates Blobs from those same bytes. The independent reader confirms their bytes and CRCs. - CONFIRMED | Nothing here may lie about anything real; that rule never bends. | git show a77c45dd68:WAKE.md | [shared-widget-1-0] WAKE.md: "It must never lie about anything real." This is the stated operating rule, not a claim that every existing page has already passed an exhaustive audit. - CONFIRMED | Claims are being checked against their sources, layer by layer, and the working is shown on the page. | git show a77c45dd68:assay/README.md | [shared-widget-1-1] assay/README.md describes per-layer records and source checks and instructs: "add a dated Corrected YYYY-MM-DD" line for false claims or "Updated YYYY-MM-DD" for stale claims. These sentences describe the stated checking/correction process. - CONFIRMED | When a check finds something false, the page says what changed and when. | git show a77c45dd68:assay/README.md | [shared-widget-1-2] assay/README.md describes per-layer records and source checks and instructs: "add a dated Corrected YYYY-MM-DD" line for false claims or "Updated YYYY-MM-DD" for stale claims. These sentences describe the stated checking/correction process. ## Findings - [fixed] X1 (recognition-scans-every-xml-part): Scoped recognition to the two recognition parts in index.html and the README, and named the later relationship/Word scan scope. Added and mirrored a Corrected line. - [fixed] X2 (utf16-always-means-generic-zip): Replaced the universal UTF-16 generic-ZIP outcome with the recognition, later-scan and unscanned-part outcomes. Added and mirrored a Corrected line. - [fixed] X3 (xml-limits-applied-to-every-part): Scoped the 1000-part cap to relationship XML and the 10 MiB cap to scanned parts; labelled depth 128 unused. Corrected the verifier's hard-limit description. Added and mirrored a Corrected line. Review repair: the rendered free-choice ledger also now labels 128 an unused declaration. Replaced the damaged code quotation in the X3 evidence with an unquoted description of the source condition. - [fixed] X4 (zip64-gap-always-76-bytes): Qualified the historical ZIP64 directory error as at least 76 bytes. The minimum is 56 fixed EOCD bytes plus the 20-byte locator in APPNOTE 4.3.14-4.3.15. MINOR: no page correction line; historical log unchanged. - [fixed] X5 (singh-given-name-spelling): Changed Claire L. Singh to Clare L. Singh in the HTML citation and layer README, following the PDF title page. MINOR: no page correction line. - [fixed] X6 (opc-reference-excerpt-mismatch): Replaced the unrelated W3C excerpt in N1-sources.json with the exact ZIP Appnote normative-reference entry and corrected its printed page to 3. The page's APPNOTE 6.2.0 claim remains true and unchanged. MINOR: no page correction line. - [fixed] X7 (pairing-policy-attributed-to-appnote): Named duplicate-pairing rejection as this checker's policy in the rendered explanation, parser diagnostic and code comment. Distinct-header counting is unchanged. MINOR: no page correction line. - [fixed] X8 (utf8-warning-invents-set-flag): Replaced the false flag assertion with a diagnostic about invalid UTF-8 under the selected decoding. Covered flags 0 and 2048 and a CP437 control. Raised from checker MINOR to WRONG on the stored-byte counterexample. Added and mirrored a Corrected line. - [dated] X9 (stale-jsonld-modification-date): Set JSON-LD dateModified to 2026-10-18T00:00:00Z, retaining datePublished. This is the explicit metadata exception: decision fix with no Updated line. The [dated] disposition accounts for the STALE claim in the gate. - [fixed] X10 (status-counts-central-records-as-local-headers): Changed the completion status to count currentParsed.distinctLocals and label distinct local headers, with singular grammar for one. Covered normal 5/5 and duplicate 2/1 inputs. Added and mirrored a Corrected line. - [fixed] X11 (anchor-number-check-is-unscoped): Replaced global bare-number substring matches with extraction of the six signature and fixed-length figures from their own paragraph. This repairs the additional N2 finding omitted from the original triage. MINOR: no page correction line.